/* 
 * 7990.c -- LANCE ethernet IC generic routines. 
 * This is an attempt to separate out the bits of various ethernet
 * drivers that are common because they all use the AMD 7990 LANCE 
 * (Local Area Network Controller for Ethernet) chip.
 *
 * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
 *
 * Most of this stuff was obtained by looking at other LANCE drivers,
 * in particular a2065.[ch]. The AMD C-LANCE datasheet was also helpful.
 * NB: this was made easy by the fact that Jes Sorensen had cleaned up
 * most of a2025 and sunlance with the aim of merging them, so the 
 * common code was pretty obvious.
 */
#include <linux/crc32.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/route.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <asm/irq.h>
/* Used for the temporal inet entries and routing */
#include <linux/socket.h>
#include <linux/bitops.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/pgtable.h>
#ifdef CONFIG_HP300
#include <asm/blinken.h>
#endif

#include "7990.h"

#define WRITERAP(lp,x) out_be16(lp->base + LANCE_RAP, (x))
#define WRITERDP(lp,x) out_be16(lp->base + LANCE_RDP, (x))
#define READRDP(lp) in_be16(lp->base + LANCE_RDP)

#if defined(CONFIG_HPLANCE) || defined(CONFIG_HPLANCE_MODULE)
#include "hplance.h"

#undef WRITERAP
#undef WRITERDP
#undef READRDP

#if defined(CONFIG_MVME147_NET) || defined(CONFIG_MVME147_NET_MODULE)

/* Lossage Factor Nine, Mr Sulu. */
#define WRITERAP(lp,x) (lp->writerap(lp,x))
#define WRITERDP(lp,x) (lp->writerdp(lp,x))
#define READRDP(lp) (lp->readrdp(lp))

#else

/* These inlines can be used if only CONFIG_HPLANCE is defined */
static inline void WRITERAP(struct lance_private *lp, __u16 value)
{
	do {
		out_be16(lp->base + HPLANCE_REGOFF + LANCE_RAP, value);
	} while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
}

static inline void WRITERDP(struct lance_private *lp, __u16 value)
{
	do {
		out_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP, value);
	} while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
}

static inline __u16 READRDP(struct lance_private *lp)
{
	__u16 value;
	do {
		value = in_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP);
	} while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
	return value;
}

#endif
#endif /* CONFIG_HPLANCE || CONFIG_HPLANCE_MODULE */

/* debugging output macros, various flavours */
/* #define TEST_HITS */
#ifdef UNDEF
#define PRINT_RINGS() \
do { \
        int t; \
        for (t=0; t < RX_RING_SIZE; t++) { \
                printk("R%d: @(%02X %04X) len %04X, mblen %04X, bits %02X\n",\
                       t, ib->brx_ring[t].rmd1_hadr, ib->brx_ring[t].rmd0,\
                       ib->brx_ring[t].length,\
                       ib->brx_ring[t].mblength, ib->brx_ring[t].rmd1_bits);\
        }\
        for (t=0; t < TX_RING_SIZE; t++) { \
                printk("T%d: @(%02X %04X) len %04X, misc %04X, bits %02X\n",\
                       t, ib->btx_ring[t].tmd1_hadr, ib->btx_ring[t].tmd0,\
                       ib->btx_ring[t].length,\
                       ib->btx_ring[t].misc, ib->btx_ring[t].tmd1_bits);\
        }\
} while (0) 
#else
#define PRINT_RINGS()
#endif        

/* Load the CSR registers. The LANCE has to be STOPped when we do this! */
static void load_csrs (struct lance_private *lp)
{
        volatile struct lance_init_block *aib = lp->lance_init_block;
        int leptr;

        leptr = LANCE_ADDR (aib);

        WRITERAP(lp, LE_CSR1);                    /* load address of init block */
        WRITERDP(lp, leptr & 0xFFFF);
        WRITERAP(lp, LE_CSR2);
        WRITERDP(lp, leptr >> 16);
        WRITERAP(lp, LE_CSR3);
        WRITERDP(lp, lp->busmaster_regval);       /* set byteswap/ALEctrl/byte ctrl */

        /* Point back to csr0 */
        WRITERAP(lp, LE_CSR0);
}

/* #define to 0 or 1 appropriately */
#define DEBUG_IRING 0
/* Set up the Lance Rx and Tx rings and the init block */
static void lance_init_ring (struct net_device *dev)
{
        struct lance_private *lp = netdev_priv(dev);
        volatile struct lance_init_block *ib = lp->init_block;
        volatile struct lance_init_block *aib; /* for LANCE_ADDR computations */
        int leptr;
        int i;

        aib = lp->lance_init_block;

        lp->rx_new = lp->tx_new = 0;
        lp->rx_old = lp->tx_old = 0;

        ib->mode = LE_MO_PROM;                             /* normal, enable Tx & Rx */

        /* Copy the ethernet address to the lance init block
         * Notice that we do a byteswap if we're big endian.
         * [I think this is the right criterion; at least, sunlance,
         * a2065 and atarilance do the byteswap and lance.c (PC) doesn't.
         * However, the datasheet says that the BSWAP bit doesn't affect
         * the init block, so surely it should be low byte first for
         * everybody? Um.] 
         * We could define the ib->physaddr as three 16bit values and
         * use (addr[1] << 8) | addr[0] & co, but this is more efficient.
         */
#ifdef __BIG_ENDIAN
        ib->phys_addr [0] = dev->dev_addr [1];
        ib->phys_addr [1] = dev->dev_addr [0];
        ib->phys_addr [2] = dev->dev_addr [3];
        ib->phys_addr [3] = dev->dev_addr [2];
        ib->phys_addr [4] = dev->dev_addr [5];
        ib->phys_addr [5] = dev->dev_addr [4];
#else
        for (i=0; i<6; i++)
           ib->phys_addr[i] = dev->dev_addr[i];
#endif        

        if (DEBUG_IRING)
                printk ("TX rings:\n");
    
	lp->tx_full = 0;
        /* Setup the Tx ring entries */
        for (i = 0; i < (1<<lp->lance_log_tx_bufs); i++) {
                leptr = LANCE_ADDR(&aib->tx_buf[i][0]);
                ib->btx_ring [i].tmd0      = leptr;
                ib->btx_ring [i].tmd1_hadr = leptr >> 16;
                ib->btx_ring [i].tmd1_bits = 0;
                ib->btx_ring [i].length    = 0xf000; /* The ones required by tmd2 */
                ib->btx_ring [i].misc      = 0;
                if (DEBUG_IRING) 
                   printk ("%d: 0x%8.8x\n", i, leptr);
        }

        /* Setup the Rx ring entries */
        if (DEBUG_IRING)
                printk ("RX rings:\n");
        for (i = 0; i < (1<<lp->lance_log_rx_bufs); i++) {
                leptr = LANCE_ADDR(&aib->rx_buf[i][0]);

                ib->brx_ring [i].rmd0      = leptr;
                ib->brx_ring [i].rmd1_hadr = leptr >> 16;
                ib->brx_ring [i].rmd1_bits = LE_R1_OWN;
                /* 0xf000 == bits that must be one (reserved, presumably) */
                ib->brx_ring [i].length    = -RX_BUFF_SIZE | 0xf000;
                ib->brx_ring [i].mblength  = 0;
                if (DEBUG_IRING)
                        printk ("%d: 0x%8.8x\n", i, leptr);
        }

        /* Setup the initialization block */
    
        /* Setup rx descriptor pointer */
        leptr = LANCE_ADDR(&aib->brx_ring);
        ib->rx_len = (lp->lance_log_rx_bufs << 13) | (leptr >> 16);
        ib->rx_ptr = leptr;
        if (DEBUG_IRING)
                printk ("RX ptr: %8.8x\n", leptr);
    
        /* Setup tx descriptor pointer */
        leptr = LANCE_ADDR(&aib->btx_ring);
        ib->tx_len = (lp->lance_log_tx_bufs << 13) | (leptr >> 16);
        ib->tx_ptr = leptr;
        if (DEBUG_IRING)
                printk ("TX ptr: %8.8x\n", leptr);

        /* Clear the multicast filter */
        ib->filter [0] = 0;
        ib->filter [1] = 0;
        PRINT_RINGS();
}

/* LANCE must be STOPped before we do this, too... */
static int init_restart_lance (struct lance_private *lp)
{
        int i;

        WRITERAP(lp, LE_CSR0);
        WRITERDP(lp, LE_C0_INIT);

        /* Need a hook here for sunlance ledma stuff */

        /* Wait for the lance to complete initialization */
        for (i = 0; (i < 100) && !(READRDP(lp) & (LE_C0_ERR | LE_C0_IDON)); i++)
                barrier();
        if ((i == 100) || (READRDP(lp) & LE_C0_ERR)) {
                printk ("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, READRDP(lp));
                return -1;
        }

        /* Clear IDON by writing a "1", enable interrupts and start lance */
        WRITERDP(lp, LE_C0_IDON);
        WRITERDP(lp, LE_C0_INEA | LE_C0_STRT);

        return 0;
}

static int lance_reset (struct net_device *dev)
{
        struct lance_private *lp = netdev_priv(dev);
        int status;
    
        /* Stop the lance */
        WRITERAP(lp, LE_CSR0);
        WRITERDP(lp, LE_C0_STOP);

        load_csrs (lp);
        lance_init_ring (dev);
        dev->trans_start = jiffies;
        status = init_restart_lance (lp);
#ifdef DEBUG_DRIVER
        printk ("Lance restart=%d\n", status);
#endif
        return status;
}

static int lance_rx (struct net_device *dev)
{
        struct lance_private *lp = netdev_priv(dev);
        volatile struct lance_init_block *ib = lp->init_block;
        volatile struct lance_rx_desc *rd;
        unsigned char bits;
        int len = 0;                    /* XXX shut up gcc warnings */
        struct sk_buff *skb = 0;        /* XXX shut up gcc warnings */
#ifdef TEST_HITS
        int i;
#endif

#ifdef TEST_HITS
        printk ("[");
        for (i = 0; i < RX_RING_SIZE; i++) {
                if (i == lp->rx_new)
                        printk ("%s",
                                ib->brx_ring [i].rmd1_bits & LE_R1_OWN ? "_" : "X");
                else
                        printk ("%s",
                                ib->brx_ring [i].rmd1_bits & LE_R1_OWN ? "." : "1");
        }
        printk ("]");
#endif
#ifdef CONFIG_HP300
	blinken_leds(0x40, 0);
#endif    
        WRITERDP(lp, LE_C0_RINT | LE_C0_INEA);     /* ack Rx int, reenable ints */
        for (rd = &ib->brx_ring [lp->rx_new];     /* For each Rx ring we own... */
             !((bits = rd->rmd1_bits) & LE_R1_OWN);
             rd = &ib->brx_ring [lp->rx_new]) {

                /* We got an incomplete frame? */
                if ((bits & LE_R1_POK) != LE_R1_POK) {
                        lp->stats.rx_over_errors++;
                        lp->stats.rx_errors++;
                        continue;
                } else if (bits & LE_R1_ERR) {
                        /* Count only the end frame as a rx error,
                         * not the beginning
                         */
                        if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++;
                        if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++;
                        if (bits & LE_R1_OFL) lp->stats.rx_over_errors++;
                        if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++;
                        if (bits & LE_R1_EOP) lp->stats.rx_errors++;
                } else {
                        len = (rd->mblength & 0xfff) - 4;
                        skb = dev_alloc_skb (len+2);

                        if (skb == 0) {
                                printk ("%s: Memory squeeze, deferring packet.\n",
                                        dev->name);
                                lp->stats.rx_dropped++;
                                rd->mblength = 0;
                                rd->rmd1_bits = LE_R1_OWN;
                                lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask;
                                return 0;
                        }
            
                        skb->dev = dev;
                        skb_reserve (skb, 2);           /* 16 byte align */
                        skb_put (skb, len);             /* make room */
                        eth_copy_and_sum(skb,
                                         (unsigned char *)&(ib->rx_buf [lp->rx_new][0]),
                                         len, 0);
                        skb->protocol = eth_type_trans (skb, dev);
			netif_rx (skb);
			dev->last_rx = jiffies;
			lp->stats.rx_packets++;
			lp->stats.rx_bytes += len;
                }

                /* Return the packet to the pool */
                rd->mblength = 0;
                rd->rmd1_bits = LE_R1_OWN;
                lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask;
        }
        return 0;
}

static int lance_tx (struct net_device *dev)
{
        struct lance_private *lp = netdev_priv(dev);
        volatile struct lance_init_block *ib = lp->init_block;
        volatile struct lance_tx_desc *td;
        int i, j;
        int status;

#ifdef CONFIG_HP300
	blinken_leds(0x80, 0);
#endif
        /* csr0 is 2f3 */
        WRITERDP(lp, LE_C0_TINT | LE_C0_INEA);
        /* csr0 is 73 */

        j = lp->tx_old;
        for (i = j; i != lp->tx_new; i = j) {
                td = &ib->btx_ring [i];

                /* If we hit a packet not owned by us, stop */
                if (td->tmd1_bits & LE_T1_OWN)
                        break;
                
                if (td->tmd1_bits & LE_T1_ERR) {
                        status = td->misc;
            
                        lp->stats.tx_errors++;
                        if (status & LE_T3_RTY)  lp->stats.tx_aborted_errors++;
                        if (status & LE_T3_LCOL) lp->stats.tx_window_errors++;

                        if (status & LE_T3_CLOS) {
                                lp->stats.tx_carrier_errors++;
                                if (lp->auto_select) {
                                        lp->tpe = 1 - lp->tpe;
                                        printk("%s: Carrier Lost, trying %s\n",
                                               dev->name, lp->tpe?"TPE":"AUI");
                                        /* Stop the lance */
                                        WRITERAP(lp, LE_CSR0);
                                        WRITERDP(lp, LE_C0_STOP);
                                        lance_init_ring (dev);
                                        load_csrs (lp);
                                        init_restart_lance (lp);
                                        return 0;
                                }
                        }

                        /* buffer errors and underflows turn off the transmitter */
                        /* Restart the adapter */
                        if (status & (LE_T3_BUF|LE_T3_UFL)) {
                                lp->stats.tx_fifo_errors++;

                                printk ("%s: Tx: ERR_BUF|ERR_UFL, restarting\n",
                                        dev->name);
                                /* Stop the lance */
                                WRITERAP(lp, LE_CSR0);
                                WRITERDP(lp, LE_C0_STOP);
                                lance_init_ring (dev);
                                load_csrs (lp);
                                init_restart_lance (lp);
                                return 0;
                        }
                } else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) {
                        /*
                         * So we don't count the packet more than once.
                         */
                        td->tmd1_bits &= ~(LE_T1_POK);

                        /* One collision before packet was sent. */
                        if (td->tmd1_bits & LE_T1_EONE)
                                lp->stats.collisions++;

                        /* More than one collision, be optimistic. */
                        if (td->tmd1_bits & LE_T1_EMORE)
                                lp->stats.collisions += 2;

                        lp->stats.tx_packets++;
                }
        
                j = (j + 1) & lp->tx_ring_mod_mask;
        }
        lp->tx_old = j;
        WRITERDP(lp, LE_C0_TINT | LE_C0_INEA);
        return 0;
}

static irqreturn_t
lance_interrupt (int irq, void *dev_id, struct pt_regs *regs)
{
        struct net_device *dev = (struct net_device *)dev_id;
        struct lance_private *lp = netdev_priv(dev);
        int csr0;

	spin_lock (&lp->devlock);

        WRITERAP(lp, LE_CSR0);              /* LANCE Controller Status */
        csr0 = READRDP(lp);

        PRINT_RINGS();
        
        if (!(csr0 & LE_C0_INTR)) {     /* Check if any interrupt has */
		spin_unlock (&lp->devlock);
                return IRQ_NONE;        /* been generated by the Lance. */
	}

        /* Acknowledge all the interrupt sources ASAP */
        WRITERDP(lp, csr0 & ~(LE_C0_INEA|LE_C0_TDMD|LE_C0_STOP|LE_C0_STRT|LE_C0_INIT));

        if ((csr0 & LE_C0_ERR)) {
                /* Clear the error condition */
                WRITERDP(lp, LE_C0_BABL|LE_C0_ERR|LE_C0_MISS|LE_C0_INEA);
        }

        if (csr0 & LE_C0_RINT)
                lance_rx (dev);

        if (csr0 & LE_C0_TINT)
                lance_tx (dev);

        /* Log misc errors. */
        if (csr0 & LE_C0_BABL)
                lp->stats.tx_errors++;       /* Tx babble. */
        if (csr0 & LE_C0_MISS)
                lp->stats.rx_errors++;       /* Missed a Rx frame. */
        if (csr0 & LE_C0_MERR) {
                printk("%s: Bus master arbitration failure, status %4.4x.\n", 
                       dev->name, csr0);
                /* Restart the chip. */
                WRITERDP(lp, LE_C0_STRT);
        }

        if (lp->tx_full && netif_queue_stopped(dev) && (TX_BUFFS_AVAIL >= 0)) {
		lp->tx_full = 0;
		netif_wake_queue (dev);
        }
        
        WRITERAP(lp, LE_CSR0);
        WRITERDP(lp, LE_C0_BABL|LE_C0_CERR|LE_C0_MISS|LE_C0_MERR|LE_C0_IDON|LE_C0_INEA);

	spin_unlock (&lp->devlock);
	return IRQ_HANDLED;
}

int lance_open (struct net_device *dev)
{
        struct lance_private *lp = netdev_priv(dev);
	int res;
        
        /* Install the Interrupt handler. Or we could shunt this out to specific drivers? */
        if (request_irq(lp->irq, lance_interrupt, 0, lp->name, dev))
                return -EAGAIN;

        res = lance_reset(dev);
	spin_lock_init(&lp->devlock);
	netif_start_queue (dev);

	return res;
}

int lance_close (struct net_device *dev)
{
        struct lance_private *lp = netdev_priv(dev);
        
	netif_stop_queue (dev);

        /* Stop the LANCE */
        WRITERAP(lp, LE_CSR0);
        WRITERDP(lp, LE_C0_STOP);

        free_irq(lp->irq, dev);

        return 0;
}

void lance_tx_timeout(struct net_device *dev)
{
	printk("lance_tx_timeout\n");
	lance_reset(dev);
	dev->trans_start = jiffies;
	netif_wake_queue (dev);
}


int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
{
        struct lance_private *lp = netdev_priv(dev);
        volatile struct lance_init_block *ib = lp->init_block;
        int entry, skblen, len;
        static int outs;
	unsigned long flags;

        if (!TX_BUFFS_AVAIL)
                return -1;

	netif_stop_queue (dev);

        skblen = skb->len;

#ifdef DEBUG_DRIVER
        /* dump the packet */
        {
                int i;
        
                for (i = 0; i < 64; i++) {
                        if ((i % 16) == 0)
                                printk ("\n");
                        printk ("%2.2x ", skb->data [i]);
                }
        }
#endif
        len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;
        entry = lp->tx_new & lp->tx_ring_mod_mask;
        ib->btx_ring [entry].length = (-len) | 0xf000;
        ib->btx_ring [entry].misc = 0;
    
    	if (skb->len < ETH_ZLEN)
    		memset((char *)&ib->tx_buf[entry][0], 0, ETH_ZLEN);
        memcpy ((char *)&ib->tx_buf [entry][0], skb->data, skblen);
    
        /* Now, give the packet to the lance */
        ib->btx_ring [entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN);
        lp->tx_new = (lp->tx_new+1) & lp->tx_ring_mod_mask;

        outs++;
        /* Kick the lance: transmit now */
        WRITERDP(lp, LE_C0_INEA | LE_C0_TDMD);
        dev->trans_start = jiffies;
        dev_kfree_skb (skb);
    
	spin_lock_irqsave (&lp->devlock, flags);
        if (TX_BUFFS_AVAIL)
		netif_start_queue (dev);
	else
		lp->tx_full = 1;
	spin_unlock_irqrestore (&lp->devlock, flags);

        return 0;
}

struct net_device_stats *lance_get_stats (struct net_device *dev)
{
        struct lance_private *lp = netdev_priv(dev);

        return &lp->stats;
}

/* taken from the depca driver via a2065.c */
static void lance_load_multicast (struct net_device *dev)
{
        struct lance_private *lp = netdev_priv(dev);
        volatile struct lance_init_block *ib = lp->init_block;
        volatile u16 *mcast_table = (u16 *)&ib->filter;
        struct dev_mc_list *dmi=dev->mc_list;
        char *addrs;
        int i;
        u32 crc;
        
        /* set all multicast bits */
        if (dev->flags & IFF_ALLMULTI){ 
                ib->filter [0] = 0xffffffff;
                ib->filter [1] = 0xffffffff;
                return;
        }
        /* clear the multicast filter */
        ib->filter [0] = 0;
        ib->filter [1] = 0;

        /* Add addresses */
        for (i = 0; i < dev->mc_count; i++){
                addrs = dmi->dmi_addr;
                dmi   = dmi->next;

                /* multicast address? */
                if (!(*addrs & 1))
                        continue;
                
		crc = ether_crc_le(6, addrs);
                crc = crc >> 26;
                mcast_table [crc >> 4] |= 1 << (crc & 0xf);
        }
        return;
}


void lance_set_multicast (struct net_device *dev)
{
        struct lance_private *lp = netdev_priv(dev);
        volatile struct lance_init_block *ib = lp->init_block;
	int stopped;

	stopped = netif_queue_stopped(dev);
	if (!stopped)
		netif_stop_queue (dev);

        while (lp->tx_old != lp->tx_new)
                schedule();

        WRITERAP(lp, LE_CSR0);
        WRITERDP(lp, LE_C0_STOP);
        lance_init_ring (dev);

        if (dev->flags & IFF_PROMISC) {
                ib->mode |= LE_MO_PROM;
        } else {
                ib->mode &= ~LE_MO_PROM;
                lance_load_multicast (dev);
        }
        load_csrs (lp);
        init_restart_lance (lp);

	if (!stopped)
		netif_start_queue (dev);
}

#ifdef CONFIG_NET_POLL_CONTROLLER
void lance_poll(struct net_device *dev)
{
	struct lance_private *lp = netdev_priv(dev);

	spin_lock (&lp->devlock);
	WRITERAP(lp, LE_CSR0);
	WRITERDP(lp, LE_C0_STRT);
	spin_unlock (&lp->devlock);
	lance_interrupt(dev->irq, dev, NULL);
}
#endif

MODULE_LICENSE("GPL");
