/*
 * ft1000_proc.c - ft1000 proc interface
 *
 * Copyright	(C) 2009-2010 Quintec
 *		(C) 2010 Open-nandra
 *      <marek.belisko@open-nandra.com>
 *
 * This file is subject to the terms and conditions of the GNU General
 * Public License. See the file "COPYING" in the main directory of this
 * archive for more details.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/netdevice.h>


#include "ft1000_usb.h"

#define FT1000_PROC_DIR "ft1000"


#define seq_putx(m, message, size, var) \
	seq_printf(m, message);	\
	for(i = 0; i < (size - 1); i++) \
		seq_printf(m, "%02x:", var[i]); \
	seq_printf(m, "%02x\n", var[i])

#define seq_putd(m, message, size, var) \
	seq_printf(m, message); \
	for(i = 0; i < (size - 1); i++) \
		seq_printf(m, "%d.", var[i]); \
	seq_printf(m, "%d\n", var[i])


#define FTNET_PROC init_net.proc_net


int ft1000_read_dpram16 (struct ft1000_usb *ft1000dev, u16 indx,
			 u8 *buffer, u8 highlow);


static int ft1000ReadProc(struct seq_file *m, void *v)
{
	static const char *status[] = { 
		"Idle (Disconnect)", 
		"Searching",
		"Active (Connected)",
		"Waiting for L2",
		"Sleep",
		"No Coverage",
		"",
		"",
	};
	static const char *signal[] = { "", "*", "**", "***", "****" };

	struct net_device *dev = m->private;
	struct ft1000_info *info = netdev_priv(dev);
	int i;
	unsigned short ledStat;
	unsigned short conStat;
	int strength;
	int quality;
	struct timeval tv;
	time_t delta;

	if (info->ProgConStat != 0xFF) {
		ft1000_read_dpram16(info->priv, FT1000_MAG_DSP_LED,
			   (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX);
		info->LedStat = ntohs(ledStat);

		ft1000_read_dpram16(info->priv, FT1000_MAG_DSP_CON_STATE,
			(u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX);
		info->ConStat = ntohs(conStat);
		do_gettimeofday(&tv);
		delta = (tv.tv_sec - info->ConTm);
	} else {
		info->ConStat = 0xf;
		delta = 0;
	}

	i = (info->LedStat) & 0xf;
	switch (i) {
	case 0x1:
		strength = 1;
		break;
	case 0x3:
		strength = 2;
		break;
	case 0x7:
		strength = 3;
		break;
	case 0xf:
		strength = 4;
		break;
	default:
		strength = 0;
	}

	i = (info->LedStat >> 8) & 0xf;
	switch (i) {
	case 0x1:
		quality = 1;
		break;
	case 0x3:
		quality = 2;
		break;
	case 0x7:
		quality = 3;
		break;
	case 0xf:
		quality = 4;
		break;
	default:
		quality = 0;
	}

	seq_printf(m, "Connection Time: %02ld:%02ld:%02ld\n",
      		((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60));
	seq_printf(m, "Connection Time[s]: %ld\n", delta);
	seq_printf(m, "Asic ID: %s\n",
      	(info->AsicID) == ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC");
	seq_putx(m, "SKU: ", SKUSZ, info->Sku);
	seq_putx(m, "EUI64: ", EUISZ, info->eui64);
	seq_putd(m, "DSP version number: ", DSPVERSZ, info->DspVer);
	seq_putx(m, "Hardware Serial Number: ", HWSERNUMSZ, info->HwSerNum);
	seq_putx(m, "Caliberation Version: ", CALVERSZ, info->RfCalVer);
	seq_putd(m, "Caliberation Date: ", CALDATESZ, info->RfCalDate);
	seq_printf(m, "Media State: %s\n", (info->mediastate) ? "link" : "no link");
	seq_printf(m, "Connection Status: %s\n", status[info->ConStat & 0x7]);
	seq_printf(m, "RX packets: %ld\n", info->stats.rx_packets);
	seq_printf(m, "TX packets: %ld\n", info->stats.tx_packets);
	seq_printf(m, "RX bytes: %ld\n", info->stats.rx_bytes);
	seq_printf(m, "TX bytes: %ld\n", info->stats.tx_bytes);
	seq_printf(m, "Signal Strength: %s\n", signal[strength]);
	seq_printf(m, "Signal Quality: %s\n", signal[quality]);
	return 0;
}

/*
 * seq_file wrappers for procfile show routines.
 */
static int ft1000_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, ft1000ReadProc, PDE_DATA(inode));
}

static const struct file_operations ft1000_proc_fops = {
	.open		= ft1000_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static int
ft1000NotifyProc(struct notifier_block *this, unsigned long event, void *ptr)
{
	struct net_device *dev = ptr;
	struct ft1000_info *info;
	struct proc_dir_entry *ft1000_proc_file;

	info = netdev_priv(dev);

	switch (event) {
	case NETDEV_CHANGENAME:
		remove_proc_entry(info->netdevname, info->ft1000_proc_dir);
		ft1000_proc_file =
			proc_create_data(dev->name, 0644, info->ft1000_proc_dir,
					 &ft1000_proc_fops, dev);
		snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
		break;
	}

	return NOTIFY_DONE;
}

static struct notifier_block ft1000_netdev_notifier = {
	.notifier_call = ft1000NotifyProc,
};


int ft1000_init_proc(struct net_device *dev)
{
	struct ft1000_info *info;
	struct proc_dir_entry *ft1000_proc_file;
	int ret = -EINVAL;

	info = netdev_priv(dev);

	info->ft1000_proc_dir = proc_mkdir(FT1000_PROC_DIR, FTNET_PROC);
	if (info->ft1000_proc_dir == NULL) {
		printk(KERN_WARNING "Unable to create %s dir.\n",
			FT1000_PROC_DIR);
		goto fail;
	}

	ft1000_proc_file =
		proc_create_data(dev->name, 0644, info->ft1000_proc_dir,
				 &ft1000_proc_fops, dev);

	if (!ft1000_proc_file) {
		printk(KERN_WARNING "Unable to create /proc entry.\n");
		goto fail_entry;
	}

	snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);

	ret = register_netdevice_notifier(&ft1000_netdev_notifier);
	if (ret)
		goto fail_notif;

	return 0;

fail_notif:
	remove_proc_entry(info->netdevname, info->ft1000_proc_dir);
fail_entry:
	remove_proc_entry(FT1000_PROC_DIR, FTNET_PROC);
fail:
	return ret;
}

void ft1000_cleanup_proc(struct ft1000_info *info)
{
	remove_proc_entry(info->netdevname, info->ft1000_proc_dir);
	remove_proc_entry(FT1000_PROC_DIR, FTNET_PROC);
	unregister_netdevice_notifier(&ft1000_netdev_notifier);
}
