/*
<:copyright-BRCM:2016:DUAL/GPL:standard

   Broadcom Proprietary and Confidential.(c) 2016 Broadcom
   All Rights Reserved

Unless you and Broadcom execute a separate written software license
agreement governing use of this software, this software is licensed
to you under the terms of the GNU General Public License version 2
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
with the following added to such license:

   As a special exception, the copyright holders of this software give
   you permission to link this software with independent modules, and
   to copy and distribute the resulting executable under terms of your
   choice, provided that you also meet, for each linked independent
   module, the terms and conditions of the license of that module.
   An independent module is a module which is not derived from this
   software.  The special exception does not apply to any modifications
   of the software.

Not withstanding the above, under no circumstances may you combine
this software in any way with any other Broadcom software provided
under a license other than the GPL, without Broadcom's express prior
written consent.

:>
 */

/*
    might use readl or ioread32
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/compiler.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/gfp.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/spinlock.h>

#ifdef TX_ENABLE_EVENT_TRACE
#include <linux/ctype.h>
#include <linux/file.h>
#include <linux/fs.h>
#include "bcm_fld_common.h"
#endif
#include <bcmolt_board_selector.h>
#include "bcmolt_llpcie.h"

#define DRV_NAME	"maple"
#define DRV_VERSION	"1.0.3"

#define BAR_REGS                        0
#define BAR_DDR                         2
#define BAR_SRAM                        4
/*
bar 1 = 8  Mbyte register space
bar 2 = 16 Mbyte DDR space
bar 3 = 64 Kbyte SRAM space
*/
#define MAPLE_REGS_LENGTH                   0x00800000
#define MAPLE_DDR_LENGTH                    0x01000000
#define MAPLE_SRAM_LENGTH                   0x00010000

#ifdef TX_ENABLE_EVENT_TRACE
#define PCIE_PCIE_0_MISC_CPU_2_PCIE_MEM_WIN1_LO			0x064014U
#define PCIE_PCIE_0_MISC_CPU_2_PCIE_MEM_WIN1_HI			0x064018U
#define PCIE_PCIE_0_MISC_CPU_2_PCIE_MEM_WIN1_BASE_LIMIT	0x064074U
#endif
#define PCIE_REVISION_REGISTER_OFFSET       0x6406CU /* PCIE_PCIE_PCIE_0_PCIE_PCIE_0_MISC_REVISION    */
#define PCIE_STATUS_REGISTER_OFFSET         0x64068U /* PCIE_PCIE_PCIE_0_PCIE_PCIE_0_MISC_PCIE_STATUS */
#define PCIE_HARD_DEBUG_REGISTER_OFFSET     0x64204U /* PCIE_PCIE_PCIE_0_PCIE_PCIE_0_MISC_HARD_DEBUG  */
#define PCIE_INT_STATUS_REGISTER_OFFSET     0x69400U /* PCIE_PCIE_PCIE_0_CPU_INTR1_INTR_STATUS        */
#define PCIE_INT_CLEAR_MASK_OFFSET          0x6940CU /* PCIE_PCIE_PCIE_0_CPU_INTR1_INTR_MASK_CLEAR    */
#define PCIE_INTR1_STATUS_REGISTER_OFFSET   0x69300U /* Interrupt Status Register */

#define PCIE_MAPLE_VENDOR_ID                0x14E4 /* PCIE_CFG_TYPE0_EP_SUBSYSTEM_ID_VENDOR_ID      */
#define PCIE_MAPLE_DEVICE_ID                0x6862
#define PCIE_MAPLE_6863_SKU_DEVICE_ID       0x6863
#define PCIE_MAPLE_EPON_DEVICE_ID           0x5554

#define MAPLE_DRIVER_NAME   DRV_NAME " BCM68620 (Maple) PCI driver " DRV_VERSION

struct proc_dir_entry *bcmolt_dir = NULL;
static DEFINE_PCI_DEVICE_TABLE(maple_pci_tbl) =
{ /* vendor_id,                  device_id,       any,       any */
    {PCI_DEVICE(PCIE_MAPLE_VENDOR_ID, PCIE_MAPLE_DEVICE_ID)},
    {PCI_DEVICE(PCIE_MAPLE_VENDOR_ID, PCIE_MAPLE_6863_SKU_DEVICE_ID)},
    {PCI_DEVICE(PCIE_MAPLE_VENDOR_ID, PCIE_MAPLE_EPON_DEVICE_ID)},
    {0}
};
MODULE_DEVICE_TABLE (pci, maple_pci_tbl);

typedef struct
{
    bcm_ll_dev_info  device;
    spinlock_t       lock;
    int              err_status;
    int              phylink;
    int              prev_datalink;
    int              datalink;
    uint32_t         deviceid;
    unsigned int    *traceaddr;
    struct pci_dev  *pdev;
    int              enabled;
} maple_device_info;

static int crt_device = 0;
static bcm_ll_pcie_status_change callback;
static bcmos_bool is_initialized = BCMOS_FALSE;

static maple_device_info devices[MAPLE_MAX_DEVICES];
//static irqreturn_t maple_interrupt (int irq, void *dev_instance);
static maple_device_info *get_maple_pci_info(int crt);

static int maple_write(struct file *file,const char *buffer,size_t count, void *data);
static int maple_read(char *page, char **start, off_t off, int count, int *eof, void *data);

/* Map bus/device to device_id */
static int _pcie_bus_devfv_to_devid(int bus, int devfn)
{
    const bus_devfn_devid *map;
    for (map = bcmolt_board_pci_map_table_get(); map && map->bus > 0; map++)
    {
        if (map->bus == bus && map->devfn == devfn)
        {
            return map->device;
        }
    }
    /* Not found - use incremental mapping */
    return crt_device;
}

/* procedure used by OS to connect Maple PCI to allocated memory */

static int __devinit maple_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
    int rc;
    volatile unsigned int readval;
    maple_device_info *device_info = NULL;
    int dev_id;
    u32 val;

    if (!pdev)
        return 1;

    dev_info(&pdev->dev,
        "Bus = %d Slot = %d Vendor:device = 0x%04x:0x%04x revision = 0x%02x\n",
        pdev->bus->number, pdev->devfn,
        pdev->vendor, pdev->device, pdev->revision);

    if (crt_device == MAPLE_MAX_DEVICES)
    {
        printk(" Maximum Maple devices already defined (%d)\n", MAPLE_MAX_DEVICES);
        return -ENODEV;
    }

    dev_id = _pcie_bus_devfv_to_devid(pdev->bus->number, pdev->devfn);
    ++crt_device;
    device_info = &devices[dev_id];
    memset(device_info, 0, sizeof(maple_device_info));

    spin_lock_init(&device_info->lock);
    device_info->deviceid = dev_id;
    device_info->pdev = pdev;

    /* Enable maple device on PCIe bus and fixup BARs.
     * Without fixup, module unload/reload crashes with WRX host
     * because PCI hotplug doesn't work and after unload/re-load
     * linux believes that BARs are already set.
     */
    rc = bcm_ll_pcie_dev_enable(dev_id);
    if (rc)
    {
        printk("Error pci_enable_device_mem = %d\n",rc);
        goto err_out;
    }

    rc = pci_request_selected_regions(pdev, pci_select_bars(pdev, IORESOURCE_MEM), DRV_NAME);
    if (rc)
        goto err_out;

    pci_set_master(pdev);
    pci_save_state(pdev);

    device_info->device.soc_regs_base = (unsigned long)pci_ioremap_bar(pdev, BAR_REGS);
    device_info->device.soc_sram_base = (unsigned long)pci_ioremap_bar(pdev, BAR_SRAM);
    device_info->device.soc_ddr_base = (unsigned long)pci_ioremap_bar(pdev, BAR_DDR);
    device_info->device.soc_ddr_length = (uint32_t)pci_resource_len(pdev, BAR_DDR);
    device_info->device.irq = pdev->irq;
    pci_set_drvdata(pdev, device_info);

    //rc = request_irq(device_info->device.irq, maple_interrupt, IRQF_SHARED, "maple-pcie", device_info);
    if (!rc && device_info->device.soc_sram_base)
    {
        device_info->device.irq_connected = 1;
        readval = bcm_pci_read32((uint32_t *)(device_info->device.soc_regs_base + PCIE_REVISION_REGISTER_OFFSET));
        printk("Card %d version major=%02x minor=%02x\n",device_info->deviceid,
               ((readval & 0x0000ff00) >> 8),(readval & 0x000000ff));
        printk("regs_start = 0x%lx\nddr_start  = 0x%lx\nsram_start = 0x%lx\nddr_length  = %d\n",
                 device_info->device.soc_regs_base,device_info->device.soc_ddr_base,
                 device_info->device.soc_sram_base, (int)device_info->device.soc_ddr_length);
        pci_read_config_dword(pdev,PCI_BASE_ADDRESS_0,&val);
        printk("BAR REGS = 0x%x\n",(unsigned int)val);
        pci_read_config_dword(pdev,PCI_BASE_ADDRESS_2,&val);
        printk("BAR DDR = 0x%x\n",(unsigned int)val);
        pci_read_config_dword(pdev,PCI_BASE_ADDRESS_4,&val);
        printk("BAR SRAM = 0x%x\n",(unsigned int)val);
        readval = bcm_pci_read32((uint32_t *)(device_info->device.soc_regs_base + PCIE_STATUS_REGISTER_OFFSET));
        device_info->err_status = readval & 0x0000000f;
        device_info->phylink    = (readval >> 4) & 0x1;
        device_info->datalink   = (readval >> 5) & 0x1;
        device_info->prev_datalink  = device_info->datalink;
    }
    else
        goto err_out;

    return rc;

err_out:
    pci_disable_device (pdev);
    memset(device_info, 0, sizeof(*device_info));
    --crt_device;

    return rc;
}

static void __devexit maple_pci_remove(struct pci_dev *pdev)
{
    int i;
    maple_device_info *dev = pci_get_drvdata(pdev);

    if (!dev)
        return;

    if (dev->device.irq_connected)
    {
        //free_irq(dev->device.irq, dev);
        dev->device.irq_connected = 0;
    }
    if (callback)
    {
        for (i = 0; i < crt_device; i++)
        {
            if (devices[i].pdev == pdev)
            {
                callback(i, BCM_LL_PCIE_LINK_DOWN);
                break;
            }
        }
    }
    pci_disable_device(pdev);
    pci_release_regions(pdev);
    pci_set_drvdata(pdev, NULL);
    dev->device.soc_sram_base = 0;
    dev->device.soc_regs_base = 0;
    dev->pdev = NULL;
}

static struct pci_driver maple_pci_driver = {
    .name       = DRV_NAME,
    .id_table   = maple_pci_tbl,
    .probe      = maple_pci_probe,
    .remove     = __devexit_p(maple_pci_remove),
};

static maple_device_info *get_maple_pci_info(int crt)
{
    unsigned int readval=0;
    maple_device_info *device;

    if (crt >= BCMTR_MAX_OLTS)
        return NULL;

    device = &devices[crt];
    if (device->device.soc_regs_base)
    {
        if (device->enabled)
        {
            readval = bcm_pci_read32((uint32_t *)(device->device.soc_regs_base + PCIE_STATUS_REGISTER_OFFSET));
            device->err_status = readval & 0x0000000f;
            device->phylink    = (readval >> 4) & 0x1;
            device->datalink   = (readval >> 5) & 0x1;
        }
        else
        {
            device->err_status = 0;
            device->phylink    = 0;
            device->datalink   = 0;
        }
    }
    else
        device = NULL;

    return device;
}

#if 0
static irqreturn_t maple_interrupt (int irq, void *dev_instance)
{
    volatile unsigned int value;
    maple_device_info *device_info;
    unsigned long flags;
    int handled = IRQ_NONE;
    uint32_t device;

    spin_lock_irqsave(&device_info->lock, flags);
    value = bcm_pci_read32((uint32_t *)(device_info->device.soc_regs_base + PCIE_INT_STATUS_REGISTER_OFFSET));
    if (value)
    {
        if (device_info->datalink != device_info->prev_datalink)
        {
            if (device_info->datalink == BCM_LL_PCIE_LINK_UP)
                printk("Device=%d : Link is up !!!\n", device);
            else
            {
                printk("Device=%d : Link is down !!!\n", device);
                printk("phy status = 0x%x error status = 0x%x\n", device_info->phylink, device_info->err_status);
            }
            device_info->prev_datalink = device_info->datalink;
            if (callback)
                callback(device, device_info->datalink);
        }
        value = bcm_pci_read32((uint32_t *)(device_info->device.soc_regs_base + PCIE_INTR1_STATUS_REGISTER_OFFSET));
        if (!value)
            handled = IRQ_HANDLED;
    }
    spin_unlock_irqrestore(&device_info->lock, flags);

    return IRQ_RETVAL(handled);
}
#endif

/* Returns BAR register address */
static int _pci_bar_reg_addr(int res)
{
    return 0x10 + res*4;
}

static void _pci_update_resource(struct pci_dev *dev, int resno)
{
        struct pci_bus_region region;
        u16 cmd;
        u32 new, check, mask;
        int reg;
        struct resource *res = dev->resource + resno;

        /*
         * Ignore resources for unimplemented BARs and unused resource slots
         * for 64 bit BARs.
         */
        if (!res->flags)
                return;

        /*
         * Ignore non-moveable resources.  This might be legacy resources for
         * which no functional BAR register exists or another important
         * system resource we shouldn't move around.
         */
        if (res->flags & IORESOURCE_PCI_FIXED)
                return;

        pcibios_resource_to_bus(dev, &region, res);

        new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
        if (res->flags & IORESOURCE_IO)
                mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
        else
                mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;

        reg = _pci_bar_reg_addr(resno);

        pci_write_config_dword(dev, reg, new);
        pci_read_config_dword(dev, reg, &check);

        if ((new ^ check) & mask) {
                dev_err(&dev->dev, "BAR %d: error updating (%#08x != %#08x)\n",
                        resno, new, check);
        }

        if (res->flags & IORESOURCE_MEM_64) {
                new = region.start >> 16 >> 16;
                pci_write_config_dword(dev, reg + 4, new);
                pci_read_config_dword(dev, reg + 4, &check);
                if (check != new) {
                        dev_err(&dev->dev, "BAR %d: error updating "
                               "(high %#08x != %#08x)\n", resno, new, check);
                }
        }

        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        pci_write_config_word(dev, PCI_COMMAND, cmd | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);

        res->flags &= ~IORESOURCE_UNSET;
        dev_info(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n",
                resno, res, (unsigned long long)region.start,
                (unsigned long long)region.end);
}

/* Enable PCI access to device */
bcmos_errno bcm_ll_pcie_dev_enable(int dev_id)
{
    maple_device_info *device;
    int rc;

    if (dev_id >= MAPLE_MAX_DEVICES)
        return BCM_ERR_PARM;

    device = &devices[dev_id];
    if (!device->pdev)
        return BCM_ERR_IO;

    rc = pci_enable_device_mem(device->pdev);
    if (rc)
    {
        printk("Error pci_enable_device_mem for device %d = %d\n", dev_id, rc);\
        goto out;
    }

    /* Refresh devices's PCIe header */
    _pci_update_resource(device->pdev, BAR_REGS);
    _pci_update_resource(device->pdev, BAR_SRAM);
    _pci_update_resource(device->pdev, BAR_DDR);
    device->enabled = 1;

out:
    return rc ? BCM_ERR_IO : BCM_ERR_OK;
}

/* Disable PCI access to device */
bcmos_errno bcm_ll_pcie_dev_disable(int dev_id)
{
    maple_device_info *device;

    printk("%s: device %d\n", __FUNCTION__, dev_id);

    if (dev_id >= MAPLE_MAX_DEVICES)
        return BCM_ERR_PARM;

    device = &devices[dev_id];
    if (!device->pdev || !device->enabled)
        return BCM_ERR_OK;
    pci_disable_device(device->pdev);
    device->enabled = 0;

    return BCM_ERR_OK;
}

bcmos_errno bcm_ll_pcie_init(void)
{
    int rc;
    if (is_initialized)
        return BCM_ERR_OK;
    is_initialized = BCMOS_TRUE;
    rc = pci_register_driver(&maple_pci_driver);
    printk(KERN_INFO "Maple PCI driver registered with PCI subsystem. rc=%d\n", rc);
    return rc ? BCM_ERR_INTERNAL : BCM_ERR_OK;
}

void bcm_ll_pcie_cleanup(void)
{
    if (!is_initialized)
        return;
    is_initialized = BCMOS_FALSE;

    pci_unregister_driver(&maple_pci_driver);
    crt_device = 0;
    memset(devices, 0, sizeof(devices));
}

/*******************************************/
/* procedures executed on insmod and rmmod */
/*******************************************/
static int __init bcm_ll_init_module(void)
{
    struct proc_dir_entry *bcmolt_file = NULL;

    if ((bcmolt_dir = create_proc_entry("bcmolt", S_IFDIR, NULL)) == NULL)
    {
        printk("Unable to create /proc/bcmolt entry\n");
        return -1;
    }
    if ((bcmolt_file = create_proc_entry("card", S_IFREG | S_IWUSR | S_IRUGO, bcmolt_dir)) == NULL)
    {
        printk("Unable to create /proc/bcmolt/card entry\n");
        remove_proc_entry("bcmolt", bcmolt_dir);
        return -1;
    }
    bcmolt_file->write_proc = (write_proc_t *)maple_write;
    bcmolt_file->read_proc = (read_proc_t *)maple_read;

    return 0;
}

static void __exit bcm_ll_cleanup_module(void)
{
    bcm_ll_pcie_cleanup();
    remove_proc_entry("card", bcmolt_dir);
    remove_proc_entry("bcmolt", NULL);
    printk("Unregister done\n");
}

/*****************************/
/* APIs used by Host drivers */
/*****************************/
bcmos_errno bcm_ll_pcie_status_change_register(bcm_ll_pcie_status_change cb)
{
    int i;
    maple_device_info *device_info;

    callback = cb;
    if(callback)
    {
        for (i = 0; i < crt_device; i++)
        {
            device_info = get_maple_pci_info(i);
            if (device_info)
                callback(i, device_info->datalink);
            else
                callback(i, BCM_LL_PCIE_LINK_DOWN);
        }
    }

    return BCM_ERR_OK;
}

bcmos_errno bcm_ll_pcie_status_change_unregister(void)
{
    callback = NULL;

    return BCM_ERR_OK;
}

bcmos_errno bcm_ll_pcie_query(uint8_t dev_id, bcm_ll_dev_info *info)
{
    maple_device_info *device_info;

    if (!info)
        return BCM_ERR_PARM;

    if (dev_id < MAPLE_MAX_DEVICES)
    {
        device_info = get_maple_pci_info(dev_id);
        if (device_info && device_info->pdev)
        {
            if (device_info->datalink == BCM_LL_PCIE_LINK_DOWN)
                return BCM_ERR_IO;
            *info = device_info->device;
            return BCM_ERR_OK;
        }
        return BCM_ERR_IO;
    }
    return BCM_ERR_RANGE;
}

bcm_ll_pcie_dev bcm_ll_pcie_dev_get(uint8_t dev_id)
{
    maple_device_info *device_info;

    if (dev_id < crt_device)
    {
        device_info = get_maple_pci_info(dev_id);
        return (device_info ? device_info->pdev : NULL);
    }

    return NULL;
}

bcmos_errno bcm_ll_pcie_host_reset_enable(uint8_t dev_id, bcmos_bool enabled)
{
    uint32_t val;

    val = enabled ? 0 : 1;
    bcm_pci_write32((uint32_t *)(devices[dev_id].device.soc_regs_base + PCIE_HARD_DEBUG_REGISTER_OFFSET), val);

    return BCM_ERR_OK;
}

#ifdef TX_ENABLE_EVENT_TRACE
bcmos_errno bcm_ll_pcie_setrace(uint8_t dev_id)
{
    maple_device_info *device_info;
    uint32_t val,lim,base,size;
    uint32_t reglo,reghi,baselim;
    unsigned long addr;

    if (dev_id < crt_device)
    {
        device_info = &devices[dev_id];
        if (!device_info)
            return BCM_ERR_IO;
        size = EVENT_BUFFER_SIZE;
        device_info->traceaddr = (unsigned int *)bcmos_alloc_not_cache(size);
        memset(device_info->traceaddr,0,size);
        addr = bcmos_virt_to_phys(device_info->traceaddr); /* | 0x02 = reverse byte order = swap */
        printk("trace window : alloc=0x%lx size=0x%x\n",(unsigned long)device_info->traceaddr, (unsigned int)size);
        reglo = PCIE_PCIE_0_MISC_CPU_2_PCIE_MEM_WIN1_LO;
        reghi = PCIE_PCIE_0_MISC_CPU_2_PCIE_MEM_WIN1_HI;
        baselim = PCIE_PCIE_0_MISC_CPU_2_PCIE_MEM_WIN1_BASE_LIMIT;
        bcm_pci_write32((uint32_t *)(device_info->device.soc_regs_base + reglo),addr & 0xffffffff);
        bcm_pci_write32((uint32_t *)(device_info->device.soc_regs_base + reghi)),((addr >> 32) & 0xffffffff);
        /* base */
        base = CPU_2_PCIE_MEM_WIN1_BASE;
        /* limit */
        lim = base + size;
        val = lim  | (base >> 16);
        bcm_pci_write32((uint32_t *)(device_info->device.soc_regs_base + baselim),val);
        //bcm_fld_set_event_trace(dev_id);
        bcm_pci_write32((uint32_t *)(device_info->device.soc_sram_base + BCM_FLD_EVENT_TRACE_OFFSET),0x1);

        return BCM_ERR_OK;
    }
    return BCM_ERR_RANGE;
}
bcmos_errno bcm_ll_pcie_cleartrace(uint8_t dev_id)
{
    maple_device_info *device_info;

    if (dev_id < crt_device)
    {
        device_info = &devices[dev_id];
        if (!device_info)
            return BCM_ERR_IO;
        //bcm_fld_clear_event_trace(dev_id);
        bcm_pci_write32((uint32_t *)(device_info->device.soc_sram_base + BCM_FLD_EVENT_TRACE_OFFSET),0x0);
        return BCM_ERR_OK;
    }
    return BCM_ERR_RANGE;
}
bcmos_errno bcm_ll_pcie_savetrace(uint8_t dev_id, char *tracefilename)
{
    maple_device_info *device_info;
    struct file         *fp;
    unsigned long seg   = 0;
    mm_segment_t memseg;

    if (!tracefilename)
        return BCM_ERR_PARM;

    printk("device=%d from=%d, Go to write to file %s\n",dev_id , crt_device, tracefilename);

    if (dev_id < crt_device)
    {
        device_info = &devices[dev_id];
        if (!device_info)
        {
            printk("Error: device_info is null\n");
            goto exit;
        }
        fp = filp_open(tracefilename, O_WRONLY | O_CREAT, 0666);
        if ((fp == NULL) || (fp == (void *)-ENOENT))
        {
            printk("Error: Can't open file %s\n",tracefilename);
            goto exit;
        }
        // Get current segment descriptor
        seg = get_fs().seg;

        // Set segment descriptor associated to kernel space
        set_fs(get_ds());
        fp->f_op->write(fp, (char *)device_info->traceaddr,EVENT_BUFFER_SIZE, &fp->f_pos);

        memseg.seg = seg;
        set_fs(memseg);
        filp_close(fp, NULL);
        printk("Wrote file %s\n",tracefilename);
exit:
        bcmos_free_not_cache(device_info->traceaddr);

        return BCM_ERR_OK;
    }
    return BCM_ERR_RANGE;
}
#endif

/*************************************************************/
/* User interface functions : implement echo/cat to proc file*/
/*************************************************************/

typedef struct
{
    char *name;
	void (*callback)(int cmdid, char *cmd);
    char *description;
} maple_card_command;

static char *find_command(char *cmd);
static void command_reg(int cmdid, char *line);
static void command_mem(int cmdid, char *line);
static void command_cfg(int cmdid, char *line);
#ifdef TX_ENABLE_EVENT_TRACE
static void command_trace(int cmdid, char *line);
#endif

#define READCMD     0
#define WRITECMD    1

static maple_card_command commands[] =
{
    {"readreg",     command_reg, "read register <index> <register offset - hex>"},
    {"writereg",    command_reg, "write register <index> <register offset - hex> <value - hex>"},
    {"read",        command_mem, "read <address - hex> <number of words - dec>"},
    {"write",       command_mem, "write <address - hex> <value - hex>"},
    {"rcfg",        command_cfg, "read dev <address - hex> <number of words - dec>"},
    {"wcfg",        command_cfg, "write dev <address - hex> <value - hex>"},
#ifdef TX_ENABLE_EVENT_TRACE
    {"trace",       command_trace, "trace <index> on/off/save tx trace"},
#endif
    {NULL, NULL, NULL}
};

static char *find_command(char *cmd)
{
    char *rest;
    int i = 0;
    maple_card_command *cmdptr = &commands[0];

    cmd = skip_spaces(cmd);
    if (!strncmp(cmd,"help",strlen("help")))
    {
        while (cmdptr->name)
        {
            printk("%s\t: %s\n",cmdptr->name, cmdptr->description);
            cmdptr = &commands[++i];
        }
        return NULL;
    }
    while (cmdptr->name)
    {
        if (!strncmp(cmdptr->name, cmd, strlen(cmdptr->name)))
        {
            rest = cmd + strlen(cmdptr->name);
            rest = skip_spaces(rest);
            cmdptr->callback(i%2, rest);
            return NULL;
        }
        cmdptr = &commands[++i];
    }

    return "Wrong command name";
}
/**********************************************************************
  answers to cat /proc/bcmolt command
**********************************************************************/
static int maple_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
    int i;
    int len;
    maple_device_info *dev = NULL;

    len = sprintf(page, "Maple Device Info\n\n");
    for (i = 0; i < MAPLE_MAX_DEVICES; i++)
    {
        dev = get_maple_pci_info(i);
        if (dev)
        {
            len += sprintf(page + len, "id=%d regs_start=0x%lx ddr_start=0x%lx sram_start=0x%lx ddr_length=%d\n",
                dev->deviceid,
                dev->device.soc_regs_base,dev->device.soc_ddr_base,
                dev->device.soc_sram_base, (int)dev->device.soc_ddr_length);
            len += sprintf(page + len, "Phy Link is %s Data Link is %s Error status = %d\n\n",
                dev->phylink == 1 ? "UP" : "DOWN", dev->datalink == 1 ? "UP" : "DOWN", (int)dev->err_status);
        }
    }

    return len;
}
#ifdef TX_ENABLE_EVENT_TRACE
static void command_trace(int cmdid, char *line)
{
    char token[5];
    int  index;

    if (sscanf(line, "%d %s", &index, token) != 2)
    {
        printk("Wrong parameter\n");
        return;
    }
    printk("TRACE commands : %s\n",token);
    if (!strncmp(token,"on",2))
    {
        //on
        bcm_ll_pcie_setrace(index);
        return;
    }
    if (!strncmp(token,"off",3))
    {
        // off
        bcm_ll_pcie_cleartrace(index);
        return;
    }
    if (!strncmp(token,"save",4))
    {
        //get
        char filename[20];
        sprintf(filename,"./tt_trace_%d.trx",index);
        bcm_ll_pcie_savetrace(index,filename);
        return;
    }
    printk("Wrong command\n");
}
#endif


static void command_reg(int cmdindex, char *line)
{
    char *rest;
    char *token;
    int  index;
    unsigned long address;
    unsigned int reg;

    if (sscanf(line, "%d %lx", &index, &address) != 2)
    {
        printk("Wrong parameter\n");
        return;
    }
    address += (unsigned long)devices[index].device.soc_regs_base;
    switch (cmdindex)
    {
    case READCMD:
        reg = bcm_pci_read32((uint32_t *)address);
        printk("0x%lx : %08x\n", address, reg);
        break;
    case WRITECMD:
        rest = line;
        token = strsep(&rest, " "); /* skip index */
        token = strsep(&rest, " "); /* skip address */
        token = strsep(&rest, " ");
        if (!token)
        {
            printk("Wrong parameter\n");
            return;
        }
        sscanf(token, "%x", &reg);
        printk("write 0x%x to 0x%lx\n", reg, address);
        bcm_pci_write32((uint32_t *)address,reg);
        break;
    }
}

static void command_mem(int cmdindex, char *line)
{
    char *token;
    char *rest;
    unsigned long address;
    unsigned int reg;
    int i, number_of_words;
    int in_line=0, max_in_line;

    if (sscanf(line, "%lx", &address) != 1)
    {
        printk("Wrong parameter\n");
        return;
    }
    rest = line;
    token = strsep(&rest, " "); /* skip address */
    switch (cmdindex)
    {
    case READCMD:
        token = strsep(&rest, " ");
        if (!token)
            number_of_words = 1;
        else
            sscanf(token, "%d", &number_of_words);

        max_in_line = 4;
        for (i = 0; i < number_of_words; i++, address += 4)
        {
            if (!in_line)
                printk("%08lx: ", address);
            reg = bcm_pci_read32((uint32_t *)address);
            printk("%08x", reg);
            if (++in_line < max_in_line)
                printk(" ");
            else
            {
                printk("\n");
                in_line = 0;
            }
        }
        if (in_line)
            printk("\n");
        break;
    case WRITECMD:
        token = strsep(&rest, " ");
        if (!token)
        {
            printk("Wrong parameter\n");
            return;
        }
        sscanf(token, "%x", &reg);
        bcm_pci_write32((uint32_t *)address,reg);
        break;
    }
}

static void command_cfg(int cmdindex, char *line)
{
    unsigned long address;
    unsigned int reg;
    unsigned int val_or_num;
    int crt;
    int i;
    int in_line=0, max_in_line;
    maple_device_info *device;

    if (sscanf(line, "%d %lx %x", &crt, &address, &val_or_num) != 3)
    {
        printk("Wrong parameter\n");
        return;
    }

    if (crt >= crt_device || !devices[crt].pdev)
    {
        printk("Invalid device %d\n", crt);
        return;
    }

    device = &devices[crt];

    switch (cmdindex)
    {
    case READCMD:
        max_in_line = 4;
        for (i = 0; i < val_or_num; i++, address += 4)
        {
            if (!in_line)
                printk("%08lx: ", address);
            pci_read_config_dword(device->pdev, address, &reg);
            printk("%08x", reg);
            if (++in_line < max_in_line)
                printk(" ");
            else
            {
                printk("\n");
                in_line = 0;
            }
        }
        if (in_line)
            printk("\n");
        break;

    case WRITECMD:
        pci_write_config_dword(device->pdev, address, val_or_num);
        break;
    }
}

/**********************************************************************
  answers to echo [...] > /proc/bcmolt command
**********************************************************************/
static int maple_write(struct file *file,const char *buffer,size_t count, void *data)
{
    char *internal;

    if (buffer == NULL)
        return -EFAULT;

    internal = kmalloc(count, GFP_KERNEL);
    if (!internal)
    {
        printk("Not enough memmory\n");
        return count;
    }

    memset(internal, 0, count);
    if (copy_from_user(internal, buffer, count))
    {
        printk("Not enough memmory\n");
        goto error;
    }
    find_command(internal);

error:
    kfree(internal);

    return count;
}

EXPORT_SYMBOL(bcmolt_dir);
EXPORT_SYMBOL(bcm_ll_pcie_init);
EXPORT_SYMBOL(bcm_ll_pcie_cleanup);
EXPORT_SYMBOL(bcm_ll_pcie_status_change_register);
EXPORT_SYMBOL(bcm_ll_pcie_status_change_unregister);
EXPORT_SYMBOL(bcm_ll_pcie_query);
EXPORT_SYMBOL(bcm_ll_pcie_dev_get);
EXPORT_SYMBOL(bcm_ll_pcie_dev_enable);
EXPORT_SYMBOL(bcm_ll_pcie_dev_disable);
EXPORT_SYMBOL(bcm_ll_pcie_host_reset_enable);

#ifdef TX_ENABLE_EVENT_TRACE
EXPORT_SYMBOL(bcm_ll_pcie_setrace);
EXPORT_SYMBOL(bcm_ll_pcie_cleartrace);
EXPORT_SYMBOL(bcm_ll_pcie_savetrace);
#endif
module_init(bcm_ll_init_module);
module_exit(bcm_ll_cleanup_module);

MODULE_DESCRIPTION("maple line card");
MODULE_LICENSE("Dual BSD/GPL");
