/*
 * 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) \
	do { \
		seq_printf(m, message);	\
		for (i = 0; i < (size - 1); i++) \
			seq_printf(m, "%02x:", var[i]); \
		seq_printf(m, "%02x\n", var[i]);	\
	} while (0)

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

#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 = netdev_notifier_info_to_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) {
		netdev_warn(dev, "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) {
		netdev_warn(dev, "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);
}
