/*---------------------------------------------------------------------------
   FT1000 driver for Flarion Flash OFDM NIC Device

   Copyright (C) 2006 Patrik Ostrihon, All rights reserved.
   Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved.

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the Free
   Software Foundation; either version 2 of the License, or (at your option) any
   later version. 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/string.h>
#include <linux/vmalloc.h>
#include <linux/netdevice.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include "ft1000.h"

#define FT1000_PROC "ft1000"
#define MAX_FILE_LEN 255

#define PUTM_TO_PAGE(len, page, args...) \
	len += snprintf(page+len, PAGE_SIZE - len, args)

#define PUTX_TO_PAGE(len, page, message, size, var) \
	len += snprintf(page+len, PAGE_SIZE - len, message); \
	for(i = 0; i < (size - 1); i++) { \
		len += snprintf(page+len, PAGE_SIZE - len, "%02x:", var[i]); \
	} \
	len += snprintf(page+len, PAGE_SIZE - len, "%02x\n", var[i])

#define PUTD_TO_PAGE(len, page, message, size, var) \
	len += snprintf(page+len, PAGE_SIZE - len, message); \
	for(i = 0; i < (size - 1); i++) { \
		len += snprintf(page+len, PAGE_SIZE - len, "%d.", var[i]); \
	} \
	len += snprintf(page+len, PAGE_SIZE - len, "%d\n", var[i])

static int ft1000ReadProc(char *page, char **start, off_t off,
			  int count, int *eof, void *data)
{
	struct net_device *dev;
	int len;
	int i;
	struct ft1000_info *info;
	char *status[] = {
		"Idle (Disconnect)", "Searching", "Active (Connected)",
		"Waiting for L2", "Sleep", "No Coverage", "", ""
	};
	char *signal[] = { "", "*", "**", "***", "****" };
	int strength;
	int quality;
	struct timeval tv;
	time_t delta;

	dev = (struct net_device *)data;
	info = netdev_priv(dev);

	if (off > 0) {
		*eof = 1;
		return 0;
	}

	/* Wrap-around */

	if (info->AsicID == ELECTRABUZZ_ID) {
		if (info->ProgConStat != 0xFF) {
			info->LedStat =
				ft1000_read_dpram(dev, FT1000_DSP_LED);
			info->ConStat =
				ft1000_read_dpram(dev,
						  FT1000_DSP_CON_STATE);
		} else {
			info->ConStat = 0xf;
		}
	} else {
		if (info->ProgConStat != 0xFF) {
			info->LedStat =
				ntohs(ft1000_read_dpram_mag_16
				  (dev, FT1000_MAG_DSP_LED,
				   FT1000_MAG_DSP_LED_INDX));
			info->ConStat =
				ntohs(ft1000_read_dpram_mag_16
				  (dev, FT1000_MAG_DSP_CON_STATE,
				   FT1000_MAG_DSP_CON_STATE_INDX));
		} else {
			info->ConStat = 0xf;
		}
	}

	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;
	}

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

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

	info = netdev_priv(dev);

	switch (event) {
	case NETDEV_CHANGENAME:
		remove_proc_entry(info->netdevname, info->proc_ft1000);
		create_proc_read_entry(dev->name, 0644, info->proc_ft1000,
					   ft1000ReadProc, dev);
		snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
		break;
	}
	return NOTIFY_DONE;
}

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

void ft1000InitProc(struct net_device *dev)
{
	struct ft1000_info *info;

	info = netdev_priv(dev);

	info->proc_ft1000 = proc_mkdir(FT1000_PROC, init_net.proc_net);
	create_proc_read_entry(dev->name, 0644, info->proc_ft1000,
				   ft1000ReadProc, dev);
	snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
	register_netdevice_notifier(&ft1000_netdev_notifier);
}

void ft1000CleanupProc(struct net_device *dev)
{
	struct ft1000_info *info;

	info = netdev_priv(dev);

	remove_proc_entry(dev->name, info->proc_ft1000);
	remove_proc_entry(FT1000_PROC, init_net.proc_net);
	unregister_netdevice_notifier(&ft1000_netdev_notifier);
}
