/* Copyright (C) 2004-2005  SBE, Inc.
 *
 *   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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/types.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include "pmcc4_sysdep.h"
#include "sbecom_inline_linux.h"
#include "pmcc4_private.h"
#include "sbeproc.h"

extern void sbecom_get_brdinfo(ci_t *, struct sbe_brd_info *, u_int8_t *);
extern struct s_hdw_info hdw_info[MAX_BOARDS];

void sbecom_proc_brd_cleanup(ci_t *ci)
{
	if (ci->dir_dev) {
		char dir[7 + SBE_IFACETMPL_SIZE + 1];
		snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
		remove_proc_entry("info", ci->dir_dev);
		remove_proc_entry(dir, NULL);
		ci->dir_dev = NULL;
	}
}

static void sbecom_proc_get_brdinfo(ci_t *ci, struct sbe_brd_info *bip)
{
	hdw_info_t *hi = &hdw_info[ci->brdno];
	u_int8_t *bsn = NULL;

	switch (hi->promfmt)
	{
	case PROM_FORMAT_TYPE1:
		bsn = (u_int8_t *) hi->mfg_info.pft1.Serial;
		break;
	case PROM_FORMAT_TYPE2:
		bsn = (u_int8_t *) hi->mfg_info.pft2.Serial;
		break;
	}

	sbecom_get_brdinfo (ci, bip, bsn);

	pr_devel(">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n",
		 bip->first_iname, bip->first_iname,
		 bip->last_iname, bip->last_iname);
}

/*
 * Describe the driver state through /proc
 */
static int sbecom_proc_get_sbe_info(struct seq_file *m, void *v)
{
	ci_t       *ci = m->private;
	char       *spd;
	struct sbe_brd_info *bip;

	bip = kzalloc(sizeof(struct sbe_brd_info), GFP_KERNEL | GFP_DMA);
	if (!bip)
		return -ENOMEM;

	pr_devel(">> sbecom_proc_get_sbe_info: entered\n");

	sbecom_proc_get_brdinfo(ci, bip);

	seq_puts(m, "Board Type:    ");
	switch (bip->brd_id) {
	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3):
		seq_puts(m, "wanPMC-C1T3");
		break;
	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
		seq_puts(m, "wanPTMC-256T3 <E1>");
		break;
	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
		seq_puts(m, "wanPTMC-256T3 <T1>");
		break;
	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1):
		seq_puts(m, "wanPTMC-C24TE1");
		break;

	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
		seq_puts(m, "wanPMC-C4T1E1");
		break;
	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
		seq_puts(m, "wanPMC-C2T1E1");
		break;
	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
		seq_puts(m, "wanPMC-C1T1E1");
		break;

	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
		seq_puts(m, "wanPCI-C4T1E1");
		break;
	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
		seq_puts(m, "wanPCI-C2T1E1");
		break;
	case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
		seq_puts(m, "wanPCI-C1T1E1");
		break;

	default:
		seq_puts(m, "unknown");
		break;
	}

	seq_printf(m, "  [%08X]\n", bip->brd_id);

	seq_printf(m, "Board Number:  %d\n", bip->brdno);
	seq_printf(m, "Hardware ID:   0x%02X\n", ci->hdw_bid);
	seq_printf(m, "Board SN:      %06X\n", bip->brd_sn);
	seq_printf(m, "Board MAC:     %pMF\n", bip->brd_mac_addr);
	seq_printf(m, "Ports:         %d\n", ci->max_port);
	seq_printf(m, "Channels:      %d\n", bip->brd_chan_cnt);
#if 1
	seq_printf(m, "Interface:     %s -> %s\n",
		   bip->first_iname, bip->last_iname);
#else
	seq_printf(m, "Interface:     <not available> 1st %p lst %p\n",
		   bip->first_iname, bip->last_iname);
#endif

	switch (bip->brd_pci_speed) {
	case BINFO_PCI_SPEED_33:
		spd = "33Mhz";
		break;
	case BINFO_PCI_SPEED_66:
		spd = "66Mhz";
		break;
	default:
		spd = "<not available>";
		break;
	}
	seq_printf(m, "PCI Bus Speed: %s\n", spd);

#ifdef SBE_PMCC4_ENABLE
	{
		extern int cxt1e1_max_mru;
#if 0
		extern int max_chans_used;
		extern int cxt1e1_max_mtu;
#endif
		extern int max_rxdesc_used, max_txdesc_used;

		seq_printf(m, "\ncxt1e1_max_mru:         %d\n", cxt1e1_max_mru);
#if 0
		seq_printf(m, "\nmax_chans_used:  %d\n", max_chans_used);
		seq_printf(m, "cxt1e1_max_mtu:         %d\n", cxt1e1_max_mtu);
#endif
		seq_printf(m, "max_rxdesc_used: %d\n", max_rxdesc_used);
		seq_printf(m, "max_txdesc_used: %d\n", max_txdesc_used);
	}
#endif

	kfree(bip);

	pr_devel(">> proc_fs: finished\n");
	return 0;
}

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

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

/*
 * Initialize the /proc subsystem for the specific SBE driver
 */
int __init sbecom_proc_brd_init(ci_t *ci)
{
	char dir[7 + SBE_IFACETMPL_SIZE + 1];

	snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
	ci->dir_dev = proc_mkdir(dir, NULL);
	if (!ci->dir_dev) {
		pr_err("Unable to create directory /proc/driver/%s\n", ci->devname);
		goto fail;
	}

	if (!proc_create_data("info", S_IFREG | S_IRUGO, ci->dir_dev,
			      &sbecom_proc_fops, ci)) {
		pr_err("Unable to create entry /proc/driver/%s/info\n", ci->devname);
		goto fail;
	}
	return 0;

fail:
	sbecom_proc_brd_cleanup(ci);
	return 1;
}
