/* Copyright (C) 2007  One Stop Systems
 * Copyright (C) 2003-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/netdevice.h>
#include <linux/hdlc.h>
#include <linux/if_arp.h>
#include <asm/uaccess.h>
#include <linux/rtnetlink.h>
#include <linux/pci.h>
#include "pmcc4_sysdep.h"
#include "sbecom_inline_linux.h"
#include "libsbew.h"
#include "pmcc4_private.h"
#include "pmcc4.h"
#include "pmcc4_ioctls.h"
#include "pmc93x6_eeprom.h"
#ifdef CONFIG_PROC_FS
#include "sbeproc.h"
#endif

extern int  cxt1e1_log_level;
extern int  error_flag;
extern int  drvr_state;

/* forward references */
void        c4_stopwd (ci_t *);
struct net_device * __init c4_add_dev (hdw_info_t *, int, unsigned long, unsigned long, int, int);


struct s_hdw_info hdw_info[MAX_BOARDS];


void        __init
show_two (hdw_info_t *hi, int brdno)
{
    ci_t       *ci;
    struct pci_dev *pdev;
    char       *bid;
    char       *bp, banner[80];
    char        sn[6];

    bp = banner;
    memset (banner, 0, 80);         /* clear print buffer */

    ci = (ci_t *)(netdev_priv(hi->ndev));
    bid = sbeid_get_bdname (ci);
    switch (hi->promfmt)
    {
    case PROM_FORMAT_TYPE1:
        memcpy (sn, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
        break;
    case PROM_FORMAT_TYPE2:
        memcpy (sn, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
        break;
    default:
        memset (sn, 0, 6);
        break;
    }

    sprintf (banner, "%s: %s  S/N %06X, MUSYCC Rev %02X",
             hi->devname, bid,
             ((sn[3] << 16) & 0xff0000) |
              ((sn[4] << 8) & 0x00ff00) |
              (sn[5] & 0x0000ff),
             (u_int8_t) hi->revid[0]);

    pr_info("%s\n", banner);

    pdev = hi->pdev[0];
    pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
            hi->devname, "MUSYCC",
            (unsigned long) hi->addr_mapped[0], hi->addr[0],
            hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn),
            (u_int8_t) PCI_FUNC (pdev->devfn), pdev->irq);

    pdev = hi->pdev[1];
    pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
            hi->devname, "EBUS  ",
            (unsigned long) hi->addr_mapped[1], hi->addr[1],
            hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn),
            (u_int8_t) PCI_FUNC (pdev->devfn), pdev->irq);
}


void        __init
hdw_sn_get (hdw_info_t *hi, int brdno)
{
    /* obtain hardware EEPROM information */
    long        addr;

    addr = (long) hi->addr_mapped[1] + EEPROM_OFFSET;

    /* read EEPROM with largest known format size... */
    pmc_eeprom_read_buffer (addr, 0, (char *) hi->mfg_info.data, sizeof (FLD_TYPE2));

#if 0
    {
        unsigned char *ucp = (unsigned char *) &hi->mfg_info.data;

        pr_info("eeprom[00]:  %02x %02x %02x %02x  %02x %02x %02x %02x\n",
                *(ucp + 0), *(ucp + 1), *(ucp + 2), *(ucp + 3), *(ucp + 4), *(ucp + 5), *(ucp + 6), *(ucp + 7));
        pr_info("eeprom[08]:  %02x %02x %02x %02x  %02x %02x %02x %02x\n",
                *(ucp + 8), *(ucp + 9), *(ucp + 10), *(ucp + 11), *(ucp + 12), *(ucp + 13), *(ucp + 14), *(ucp + 15));
        pr_info("eeprom[16]:  %02x %02x %02x %02x  %02x %02x %02x %02x\n",
                *(ucp + 16), *(ucp + 17), *(ucp + 18), *(ucp + 19), *(ucp + 20), *(ucp + 21), *(ucp + 22), *(ucp + 23));
        pr_info("eeprom[24]:  %02x %02x %02x %02x  %02x %02x %02x %02x\n",
                *(ucp + 24), *(ucp + 25), *(ucp + 26), *(ucp + 27), *(ucp + 28), *(ucp + 29), *(ucp + 30), *(ucp + 31));
        pr_info("eeprom[32]:  %02x %02x %02x %02x  %02x %02x %02x %02x\n",
                *(ucp + 32), *(ucp + 33), *(ucp + 34), *(ucp + 35), *(ucp + 36), *(ucp + 37), *(ucp + 38), *(ucp + 39));
        pr_info("eeprom[40]:  %02x %02x %02x %02x  %02x %02x %02x %02x\n",
                *(ucp + 40), *(ucp + 41), *(ucp + 42), *(ucp + 43), *(ucp + 44), *(ucp + 45), *(ucp + 46), *(ucp + 47));
    }
#endif
#if 0
    pr_info("sn: %x %x %x %x %x %x\n",
            hi->mfg_info.Serial[0],
            hi->mfg_info.Serial[1],
            hi->mfg_info.Serial[2],
            hi->mfg_info.Serial[3],
            hi->mfg_info.Serial[4],
            hi->mfg_info.Serial[5]);
#endif

    if ((hi->promfmt = pmc_verify_cksum (&hi->mfg_info.data)) == PROM_FORMAT_Unk)
    {
        /* bad crc, data is suspect */
        if (cxt1e1_log_level >= LOG_WARN)
            pr_info("%s: EEPROM cksum error\n", hi->devname);
        hi->mfg_info_sts = EEPROM_CRCERR;
    } else
        hi->mfg_info_sts = EEPROM_OK;
}


void        __init
prep_hdw_info (void)
{
    hdw_info_t *hi;
    int         i;

    for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
    {
        hi->pci_busno = 0xff;
        hi->pci_slot = 0xff;
        hi->pci_pin[0] = 0;
        hi->pci_pin[1] = 0;
        hi->ndev = NULL;
        hi->addr[0] = 0L;
        hi->addr[1] = 0L;
        hi->addr_mapped[0] = 0L;
        hi->addr_mapped[1] = 0L;
    }
}

void
cleanup_ioremap (void)
{
    hdw_info_t *hi;
    int         i;

    for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
    {
        if (hi->pci_slot == 0xff)
            break;
        if (hi->addr_mapped[0])
        {
            iounmap ((void *) (hi->addr_mapped[0]));
            release_mem_region ((long) hi->addr[0], hi->len[0]);
            hi->addr_mapped[0] = 0;
        }
        if (hi->addr_mapped[1])
        {
            iounmap ((void *) (hi->addr_mapped[1]));
            release_mem_region ((long) hi->addr[1], hi->len[1]);
            hi->addr_mapped[1] = 0;
        }
    }
}


void
cleanup_devs (void)
{
    hdw_info_t *hi;
    int         i;

    for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
    {
        if (hi->pci_slot == 0xff || !hi->ndev)
            break;
        c4_stopwd(netdev_priv(hi->ndev));
#ifdef CONFIG_PROC_FS
        sbecom_proc_brd_cleanup(netdev_priv(hi->ndev));
#endif
        unregister_netdev (hi->ndev);
        free_irq (hi->pdev[0]->irq, hi->ndev);
#ifdef CONFIG_SBE_PMCC4_NCOMM
        free_irq (hi->pdev[1]->irq, hi->ndev);
#endif
        OS_kfree (hi->ndev);
    }
}


static int  __init
c4_hdw_init (struct pci_dev *pdev, int found)
{
    hdw_info_t *hi;
    int         i;
    int         fun, slot;
    unsigned char busno = 0xff;

    /* our MUSYCC chip supports two functions, 0 & 1 */
    if ((fun = PCI_FUNC (pdev->devfn)) > 1)
    {
        pr_warning("unexpected devfun: 0x%x\n", pdev->devfn);
        return 0;
    }
    if (pdev->bus)                  /* obtain bus number */
        busno = pdev->bus->number;
    else
        busno = 0;                  /* default for system PCI inconsistency */
    slot = pdev->devfn & ~0x07;

    /*
     * Functions 0 & 1 for a given board (identified by same bus(busno) and
     * slot(slot)) are placed into the same 'hardware' structure.  The first
     * part of the board's functionality will be placed into an unpopulated
     * element, identified by "slot==(0xff)".  The second part of a board's
     * functionality will match the previously loaded slot/busno.
     */
    for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
    {
        /*
         * match with board's first found interface, otherwise this is first
         * found
         */
        if ((hi->pci_slot == 0xff) ||   /* new board */
            ((hi->pci_slot == slot) && (hi->bus == pdev->bus)))
            break;                  /* found for-loop exit */
    }
    if (i == MAX_BOARDS)            /* no match in above loop means MAX
                                     * exceeded */
    {
        pr_warning("exceeded number of allowed devices (>%d)?\n", MAX_BOARDS);
        return 0;
    }
    if (pdev->bus)
        hi->pci_busno = pdev->bus->number;
    else
        hi->pci_busno = 0;          /* default for system PCI inconsistency */
    hi->pci_slot = slot;
    pci_read_config_byte (pdev, PCI_INTERRUPT_PIN, &hi->pci_pin[fun]);
    pci_read_config_byte (pdev, PCI_REVISION_ID, &hi->revid[fun]);
    hi->bus = pdev->bus;
    hi->addr[fun] = pci_resource_start (pdev, 0);
    hi->len[fun] = pci_resource_end (pdev, 0) - hi->addr[fun] + 1;
    hi->pdev[fun] = pdev;

    {
        /*
         * create device name from module name, plus add the appropriate
         * board number
         */
        char       *cp = hi->devname;

        strcpy (cp, KBUILD_MODNAME);
        cp += strlen (cp);          /* reposition */
        *cp++ = '-';
        *cp++ = '0' + (found / 2);  /* there are two found interfaces per
                                     * board */
        *cp = 0;                    /* termination */
    }

    return 1;
}


status_t    __init
c4hw_attach_all (void)
{
    hdw_info_t *hi;
    struct pci_dev *pdev = NULL;
    int         found = 0, i, j;

    error_flag = 0;
    prep_hdw_info ();
    /*** scan PCI bus for all possible boards */
    while ((pdev = pci_get_device (PCI_VENDOR_ID_CONEXANT,
                                    PCI_DEVICE_ID_CN8474,
                                    pdev)))
    {
        if (c4_hdw_init (pdev, found))
            found++;
    }
    if (!found)
    {
        pr_warning("No boards found\n");
        return -ENODEV;
    }
    /* sanity check for consistent hardware found */
    for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
    {
        if (hi->pci_slot != 0xff && (!hi->addr[0] || !hi->addr[1]))
        {
            pr_warning("%s: something very wrong with pci_get_device\n",
                       hi->devname);
            return -EIO;
        }
    }
    /* bring board's memory regions on/line */
    for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
    {
        if (hi->pci_slot == 0xff)
            break;
        for (j = 0; j < 2; j++)
        {
	    if (!request_mem_region (hi->addr[j], hi->len[j], hi->devname))
            {
                pr_warning("%s: memory in use, addr=0x%lx, len=0x%lx ?\n",
                           hi->devname, hi->addr[j], hi->len[j]);
                cleanup_ioremap ();
                return -ENOMEM;
            }
            hi->addr_mapped[j] = (unsigned long) ioremap (hi->addr[j], hi->len[j]);
            if (!hi->addr_mapped[j])
            {
                pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n",
                           hi->devname, hi->addr[j], hi->len[j]);
                cleanup_ioremap ();
                return -ENOMEM;
            }
#ifdef SBE_MAP_DEBUG
            pr_warning("%s: io remapped from phys %x to virt %x\n",
                       hi->devname, (u_int32_t) hi->addr[j], (u_int32_t) hi->addr_mapped[j]);
#endif
        }
    }

    drvr_state = SBE_DRVR_AVAILABLE;

    /* Have now memory mapped all boards.  Now allow board's access to system */
    for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
    {
        if (hi->pci_slot == 0xff)
            break;
        if (pci_enable_device (hi->pdev[0]) ||
            pci_enable_device (hi->pdev[1]))
        {
            drvr_state = SBE_DRVR_DOWN;
            pr_warning("%s: failed to enable card %d slot %d\n",
                       hi->devname, i, hi->pci_slot);
            cleanup_devs ();
            cleanup_ioremap ();
            return -EIO;
        }
        pci_set_master (hi->pdev[0]);
        pci_set_master (hi->pdev[1]);
        if (!(hi->ndev = c4_add_dev (hi, i, (long) hi->addr_mapped[0],
                                     (long) hi->addr_mapped[1],
                                     hi->pdev[0]->irq,
                                     hi->pdev[1]->irq)))
        {
            drvr_state = SBE_DRVR_DOWN;
            cleanup_ioremap ();
            /* NOTE: c4_add_dev() does its own device cleanup */
#if 0
            cleanup_devs ();
#endif
            return error_flag;      /* error_flag set w/in add_dev() */
        }
        show_two (hi, i);           /* displays found information */
    }
    return 0;
}

/***  End-of-File  ***/
