Merge branch 'master' into upstream
authorJeff Garzik <jeff@garzik.org>
Thu, 7 Dec 2006 09:57:19 +0000 (04:57 -0500)
committerJeff Garzik <jeff@garzik.org>
Thu, 7 Dec 2006 09:57:19 +0000 (04:57 -0500)
Conflicts:

drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_main.c

55 files changed:
drivers/net/3c501.c
drivers/net/3c503.c
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c523.c
drivers/net/3c527.c
drivers/net/ac3200.c
drivers/net/apne.c
drivers/net/appletalk/cops.c
drivers/net/arm/ether1.c
drivers/net/arm/ether3.c
drivers/net/at1700.c
drivers/net/atarilance.c
drivers/net/bonding/bond_main.c
drivers/net/cs89x0.c
drivers/net/declance.c
drivers/net/e2100.c
drivers/net/eepro.c
drivers/net/eexpress.c
drivers/net/es3210.c
drivers/net/eth16i.c
drivers/net/hp-plus.c
drivers/net/hp.c
drivers/net/lance.c
drivers/net/lne390.c
drivers/net/mv643xx_eth.c
drivers/net/mvme147.c
drivers/net/myri10ge/myri10ge.c
drivers/net/myri10ge/myri10ge_mcp.h
drivers/net/myri10ge/myri10ge_mcp_gen_header.h
drivers/net/ne.c
drivers/net/ne2.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_ethtool.c
drivers/net/netxen/netxen_nic_hdr.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_hw.h
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_ioctl.h
drivers/net/netxen/netxen_nic_isr.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/netxen/netxen_nic_niu.c
drivers/net/netxen/netxen_nic_phan_reg.h
drivers/net/ni52.c
drivers/net/ni65.c
drivers/net/ns83820.c
drivers/net/seeq8005.c
drivers/net/sk98lin/skgesirq.c
drivers/net/smc-ultra.c
drivers/net/smc-ultra32.c
drivers/net/smc9194.c
drivers/net/smc91x.h
drivers/net/sun3lance.c
drivers/net/tokenring/smctr.c
drivers/net/wd.c

index 11d170a..06e3378 100644 (file)
@@ -922,7 +922,7 @@ int __init init_module(void)
  * and then free up the resources we took when the card was found.
  */
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        struct net_device *dev = dev_3c501;
        unregister_netdev(dev);
index a34b220..7e34c4f 100644 (file)
@@ -726,7 +726,7 @@ static void cleanup_card(struct net_device *dev)
                iounmap(ei_status.mem);
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        int this_dev;
index 458cb9c..702bfb2 100644 (file)
@@ -1670,7 +1670,7 @@ int __init init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        int this_dev;
 
index aa43563..54e1d5a 100644 (file)
@@ -940,7 +940,7 @@ int __init init_module(void)
        return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        struct net_device *dev = dev_3c507;
index 9184946..17d61eb 100644 (file)
@@ -1302,7 +1302,7 @@ int __init init_module(void)
        } else return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        int this_dev;
        for (this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
index f4aca53..6c7437e 100644 (file)
@@ -1659,7 +1659,7 @@ int __init init_module(void)
  *     transmit operations are allowed to start scribbling into memory.
  */
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        unregister_netdev(this_device);
        cleanup_card(this_device);
index 0dca8bb..c01f87f 100644 (file)
@@ -405,7 +405,7 @@ static void cleanup_card(struct net_device *dev)
        iounmap(ei_status.mem);
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        int this_dev;
index 9164d8c..d4e4081 100644 (file)
@@ -568,7 +568,7 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id)
 #ifdef MODULE
 static struct net_device *apne_dev;
 
-int init_module(void)
+int __init init_module(void)
 {
        apne_dev = apne_probe(-1);
        if (IS_ERR(apne_dev))
@@ -576,7 +576,7 @@ int init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        unregister_netdev(apne_dev);
 
index cc1a27e..dba5e51 100644 (file)
@@ -1041,7 +1041,7 @@ int __init init_module(void)
         return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        unregister_netdev(cops_dev);
        cleanup_card(cops_dev);
index f3478a3..d6da3ce 100644 (file)
@@ -254,7 +254,7 @@ ether1_readbuffer (struct net_device *dev, void *data, unsigned int start, unsig
        } while (thislen);
 }
 
-static int __init
+static int __devinit
 ether1_ramtest(struct net_device *dev, unsigned char byte)
 {
        unsigned char *buffer = kmalloc (BUFFER_SIZE, GFP_KERNEL);
@@ -308,7 +308,7 @@ ether1_reset (struct net_device *dev)
        return BUS_16;
 }
 
-static int __init
+static int __devinit
 ether1_init_2(struct net_device *dev)
 {
        int i;
@@ -986,7 +986,7 @@ ether1_setmulticastlist (struct net_device *dev)
 
 /* ------------------------------------------------------------------------- */
 
-static void __init ether1_banner(void)
+static void __devinit ether1_banner(void)
 {
        static unsigned int version_printed = 0;
 
index 84686c8..4fc2347 100644 (file)
@@ -198,7 +198,7 @@ static inline void ether3_ledon(struct net_device *dev)
  * Read the ethernet address string from the on board rom.
  * This is an ascii string!!!
  */
-static int __init
+static int __devinit
 ether3_addr(char *addr, struct expansion_card *ec)
 {
        struct in_chunk_dir cd;
@@ -223,7 +223,7 @@ ether3_addr(char *addr, struct expansion_card *ec)
 
 /* --------------------------------------------------------------------------- */
 
-static int __init
+static int __devinit
 ether3_ramtest(struct net_device *dev, unsigned char byte)
 {
        unsigned char *buffer = kmalloc(RX_END, GFP_KERNEL);
@@ -272,7 +272,7 @@ ether3_ramtest(struct net_device *dev, unsigned char byte)
 
 /* ------------------------------------------------------------------------------- */
 
-static int __init ether3_init_2(struct net_device *dev)
+static int __devinit ether3_init_2(struct net_device *dev)
 {
        int i;
 
@@ -765,7 +765,7 @@ static void ether3_tx(struct net_device *dev)
        }
 }
 
-static void __init ether3_banner(void)
+static void __devinit ether3_banner(void)
 {
        static unsigned version_printed = 0;
 
index 8620a5b..56ae8ba 100644 (file)
@@ -908,7 +908,7 @@ int __init init_module(void)
        return 0;
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        unregister_netdev(dev_at1700);
index d79489e..7e37ac8 100644 (file)
@@ -1179,7 +1179,7 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
 #ifdef MODULE
 static struct net_device *atarilance_dev;
 
-int init_module(void)
+int __init init_module(void)
 {
        atarilance_dev = atarilance_probe(-1);
        if (IS_ERR(atarilance_dev))
@@ -1187,7 +1187,7 @@ int init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        unregister_netdev(atarilance_dev);
        free_irq(atarilance_dev->irq, atarilance_dev);
index 488d8ed..6482aed 100644 (file)
@@ -3684,7 +3684,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                        mii->val_out = 0;
                        read_lock_bh(&bond->lock);
                        read_lock(&bond->curr_slave_lock);
-                       if (bond->curr_active_slave) {
+                       if (netif_carrier_ok(bond->dev)) {
                                mii->val_out = BMSR_LSTATUS;
                        }
                        read_unlock(&bond->curr_slave_lock);
index dec70c2..4612f71 100644 (file)
@@ -1974,7 +1974,7 @@ out:
        return ret;
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        unregister_netdev(dev_cs89x0);
index 00e2a8a..4ae0fed 100644 (file)
  *
  *      v0.009: Module support fixes, multiple interfaces support, various
  *              bits. macro
+ *
+ *      v0.010: Fixes for the PMAD mapping of the LANCE buffer and for the
+ *              PMAX requirement to only use halfword accesses to the
+ *              buffer. macro
  */
 
 #include <linux/crc32.h>
@@ -54,6 +58,7 @@
 #include <linux/spinlock.h>
 #include <linux/stddef.h>
 #include <linux/string.h>
+#include <linux/types.h>
 
 #include <asm/addrspace.h>
 #include <asm/system.h>
@@ -67,7 +72,7 @@
 #include <asm/dec/tc.h>
 
 static char version[] __devinitdata =
-"declance.c: v0.009 by Linux MIPS DECstation task force\n";
+"declance.c: v0.010 by Linux MIPS DECstation task force\n";
 
 MODULE_AUTHOR("Linux MIPS DECstation task force");
 MODULE_DESCRIPTION("DEC LANCE (DECstation onboard, PMAD-xx) driver");
@@ -110,24 +115,25 @@ MODULE_LICENSE("GPL");
 #define        LE_C3_BCON      0x1     /* Byte control */
 
 /* Receive message descriptor 1 */
-#define LE_R1_OWN       0x80   /* Who owns the entry */
-#define LE_R1_ERR       0x40   /* Error: if FRA, OFL, CRC or BUF is set */
-#define LE_R1_FRA       0x20   /* FRA: Frame error */
-#define LE_R1_OFL       0x10   /* OFL: Frame overflow */
-#define LE_R1_CRC       0x08   /* CRC error */
-#define LE_R1_BUF       0x04   /* BUF: Buffer error */
-#define LE_R1_SOP       0x02   /* Start of packet */
-#define LE_R1_EOP       0x01   /* End of packet */
-#define LE_R1_POK       0x03   /* Packet is complete: SOP + EOP */
-
-#define LE_T1_OWN       0x80   /* Lance owns the packet */
-#define LE_T1_ERR       0x40   /* Error summary */
-#define LE_T1_EMORE     0x10   /* Error: more than one retry needed */
-#define LE_T1_EONE      0x08   /* Error: one retry needed */
-#define LE_T1_EDEF      0x04   /* Error: deferred */
-#define LE_T1_SOP       0x02   /* Start of packet */
-#define LE_T1_EOP       0x01   /* End of packet */
-#define LE_T1_POK      0x03    /* Packet is complete: SOP + EOP */
+#define LE_R1_OWN      0x8000  /* Who owns the entry */
+#define LE_R1_ERR      0x4000  /* Error: if FRA, OFL, CRC or BUF is set */
+#define LE_R1_FRA      0x2000  /* FRA: Frame error */
+#define LE_R1_OFL      0x1000  /* OFL: Frame overflow */
+#define LE_R1_CRC      0x0800  /* CRC error */
+#define LE_R1_BUF      0x0400  /* BUF: Buffer error */
+#define LE_R1_SOP      0x0200  /* Start of packet */
+#define LE_R1_EOP      0x0100  /* End of packet */
+#define LE_R1_POK      0x0300  /* Packet is complete: SOP + EOP */
+
+/* Transmit message descriptor 1 */
+#define LE_T1_OWN      0x8000  /* Lance owns the packet */
+#define LE_T1_ERR      0x4000  /* Error summary */
+#define LE_T1_EMORE    0x1000  /* Error: more than one retry needed */
+#define LE_T1_EONE     0x0800  /* Error: one retry needed */
+#define LE_T1_EDEF     0x0400  /* Error: deferred */
+#define LE_T1_SOP      0x0200  /* Start of packet */
+#define LE_T1_EOP      0x0100  /* End of packet */
+#define LE_T1_POK      0x0300  /* Packet is complete: SOP + EOP */
 
 #define LE_T3_BUF       0x8000 /* Buffer error */
 #define LE_T3_UFL       0x4000 /* Error underflow */
@@ -156,69 +162,57 @@ MODULE_LICENSE("GPL");
 #undef TEST_HITS
 #define ZERO 0
 
-/* The DS2000/3000 have a linear 64 KB buffer.
-
- * The PMAD-AA has 128 kb buffer on-board.
+/*
+ * The DS2100/3100 have a linear 64 kB buffer which supports halfword
+ * accesses only.  Each halfword of the buffer is word-aligned in the
+ * CPU address space.
  *
- * The IOASIC LANCE devices use a shared memory region. This region as seen
- * from the CPU is (max) 128 KB long and has to be on an 128 KB boundary.
- * The LANCE sees this as a 64 KB long continuous memory region.
+ * The PMAD-AA has a 128 kB buffer on-board.
  *
- * The LANCE's DMA address is used as an index in this buffer and DMA takes
- * place in bursts of eight 16-Bit words which are packed into four 32-Bit words
- * by the IOASIC. This leads to a strange padding: 16 bytes of valid data followed
- * by a 16 byte gap :-(.
+ * The IOASIC LANCE devices use a shared memory region.  This region
+ * as seen from the CPU is (max) 128 kB long and has to be on an 128 kB
+ * boundary.  The LANCE sees this as a 64 kB long continuous memory
+ * region.
+ *
+ * The LANCE's DMA address is used as an index in this buffer and DMA
+ * takes place in bursts of eight 16-bit words which are packed into
+ * four 32-bit words by the IOASIC.  This leads to a strange padding:
+ * 16 bytes of valid data followed by a 16 byte gap :-(.
  */
 
 struct lance_rx_desc {
        unsigned short rmd0;            /* low address of packet */
-       short gap0;
-       unsigned char rmd1_hadr;        /* high address of packet */
-       unsigned char rmd1_bits;        /* descriptor bits */
-       short gap1;
+       unsigned short rmd1;            /* high address of packet
+                                          and descriptor bits */
        short length;                   /* 2s complement (negative!)
                                           of buffer length */
-       short gap2;
        unsigned short mblength;        /* actual number of bytes received */
-       short gap3;
 };
 
 struct lance_tx_desc {
        unsigned short tmd0;            /* low address of packet */
-       short gap0;
-       unsigned char tmd1_hadr;        /* high address of packet */
-       unsigned char tmd1_bits;        /* descriptor bits */
-       short gap1;
+       unsigned short tmd1;            /* high address of packet
+                                          and descriptor bits */
        short length;                   /* 2s complement (negative!)
                                           of buffer length */
-       short gap2;
        unsigned short misc;
-       short gap3;
 };
 
 
 /* First part of the LANCE initialization block, described in databook. */
 struct lance_init_block {
        unsigned short mode;            /* pre-set mode (reg. 15) */
-       short gap0;
 
-       unsigned char phys_addr[12];    /* physical ethernet address
-                                          only 0, 1, 4, 5, 8, 9 are valid
-                                          2, 3, 6, 7, 10, 11 are gaps */
-       unsigned short filter[8];       /* multicast filter
-                                          only 0, 2, 4, 6 are valid
-                                          1, 3, 5, 7 are gaps */
+       unsigned short phys_addr[3];    /* physical ethernet address */
+       unsigned short filter[4];       /* multicast filter */
 
        /* Receive and transmit ring base, along with extra bits. */
        unsigned short rx_ptr;          /* receive descriptor addr */
-       short gap1;
        unsigned short rx_len;          /* receive len and high addr */
-       short gap2;
        unsigned short tx_ptr;          /* transmit descriptor addr */
-       short gap3;
        unsigned short tx_len;          /* transmit len and high addr */
-       short gap4;
-       short gap5[8];
+
+       short gap[4];
 
        /* The buffer descriptors */
        struct lance_rx_desc brx_ring[RX_RING_SIZE];
@@ -226,15 +220,28 @@ struct lance_init_block {
 };
 
 #define BUF_OFFSET_CPU sizeof(struct lance_init_block)
-#define BUF_OFFSET_LNC (sizeof(struct lance_init_block)>>1)
+#define BUF_OFFSET_LNC sizeof(struct lance_init_block)
 
-#define libdesc_offset(rt, elem) \
-((__u32)(((unsigned long)(&(((struct lance_init_block *)0)->rt[elem])))))
+#define shift_off(off, type)                                           \
+       (type == ASIC_LANCE || type == PMAX_LANCE ? off << 1 : off)
 
-/*
- * This works *only* for the ring descriptors
- */
-#define LANCE_ADDR(x) (CPHYSADDR(x) >> 1)
+#define lib_off(rt, type)                                              \
+       shift_off(offsetof(struct lance_init_block, rt), type)
+
+#define lib_ptr(ib, rt, type)                                          \
+       ((volatile u16 *)((u8 *)(ib) + lib_off(rt, type)))
+
+#define rds_off(rt, type)                                              \
+       shift_off(offsetof(struct lance_rx_desc, rt), type)
+
+#define rds_ptr(rd, rt, type)                                          \
+       ((volatile u16 *)((u8 *)(rd) + rds_off(rt, type)))
+
+#define tds_off(rt, type)                                              \
+       shift_off(offsetof(struct lance_tx_desc, rt), type)
+
+#define tds_ptr(td, rt, type)                                          \
+       ((volatile u16 *)((u8 *)(td) + tds_off(rt, type)))
 
 struct lance_private {
        struct net_device *next;
@@ -242,7 +249,6 @@ struct lance_private {
        int slot;
        int dma_irq;
        volatile struct lance_regs *ll;
-       volatile struct lance_init_block *init_block;
 
        spinlock_t      lock;
 
@@ -260,8 +266,8 @@ struct lance_private {
        char *tx_buf_ptr_cpu[TX_RING_SIZE];
 
        /* Pointers to the ring buffers as seen from the LANCE */
-       char *rx_buf_ptr_lnc[RX_RING_SIZE];
-       char *tx_buf_ptr_lnc[TX_RING_SIZE];
+       uint rx_buf_ptr_lnc[RX_RING_SIZE];
+       uint tx_buf_ptr_lnc[TX_RING_SIZE];
 };
 
 #define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
@@ -294,7 +300,7 @@ static inline void writereg(volatile unsigned short *regptr, short value)
 static void load_csrs(struct lance_private *lp)
 {
        volatile struct lance_regs *ll = lp->ll;
-       int leptr;
+       uint leptr;
 
        /* The address space as seen from the LANCE
         * begins at address 0. HK
@@ -316,12 +322,14 @@ static void load_csrs(struct lance_private *lp)
  * Our specialized copy routines
  *
  */
-void cp_to_buf(const int type, void *to, const void *from, int len)
+static void cp_to_buf(const int type, void *to, const void *from, int len)
 {
        unsigned short *tp, *fp, clen;
        unsigned char *rtp, *rfp;
 
-       if (type == PMAX_LANCE) {
+       if (type == PMAD_LANCE) {
+               memcpy(to, from, len);
+       } else if (type == PMAX_LANCE) {
                clen = len >> 1;
                tp = (unsigned short *) to;
                fp = (unsigned short *) from;
@@ -370,12 +378,14 @@ void cp_to_buf(const int type, void *to, const void *from, int len)
        iob();
 }
 
-void cp_from_buf(const int type, void *to, const void *from, int len)
+static void cp_from_buf(const int type, void *to, const void *from, int len)
 {
        unsigned short *tp, *fp, clen;
        unsigned char *rtp, *rfp;
 
-       if (type == PMAX_LANCE) {
+       if (type == PMAD_LANCE) {
+               memcpy(to, from, len);
+       } else if (type == PMAX_LANCE) {
                clen = len >> 1;
                tp = (unsigned short *) to;
                fp = (unsigned short *) from;
@@ -431,12 +441,10 @@ void cp_from_buf(const int type, void *to, const void *from, int len)
 static void lance_init_ring(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       volatile struct lance_init_block *ib;
-       int leptr;
+       volatile u16 *ib = (volatile u16 *)dev->mem_start;
+       uint leptr;
        int i;
 
-       ib = (struct lance_init_block *) (dev->mem_start);
-
        /* Lock out other processes while setting up hardware */
        netif_stop_queue(dev);
        lp->rx_new = lp->tx_new = 0;
@@ -445,55 +453,64 @@ static void lance_init_ring(struct net_device *dev)
        /* Copy the ethernet address to the lance init block.
         * XXX bit 0 of the physical address registers has to be zero
         */
-       ib->phys_addr[0] = dev->dev_addr[0];
-       ib->phys_addr[1] = dev->dev_addr[1];
-       ib->phys_addr[4] = dev->dev_addr[2];
-       ib->phys_addr[5] = dev->dev_addr[3];
-       ib->phys_addr[8] = dev->dev_addr[4];
-       ib->phys_addr[9] = dev->dev_addr[5];
+       *lib_ptr(ib, phys_addr[0], lp->type) = (dev->dev_addr[1] << 8) |
+                                    dev->dev_addr[0];
+       *lib_ptr(ib, phys_addr[1], lp->type) = (dev->dev_addr[3] << 8) |
+                                    dev->dev_addr[2];
+       *lib_ptr(ib, phys_addr[2], lp->type) = (dev->dev_addr[5] << 8) |
+                                    dev->dev_addr[4];
        /* Setup the initialization block */
 
        /* Setup rx descriptor pointer */
-       leptr = LANCE_ADDR(libdesc_offset(brx_ring, 0));
-       ib->rx_len = (LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16);
-       ib->rx_ptr = leptr;
+       leptr = offsetof(struct lance_init_block, brx_ring);
+       *lib_ptr(ib, rx_len, lp->type) = (LANCE_LOG_RX_BUFFERS << 13) |
+                                        (leptr >> 16);
+       *lib_ptr(ib, rx_ptr, lp->type) = leptr;
        if (ZERO)
-               printk("RX ptr: %8.8x(%8.8x)\n", leptr, libdesc_offset(brx_ring, 0));
+               printk("RX ptr: %8.8x(%8.8x)\n",
+                      leptr, lib_off(brx_ring, lp->type));
 
        /* Setup tx descriptor pointer */
-       leptr = LANCE_ADDR(libdesc_offset(btx_ring, 0));
-       ib->tx_len = (LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16);
-       ib->tx_ptr = leptr;
+       leptr = offsetof(struct lance_init_block, btx_ring);
+       *lib_ptr(ib, tx_len, lp->type) = (LANCE_LOG_TX_BUFFERS << 13) |
+                                        (leptr >> 16);
+       *lib_ptr(ib, tx_ptr, lp->type) = leptr;
        if (ZERO)
-               printk("TX ptr: %8.8x(%8.8x)\n", leptr, libdesc_offset(btx_ring, 0));
+               printk("TX ptr: %8.8x(%8.8x)\n",
+                      leptr, lib_off(btx_ring, lp->type));
 
        if (ZERO)
                printk("TX rings:\n");
 
        /* Setup the Tx ring entries */
        for (i = 0; i < TX_RING_SIZE; i++) {
-               leptr = (int) lp->tx_buf_ptr_lnc[i];
-               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;
+               leptr = lp->tx_buf_ptr_lnc[i];
+               *lib_ptr(ib, btx_ring[i].tmd0, lp->type) = leptr;
+               *lib_ptr(ib, btx_ring[i].tmd1, lp->type) = (leptr >> 16) &
+                                                          0xff;
+               *lib_ptr(ib, btx_ring[i].length, lp->type) = 0xf000;
+                                               /* The ones required by tmd2 */
+               *lib_ptr(ib, btx_ring[i].misc, lp->type) = 0;
                if (i < 3 && ZERO)
-                       printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->tx_buf_ptr_cpu[i]);
+                       printk("%d: 0x%8.8x(0x%8.8x)\n",
+                              i, leptr, (uint)lp->tx_buf_ptr_cpu[i]);
        }
 
        /* Setup the Rx ring entries */
        if (ZERO)
                printk("RX rings:\n");
        for (i = 0; i < RX_RING_SIZE; i++) {
-               leptr = (int) lp->rx_buf_ptr_lnc[i];
-               ib->brx_ring[i].rmd0 = leptr;
-               ib->brx_ring[i].rmd1_hadr = leptr >> 16;
-               ib->brx_ring[i].rmd1_bits = LE_R1_OWN;
-               ib->brx_ring[i].length = -RX_BUFF_SIZE | 0xf000;
-               ib->brx_ring[i].mblength = 0;
+               leptr = lp->rx_buf_ptr_lnc[i];
+               *lib_ptr(ib, brx_ring[i].rmd0, lp->type) = leptr;
+               *lib_ptr(ib, brx_ring[i].rmd1, lp->type) = ((leptr >> 16) &
+                                                           0xff) |
+                                                          LE_R1_OWN;
+               *lib_ptr(ib, brx_ring[i].length, lp->type) = -RX_BUFF_SIZE |
+                                                            0xf000;
+               *lib_ptr(ib, brx_ring[i].mblength, lp->type) = 0;
                if (i < 3 && ZERO)
-                       printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->rx_buf_ptr_cpu[i]);
+                       printk("%d: 0x%8.8x(0x%8.8x)\n",
+                              i, leptr, (uint)lp->rx_buf_ptr_cpu[i]);
        }
        iob();
 }
@@ -511,11 +528,13 @@ static int init_restart_lance(struct lance_private *lp)
                udelay(10);
        }
        if ((i == 100) || (ll->rdp & LE_C0_ERR)) {
-               printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, ll->rdp);
+               printk("LANCE unopened after %d ticks, csr0=%4.4x.\n",
+                      i, ll->rdp);
                return -1;
        }
        if ((ll->rdp & LE_C0_ERR)) {
-               printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, ll->rdp);
+               printk("LANCE unopened after %d ticks, csr0=%4.4x.\n",
+                      i, ll->rdp);
                return -1;
        }
        writereg(&ll->rdp, LE_C0_IDON);
@@ -528,12 +547,11 @@ static int init_restart_lance(struct lance_private *lp)
 static int lance_rx(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       volatile struct lance_init_block *ib;
-       volatile struct lance_rx_desc *rd = 0;
-       unsigned char bits;
-       int len = 0;
-       struct sk_buff *skb = 0;
-       ib = (struct lance_init_block *) (dev->mem_start);
+       volatile u16 *ib = (volatile u16 *)dev->mem_start;
+       volatile u16 *rd;
+       unsigned short bits;
+       int entry, len;
+       struct sk_buff *skb;
 
 #ifdef TEST_HITS
        {
@@ -542,19 +560,22 @@ static int lance_rx(struct net_device *dev)
                printk("[");
                for (i = 0; i < RX_RING_SIZE; i++) {
                        if (i == lp->rx_new)
-                               printk("%s", ib->brx_ring[i].rmd1_bits &
+                               printk("%s", *lib_ptr(ib, brx_ring[i].rmd1,
+                                                     lp->type) &
                                             LE_R1_OWN ? "_" : "X");
                        else
-                               printk("%s", ib->brx_ring[i].rmd1_bits &
+                               printk("%s", *lib_ptr(ib, brx_ring[i].rmd1,
+                                                     lp->type) &
                                             LE_R1_OWN ? "." : "1");
                }
                printk("]");
        }
 #endif
 
-       for (rd = &ib->brx_ring[lp->rx_new];
-            !((bits = rd->rmd1_bits) & LE_R1_OWN);
-            rd = &ib->brx_ring[lp->rx_new]) {
+       for (rd = lib_ptr(ib, brx_ring[lp->rx_new], lp->type);
+            !((bits = *rds_ptr(rd, rmd1, lp->type)) & LE_R1_OWN);
+            rd = lib_ptr(ib, brx_ring[lp->rx_new], lp->type)) {
+               entry = lp->rx_new;
 
                /* We got an incomplete frame? */
                if ((bits & LE_R1_POK) != LE_R1_POK) {
@@ -575,16 +596,18 @@ static int lance_rx(struct net_device *dev)
                        if (bits & LE_R1_EOP)
                                lp->stats.rx_errors++;
                } else {
-                       len = (rd->mblength & 0xfff) - 4;
+                       len = (*rds_ptr(rd, mblength, lp->type) & 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) & RX_RING_MOD_MASK;
+                               *rds_ptr(rd, mblength, lp->type) = 0;
+                               *rds_ptr(rd, rmd1, lp->type) =
+                                       ((lp->rx_buf_ptr_lnc[entry] >> 16) &
+                                        0xff) | LE_R1_OWN;
+                               lp->rx_new = (entry + 1) & RX_RING_MOD_MASK;
                                return 0;
                        }
                        lp->stats.rx_bytes += len;
@@ -594,8 +617,7 @@ static int lance_rx(struct net_device *dev)
                        skb_put(skb, len);      /* make room */
 
                        cp_from_buf(lp->type, skb->data,
-                                   (char *)lp->rx_buf_ptr_cpu[lp->rx_new],
-                                   len);
+                                   (char *)lp->rx_buf_ptr_cpu[entry], len);
 
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
@@ -604,10 +626,11 @@ static int lance_rx(struct net_device *dev)
                }
 
                /* Return the packet to the pool */
-               rd->mblength = 0;
-               rd->length = -RX_BUFF_SIZE | 0xf000;
-               rd->rmd1_bits = LE_R1_OWN;
-               lp->rx_new = (lp->rx_new + 1) & RX_RING_MOD_MASK;
+               *rds_ptr(rd, mblength, lp->type) = 0;
+               *rds_ptr(rd, length, lp->type) = -RX_BUFF_SIZE | 0xf000;
+               *rds_ptr(rd, rmd1, lp->type) =
+                       ((lp->rx_buf_ptr_lnc[entry] >> 16) & 0xff) | LE_R1_OWN;
+               lp->rx_new = (entry + 1) & RX_RING_MOD_MASK;
        }
        return 0;
 }
@@ -615,24 +638,24 @@ static int lance_rx(struct net_device *dev)
 static void lance_tx(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       volatile struct lance_init_block *ib;
+       volatile u16 *ib = (volatile u16 *)dev->mem_start;
        volatile struct lance_regs *ll = lp->ll;
-       volatile struct lance_tx_desc *td;
+       volatile u16 *td;
        int i, j;
        int status;
-       ib = (struct lance_init_block *) (dev->mem_start);
+
        j = lp->tx_old;
 
        spin_lock(&lp->lock);
 
        for (i = j; i != lp->tx_new; i = j) {
-               td = &ib->btx_ring[i];
+               td = lib_ptr(ib, btx_ring[i], lp->type);
                /* If we hit a packet not owned by us, stop */
-               if (td->tmd1_bits & LE_T1_OWN)
+               if (*tds_ptr(td, tmd1, lp->type) & LE_T1_OWN)
                        break;
 
-               if (td->tmd1_bits & LE_T1_ERR) {
-                       status = td->misc;
+               if (*tds_ptr(td, tmd1, lp->type) & LE_T1_ERR) {
+                       status = *tds_ptr(td, misc, lp->type);
 
                        lp->stats.tx_errors++;
                        if (status & LE_T3_RTY)
@@ -667,18 +690,19 @@ static void lance_tx(struct net_device *dev)
                                init_restart_lance(lp);
                                goto out;
                        }
-               } else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) {
+               } else if ((*tds_ptr(td, tmd1, lp->type) & LE_T1_POK) ==
+                          LE_T1_POK) {
                        /*
                         * So we don't count the packet more than once.
                         */
-                       td->tmd1_bits &= ~(LE_T1_POK);
+                       *tds_ptr(td, tmd1, lp->type) &= ~(LE_T1_POK);
 
                        /* One collision before packet was sent. */
-                       if (td->tmd1_bits & LE_T1_EONE)
+                       if (*tds_ptr(td, tmd1, lp->type) & LE_T1_EONE)
                                lp->stats.collisions++;
 
                        /* More than one collision, be optimistic. */
-                       if (td->tmd1_bits & LE_T1_EMORE)
+                       if (*tds_ptr(td, tmd1, lp->type) & LE_T1_EMORE)
                                lp->stats.collisions += 2;
 
                        lp->stats.tx_packets++;
@@ -752,7 +776,7 @@ struct net_device *last_dev = 0;
 
 static int lance_open(struct net_device *dev)
 {
-       volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);
+       volatile u16 *ib = (volatile u16 *)dev->mem_start;
        struct lance_private *lp = netdev_priv(dev);
        volatile struct lance_regs *ll = lp->ll;
        int status = 0;
@@ -769,11 +793,11 @@ static int lance_open(struct net_device *dev)
         *
         * BTW it is common bug in all lance drivers! --ANK
         */
-       ib->mode = 0;
-       ib->filter [0] = 0;
-       ib->filter [2] = 0;
-       ib->filter [4] = 0;
-       ib->filter [6] = 0;
+       *lib_ptr(ib, mode, lp->type) = 0;
+       *lib_ptr(ib, filter[0], lp->type) = 0;
+       *lib_ptr(ib, filter[1], lp->type) = 0;
+       *lib_ptr(ib, filter[2], lp->type) = 0;
+       *lib_ptr(ib, filter[3], lp->type) = 0;
 
        lance_init_ring(dev);
        load_csrs(lp);
@@ -874,12 +898,10 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
        volatile struct lance_regs *ll = lp->ll;
-       volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);
-       int entry, skblen, len;
+       volatile u16 *ib = (volatile u16 *)dev->mem_start;
+       int entry, len;
 
-       skblen = skb->len;
-
-       len = skblen;
+       len = skb->len;
 
        if (len < ETH_ZLEN) {
                if (skb_padto(skb, ETH_ZLEN))
@@ -889,23 +911,17 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        lp->stats.tx_bytes += len;
 
-       entry = lp->tx_new & TX_RING_MOD_MASK;
-       ib->btx_ring[entry].length = (-len);
-       ib->btx_ring[entry].misc = 0;
-
-       cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data,
-                 skblen);
+       entry = lp->tx_new;
+       *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len);
+       *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0;
 
-       /* Clear the slack of the packet, do I need this? */
-       /* For a firewall it's a good idea - AC */
-/*
-   if (len != skblen)
-   memset ((char *) &ib->tx_buf [entry][skblen], 0, (len - skblen) << 1);
- */
+       cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data, len);
 
        /* 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) & TX_RING_MOD_MASK;
+       *lib_ptr(ib, btx_ring[entry].tmd1, lp->type) =
+               ((lp->tx_buf_ptr_lnc[entry] >> 16) & 0xff) |
+               (LE_T1_POK | LE_T1_OWN);
+       lp->tx_new = (entry + 1) & TX_RING_MOD_MASK;
 
        if (TX_BUFFS_AVAIL <= 0)
                netif_stop_queue(dev);
@@ -930,8 +946,8 @@ static struct net_device_stats *lance_get_stats(struct net_device *dev)
 
 static void lance_load_multicast(struct net_device *dev)
 {
-       volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);
-       volatile u16 *mcast_table = (u16 *) & ib->filter;
+       struct lance_private *lp = netdev_priv(dev);
+       volatile u16 *ib = (volatile u16 *)dev->mem_start;
        struct dev_mc_list *dmi = dev->mc_list;
        char *addrs;
        int i;
@@ -939,17 +955,17 @@ static void lance_load_multicast(struct net_device *dev)
 
        /* set all multicast bits */
        if (dev->flags & IFF_ALLMULTI) {
-               ib->filter[0] = 0xffff;
-               ib->filter[2] = 0xffff;
-               ib->filter[4] = 0xffff;
-               ib->filter[6] = 0xffff;
+               *lib_ptr(ib, filter[0], lp->type) = 0xffff;
+               *lib_ptr(ib, filter[1], lp->type) = 0xffff;
+               *lib_ptr(ib, filter[2], lp->type) = 0xffff;
+               *lib_ptr(ib, filter[3], lp->type) = 0xffff;
                return;
        }
        /* clear the multicast filter */
-       ib->filter[0] = 0;
-       ib->filter[2] = 0;
-       ib->filter[4] = 0;
-       ib->filter[6] = 0;
+       *lib_ptr(ib, filter[0], lp->type) = 0;
+       *lib_ptr(ib, filter[1], lp->type) = 0;
+       *lib_ptr(ib, filter[2], lp->type) = 0;
+       *lib_ptr(ib, filter[3], lp->type) = 0;
 
        /* Add addresses */
        for (i = 0; i < dev->mc_count; i++) {
@@ -962,7 +978,7 @@ static void lance_load_multicast(struct net_device *dev)
 
                crc = ether_crc_le(ETH_ALEN, addrs);
                crc = crc >> 26;
-               mcast_table[2 * (crc >> 4)] |= 1 << (crc & 0xf);
+               *lib_ptr(ib, filter[crc >> 4], lp->type) |= 1 << (crc & 0xf);
        }
        return;
 }
@@ -970,11 +986,9 @@ static void lance_load_multicast(struct net_device *dev)
 static void lance_set_multicast(struct net_device *dev)
 {
        struct lance_private *lp = netdev_priv(dev);
-       volatile struct lance_init_block *ib;
+       volatile u16 *ib = (volatile u16 *)dev->mem_start;
        volatile struct lance_regs *ll = lp->ll;
 
-       ib = (struct lance_init_block *) (dev->mem_start);
-
        if (!netif_running(dev))
                return;
 
@@ -992,9 +1006,9 @@ static void lance_set_multicast(struct net_device *dev)
        lance_init_ring(dev);
 
        if (dev->flags & IFF_PROMISC) {
-               ib->mode |= LE_MO_PROM;
+               *lib_ptr(ib, mode, lp->type) |= LE_MO_PROM;
        } else {
-               ib->mode &= ~LE_MO_PROM;
+               *lib_ptr(ib, mode, lp->type) &= ~LE_MO_PROM;
                lance_load_multicast(dev);
        }
        load_csrs(lp);
@@ -1051,7 +1065,6 @@ static int __init dec_lance_init(const int type, const int slot)
        lp->type = type;
        lp->slot = slot;
        switch (type) {
-#ifdef CONFIG_TC
        case ASIC_LANCE:
                dev->base_addr = CKSEG1ADDR(dec_kn_slot_base + IOASIC_LANCE);
 
@@ -1073,20 +1086,20 @@ static int __init dec_lance_init(const int type, const int slot)
                 */
                for (i = 0; i < RX_RING_SIZE; i++) {
                        lp->rx_buf_ptr_cpu[i] =
-                               (char *)(dev->mem_start + BUF_OFFSET_CPU +
+                               (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU +
                                         2 * i * RX_BUFF_SIZE);
                        lp->rx_buf_ptr_lnc[i] =
-                               (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
+                               (BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
                }
                for (i = 0; i < TX_RING_SIZE; i++) {
                        lp->tx_buf_ptr_cpu[i] =
-                               (char *)(dev->mem_start + BUF_OFFSET_CPU +
+                               (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU +
                                         2 * RX_RING_SIZE * RX_BUFF_SIZE +
                                         2 * i * TX_BUFF_SIZE);
                        lp->tx_buf_ptr_lnc[i] =
-                               (char *)(BUF_OFFSET_LNC +
-                                        RX_RING_SIZE * RX_BUFF_SIZE +
-                                        i * TX_BUFF_SIZE);
+                               (BUF_OFFSET_LNC +
+                                RX_RING_SIZE * RX_BUFF_SIZE +
+                                i * TX_BUFF_SIZE);
                }
 
                /* Setup I/O ASIC LANCE DMA.  */
@@ -1095,11 +1108,12 @@ static int __init dec_lance_init(const int type, const int slot)
                             CPHYSADDR(dev->mem_start) << 3);
 
                break;
-
+#ifdef CONFIG_TC
        case PMAD_LANCE:
                claim_tc_card(slot);
 
                dev->mem_start = CKSEG1ADDR(get_tc_base_addr(slot));
+               dev->mem_end = dev->mem_start + 0x100000;
                dev->base_addr = dev->mem_start + 0x100000;
                dev->irq = get_tc_irq_nr(slot);
                esar_base = dev->mem_start + 0x1c0002;
@@ -1110,7 +1124,7 @@ static int __init dec_lance_init(const int type, const int slot)
                                (char *)(dev->mem_start + BUF_OFFSET_CPU +
                                         i * RX_BUFF_SIZE);
                        lp->rx_buf_ptr_lnc[i] =
-                               (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
+                               (BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
                }
                for (i = 0; i < TX_RING_SIZE; i++) {
                        lp->tx_buf_ptr_cpu[i] =
@@ -1118,18 +1132,18 @@ static int __init dec_lance_init(const int type, const int slot)
                                         RX_RING_SIZE * RX_BUFF_SIZE +
                                         i * TX_BUFF_SIZE);
                        lp->tx_buf_ptr_lnc[i] =
-                               (char *)(BUF_OFFSET_LNC +
-                                        RX_RING_SIZE * RX_BUFF_SIZE +
-                                        i * TX_BUFF_SIZE);
+                               (BUF_OFFSET_LNC +
+                                RX_RING_SIZE * RX_BUFF_SIZE +
+                                i * TX_BUFF_SIZE);
                }
 
                break;
 #endif
-
        case PMAX_LANCE:
                dev->irq = dec_interrupt[DEC_IRQ_LANCE];
                dev->base_addr = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE);
                dev->mem_start = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE_MEM);
+               dev->mem_end = dev->mem_start + KN01_SLOT_SIZE;
                esar_base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_ESAR + 1);
                lp->dma_irq = -1;
 
@@ -1138,20 +1152,20 @@ static int __init dec_lance_init(const int type, const int slot)
                 */
                for (i = 0; i < RX_RING_SIZE; i++) {
                        lp->rx_buf_ptr_cpu[i] =
-                               (char *)(dev->mem_start + BUF_OFFSET_CPU +
+                               (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU +
                                         2 * i * RX_BUFF_SIZE);
                        lp->rx_buf_ptr_lnc[i] =
-                               (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
+                               (BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
                }
                for (i = 0; i < TX_RING_SIZE; i++) {
                        lp->tx_buf_ptr_cpu[i] =
-                               (char *)(dev->mem_start + BUF_OFFSET_CPU +
+                               (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU +
                                         2 * RX_RING_SIZE * RX_BUFF_SIZE +
                                         2 * i * TX_BUFF_SIZE);
                        lp->tx_buf_ptr_lnc[i] =
-                               (char *)(BUF_OFFSET_LNC +
-                                        RX_RING_SIZE * RX_BUFF_SIZE +
-                                        i * TX_BUFF_SIZE);
+                               (BUF_OFFSET_LNC +
+                                RX_RING_SIZE * RX_BUFF_SIZE +
+                                i * TX_BUFF_SIZE);
                }
 
                break;
@@ -1279,10 +1293,8 @@ static int __init dec_lance_probe(void)
        /* Then handle onboard devices. */
        if (dec_interrupt[DEC_IRQ_LANCE] >= 0) {
                if (dec_interrupt[DEC_IRQ_LANCE_MERR] >= 0) {
-#ifdef CONFIG_TC
                        if (dec_lance_init(ASIC_LANCE, -1) >= 0)
                                count++;
-#endif
                } else if (!TURBOCHANNEL) {
                        if (dec_lance_init(PMAX_LANCE, -1) >= 0)
                                count++;
index d39e848..c62d9c6 100644 (file)
@@ -463,7 +463,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr, E21_IO_EXTENT);
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        int this_dev;
index a4eb0dc..b446309 100644 (file)
@@ -1827,7 +1827,7 @@ int __init init_module(void)
        return n_eepro ? 0 : -ENODEV;
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        int i;
index e14be02..4a50fcb 100644 (file)
@@ -1719,7 +1719,7 @@ int __init init_module(void)
        return -ENXIO;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        int this_dev;
 
index fd7b32a..2d2ea94 100644 (file)
@@ -455,7 +455,7 @@ static void cleanup_card(struct net_device *dev)
        iounmap(ei_status.mem);
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        int this_dev;
index b7b8bc2..93283e3 100644 (file)
@@ -1475,7 +1475,7 @@ int __init init_module(void)
        return -ENXIO;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        int this_dev;
 
index 6abcfd2..99a36cc 100644 (file)
@@ -482,7 +482,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        int this_dev;
index 2947097..635b13c 100644 (file)
@@ -444,7 +444,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        int this_dev;
index 4256c13..a384332 100644 (file)
@@ -368,7 +368,7 @@ static void cleanup_card(struct net_device *dev)
        kfree(lp);
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        int this_dev;
 
index 5795ee1..0a08d0c 100644 (file)
@@ -440,7 +440,7 @@ static void cleanup_card(struct net_device *dev)
        iounmap(ei_status.mem);
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        int this_dev;
 
index d9f48bb..c41ae42 100644 (file)
@@ -1100,7 +1100,7 @@ static void eth_tx_fill_frag_descs(struct mv643xx_private *mp,
                                         ETH_TX_ENABLE_INTERRUPT;
                        mp->tx_skb[tx_index] = skb;
                } else
-                       mp->tx_skb[tx_index] = 0;
+                       mp->tx_skb[tx_index] = NULL;
 
                desc = &mp->p_tx_desc_area[tx_index];
                desc->l4i_chk = 0;
@@ -1136,7 +1136,7 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
                eth_tx_fill_frag_descs(mp, skb);
 
                length = skb_headlen(skb);
-               mp->tx_skb[tx_index] = 0;
+               mp->tx_skb[tx_index] = NULL;
        } else {
                cmd_sts |= ETH_ZERO_PADDING |
                           ETH_TX_LAST_DESC |
index 56a82d8..e246d00 100644 (file)
@@ -184,7 +184,7 @@ static int m147lance_close(struct net_device *dev)
 MODULE_LICENSE("GPL");
 
 static struct net_device *dev_mvme147_lance;
-int init_module(void)
+int __init init_module(void)
 {
        dev_mvme147_lance = mvme147lance_probe(-1);
        if (IS_ERR(dev_mvme147_lance))
@@ -192,7 +192,7 @@ int init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        struct m147lance_private *lp = dev_mvme147_lance->priv;
        unregister_netdev(dev_mvme147_lance);
index 38df428..b8f57df 100644 (file)
@@ -89,7 +89,7 @@ MODULE_LICENSE("Dual BSD/GPL");
 #define MYRI10GE_EEPROM_STRINGS_SIZE 256
 #define MYRI10GE_MAX_SEND_DESC_TSO ((65536 / 2048) * 2)
 
-#define MYRI10GE_NO_CONFIRM_DATA 0xffffffff
+#define MYRI10GE_NO_CONFIRM_DATA htonl(0xffffffff)
 #define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff
 
 struct myri10ge_rx_buffer_state {
@@ -156,8 +156,8 @@ struct myri10ge_priv {
        int sram_size;
        unsigned long board_span;
        unsigned long iomem_base;
-       u32 __iomem *irq_claim;
-       u32 __iomem *irq_deassert;
+       __be32 __iomem *irq_claim;
+       __be32 __iomem *irq_deassert;
        char *mac_addr_string;
        struct mcp_cmd_response *cmd;
        dma_addr_t cmd_bus;
@@ -165,10 +165,10 @@ struct myri10ge_priv {
        dma_addr_t fw_stats_bus;
        struct pci_dev *pdev;
        int msi_enabled;
-       unsigned int link_state;
+       __be32 link_state;
        unsigned int rdma_tags_available;
        int intr_coal_delay;
-       u32 __iomem *intr_coal_delay_ptr;
+       __be32 __iomem *intr_coal_delay_ptr;
        int mtrr;
        int wake_queue;
        int stop_queue;
@@ -273,6 +273,11 @@ MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)");
 
 #define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8)
 
+static inline void put_be32(__be32 val, __be32 __iomem *p)
+{
+       __raw_writel((__force __u32)val, (__force void __iomem *)p);
+}
+
 static int
 myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
                  struct myri10ge_cmd *data, int atomic)
@@ -296,7 +301,7 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
 
        buf->response_addr.low = htonl(dma_low);
        buf->response_addr.high = htonl(dma_high);
-       response->result = MYRI10GE_NO_RESPONSE_RESULT;
+       response->result = htonl(MYRI10GE_NO_RESPONSE_RESULT);
        mb();
        myri10ge_pio_copy(cmd_addr, buf, sizeof(*buf));
 
@@ -311,14 +316,14 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
                 * (1ms will be enough for those commands) */
                for (sleep_total = 0;
                     sleep_total < 1000
-                    && response->result == MYRI10GE_NO_RESPONSE_RESULT;
+                    && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT);
                     sleep_total += 10)
                        udelay(10);
        } else {
                /* use msleep for most command */
                for (sleep_total = 0;
                     sleep_total < 15
-                    && response->result == MYRI10GE_NO_RESPONSE_RESULT;
+                    && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT);
                     sleep_total++)
                        msleep(1);
        }
@@ -393,7 +398,7 @@ abort:
 static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable)
 {
        char __iomem *submit;
-       u32 buf[16];
+       __be32 buf[16];
        u32 dma_low, dma_high;
        int i;
 
@@ -410,7 +415,7 @@ static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable)
 
        buf[0] = htonl(dma_high);       /* confirm addr MSW */
        buf[1] = htonl(dma_low);        /* confirm addr LSW */
-       buf[2] = htonl(MYRI10GE_NO_CONFIRM_DATA);       /* confirm data */
+       buf[2] = MYRI10GE_NO_CONFIRM_DATA;      /* confirm data */
        buf[3] = htonl(dma_high);       /* dummy addr MSW */
        buf[4] = htonl(dma_low);        /* dummy addr LSW */
        buf[5] = htonl(enable); /* enable? */
@@ -479,7 +484,7 @@ static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size)
        }
 
        /* check id */
-       hdr_offset = ntohl(*(u32 *) (fw->data + MCP_HEADER_PTR_OFFSET));
+       hdr_offset = ntohl(*(__be32 *) (fw->data + MCP_HEADER_PTR_OFFSET));
        if ((hdr_offset & 3) || hdr_offset + sizeof(*hdr) > fw->size) {
                dev_err(dev, "Bad firmware file\n");
                status = -EINVAL;
@@ -550,7 +555,7 @@ static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp)
 static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
 {
        char __iomem *submit;
-       u32 buf[16];
+       __be32 buf[16];
        u32 dma_low, dma_high, size;
        int status, i;
 
@@ -600,7 +605,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
 
        buf[0] = htonl(dma_high);       /* confirm addr MSW */
        buf[1] = htonl(dma_low);        /* confirm addr LSW */
-       buf[2] = htonl(MYRI10GE_NO_CONFIRM_DATA);       /* confirm data */
+       buf[2] = MYRI10GE_NO_CONFIRM_DATA;      /* confirm data */
 
        /* FIX: All newest firmware should un-protect the bottom of
         * the sram before handoff. However, the very first interfaces
@@ -705,21 +710,21 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
 
        status |=
            myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0);
-       mgp->irq_claim = (__iomem u32 *) (mgp->sram + cmd.data0);
+       mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0);
        if (!mgp->msi_enabled) {
                status |= myri10ge_send_cmd
                    (mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd, 0);
-               mgp->irq_deassert = (__iomem u32 *) (mgp->sram + cmd.data0);
+               mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0);
 
        }
        status |= myri10ge_send_cmd
            (mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0);
-       mgp->intr_coal_delay_ptr = (__iomem u32 *) (mgp->sram + cmd.data0);
+       mgp->intr_coal_delay_ptr = (__iomem __be32 *) (mgp->sram + cmd.data0);
        if (status != 0) {
                dev_err(&mgp->pdev->dev, "failed set interrupt parameters\n");
                return status;
        }
-       __raw_writel(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
+       put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
 
        /* Run a small DMA test.
         * The magic multipliers to the length tell the firmware
@@ -786,14 +791,14 @@ static inline void
 myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst,
                    struct mcp_kreq_ether_recv *src)
 {
-       u32 low;
+       __be32 low;
 
        low = src->addr_low;
-       src->addr_low = DMA_32BIT_MASK;
+       src->addr_low = htonl(DMA_32BIT_MASK);
        myri10ge_pio_copy(dst, src, 8 * sizeof(*src));
        mb();
        src->addr_low = low;
-       __raw_writel(low, &dst->addr_low);
+       put_be32(low, &dst->addr_low);
        mb();
 }
 
@@ -939,11 +944,11 @@ done:
        return retval;
 }
 
-static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, u16 hw_csum)
+static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum)
 {
        struct vlan_hdr *vh = (struct vlan_hdr *)(skb->data);
 
-       if ((skb->protocol == ntohs(ETH_P_8021Q)) &&
+       if ((skb->protocol == htons(ETH_P_8021Q)) &&
            (vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) ||
             vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) {
                skb->csum = hw_csum;
@@ -953,7 +958,7 @@ static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, u16 hw_csum)
 
 static inline unsigned long
 myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
-                int bytes, int len, int csum)
+                int bytes, int len, __wsum csum)
 {
        dma_addr_t bus;
        struct sk_buff *skb;
@@ -986,12 +991,12 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
 
        skb->protocol = eth_type_trans(skb, mgp->dev);
        if (mgp->csum_flag) {
-               if ((skb->protocol == ntohs(ETH_P_IP)) ||
-                   (skb->protocol == ntohs(ETH_P_IPV6))) {
-                       skb->csum = ntohs((u16) csum);
+               if ((skb->protocol == htons(ETH_P_IP)) ||
+                   (skb->protocol == htons(ETH_P_IPV6))) {
+                       skb->csum = csum;
                        skb->ip_summed = CHECKSUM_COMPLETE;
                } else
-                       myri10ge_vlan_ip_csum(skb, ntohs((u16) csum));
+                       myri10ge_vlan_ip_csum(skb, csum);
        }
 
        netif_receive_skb(skb);
@@ -1060,12 +1065,12 @@ static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit)
        int idx = rx_done->idx;
        int cnt = rx_done->cnt;
        u16 length;
-       u16 checksum;
+       __wsum checksum;
 
        while (rx_done->entry[idx].length != 0 && *limit != 0) {
                length = ntohs(rx_done->entry[idx].length);
                rx_done->entry[idx].length = 0;
-               checksum = ntohs(rx_done->entry[idx].checksum);
+               checksum = csum_unfold(rx_done->entry[idx].checksum);
                if (length <= mgp->small_bytes)
                        rx_ok = myri10ge_rx_done(mgp, &mgp->rx_small,
                                                 mgp->small_bytes,
@@ -1142,7 +1147,7 @@ static int myri10ge_poll(struct net_device *netdev, int *budget)
 
        if (rx_done->entry[rx_done->idx].length == 0 || !netif_running(netdev)) {
                netif_rx_complete(netdev);
-               __raw_writel(htonl(3), mgp->irq_claim);
+               put_be32(htonl(3), mgp->irq_claim);
                return 0;
        }
        return 1;
@@ -1166,7 +1171,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
                netif_rx_schedule(mgp->dev);
 
        if (!mgp->msi_enabled) {
-               __raw_writel(0, mgp->irq_deassert);
+               put_be32(0, mgp->irq_deassert);
                if (!myri10ge_deassert_wait)
                        stats->valid = 0;
                mb();
@@ -1195,7 +1200,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
 
        myri10ge_check_statblock(mgp);
 
-       __raw_writel(htonl(3), mgp->irq_claim + 1);
+       put_be32(htonl(3), mgp->irq_claim + 1);
        return (IRQ_HANDLED);
 }
 
@@ -1233,7 +1238,7 @@ myri10ge_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal)
        struct myri10ge_priv *mgp = netdev_priv(netdev);
 
        mgp->intr_coal_delay = coal->rx_coalesce_usecs;
-       __raw_writel(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
+       put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
        return 0;
 }
 
@@ -1748,7 +1753,7 @@ static int myri10ge_open(struct net_device *dev)
                goto abort_with_rings;
        }
 
-       mgp->link_state = -1;
+       mgp->link_state = htonl(~0U);
        mgp->rdma_tags_available = 15;
 
        netif_poll_enable(mgp->dev);    /* must happen prior to any irq */
@@ -1876,7 +1881,7 @@ myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src,
 
        /* re-write the last 32-bits with the valid flags */
        src->flags = last_flags;
-       __raw_writel(*((u32 *) src + 3), (u32 __iomem *) dst + 3);
+       put_be32(*((__be32 *) src + 3), (__be32 __iomem *) dst + 3);
        tx->req += cnt;
        mb();
 }
@@ -1919,7 +1924,8 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev)
        struct myri10ge_tx_buf *tx = &mgp->tx;
        struct skb_frag_struct *frag;
        dma_addr_t bus;
-       u32 low, high_swapped;
+       u32 low;
+       __be32 high_swapped;
        unsigned int len;
        int idx, last_idx, avail, frag_cnt, frag_idx, count, mss, max_segments;
        u16 pseudo_hdr_offset, cksum_offset;
@@ -1964,7 +1970,6 @@ again:
                        cksum_offset = 0;
                        pseudo_hdr_offset = 0;
                } else {
-                       pseudo_hdr_offset = htons(pseudo_hdr_offset);
                        odd_flag = MXGEFW_FLAGS_ALIGN_ODD;
                        flags |= MXGEFW_FLAGS_CKSUM;
                }
@@ -1986,7 +1991,7 @@ again:
                /* for TSO, pseudo_hdr_offset holds mss.
                 * The firmware figures out where to put
                 * the checksum by parsing the header. */
-               pseudo_hdr_offset = htons(mss);
+               pseudo_hdr_offset = mss;
        } else
 #endif                         /*NETIF_F_TSO */
                /* Mark small packets, and pad out tiny packets */
@@ -2086,7 +2091,7 @@ again:
 #endif                         /* NETIF_F_TSO */
                        req->addr_high = high_swapped;
                        req->addr_low = htonl(low);
-                       req->pseudo_hdr_offset = pseudo_hdr_offset;
+                       req->pseudo_hdr_offset = htons(pseudo_hdr_offset);
                        req->pad = 0;   /* complete solid 16-byte block; does this matter? */
                        req->rdma_count = 1;
                        req->length = htons(seglen);
@@ -2199,6 +2204,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
        struct myri10ge_cmd cmd;
        struct myri10ge_priv *mgp;
        struct dev_mc_list *mc_list;
+       __be32 data[2] = {0, 0};
        int err;
 
        mgp = netdev_priv(dev);
@@ -2237,10 +2243,9 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
 
        /* Walk the multicast list, and add each address */
        for (mc_list = dev->mc_list; mc_list != NULL; mc_list = mc_list->next) {
-               memcpy(&cmd.data0, &mc_list->dmi_addr, 4);
-               memcpy(&cmd.data1, ((char *)&mc_list->dmi_addr) + 4, 2);
-               cmd.data0 = htonl(cmd.data0);
-               cmd.data1 = htonl(cmd.data1);
+               memcpy(data, &mc_list->dmi_addr, 6);
+               cmd.data0 = ntohl(data[0]);
+               cmd.data1 = ntohl(data[1]);
                err = myri10ge_send_cmd(mgp, MXGEFW_JOIN_MULTICAST_GROUP,
                                        &cmd, 1);
 
index 9519ae7..29463b3 100644 (file)
@@ -6,23 +6,23 @@
 
 /* 8 Bytes */
 struct mcp_dma_addr {
-       u32 high;
-       u32 low;
+       __be32 high;
+       __be32 low;
 };
 
 /* 4 Bytes */
 struct mcp_slot {
-       u16 checksum;
-       u16 length;
+       __sum16 checksum;
+       __be16 length;
 };
 
 /* 64 Bytes */
 struct mcp_cmd {
-       u32 cmd;
-       u32 data0;              /* will be low portion if data > 32 bits */
+       __be32 cmd;
+       __be32 data0;           /* will be low portion if data > 32 bits */
        /* 8 */
-       u32 data1;              /* will be high portion if data > 32 bits */
-       u32 data2;              /* currently unused.. */
+       __be32 data1;           /* will be high portion if data > 32 bits */
+       __be32 data2;           /* currently unused.. */
        /* 16 */
        struct mcp_dma_addr response_addr;
        /* 24 */
@@ -31,8 +31,8 @@ struct mcp_cmd {
 
 /* 8 Bytes */
 struct mcp_cmd_response {
-       u32 data;
-       u32 result;
+       __be32 data;
+       __be32 result;
 };
 
 /*
@@ -73,10 +73,10 @@ union mcp_pso_or_cumlen {
 
 /* 16 Bytes */
 struct mcp_kreq_ether_send {
-       u32 addr_high;
-       u32 addr_low;
-       u16 pseudo_hdr_offset;
-       u16 length;
+       __be32 addr_high;
+       __be32 addr_low;
+       __be16 pseudo_hdr_offset;
+       __be16 length;
        u8 pad;
        u8 rdma_count;
        u8 cksum_offset;        /* where to start computing cksum */
@@ -85,8 +85,8 @@ struct mcp_kreq_ether_send {
 
 /* 8 Bytes */
 struct mcp_kreq_ether_recv {
-       u32 addr_high;
-       u32 addr_low;
+       __be32 addr_high;
+       __be32 addr_low;
 };
 
 /* Commands */
@@ -219,19 +219,19 @@ enum myri10ge_mcp_cmd_status {
 
 struct mcp_irq_data {
        /* add new counters at the beginning */
-       u32 future_use[5];
-       u32 dropped_multicast_filtered;
+       __be32 future_use[5];
+       __be32 dropped_multicast_filtered;
        /* 40 Bytes */
-       u32 send_done_count;
-
-       u32 link_up;
-       u32 dropped_link_overflow;
-       u32 dropped_link_error_or_filtered;
-       u32 dropped_runt;
-       u32 dropped_overrun;
-       u32 dropped_no_small_buffer;
-       u32 dropped_no_big_buffer;
-       u32 rdma_tags_available;
+       __be32 send_done_count;
+
+       __be32 link_up;
+       __be32 dropped_link_overflow;
+       __be32 dropped_link_error_or_filtered;
+       __be32 dropped_runt;
+       __be32 dropped_overrun;
+       __be32 dropped_no_small_buffer;
+       __be32 dropped_no_big_buffer;
+       __be32 rdma_tags_available;
 
        u8 tx_stopped;
        u8 link_down;
index 487f779..16a810d 100644 (file)
@@ -36,7 +36,7 @@
 struct mcp_gen_header {
        /* the first 4 fields are filled at compile time */
        unsigned header_length;
-       unsigned mcp_type;
+       __be32 mcp_type;
        char version[128];
        unsigned mcp_globals;   /* pointer to mcp-type specific structure */
 
index 787aa42..a5c4199 100644 (file)
@@ -867,7 +867,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr, NE_IO_EXTENT);
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        int this_dev;
 
index 5fccfea..089b5bb 100644 (file)
@@ -813,7 +813,7 @@ static void cleanup_card(struct net_device *dev)
        release_region(dev->base_addr, NE_IO_EXTENT);
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        int this_dev;
 
index 9c588af..b5410be 100644 (file)
@@ -1,25 +1,25 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * 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.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
 
 #include "netxen_nic_hw.h"
 
-#define NETXEN_NIC_BUILD_NO     "5"
-#define _NETXEN_NIC_LINUX_MAJOR 2
+#define NETXEN_NIC_BUILD_NO     "1"
+#define _NETXEN_NIC_LINUX_MAJOR 3
 #define _NETXEN_NIC_LINUX_MINOR 3
-#define _NETXEN_NIC_LINUX_SUBVERSION 59
-#define NETXEN_NIC_LINUX_VERSIONID  "2.3.59" "-" NETXEN_NIC_BUILD_NO
-#define NETXEN_NIC_FW_VERSIONID "2.3.59"
+#define _NETXEN_NIC_LINUX_SUBVERSION 2
+#define NETXEN_NIC_LINUX_VERSIONID  "3.3.2" "-" NETXEN_NIC_BUILD_NO
+#define NETXEN_NIC_FW_VERSIONID "3.3.2"
 
 #define RCV_DESC_RINGSIZE      \
        (sizeof(struct rcv_desc) * adapter->max_rx_desc_count)
 #define STATUS_DESC_RINGSIZE   \
        (sizeof(struct status_desc)* adapter->max_rx_desc_count)
+#define LRO_DESC_RINGSIZE      \
+       (sizeof(rcvDesc_t) * adapter->max_lro_rx_desc_count)
 #define TX_RINGSIZE    \
        (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count)
 #define RCV_BUFFSIZE   \
        (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count)
 #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
 
-#define NETXEN_NETDEV_STATUS 0x1
+#define NETXEN_NETDEV_STATUS           0x1
+#define NETXEN_RCV_PRODUCER_OFFSET     0
+#define NETXEN_RCV_PEG_DB_ID           2
+#define NETXEN_HOST_DUMMY_DMA_SIZE 1024
 
 #define ADDR_IN_WINDOW1(off)   \
        ((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0
+/*
+ * In netxen_nic_down(), we must wait for any pending callback requests into
+ * netxen_watchdog_task() to complete; eg otherwise the watchdog_timer could be
+ * reenabled right after it is deleted in netxen_nic_down(). FLUSH_SCHEDULED_WORK()
+ * does this synchronization.
+ *
+ * Normally, schedule_work()/flush_scheduled_work() could have worked, but
+ * netxen_nic_close() is invoked with kernel rtnl lock held. netif_carrier_off()
+ * call in netxen_nic_close() triggers a schedule_work(&linkwatch_work), and a
+ * subsequent call to flush_scheduled_work() in netxen_nic_down() would cause
+ * linkwatch_event() to be executed which also attempts to acquire the rtnl
+ * lock thus causing a deadlock.
+ */
+
+#define SCHEDULE_WORK(tp)      queue_work(netxen_workq, tp)
+#define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq)
+extern struct workqueue_struct *netxen_workq;
 
 /* 
  * normalize a 64MB crb address to 32MB PCI window 
  * To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1
  */
-#define NETXEN_CRB_NORMAL(reg)        \
-       (reg) - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST
+#define NETXEN_CRB_NORMAL(reg) \
+       ((reg) - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST)
 
 #define NETXEN_CRB_NORMALIZE(adapter, reg) \
        pci_base_offset(adapter, NETXEN_CRB_NORMAL(reg))
 
+#define DB_NORMALIZE(adapter, off) \
+       (adapter->ahw.db_base + (off))
+
+#define NX_P2_C0               0x24
+#define NX_P2_C1               0x25
+
 #define FIRST_PAGE_GROUP_START 0
-#define FIRST_PAGE_GROUP_END   0x400000
+#define FIRST_PAGE_GROUP_END   0x100000
 
 #define SECOND_PAGE_GROUP_START        0x4000000
 #define SECOND_PAGE_GROUP_END  0x66BC000
 #define SECOND_PAGE_GROUP_SIZE SECOND_PAGE_GROUP_END - SECOND_PAGE_GROUP_START
 #define THIRD_PAGE_GROUP_SIZE  THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START
 
-#define MAX_RX_BUFFER_LENGTH           2000
+#define MAX_RX_BUFFER_LENGTH           1760
 #define MAX_RX_JUMBO_BUFFER_LENGTH     9046
-#define RX_DMA_MAP_LEN                 (MAX_RX_BUFFER_LENGTH - NET_IP_ALIGN)
+#define MAX_RX_LRO_BUFFER_LENGTH       ((48*1024)-512)
+#define RX_DMA_MAP_LEN                 (MAX_RX_BUFFER_LENGTH - 2)
 #define RX_JUMBO_DMA_MAP_LEN   \
-       (MAX_RX_JUMBO_BUFFER_LENGTH - NET_IP_ALIGN)
+       (MAX_RX_JUMBO_BUFFER_LENGTH - 2)
+#define RX_LRO_DMA_MAP_LEN             (MAX_RX_LRO_BUFFER_LENGTH - 2)
 #define NETXEN_ROM_ROUNDUP             0x80000000ULL
 
 /*
@@ -151,30 +181,38 @@ enum {
 /* Host writes the following to notify that it has done the init-handshake */
 #define PHAN_INITIALIZE_ACK    0xf00f
 
-#define NUM_RCV_DESC_RINGS     2       /* No of Rcv Descriptor contexts */
+#define NUM_RCV_DESC_RINGS     3       /* No of Rcv Descriptor contexts */
 
 /* descriptor types */
 #define RCV_DESC_NORMAL                0x01
 #define RCV_DESC_JUMBO         0x02
+#define RCV_DESC_LRO           0x04
 #define RCV_DESC_NORMAL_CTXID  0
 #define RCV_DESC_JUMBO_CTXID   1
+#define RCV_DESC_LRO_CTXID     2
 
 #define RCV_DESC_TYPE(ID) \
-       ((ID == RCV_DESC_JUMBO_CTXID) ? RCV_DESC_JUMBO : RCV_DESC_NORMAL)
+       ((ID == RCV_DESC_JUMBO_CTXID)   \
+               ? RCV_DESC_JUMBO        \
+               : ((ID == RCV_DESC_LRO_CTXID)   \
+                       ? RCV_DESC_LRO :        \
+                       (RCV_DESC_NORMAL)))
 
 #define MAX_CMD_DESCRIPTORS            1024
 #define MAX_RCV_DESCRIPTORS            32768
-#define MAX_JUMBO_RCV_DESCRIPTORS      1024
+#define MAX_JUMBO_RCV_DESCRIPTORS      4096
+#define MAX_LRO_RCV_DESCRIPTORS                2048
 #define MAX_RCVSTATUS_DESCRIPTORS      MAX_RCV_DESCRIPTORS
 #define MAX_JUMBO_RCV_DESC     MAX_JUMBO_RCV_DESCRIPTORS
 #define MAX_RCV_DESC           MAX_RCV_DESCRIPTORS
 #define MAX_RCVSTATUS_DESC     MAX_RCV_DESCRIPTORS
-#define NUM_RCV_DESC           (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS)
 #define MAX_EPG_DESCRIPTORS    (MAX_CMD_DESCRIPTORS * 8)
-
+#define NUM_RCV_DESC           (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS + \
+                                MAX_LRO_RCV_DESCRIPTORS)
 #define MIN_TX_COUNT   4096
 #define MIN_RX_COUNT   4096
-
+#define NETXEN_CTX_SIGNATURE   0xdee0
+#define NETXEN_RCV_PRODUCER(ringid)    (ringid)
 #define MAX_FRAME_SIZE 0x10000 /* 64K MAX size for LSO */
 
 #define PHAN_PEG_RCV_INITIALIZED       0xff01
@@ -186,6 +224,67 @@ enum {
 #define get_index_range(index,length,count)    \
        (((index) + (count)) & ((length) - 1))
 
+#define MPORT_SINGLE_FUNCTION_MODE 0x1111
+
+extern unsigned long long netxen_dma_mask;
+
+/*
+ * NetXen host-peg signal message structure
+ *
+ *     Bit 0-1         : peg_id => 0x2 for tx and 01 for rx
+ *     Bit 2           : priv_id => must be 1
+ *     Bit 3-17        : count => for doorbell
+ *     Bit 18-27       : ctx_id => Context id
+ *     Bit 28-31       : opcode
+ */
+
+typedef u32 netxen_ctx_msg;
+
+#define _netxen_set_bits(config_word, start, bits, val)        {\
+       unsigned long long mask = (((1ULL << (bits)) - 1) << (start));  \
+       unsigned long long value = (val);       \
+       (config_word) &= ~mask; \
+       (config_word) |= (((value) << (start)) & mask); \
+}
+
+#define netxen_set_msg_peg_id(config_word, val)        \
+       _netxen_set_bits(config_word, 0, 2, val)
+#define netxen_set_msg_privid(config_word)     \
+       set_bit(2, (unsigned long*)&config_word)
+#define netxen_set_msg_count(config_word, val) \
+       _netxen_set_bits(config_word, 3, 15, val)
+#define netxen_set_msg_ctxid(config_word, val) \
+       _netxen_set_bits(config_word, 18, 10, val)
+#define netxen_set_msg_opcode(config_word, val)        \
+       _netxen_set_bits(config_word, 28, 4, val)
+
+struct netxen_rcv_context {
+       u32 rcv_ring_addr_lo;
+       u32 rcv_ring_addr_hi;
+       u32 rcv_ring_size;
+       u32 rsrvd;
+};
+
+struct netxen_ring_ctx {
+
+       /* one command ring */
+       u64 cmd_consumer_offset;
+       u32 cmd_ring_addr_lo;
+       u32 cmd_ring_addr_hi;
+       u32 cmd_ring_size;
+       u32 rsrvd;
+
+       /* three receive rings */
+       struct netxen_rcv_context rcv_ctx[3];
+
+       /* one status ring */
+       u32 sts_ring_addr_lo;
+       u32 sts_ring_addr_hi;
+       u32 sts_ring_size;
+
+       u32 ctx_id;
+} __attribute__ ((aligned(64)));
+
 /*
  * Following data structures describe the descriptors that will be used.
  * Added fileds of tcpHdrSize and ipHdrSize, The driver needs to do it only when
@@ -203,22 +302,32 @@ enum {
 #define FLAGS_IPSEC_SA_DELETE  0x08
 #define FLAGS_VLAN_TAGGED      0x10
 
-#define CMD_DESC_TOTAL_LENGTH(cmd_desc)        \
-               ((cmd_desc)->length_tcp_hdr & 0x00FFFFFF)
-#define CMD_DESC_TCP_HDR_OFFSET(cmd_desc)      \
-               (((cmd_desc)->length_tcp_hdr >> 24) & 0x0FF)
-#define CMD_DESC_PORT(cmd_desc)                ((cmd_desc)->port_ctxid & 0x0F)
-#define CMD_DESC_CTX_ID(cmd_desc)      (((cmd_desc)->port_ctxid >> 4) & 0x0F)
+#define netxen_set_cmd_desc_port(cmd_desc, var)        \
+       ((cmd_desc)->port_ctxid |= ((var) & 0x0F))
 
-#define CMD_DESC_TOTAL_LENGTH_WRT(cmd_desc, var)       \
-               ((cmd_desc)->length_tcp_hdr |= ((var) & 0x00FFFFFF))
-#define CMD_DESC_TCP_HDR_OFFSET_WRT(cmd_desc, var)     \
-               ((cmd_desc)->length_tcp_hdr |= (((var) << 24) & 0xFF000000))
-#define CMD_DESC_PORT_WRT(cmd_desc, var)       \
-               ((cmd_desc)->port_ctxid |= ((var) & 0x0F))
+#define netxen_set_cmd_desc_flags(cmd_desc, val)       \
+       _netxen_set_bits((cmd_desc)->flags_opcode, 0, 7, val)
+#define netxen_set_cmd_desc_opcode(cmd_desc, val)      \
+       _netxen_set_bits((cmd_desc)->flags_opcode, 7, 6, val)
+
+#define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \
+       _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 0, 8, val);
+#define netxen_set_cmd_desc_totallength(cmd_desc, val) \
+       _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 8, 24, val);
+
+#define netxen_get_cmd_desc_opcode(cmd_desc)   \
+       (((cmd_desc)->flags_opcode >> 7) & 0x003F)
+#define netxen_get_cmd_desc_totallength(cmd_desc)      \
+       (((cmd_desc)->num_of_buffers_total_length >> 8) & 0x0FFFFFF)
 
 struct cmd_desc_type0 {
-       u64 netxen_next;        /* for fragments handled by Phantom */
+       u8 tcp_hdr_offset;      /* For LSO only */
+       u8 ip_hdr_offset;       /* For LSO only */
+       /* Bit pattern: 0-6 flags, 7-12 opcode, 13-15 unused */
+       u16 flags_opcode;
+       /* Bit pattern: 0-7 total number of segments,
+          8-31 Total size of the packet */
+       u32 num_of_buffers_total_length;
        union {
                struct {
                        u32 addr_low_part2;
@@ -227,13 +336,6 @@ struct cmd_desc_type0 {
                u64 addr_buffer2;
        };
 
-       /* Bit pattern: 0-23 total length, 24-32 tcp header offset */
-       u32 length_tcp_hdr;
-       u8 ip_hdr_offset;       /* For LSO only */
-       u8 num_of_buffers;      /* total number of segments */
-       u8 flags;               /* as defined above */
-       u8 opcode;
-
        u16 reference_handle;   /* changed to u16 to add mss */
        u16 mss;                /* passed by NDIS_PACKET for LSO */
        /* Bit pattern 0-3 port, 0-3 ctx id */
@@ -248,7 +350,6 @@ struct cmd_desc_type0 {
                };
                u64 addr_buffer3;
        };
-
        union {
                struct {
                        u32 addr_low_part1;
@@ -270,6 +371,8 @@ struct cmd_desc_type0 {
                u64 addr_buffer4;
        };
 
+       u64 unused;
+
 } __attribute__ ((aligned(64)));
 
 /* Note: sizeof(rcv_desc) should always be a mutliple of 2 */
@@ -296,22 +399,49 @@ struct rcv_desc {
 #define NETXEN_PROT_UNKNOWN    (0)
 
 /* Note: sizeof(status_desc) should always be a mutliple of 2 */
-#define STATUS_DESC_PORT(status_desc)  \
-               ((status_desc)->port_status_type_op & 0x0F)
-#define STATUS_DESC_STATUS(status_desc)        \
-               (((status_desc)->port_status_type_op >> 4) & 0x0F)
-#define STATUS_DESC_TYPE(status_desc)  \
-               (((status_desc)->port_status_type_op >> 8) & 0x0F)
-#define STATUS_DESC_OPCODE(status_desc)        \
-               (((status_desc)->port_status_type_op >> 12) & 0x0F)
+
+#define netxen_get_sts_desc_lro_cnt(status_desc)       \
+       ((status_desc)->lro & 0x7F)
+#define netxen_get_sts_desc_lro_last_frag(status_desc) \
+       (((status_desc)->lro & 0x80) >> 7)
+
+#define netxen_get_sts_port(status_desc)       \
+       ((status_desc)->status_desc_data & 0x0F)
+#define netxen_get_sts_status(status_desc)     \
+       (((status_desc)->status_desc_data >> 4) & 0x0F)
+#define netxen_get_sts_type(status_desc)       \
+       (((status_desc)->status_desc_data >> 8) & 0x0F)
+#define netxen_get_sts_totallength(status_desc)        \
+       (((status_desc)->status_desc_data >> 12) & 0xFFFF)
+#define netxen_get_sts_refhandle(status_desc)  \
+       (((status_desc)->status_desc_data >> 28) & 0xFFFF)
+#define netxen_get_sts_prot(status_desc)       \
+       (((status_desc)->status_desc_data >> 44) & 0x0F)
+#define netxen_get_sts_owner(status_desc)      \
+       (((status_desc)->status_desc_data >> 56) & 0x03)
+#define netxen_get_sts_opcode(status_desc)     \
+       (((status_desc)->status_desc_data >> 58) & 0x03F)
+
+#define netxen_clear_sts_owner(status_desc)    \
+       ((status_desc)->status_desc_data &=     \
+       ~(((unsigned long long)3) << 56 ))
+#define netxen_set_sts_owner(status_desc, val) \
+       ((status_desc)->status_desc_data |=     \
+       (((unsigned long long)((val) & 0x3)) << 56 ))
 
 struct status_desc {
-       /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-15 opcode */
-       u16 port_status_type_op;
-       u16 total_length;       /* NIC mode */
-       u16 reference_handle;   /* handle for the associated packet */
-       /* Bit pattern: 0-1 owner, 2-5 protocol */
-       u16 owner;              /* Owner of the descriptor */
+       /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
+          28-43 reference_handle, 44-47 protocol, 48-52 unused
+          53-55 desc_cnt, 56-57 owner, 58-63 opcode
+        */
+       u64 status_desc_data;
+       u32 hash_value;
+       u8 hash_type;
+       u8 msg_type;
+       u8 unused;
+       /* Bit pattern: 0-6 lro_count indicates frag sequence,
+          7 last_frag indicates last frag */
+       u8 lro;
 } __attribute__ ((aligned(8)));
 
 enum {
@@ -559,11 +689,12 @@ typedef enum {
 #define PRIMARY_START          (BOOTLD_START)
 #define FLASH_CRBINIT_SIZE     (0x4000)
 #define FLASH_BRDCFG_SIZE      (sizeof(struct netxen_board_info))
-#define FLASH_USER_SIZE                (sizeof(netxen_user_info)/sizeof(u32))
+#define FLASH_USER_SIZE                (sizeof(struct netxen_user_info)/sizeof(u32))
 #define FLASH_SECONDARY_SIZE   (USER_START-SECONDARY_START)
 #define NUM_PRIMARY_SECTORS    (0x20)
 #define NUM_CONFIG_SECTORS     (1)
-#define PFX "netxen: "
+#define PFX "NetXen: "
+extern char netxen_nic_driver_name[];
 
 /* Note: Make sure to not call this before adapter->port is valid */
 #if !defined(NETXEN_DEBUG)
@@ -572,7 +703,7 @@ typedef enum {
 #else
 #define DPRINTK(klevel, fmt, args...)  do { \
        printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\
-               (adapter != NULL && adapter->port != NULL && \
+               (adapter != NULL && \
                adapter->port[0] != NULL && \
                adapter->port[0]->netdev != NULL) ? \
                adapter->port[0]->netdev->name : NULL, \
@@ -609,7 +740,6 @@ struct netxen_cmd_buffer {
        u8 frag_count;
        unsigned long time_stamp;
        u32 state;
-       u32 no_of_descriptors;
 };
 
 /* In rx_buffer, we do not need multiple fragments as is a single buffer */
@@ -618,6 +748,9 @@ struct netxen_rx_buffer {
        u64 dma;
        u16 ref_handle;
        u16 state;
+       u32 lro_expected_frags;
+       u32 lro_current_frags;
+       u32 lro_length;
 };
 
 /* Board types */
@@ -633,6 +766,8 @@ struct netxen_hardware_context {
        void __iomem *pci_base0;
        void __iomem *pci_base1;
        void __iomem *pci_base2;
+       void __iomem *db_base;
+       unsigned long db_len;
 
        u8 revision_id;
        u16 board_type;
@@ -642,14 +777,13 @@ struct netxen_hardware_context {
        u32 qg_linksup;
        /* Address of cmd ring in Phantom */
        struct cmd_desc_type0 *cmd_desc_head;
-       char *pauseaddr;
        struct pci_dev *cmd_desc_pdev;
        dma_addr_t cmd_desc_phys_addr;
-       dma_addr_t pause_physaddr;
-       struct pci_dev *pause_pdev;
        struct netxen_adapter *adapter;
 };
 
+#define RCV_RING_LRO   RCV_DESC_LRO
+
 #define MINIMUM_ETHERNET_FRAME_SIZE    64      /* With FCS */
 #define ETHERNET_FCS_SIZE              4
 
@@ -702,8 +836,13 @@ struct netxen_recv_context {
 };
 
 #define NETXEN_NIC_MSI_ENABLED 0x02
+#define NETXEN_DMA_MASK        0xfffffffe
+#define NETXEN_DB_MAPSIZE_BYTES    0x1000
 
-struct netxen_drvops;
+struct netxen_dummy_dma {
+       void *addr;
+       dma_addr_t phys_addr;
+};
 
 struct netxen_adapter {
        struct netxen_hardware_context ahw;
@@ -720,12 +859,13 @@ struct netxen_adapter {
        u32 curr_window;
 
        u32 cmd_producer;
-       u32 cmd_consumer;
+       u32 *cmd_consumer;
 
        u32 last_cmd_consumer;
        u32 max_tx_desc_count;
        u32 max_rx_desc_count;
        u32 max_jumbo_rx_desc_count;
+       u32 max_lro_rx_desc_count;
        /* Num of instances active on cmd buffer ring */
        u32 proc_cmd_buf_counter;
 
@@ -747,8 +887,27 @@ struct netxen_adapter {
        struct netxen_recv_context recv_ctx[MAX_RCV_CTX];
 
        int is_up;
-       int work_done;
-       struct netxen_drvops *ops;
+       int number;
+       struct netxen_dummy_dma dummy_dma;
+
+       /* Context interface shared between card and host */
+       struct netxen_ring_ctx *ctx_desc;
+       struct pci_dev *ctx_desc_pdev;
+       dma_addr_t ctx_desc_phys_addr;
+       int (*enable_phy_interrupts) (struct netxen_adapter *, int);
+       int (*disable_phy_interrupts) (struct netxen_adapter *, int);
+       void (*handle_phy_intr) (struct netxen_adapter *);
+       int (*macaddr_set) (struct netxen_port *, netxen_ethernet_macaddr_t);
+       int (*set_mtu) (struct netxen_port *, int);
+       int (*set_promisc) (struct netxen_adapter *, int,
+                           netxen_niu_prom_mode_t);
+       int (*unset_promisc) (struct netxen_adapter *, int,
+                             netxen_niu_prom_mode_t);
+       int (*phy_read) (struct netxen_adapter *, long phy, long reg, u32 *);
+       int (*phy_write) (struct netxen_adapter *, long phy, long reg, u32 val);
+       int (*init_port) (struct netxen_adapter *, int);
+       void (*init_niu) (struct netxen_adapter *);
+       int (*stop_port) (struct netxen_adapter *, int);
 };                             /* netxen_adapter structure */
 
 /* Max number of xmit producer threads that can run simultaneously */
@@ -830,25 +989,6 @@ static inline void __iomem *pci_base(struct netxen_adapter *adapter,
        return NULL;
 }
 
-struct netxen_drvops {
-       int (*enable_phy_interrupts) (struct netxen_adapter *, int);
-       int (*disable_phy_interrupts) (struct netxen_adapter *, int);
-       void (*handle_phy_intr) (struct netxen_adapter *);
-       int (*macaddr_set) (struct netxen_port *, netxen_ethernet_macaddr_t);
-       int (*set_mtu) (struct netxen_port *, int);
-       int (*set_promisc) (struct netxen_adapter *, int,
-                           netxen_niu_prom_mode_t);
-       int (*unset_promisc) (struct netxen_adapter *, int,
-                             netxen_niu_prom_mode_t);
-       int (*phy_read) (struct netxen_adapter *, long phy, long reg, u32 *);
-       int (*phy_write) (struct netxen_adapter *, long phy, long reg, u32 val);
-       int (*init_port) (struct netxen_adapter *, int);
-       void (*init_niu) (struct netxen_adapter *);
-       int (*stop_port) (struct netxen_adapter *, int);
-};
-
-extern char netxen_nic_driver_name[];
-
 int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter,
                                          int port);
 int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter,
@@ -887,10 +1027,20 @@ int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data,
                          int len);
 int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
                           int len);
+int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off,
+                            void *data, int len);
+int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off,
+                             void *data, int len);
+int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter,
+                                  u64 off, void *data, int size);
+int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter,
+                                 u64 off, void *data, int size);
 void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
                                 unsigned long off, int data);
 
 /* Functions from netxen_nic_init.c */
+void netxen_free_adapter_offload(struct netxen_adapter *adapter);
+int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
 void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
 void netxen_load_firmware(struct netxen_adapter *adapter);
 int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
@@ -925,7 +1075,9 @@ int netxen_nic_tx_has_work(struct netxen_adapter *adapter);
 void netxen_watchdog_task(struct work_struct *work);
 void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
                            u32 ringid);
-void netxen_process_cmd_ring(unsigned long data);
+void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, u32 ctx,
+                                u32 ringid);
+int netxen_process_cmd_ring(unsigned long data);
 u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
 void netxen_nic_set_multi(struct net_device *netdev);
 int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
@@ -1019,7 +1171,6 @@ static inline void get_brd_name_by_type(u32 type, char *name)
 
 int netxen_is_flash_supported(struct netxen_adapter *adapter);
 int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]);
-
 extern void netxen_change_ringparam(struct netxen_adapter *adapter);
 extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
                                int *valp);
index 9a914ae..2ab4885 100644 (file)
@@ -1,25 +1,25 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * 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.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
@@ -118,7 +118,7 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
        u32 fw_minor = 0;
        u32 fw_build = 0;
 
-       strncpy(drvinfo->driver, "netxen_nic", 32);
+       strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
        strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
        fw_major = readl(NETXEN_CRB_NORMALIZE(adapter,
                                              NETXEN_FW_VERSION_MAJOR));
@@ -210,7 +210,6 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
                printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
                       (netxen_brdtype_t) boardinfo->board_type);
                return -EIO;
-
        }
 
        return 0;
@@ -226,18 +225,18 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        /* read which mode */
        if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
                /* autonegotiation */
-               if (adapter->ops->phy_write
-                   && adapter->ops->phy_write(adapter, port->portnum,
-                                              NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
-                                              (__le32) ecmd->autoneg) != 0)
+               if (adapter->phy_write
+                   && adapter->phy_write(adapter, port->portnum,
+                                         NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
+                                         (__le32) ecmd->autoneg) != 0)
                        return -EIO;
                else
                        port->link_autoneg = ecmd->autoneg;
 
-               if (adapter->ops->phy_read
-                   && adapter->ops->phy_read(adapter, port->portnum,
-                                             NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-                                             &status) != 0)
+               if (adapter->phy_read
+                   && adapter->phy_read(adapter, port->portnum,
+                                        NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+                                        &status) != 0)
                        return -EIO;
 
                /* speed */
@@ -257,10 +256,10 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
                        netxen_clear_phy_duplex(status);
                if (ecmd->duplex == DUPLEX_FULL)
                        netxen_set_phy_duplex(status);
-               if (adapter->ops->phy_write
-                   && adapter->ops->phy_write(adapter, port->portnum,
-                                              NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-                                              *((int *)&status)) != 0)
+               if (adapter->phy_write
+                   && adapter->phy_write(adapter, port->portnum,
+                                         NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+                                         *((int *)&status)) != 0)
                        return -EIO;
                else {
                        port->link_speed = ecmd->speed;
@@ -422,10 +421,10 @@ static u32 netxen_nic_get_link(struct net_device *dev)
 
        /* read which mode */
        if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
-               if (adapter->ops->phy_read
-                   && adapter->ops->phy_read(adapter, port->portnum,
-                                             NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-                                             &status) != 0)
+               if (adapter->phy_read
+                   && adapter->phy_read(adapter, port->portnum,
+                                        NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+                                        &status) != 0)
                        return -EIO;
                else
                        return (netxen_get_phy_link(status));
@@ -460,20 +459,22 @@ netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
 {
        struct netxen_port *port = netdev_priv(dev);
        struct netxen_adapter *adapter = port->adapter;
-       int i, j;
+       int i;
 
        ring->rx_pending = 0;
+       ring->rx_jumbo_pending = 0;
        for (i = 0; i < MAX_RCV_CTX; ++i) {
-               for (j = 0; j < NUM_RCV_DESC_RINGS; j++)
-                       ring->rx_pending +=
-                           adapter->recv_ctx[i].rcv_desc[j].rcv_pending;
+               ring->rx_pending += adapter->recv_ctx[i].
+                   rcv_desc[RCV_DESC_NORMAL_CTXID].rcv_pending;
+               ring->rx_jumbo_pending += adapter->recv_ctx[i].
+                   rcv_desc[RCV_DESC_JUMBO_CTXID].rcv_pending;
        }
 
        ring->rx_max_pending = adapter->max_rx_desc_count;
        ring->tx_max_pending = adapter->max_tx_desc_count;
+       ring->rx_jumbo_max_pending = adapter->max_jumbo_rx_desc_count;
        ring->rx_mini_max_pending = 0;
        ring->rx_mini_pending = 0;
-       ring->rx_jumbo_max_pending = 0;
        ring->rx_jumbo_pending = 0;
 }
 
@@ -526,10 +527,10 @@ netxen_nic_set_pauseparam(struct net_device *dev,
                                    *(u32 *) (&val));
                /* set autoneg */
                autoneg = pause->autoneg;
-               if (adapter->ops->phy_write
-                   && adapter->ops->phy_write(adapter, port->portnum,
-                                              NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
-                                              (__le32) autoneg) != 0)
+               if (adapter->phy_write
+                   && adapter->phy_write(adapter, port->portnum,
+                                         NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
+                                         (__le32) autoneg) != 0)
                        return -EIO;
                else {
                        port->link_autoneg = pause->autoneg;
index 72c6ec4..fe8b675 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * 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
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * MA  02111-1307, USA.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
index 105c24f..9147b60 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * 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
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * MA  02111-1307, USA.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
@@ -42,7 +42,7 @@
 
 #define NETXEN_FLASH_BASE      (BOOTLD_START)
 #define NETXEN_PHANTOM_MEM_BASE        (NETXEN_FLASH_BASE)
-#define NETXEN_MAX_MTU         8000
+#define NETXEN_MAX_MTU         8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE
 #define NETXEN_MIN_MTU         64
 #define NETXEN_ETH_FCS_SIZE     4
 #define NETXEN_ENET_HEADER_SIZE 14
@@ -81,8 +81,8 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
        DPRINTK(INFO, "valid ether addr\n");
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 
-       if (adapter->ops->macaddr_set)
-               adapter->ops->macaddr_set(port, addr->sa_data);
+       if (adapter->macaddr_set)
+               adapter->macaddr_set(port, addr->sa_data);
 
        return 0;
 }
@@ -99,17 +99,17 @@ void netxen_nic_set_multi(struct net_device *netdev)
 
        mc_ptr = netdev->mc_list;
        if (netdev->flags & IFF_PROMISC) {
-               if (adapter->ops->set_promisc)
-                       adapter->ops->set_promisc(adapter,
-                                                 port->portnum,
-                                                 NETXEN_NIU_PROMISC_MODE);
+               if (adapter->set_promisc)
+                       adapter->set_promisc(adapter,
+                                            port->portnum,
+                                            NETXEN_NIU_PROMISC_MODE);
        } else {
-               if (adapter->ops->unset_promisc &&
+               if (adapter->unset_promisc &&
                    adapter->ahw.boardcfg.board_type
                    != NETXEN_BRDTYPE_P2_SB31_10G_IMEZ)
-                       adapter->ops->unset_promisc(adapter,
-                                                   port->portnum,
-                                                   NETXEN_NIU_NON_PROMISC_MODE);
+                       adapter->unset_promisc(adapter,
+                                              port->portnum,
+                                              NETXEN_NIU_NON_PROMISC_MODE);
        }
        if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
                netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x03);
@@ -160,8 +160,8 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
                return -EINVAL;
        }
 
-       if (adapter->ops->set_mtu)
-               adapter->ops->set_mtu(port, mtu);
+       if (adapter->set_mtu)
+               adapter->set_mtu(port, mtu);
        netdev->mtu = mtu;
 
        return 0;
@@ -176,22 +176,18 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
        struct netxen_hardware_context *hw = &adapter->ahw;
        u32 state = 0;
        void *addr;
-       void *pause_addr;
        int loops = 0, err = 0;
        int ctx, ring;
        u32 card_cmdring = 0;
-       struct netxen_rcv_desc_crb *rcv_desc_crb = NULL;
        struct netxen_recv_context *recv_ctx;
        struct netxen_rcv_desc_ctx *rcv_desc;
 
-       DPRINTK(INFO, "crb_base: %lx %lx", NETXEN_PCI_CRBSPACE,
+       DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE,
                PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE));
-       DPRINTK(INFO, "cam base: %lx %lx", NETXEN_CRB_CAM,
+       DPRINTK(INFO, "cam base: %lx %x", NETXEN_CRB_CAM,
                pci_base_offset(adapter, NETXEN_CRB_CAM));
-       DPRINTK(INFO, "cam RAM: %lx %lx", NETXEN_CAM_RAM_BASE,
+       DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE,
                pci_base_offset(adapter, NETXEN_CAM_RAM_BASE));
-       DPRINTK(INFO, "NIC base:%lx %lx\n", NIC_CRB_BASE_PORT1,
-               pci_base_offset(adapter, NIC_CRB_BASE_PORT1));
 
        /* Window 1 call */
        card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING));
@@ -226,33 +222,42 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
        DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n");
 
        addr = netxen_alloc(adapter->ahw.pdev,
-                           sizeof(struct cmd_desc_type0) *
-                           adapter->max_tx_desc_count,
-                           &hw->cmd_desc_phys_addr, &hw->cmd_desc_pdev);
+                           sizeof(struct netxen_ring_ctx) +
+                           sizeof(uint32_t),
+                           (dma_addr_t *) & adapter->ctx_desc_phys_addr,
+                           &adapter->ctx_desc_pdev);
 
+       printk("ctx_desc_phys_addr: 0x%llx\n",
+              (u64) adapter->ctx_desc_phys_addr);
        if (addr == NULL) {
                DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
-               return -ENOMEM;
+               err = -ENOMEM;
+               return err;
        }
+       memset(addr, 0, sizeof(struct netxen_ring_ctx));
+       adapter->ctx_desc = (struct netxen_ring_ctx *)addr;
+       adapter->ctx_desc->cmd_consumer_offset = adapter->ctx_desc_phys_addr
+           + sizeof(struct netxen_ring_ctx);
+       adapter->cmd_consumer = (uint32_t *) (((char *)addr) +
+                                             sizeof(struct netxen_ring_ctx));
+
+       addr = pci_alloc_consistent(adapter->ahw.pdev,
+                                   sizeof(struct cmd_desc_type0) *
+                                   adapter->max_tx_desc_count,
+                                   (dma_addr_t *) & hw->cmd_desc_phys_addr);
+       printk("cmd_desc_phys_addr: 0x%llx\n", (u64) hw->cmd_desc_phys_addr);
 
-       pause_addr = netxen_alloc(adapter->ahw.pdev, 512,
-                                 (dma_addr_t *) & hw->pause_physaddr,
-                                 &hw->pause_pdev);
-       if (pause_addr == NULL) {
-               DPRINTK(1, ERR, "bad return from pci_alloc_consistent\n");
+       if (addr == NULL) {
+               DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
+               netxen_free_hw_resources(adapter);
                return -ENOMEM;
        }
 
-       hw->pauseaddr = (char *)pause_addr;
-       {
-               u64 *ptr = (u64 *) pause_addr;
-               *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
-               *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
-               *ptr++ = NETXEN_NIC_UNIT_PAUSE_ADDR;
-               *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
-               *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR1;
-               *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR2;
-       }
+       adapter->ctx_desc->cmd_ring_addr_lo =
+           hw->cmd_desc_phys_addr & 0xffffffffUL;
+       adapter->ctx_desc->cmd_ring_addr_hi =
+           ((u64) hw->cmd_desc_phys_addr >> 32);
+       adapter->ctx_desc->cmd_ring_size = adapter->max_tx_desc_count;
 
        hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
 
@@ -273,6 +278,12 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
                                return err;
                        }
                        rcv_desc->desc_head = (struct rcv_desc *)addr;
+                       adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_lo =
+                           rcv_desc->phys_addr & 0xffffffffUL;
+                       adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_hi =
+                           ((u64) rcv_desc->phys_addr >> 32);
+                       adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
+                           rcv_desc->max_rx_desc_count;
                }
 
                addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE,
@@ -286,47 +297,21 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
                        return err;
                }
                recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
-               for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
-                       rcv_desc = &recv_ctx->rcv_desc[ring];
-                       rcv_desc_crb =
-                           &recv_crb_registers[ctx].rcv_desc_crb[ring];
-                       DPRINTK(INFO, "ring #%d crb global ring reg 0x%x\n",
-                               ring, rcv_desc_crb->crb_globalrcv_ring);
-                       /* Window = 1 */
-                       writel(lower32(rcv_desc->phys_addr),
-                              NETXEN_CRB_NORMALIZE(adapter,
-                                                   rcv_desc_crb->
-                                                   crb_globalrcv_ring));
-                       DPRINTK(INFO, "GLOBAL_RCV_RING ctx %d, addr 0x%x"
-                               " val 0x%llx,"
-                               " virt %p\n", ctx,
-                               rcv_desc_crb->crb_globalrcv_ring,
-                               (unsigned long long)rcv_desc->phys_addr,
-                               +rcv_desc->desc_head);
-               }
+               adapter->ctx_desc->sts_ring_addr_lo =
+                   recv_ctx->rcv_status_desc_phys_addr & 0xffffffffUL;
+               adapter->ctx_desc->sts_ring_addr_hi =
+                   ((u64) recv_ctx->rcv_status_desc_phys_addr >> 32);
+               adapter->ctx_desc->sts_ring_size = adapter->max_rx_desc_count;
 
-               /* Window = 1 */
-               writel(lower32(recv_ctx->rcv_status_desc_phys_addr),
-                      NETXEN_CRB_NORMALIZE(adapter,
-                                           recv_crb_registers[ctx].
-                                           crb_rcvstatus_ring));
-               DPRINTK(INFO, "RCVSTATUS_RING, ctx %d, addr 0x%x,"
-                       " val 0x%x,virt%p\n",
-                       ctx,
-                       recv_crb_registers[ctx].crb_rcvstatus_ring,
-                       (unsigned long long)recv_ctx->rcv_status_desc_phys_addr,
-                       recv_ctx->rcv_status_desc_head);
        }
        /* Window = 1 */
-       writel(lower32(hw->pause_physaddr),
-              NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_LO));
-       writel(upper32(hw->pause_physaddr),
-              NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_HI));
-
-       writel(lower32(hw->cmd_desc_phys_addr),
-              NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
-       writel(upper32(hw->cmd_desc_phys_addr),
-              NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_HI));
+
+       writel(lower32(adapter->ctx_desc_phys_addr),
+              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO));
+       writel(upper32(adapter->ctx_desc_phys_addr),
+              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI));
+       writel(NETXEN_CTX_SIGNATURE,
+              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG));
        return err;
 }
 
@@ -336,6 +321,15 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
        struct netxen_rcv_desc_ctx *rcv_desc;
        int ctx, ring;
 
+       if (adapter->ctx_desc != NULL) {
+               pci_free_consistent(adapter->ctx_desc_pdev,
+                                   sizeof(struct netxen_ring_ctx) +
+                                   sizeof(uint32_t),
+                                   adapter->ctx_desc,
+                                   adapter->ctx_desc_phys_addr);
+               adapter->ctx_desc = NULL;
+       }
+
        if (adapter->ahw.cmd_desc_head != NULL) {
                pci_free_consistent(adapter->ahw.cmd_desc_pdev,
                                    sizeof(struct cmd_desc_type0) *
@@ -344,11 +338,9 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
                                    adapter->ahw.cmd_desc_phys_addr);
                adapter->ahw.cmd_desc_head = NULL;
        }
-       if (adapter->ahw.pauseaddr != NULL) {
-               pci_free_consistent(adapter->ahw.pause_pdev, 512,
-                                   adapter->ahw.pauseaddr,
-                                   adapter->ahw.pause_physaddr);
-               adapter->ahw.pauseaddr = NULL;
+       /* Special handling: there are 2 ports on this board */
+       if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) {
+               adapter->ahw.max_ports = 2;
        }
 
        for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
@@ -383,19 +375,22 @@ void netxen_tso_check(struct netxen_adapter *adapter,
                desc->total_hdr_length = sizeof(struct ethhdr) +
                    ((skb->nh.iph)->ihl * sizeof(u32)) +
                    ((skb->h.th)->doff * sizeof(u32));
-               desc->opcode = TX_TCP_LSO;
+               netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO);
        } else if (skb->ip_summed == CHECKSUM_COMPLETE) {
                if (skb->nh.iph->protocol == IPPROTO_TCP) {
-                       desc->opcode = TX_TCP_PKT;
+                       netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT);
                } else if (skb->nh.iph->protocol == IPPROTO_UDP) {
-                       desc->opcode = TX_UDP_PKT;
+                       netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT);
                } else {
                        return;
                }
        }
        adapter->stats.xmitcsummed++;
-       CMD_DESC_TCP_HDR_OFFSET_WRT(desc, skb->h.raw - skb->data);
-       desc->length_tcp_hdr = cpu_to_le32(desc->length_tcp_hdr);
+       desc->tcp_hdr_offset = skb->h.raw - skb->data;
+       netxen_set_cmd_desc_totallength(desc,
+                                       cpu_to_le32
+                                       (netxen_get_cmd_desc_totallength
+                                        (desc)));
        desc->ip_hdr_offset = skb->nh.raw - skb->data;
 }
 
@@ -648,7 +643,7 @@ void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
 
        addr = NETXEN_CRB_NORMALIZE(adapter, off);
        DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n",
-               pci_base(adapter, off), off, addr);
+               pci_base(adapter, off), off, addr, val);
        writel(val, addr);
 
 }
@@ -660,7 +655,7 @@ int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
 
        addr = NETXEN_CRB_NORMALIZE(adapter, off);
        DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
-               adapter->ahw.pci_base, off, addr);
+               pci_base(adapter, off), off, addr);
        val = readl(addr);
        writel(val, addr);
 
@@ -848,8 +843,8 @@ void netxen_nic_stop_all_ports(struct netxen_adapter *adapter)
 
        for (port_nr = 0; port_nr < adapter->ahw.max_ports; port_nr++) {
                port = adapter->port[port_nr];
-               if (adapter->ops->stop_port)
-                       adapter->ops->stop_port(adapter, port->portnum);
+               if (adapter->stop_port)
+                       adapter->stop_port(adapter, port->portnum);
        }
 }
 
@@ -873,13 +868,13 @@ void netxen_nic_set_link_parameters(struct netxen_port *port)
 {
        struct netxen_adapter *adapter = port->adapter;
        __le32 status;
-       u16 autoneg;
+       __le32 autoneg;
        __le32 mode;
 
        netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode);
        if (netxen_get_niu_enable_ge(mode)) {   /* Gb 10/100/1000 Mbps mode */
-               if (adapter->ops->phy_read
-                   && adapter->ops->
+               if (adapter->phy_read
+                   && adapter->
                    phy_read(adapter, port->portnum,
                             NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
                             &status) == 0) {
@@ -909,11 +904,11 @@ void netxen_nic_set_link_parameters(struct netxen_port *port)
                                        port->link_duplex = -1;
                                        break;
                                }
-                               if (adapter->ops->phy_read
-                                   && adapter->ops->
+                               if (adapter->phy_read
+                                   && adapter->
                                    phy_read(adapter, port->portnum,
                                             NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
-                                            (__le32 *) & autoneg) != 0)
+                                            &autoneg) != 0)
                                        port->link_autoneg = autoneg;
                        } else
                                goto link_down;
@@ -1008,3 +1003,291 @@ int netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off)
        netxen_nic_hw_read_wx(adapter, off, &data, 4);
        return data;
 }
+
+int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off,
+                             void *data, int len)
+{
+       void *addr;
+       u64 offset = off;
+       u8 *mem_ptr = NULL;
+       unsigned long mem_base;
+       unsigned long mem_page;
+
+       if (ADDR_IN_WINDOW1(off)) {
+               addr = NETXEN_CRB_NORMALIZE(adapter, off);
+               if (!addr) {
+                       mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+                       offset = NETXEN_CRB_NORMAL(off);
+                       mem_page = offset & PAGE_MASK;
+                       if (mem_page != ((offset + len - 1) & PAGE_MASK))
+                               mem_ptr =
+                                   ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+                       else
+                               mem_ptr =
+                                   ioremap(mem_base + mem_page, PAGE_SIZE);
+                       if (mem_ptr == 0UL) {
+                               return 1;
+                       }
+                       addr = mem_ptr;
+                       addr += offset & (PAGE_SIZE - 1);
+               }
+       } else {
+               addr = pci_base_offset(adapter, off);
+               if (!addr) {
+                       mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+                       mem_page = off & PAGE_MASK;
+                       if (mem_page != ((off + len - 1) & PAGE_MASK))
+                               mem_ptr =
+                                   ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+                       else
+                               mem_ptr =
+                                   ioremap(mem_base + mem_page, PAGE_SIZE);
+                       if (mem_ptr == 0UL) {
+                               return 1;
+                       }
+                       addr = mem_ptr;
+                       addr += off & (PAGE_SIZE - 1);
+               }
+               netxen_nic_pci_change_crbwindow(adapter, 0);
+       }
+       switch (len) {
+       case 1:
+               writeb(*(u8 *) data, addr);
+               break;
+       case 2:
+               writew(*(u16 *) data, addr);
+               break;
+       case 4:
+               writel(*(u32 *) data, addr);
+               break;
+       case 8:
+               writeq(*(u64 *) data, addr);
+               break;
+       default:
+               DPRINTK(INFO,
+                       "writing data %lx to offset %llx, num words=%d\n",
+                       *(unsigned long *)data, off, (len >> 3));
+
+               netxen_nic_hw_block_write64((u64 __iomem *) data, addr,
+                                           (len >> 3));
+               break;
+       }
+
+       if (!ADDR_IN_WINDOW1(off))
+               netxen_nic_pci_change_crbwindow(adapter, 1);
+       if (mem_ptr)
+               iounmap(mem_ptr);
+       return 0;
+}
+
+int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off,
+                            void *data, int len)
+{
+       void *addr;
+       u64 offset;
+       u8 *mem_ptr = NULL;
+       unsigned long mem_base;
+       unsigned long mem_page;
+
+       if (ADDR_IN_WINDOW1(off)) {
+               addr = NETXEN_CRB_NORMALIZE(adapter, off);
+               if (!addr) {
+                       mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+                       offset = NETXEN_CRB_NORMAL(off);
+                       mem_page = offset & PAGE_MASK;
+                       if (mem_page != ((offset + len - 1) & PAGE_MASK))
+                               mem_ptr =
+                                   ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+                       else
+                               mem_ptr =
+                                   ioremap(mem_base + mem_page, PAGE_SIZE);
+                       if (mem_ptr == 0UL) {
+                               *(u8 *) data = 0;
+                               return 1;
+                       }
+                       addr = mem_ptr;
+                       addr += offset & (PAGE_SIZE - 1);
+               }
+       } else {
+               addr = pci_base_offset(adapter, off);
+               if (!addr) {
+                       mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+                       mem_page = off & PAGE_MASK;
+                       if (mem_page != ((off + len - 1) & PAGE_MASK))
+                               mem_ptr =
+                                   ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+                       else
+                               mem_ptr =
+                                   ioremap(mem_base + mem_page, PAGE_SIZE);
+                       if (mem_ptr == 0UL)
+                               return 1;
+                       addr = mem_ptr;
+                       addr += off & (PAGE_SIZE - 1);
+               }
+               netxen_nic_pci_change_crbwindow(adapter, 0);
+       }
+       switch (len) {
+       case 1:
+               *(u8 *) data = readb(addr);
+               break;
+       case 2:
+               *(u16 *) data = readw(addr);
+               break;
+       case 4:
+               *(u32 *) data = readl(addr);
+               break;
+       case 8:
+               *(u64 *) data = readq(addr);
+               break;
+       default:
+               netxen_nic_hw_block_read64((u64 __iomem *) data, addr,
+                                          (len >> 3));
+               break;
+       }
+       if (!ADDR_IN_WINDOW1(off))
+               netxen_nic_pci_change_crbwindow(adapter, 1);
+       if (mem_ptr)
+               iounmap(mem_ptr);
+       return 0;
+}
+
+int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter, u64 off,
+                                  void *data, int size)
+{
+       void *addr;
+       int ret = 0;
+       u8 *mem_ptr = NULL;
+       unsigned long mem_base;
+       unsigned long mem_page;
+
+       if (data == NULL || off > (128 * 1024 * 1024)) {
+               printk(KERN_ERR "%s: data: %p off:%llx\n",
+                      netxen_nic_driver_name, data, off);
+               return 1;
+       }
+       off = netxen_nic_pci_set_window(adapter, off);
+       /* Corner case : Malicious user tried to break the driver by reading
+          last few bytes in ranges and tries to read further addresses.
+        */
+       if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) {
+               printk(KERN_ERR "%s: Invalid access to memory address range"
+                      " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off,
+                      off + size);
+               return 1;
+       }
+       addr = pci_base_offset(adapter, off);
+       DPRINTK(INFO, "writing data %llx to offset %llx\n",
+               *(unsigned long long *)data, off);
+       if (!addr) {
+               mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+               mem_page = off & PAGE_MASK;
+               /* Map two pages whenever user tries to access addresses in two
+                  consecutive pages.
+                */
+               if (mem_page != ((off + size - 1) & PAGE_MASK))
+                       mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+               else
+                       mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
+               if (mem_ptr == 0UL) {
+                       return 1;
+               }
+               addr = mem_ptr;
+               addr += off & (PAGE_SIZE - 1);
+       }
+       switch (size) {
+       case 1:
+               writeb(*(u8 *) data, addr);
+               break;
+       case 2:
+               writew(*(u16 *) data, addr);
+               break;
+       case 4:
+               writel(*(u32 *) data, addr);
+               break;
+       case 8:
+               writeq(*(u64 *) data, addr);
+               break;
+       default:
+               DPRINTK(INFO,
+                       "writing data %lx to offset %llx, num words=%d\n",
+                       *(unsigned long *)data, off, (size >> 3));
+
+               netxen_nic_hw_block_write64((u64 __iomem *) data, addr,
+                                           (size >> 3));
+               break;
+       }
+
+       if (mem_ptr)
+               iounmap(mem_ptr);
+       DPRINTK(INFO, "wrote %llx\n", *(unsigned long long *)data);
+
+       return ret;
+}
+
+int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter,
+                                 u64 off, void *data, int size)
+{
+       void *addr;
+       int ret = 0;
+       u8 *mem_ptr = NULL;
+       unsigned long mem_base;
+       unsigned long mem_page;
+
+       if (data == NULL || off > (128 * 1024 * 1024)) {
+               printk(KERN_ERR "%s: data: %p off:%llx\n",
+                      netxen_nic_driver_name, data, off);
+               return 1;
+       }
+       off = netxen_nic_pci_set_window(adapter, off);
+       /* Corner case : Malicious user tried to break the driver by reading
+          last few bytes in ranges and tries to read further addresses.
+        */
+       if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) {
+               printk(KERN_ERR "%s: Invalid access to memory address range"
+                      " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off,
+                      off + size);
+               return 1;
+       }
+       addr = pci_base_offset(adapter, off);
+       if (!addr) {
+               mem_base = pci_resource_start(adapter->ahw.pdev, 0);
+               mem_page = off & PAGE_MASK;
+               /* Map two pages whenever user tries to access addresses in two
+                  consecutive pages.
+                */
+               if (mem_page != ((off + size - 1) & PAGE_MASK))
+                       mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+               else
+                       mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
+               if (mem_ptr == 0UL) {
+                       *(u8 *) data = 0;
+                       return 1;
+               }
+               addr = mem_ptr;
+               addr += off & (PAGE_SIZE - 1);
+       }
+       switch (size) {
+       case 1:
+               *(u8 *) data = readb(addr);
+               break;
+       case 2:
+               *(u16 *) data = readw(addr);
+               break;
+       case 4:
+               *(u32 *) data = readl(addr);
+               break;
+       case 8:
+               *(u64 *) data = readq(addr);
+               break;
+       default:
+               netxen_nic_hw_block_read64((u64 __iomem *) data, addr,
+                                          (size >> 3));
+               break;
+       }
+
+       if (mem_ptr)
+               iounmap(mem_ptr);
+       DPRINTK(INFO, "read %llx\n", *(unsigned long long *)data);
+
+       return ret;
+}
index 201a636..0685633 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * 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
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * MA  02111-1307, USA.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
@@ -83,8 +83,8 @@ struct netxen_adapter;
 #define NETXEN_PCI_MAPSIZE_BYTES  (NETXEN_PCI_MAPSIZE << 20)
 
 #define NETXEN_NIC_LOCKED_READ_REG(X, Y)       \
-       addr = pci_base_offset(adapter, (X));   \
-       *(u32 *)Y = readl(addr);
+       addr = pci_base_offset(adapter, X);     \
+       *(u32 *)Y = readl((void __iomem*) addr);
 
 struct netxen_port;
 void netxen_nic_set_link_parameters(struct netxen_port *port);
index eae1823..290145e 100644 (file)
@@ -1,25 +1,25 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * 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.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
@@ -137,6 +137,8 @@ int netxen_init_firmware(struct netxen_adapter *adapter)
                return err;
        }
        /* Window 1 call */
+       writel(MPORT_SINGLE_FUNCTION_MODE,
+              NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE));
        writel(PHAN_INITIALIZE_ACK,
               NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
 
@@ -184,15 +186,12 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter)
                        for (i = 0; i < num_rx_bufs; i++) {
                                rx_buf->ref_handle = i;
                                rx_buf->state = NETXEN_BUFFER_FREE;
-
                                DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:"
                                        "%p\n", ctxid, i, rx_buf);
                                rx_buf++;
                        }
                }
        }
-       DPRINTK(INFO, "initialized buffers for %s and %s\n",
-               "adapter->free_cmd_buf_list", "adapter->free_rxbuf");
 }
 
 void netxen_initialize_adapter_hw(struct netxen_adapter *adapter)
@@ -212,37 +211,36 @@ void netxen_initialize_adapter_hw(struct netxen_adapter *adapter)
 
 void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
 {
-       struct netxen_drvops *ops = adapter->ops;
        switch (adapter->ahw.board_type) {
        case NETXEN_NIC_GBE:
-               ops->enable_phy_interrupts =
+               adapter->enable_phy_interrupts =
                    netxen_niu_gbe_enable_phy_interrupts;
-               ops->disable_phy_interrupts =
+               adapter->disable_phy_interrupts =
                    netxen_niu_gbe_disable_phy_interrupts;
-               ops->handle_phy_intr = netxen_nic_gbe_handle_phy_intr;
-               ops->macaddr_set = netxen_niu_macaddr_set;
-               ops->set_mtu = netxen_nic_set_mtu_gb;
-               ops->set_promisc = netxen_niu_set_promiscuous_mode;
-               ops->unset_promisc = netxen_niu_set_promiscuous_mode;
-               ops->phy_read = netxen_niu_gbe_phy_read;
-               ops->phy_write = netxen_niu_gbe_phy_write;
-               ops->init_port = netxen_niu_gbe_init_port;
-               ops->init_niu = netxen_nic_init_niu_gb;
-               ops->stop_port = netxen_niu_disable_gbe_port;
+               adapter->handle_phy_intr = netxen_nic_gbe_handle_phy_intr;
+               adapter->macaddr_set = netxen_niu_macaddr_set;
+               adapter->set_mtu = netxen_nic_set_mtu_gb;
+               adapter->set_promisc = netxen_niu_set_promiscuous_mode;
+               adapter->unset_promisc = netxen_niu_set_promiscuous_mode;
+               adapter->phy_read = netxen_niu_gbe_phy_read;
+               adapter->phy_write = netxen_niu_gbe_phy_write;
+               adapter->init_port = netxen_niu_gbe_init_port;
+               adapter->init_niu = netxen_nic_init_niu_gb;
+               adapter->stop_port = netxen_niu_disable_gbe_port;
                break;
 
        case NETXEN_NIC_XGBE:
-               ops->enable_phy_interrupts =
+               adapter->enable_phy_interrupts =
                    netxen_niu_xgbe_enable_phy_interrupts;
-               ops->disable_phy_interrupts =
+               adapter->disable_phy_interrupts =
                    netxen_niu_xgbe_disable_phy_interrupts;
-               ops->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr;
-               ops->macaddr_set = netxen_niu_xg_macaddr_set;
-               ops->set_mtu = netxen_nic_set_mtu_xgb;
-               ops->init_port = netxen_niu_xg_init_port;
-               ops->set_promisc = netxen_niu_xg_set_promiscuous_mode;
-               ops->unset_promisc = netxen_niu_xg_set_promiscuous_mode;
-               ops->stop_port = netxen_niu_disable_xg_port;
+               adapter->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr;
+               adapter->macaddr_set = netxen_niu_xg_macaddr_set;
+               adapter->set_mtu = netxen_nic_set_mtu_xgb;
+               adapter->init_port = netxen_niu_xg_init_port;
+               adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode;
+               adapter->unset_promisc = netxen_niu_xg_set_promiscuous_mode;
+               adapter->stop_port = netxen_niu_disable_xg_port;
                break;
 
        default:
@@ -383,8 +381,8 @@ int netxen_rom_wip_poll(struct netxen_adapter *adapter)
        return 0;
 }
 
-static inline int do_rom_fast_write(struct netxen_adapter *adapter,
-                                   int addr, int data)
+static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
+                                   int data)
 {
        if (netxen_rom_wren(adapter)) {
                return -1;
@@ -622,6 +620,43 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
        return 0;
 }
 
+int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
+{
+       uint64_t addr;
+       uint32_t hi;
+       uint32_t lo;
+
+       adapter->dummy_dma.addr =
+           pci_alloc_consistent(adapter->ahw.pdev,
+                                NETXEN_HOST_DUMMY_DMA_SIZE,
+                                &adapter->dummy_dma.phys_addr);
+       if (adapter->dummy_dma.addr == NULL) {
+               printk("%s: ERROR: Could not allocate dummy DMA memory\n",
+                      __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       addr = (uint64_t) adapter->dummy_dma.phys_addr;
+       hi = (addr >> 32) & 0xffffffff;
+       lo = addr & 0xffffffff;
+
+       writel(hi, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI));
+       writel(lo, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO));
+
+       return 0;
+}
+
+void netxen_free_adapter_offload(struct netxen_adapter *adapter)
+{
+       if (adapter->dummy_dma.addr) {
+               pci_free_consistent(adapter->ahw.pdev,
+                                   NETXEN_HOST_DUMMY_DMA_SIZE,
+                                   adapter->dummy_dma.addr,
+                                   adapter->dummy_dma.phys_addr);
+               adapter->dummy_dma.addr = NULL;
+       }
+}
+
 void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
 {
        u32 val = 0;
@@ -656,7 +691,8 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
                desc_head = recv_ctx->rcv_status_desc_head;
                desc = &desc_head[consumer];
 
-               if (((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST))
+               if (((le16_to_cpu(netxen_get_sts_owner(desc)))
+                    & STATUS_OWNER_HOST))
                        return 1;
        }
 
@@ -735,8 +771,8 @@ void netxen_watchdog_task(struct work_struct *work)
                        netif_wake_queue(netdev);
        }
 
-       if (adapter->ops->handle_phy_intr)
-               adapter->ops->handle_phy_intr(adapter);
+       if (adapter->handle_phy_intr)
+               adapter->handle_phy_intr(adapter);
        mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
 }
 
@@ -749,19 +785,19 @@ void
 netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
                   struct status_desc *desc)
 {
-       struct netxen_port *port = adapter->port[STATUS_DESC_PORT(desc)];
+       struct netxen_port *port = adapter->port[netxen_get_sts_port(desc)];
        struct pci_dev *pdev = port->pdev;
        struct net_device *netdev = port->netdev;
-       int index = le16_to_cpu(desc->reference_handle);
+       int index = le16_to_cpu(netxen_get_sts_refhandle(desc));
        struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
        struct netxen_rx_buffer *buffer;
        struct sk_buff *skb;
-       u32 length = le16_to_cpu(desc->total_length);
+       u32 length = le16_to_cpu(netxen_get_sts_totallength(desc));
        u32 desc_ctx;
        struct netxen_rcv_desc_ctx *rcv_desc;
        int ret;
 
-       desc_ctx = STATUS_DESC_TYPE(desc);
+       desc_ctx = netxen_get_sts_type(desc);
        if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
                printk("%s: %s Bad Rcv descriptor ring\n",
                       netxen_nic_driver_name, netdev->name);
@@ -769,20 +805,49 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
        }
 
        rcv_desc = &recv_ctx->rcv_desc[desc_ctx];
+       if (unlikely(index > rcv_desc->max_rx_desc_count)) {
+               DPRINTK(ERR, "Got a buffer index:%x Max is %x\n",
+                       index, rcv_desc->max_rx_desc_count);
+               return;
+       }
        buffer = &rcv_desc->rx_buf_arr[index];
+       if (desc_ctx == RCV_DESC_LRO_CTXID) {
+               buffer->lro_current_frags++;
+               if (netxen_get_sts_desc_lro_last_frag(desc)) {
+                       buffer->lro_expected_frags =
+                           netxen_get_sts_desc_lro_cnt(desc);
+                       buffer->lro_length = length;
+               }
+               if (buffer->lro_current_frags != buffer->lro_expected_frags) {
+                       if (buffer->lro_expected_frags != 0) {
+                               printk("LRO: (refhandle:%x) recv frag."
+                                      "wait for last. flags: %x expected:%d"
+                                      "have:%d\n", index,
+                                      netxen_get_sts_desc_lro_last_frag(desc),
+                                      buffer->lro_expected_frags,
+                                      buffer->lro_current_frags);
+                       }
+                       return;
+               }
+       }
 
        pci_unmap_single(pdev, buffer->dma, rcv_desc->dma_size,
                         PCI_DMA_FROMDEVICE);
 
        skb = (struct sk_buff *)buffer->skb;
 
-       if (likely(STATUS_DESC_STATUS(desc) == STATUS_CKSUM_OK)) {
+       if (likely(netxen_get_sts_status(desc) == STATUS_CKSUM_OK)) {
                port->stats.csummed++;
                skb->ip_summed = CHECKSUM_UNNECESSARY;
-       } else
-               skb->ip_summed = CHECKSUM_NONE;
+       }
        skb->dev = netdev;
-       skb_put(skb, length);
+       if (desc_ctx == RCV_DESC_LRO_CTXID) {
+               /* True length was only available on the last pkt */
+               skb_put(skb, buffer->lro_length);
+       } else {
+               skb_put(skb, length);
+       }
+
        skb->protocol = eth_type_trans(skb, netdev);
 
        ret = netif_receive_skb(skb);
@@ -828,6 +893,8 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
        adapter->stats.post_called++;
        buffer->skb = NULL;
        buffer->state = NETXEN_BUFFER_FREE;
+       buffer->lro_current_frags = 0;
+       buffer->lro_expected_frags = 0;
 
        port->stats.no_rcv++;
        port->stats.rxbytes += length;
@@ -840,6 +907,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
        struct status_desc *desc_head = recv_ctx->rcv_status_desc_head;
        struct status_desc *desc;       /* used to read status desc here */
        u32 consumer = recv_ctx->status_rx_consumer;
+       u32 producer = 0;
        int count = 0, ring;
 
        DPRINTK(INFO, "procesing receive\n");
@@ -851,18 +919,22 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
         */
        while (count < max) {
                desc = &desc_head[consumer];
-               if (!((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST)) {
-                       DPRINTK(ERR, "desc %p ownedby %x\n", desc, desc->owner);
+               if (!
+                   (le16_to_cpu(netxen_get_sts_owner(desc)) &
+                    STATUS_OWNER_HOST)) {
+                       DPRINTK(ERR, "desc %p ownedby %x\n", desc,
+                               netxen_get_sts_owner(desc));
                        break;
                }
                netxen_process_rcv(adapter, ctxid, desc);
-               desc->owner = STATUS_OWNER_PHANTOM;
+               netxen_clear_sts_owner(desc);
+               netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM);
                consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1);
                count++;
        }
        if (count) {
                for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
-                       netxen_post_rx_buffers(adapter, ctxid, ring);
+                       netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
                }
        }
 
@@ -870,6 +942,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
        if (count) {
                adapter->stats.process_rcv++;
                recv_ctx->status_rx_consumer = consumer;
+               recv_ctx->status_rx_producer = producer;
 
                /* Window = 1 */
                writel(consumer,
@@ -882,12 +955,13 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
 }
 
 /* Process Command status ring */
-void netxen_process_cmd_ring(unsigned long data)
+int netxen_process_cmd_ring(unsigned long data)
 {
        u32 last_consumer;
        u32 consumer;
        struct netxen_adapter *adapter = (struct netxen_adapter *)data;
-       int count = 0;
+       int count1 = 0;
+       int count2 = 0;
        struct netxen_cmd_buffer *buffer;
        struct netxen_port *port;       /* port #1 */
        struct netxen_port *nport;
@@ -896,6 +970,7 @@ void netxen_process_cmd_ring(unsigned long data)
        u32 i;
        struct sk_buff *skb = NULL;
        int p;
+       int done;
 
        spin_lock(&adapter->tx_lock);
        last_consumer = adapter->last_cmd_consumer;
@@ -905,14 +980,13 @@ void netxen_process_cmd_ring(unsigned long data)
         * number as part of the descriptor. This way we will be able to get
         * the netdev which is associated with that device.
         */
-       consumer =
-           readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET));
 
+       consumer = *(adapter->cmd_consumer);
        if (last_consumer == consumer) {        /* Ring is empty    */
                DPRINTK(INFO, "last_consumer %d == consumer %d\n",
                        last_consumer, consumer);
                spin_unlock(&adapter->tx_lock);
-               return;
+               return 1;
        }
 
        adapter->proc_cmd_buf_counter++;
@@ -923,7 +997,7 @@ void netxen_process_cmd_ring(unsigned long data)
         */
        spin_unlock(&adapter->tx_lock);
 
-       while ((last_consumer != consumer) && (count < MAX_STATUS_HANDLE)) {
+       while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) {
                buffer = &adapter->cmd_buf_arr[last_consumer];
                port = adapter->port[buffer->port];
                pdev = port->pdev;
@@ -949,24 +1023,25 @@ void netxen_process_cmd_ring(unsigned long data)
                             && netif_carrier_ok(port->netdev))
                    && ((jiffies - port->netdev->trans_start) >
                        port->netdev->watchdog_timeo)) {
-                       schedule_work(&port->adapter->tx_timeout_task);
+                       SCHEDULE_WORK(port->adapter->tx_timeout_task
+                                     + port->portnum);
                }
 
                last_consumer = get_next_index(last_consumer,
                                               adapter->max_tx_desc_count);
-               count++;
+               count1++;
        }
-       adapter->stats.noxmitdone += count;
+       adapter->stats.noxmitdone += count1;
 
-       count = 0;
+       count2 = 0;
        spin_lock(&adapter->tx_lock);
        if ((--adapter->proc_cmd_buf_counter) == 0) {
                adapter->last_cmd_consumer = last_consumer;
                while ((adapter->last_cmd_consumer != consumer)
-                      && (count < MAX_STATUS_HANDLE)) {
+                      && (count2 < MAX_STATUS_HANDLE)) {
                        buffer =
                            &adapter->cmd_buf_arr[adapter->last_cmd_consumer];
-                       count++;
+                       count2++;
                        if (buffer->skb)
                                break;
                        else
@@ -975,7 +1050,7 @@ void netxen_process_cmd_ring(unsigned long data)
                                                   adapter->max_tx_desc_count);
                }
        }
-       if (count) {
+       if (count1 || count2) {
                for (p = 0; p < adapter->ahw.max_ports; p++) {
                        nport = adapter->port[p];
                        if (netif_queue_stopped(nport->netdev)
@@ -985,10 +1060,30 @@ void netxen_process_cmd_ring(unsigned long data)
                        }
                }
        }
+       /*
+        * If everything is freed up to consumer then check if the ring is full
+        * If the ring is full then check if more needs to be freed and
+        * schedule the call back again.
+        *
+        * This happens when there are 2 CPUs. One could be freeing and the
+        * other filling it. If the ring is full when we get out of here and
+        * the card has already interrupted the host then the host can miss the
+        * interrupt.
+        *
+        * There is still a possible race condition and the host could miss an
+        * interrupt. The card has to take care of this.
+        */
+       if (adapter->last_cmd_consumer == consumer &&
+           (((adapter->cmd_producer + 1) %
+             adapter->max_tx_desc_count) == adapter->last_cmd_consumer)) {
+               consumer = *(adapter->cmd_consumer);
+       }
+       done = (adapter->last_cmd_consumer == consumer);
 
        spin_unlock(&adapter->tx_lock);
        DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer,
                __FUNCTION__);
+       return (done);
 }
 
 /*
@@ -1000,17 +1095,16 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
        struct sk_buff *skb;
        struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
        struct netxen_rcv_desc_ctx *rcv_desc = NULL;
-       struct netxen_recv_crb *crbarea = &recv_crb_registers[ctx];
-       struct netxen_rcv_desc_crb *rcv_desc_crb = NULL;
-       u32 producer;
+       uint producer;
        struct rcv_desc *pdesc;
        struct netxen_rx_buffer *buffer;
        int count = 0;
        int index = 0;
+       netxen_ctx_msg msg = 0;
+       dma_addr_t dma;
 
        adapter->stats.post_called++;
        rcv_desc = &recv_ctx->rcv_desc[ringid];
-       rcv_desc_crb = &crbarea->rcv_desc_crb[ringid];
 
        producer = rcv_desc->producer;
        index = rcv_desc->begin_alloc;
@@ -1020,6 +1114,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
                skb = dev_alloc_skb(rcv_desc->skb_size);
                if (unlikely(!skb)) {
                        /*
+                        * TODO
                         * We need to schedule the posting of buffers to the pegs.
                         */
                        rcv_desc->begin_alloc = index;
@@ -1027,9 +1122,105 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
                                " allocated only %d buffers\n", count);
                        break;
                }
+
                count++;        /* now there should be no failure */
                pdesc = &rcv_desc->desc_head[producer];
-               skb_reserve(skb, NET_IP_ALIGN);
+
+#if defined(XGB_DEBUG)
+               *(unsigned long *)(skb->head) = 0xc0debabe;
+               if (skb_is_nonlinear(skb)) {
+                       printk("Allocated SKB @%p is nonlinear\n");
+               }
+#endif
+               skb_reserve(skb, 2);
+               /* This will be setup when we receive the
+                * buffer after it has been filled  FSL  TBD TBD
+                * skb->dev = netdev;
+                */
+               dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size,
+                                    PCI_DMA_FROMDEVICE);
+               pdesc->addr_buffer = dma;
+               buffer->skb = skb;
+               buffer->state = NETXEN_BUFFER_BUSY;
+               buffer->dma = dma;
+               /* make a rcv descriptor  */
+               pdesc->reference_handle = buffer->ref_handle;
+               pdesc->buffer_length = rcv_desc->dma_size;
+               DPRINTK(INFO, "done writing descripter\n");
+               producer =
+                   get_next_index(producer, rcv_desc->max_rx_desc_count);
+               index = get_next_index(index, rcv_desc->max_rx_desc_count);
+               buffer = &rcv_desc->rx_buf_arr[index];
+       }
+       /* if we did allocate buffers, then write the count to Phantom */
+       if (count) {
+               rcv_desc->begin_alloc = index;
+               rcv_desc->rcv_pending += count;
+               adapter->stats.lastposted = count;
+               adapter->stats.posted += count;
+               rcv_desc->producer = producer;
+               if (rcv_desc->rcv_free >= 32) {
+                       rcv_desc->rcv_free = 0;
+                       /* Window = 1 */
+                       writel((producer - 1) &
+                              (rcv_desc->max_rx_desc_count - 1),
+                              NETXEN_CRB_NORMALIZE(adapter,
+                                                   recv_crb_registers[0].
+                                                   rcv_desc_crb[ringid].
+                                                   crb_rcv_producer_offset));
+                       /*
+                        * Write a doorbell msg to tell phanmon of change in
+                        * receive ring producer
+                        */
+                       netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID);
+                       netxen_set_msg_privid(msg);
+                       netxen_set_msg_count(msg,
+                                            ((producer -
+                                              1) & (rcv_desc->
+                                                    max_rx_desc_count - 1)));
+                       netxen_set_msg_ctxid(msg, 0);
+                       netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
+                       writel(msg,
+                              DB_NORMALIZE(adapter,
+                                           NETXEN_RCV_PRODUCER_OFFSET));
+               }
+       }
+}
+
+void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx,
+                                uint32_t ringid)
+{
+       struct pci_dev *pdev = adapter->ahw.pdev;
+       struct sk_buff *skb;
+       struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
+       struct netxen_rcv_desc_ctx *rcv_desc = NULL;
+       u32 producer;
+       struct rcv_desc *pdesc;
+       struct netxen_rx_buffer *buffer;
+       int count = 0;
+       int index = 0;
+
+       adapter->stats.post_called++;
+       rcv_desc = &recv_ctx->rcv_desc[ringid];
+
+       producer = rcv_desc->producer;
+       index = rcv_desc->begin_alloc;
+       buffer = &rcv_desc->rx_buf_arr[index];
+       /* We can start writing rx descriptors into the phantom memory. */
+       while (buffer->state == NETXEN_BUFFER_FREE) {
+               skb = dev_alloc_skb(rcv_desc->skb_size);
+               if (unlikely(!skb)) {
+                       /*
+                        * We need to schedule the posting of buffers to the pegs.
+                        */
+                       rcv_desc->begin_alloc = index;
+                       DPRINTK(ERR, "netxen_post_rx_buffers_nodb: "
+                               " allocated only %d buffers\n", count);
+                       break;
+               }
+               count++;        /* now there should be no failure */
+               pdesc = &rcv_desc->desc_head[producer];
+               skb_reserve(skb, 2);
                /* 
                 * This will be setup when we receive the
                 * buffer after it has been filled
@@ -1040,6 +1231,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
                buffer->dma = pci_map_single(pdev, skb->data,
                                             rcv_desc->dma_size,
                                             PCI_DMA_FROMDEVICE);
+
                /* make a rcv descriptor  */
                pdesc->reference_handle = le16_to_cpu(buffer->ref_handle);
                pdesc->buffer_length = le16_to_cpu(rcv_desc->dma_size);
@@ -1064,7 +1256,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
                        writel((producer - 1) &
                               (rcv_desc->max_rx_desc_count - 1),
                               NETXEN_CRB_NORMALIZE(adapter,
-                                                   rcv_desc_crb->
+                                                   recv_crb_registers[0].
+                                                   rcv_desc_crb[ringid].
                                                    crb_rcv_producer_offset));
                        wmb();
                }
@@ -1197,8 +1390,8 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
 
        switch (data.cmd) {
        case netxen_nic_cmd_pci_read:
-               if ((retval = netxen_nic_hw_read_wx(adapter, data.off,
-                                                   &(data.u), data.size)))
+               if ((retval = netxen_nic_hw_read_ioctl(adapter, data.off,
+                                                      &(data.u), data.size)))
                        goto error_out;
                if (copy_to_user
                    ((void __user *)&(up_data->u), &(data.u), data.size)) {
@@ -1211,8 +1404,35 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
                break;
 
        case netxen_nic_cmd_pci_write:
-               data.rv = netxen_nic_hw_write_wx(adapter, data.off, &(data.u),
-                                                data.size);
+               if ((retval = netxen_nic_hw_write_ioctl(adapter, data.off,
+                                                       &(data.u), data.size)))
+                       goto error_out;
+               data.rv = 0;
+               break;
+
+       case netxen_nic_cmd_pci_mem_read:
+               if (netxen_nic_pci_mem_read_ioctl(adapter, data.off, &(data.u),
+                                                 data.size)) {
+                       DPRINTK(ERR, "Failed to read the data.\n");
+                       retval = -EFAULT;
+                       goto error_out;
+               }
+               if (copy_to_user
+                   ((void __user *)&(up_data->u), &(data.u), data.size)) {
+                       DPRINTK(ERR, "bad copy to userland: %d\n",
+                               (int)sizeof(data));
+                       retval = -EFAULT;
+                       goto error_out;
+               }
+               data.rv = 0;
+               break;
+
+       case netxen_nic_cmd_pci_mem_write:
+               if ((retval = netxen_nic_pci_mem_write_ioctl(adapter, data.off,
+                                                            &(data.u),
+                                                            data.size)))
+                       goto error_out;
+               data.rv = 0;
                break;
 
        case netxen_nic_cmd_pci_config_read:
@@ -1297,7 +1517,7 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
                retval = -EOPNOTSUPP;
                goto error_out;
        }
-       put_user(data.rv, (u16 __user *) (&(up_data->rv)));
+       put_user(data.rv, (&(up_data->rv)));
        DPRINTK(INFO, "done ioctl for %p well.\n", adapter);
 
       error_out:
index 23e53ad..1221fa5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * 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
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * MA  02111-1307, USA.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
@@ -36,7 +36,7 @@
 #define NETXEN_NIC_CMD         (NETXEN_CMD_START + 1)
 #define NETXEN_NIC_NAME                (NETXEN_CMD_START + 2)
 #define NETXEN_NIC_NAME_LEN    16
-#define NETXEN_NIC_NAME_RSP    "NETXEN"
+#define NETXEN_NIC_NAME_RSP    "NETXEN-UNM"
 
 typedef enum {
        netxen_nic_cmd_none = 0,
index ae180fe..1b45f50 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * 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
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * MA  02111-1307, USA.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
@@ -68,8 +68,7 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
 void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno,
                                 u32 link)
 {
-       struct netxen_port *pport = adapter->port[portno];
-       struct net_device *netdev = pport->netdev;
+       struct net_device *netdev = (adapter->port[portno])->netdev;
 
        if (link)
                netif_carrier_on(netdev);
@@ -84,46 +83,41 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno,
        struct netxen_port *port;
 
        /*  This should clear the interrupt source */
-       if (adapter->ops->phy_read)
-               adapter->ops->phy_read(adapter, portno,
-                                      NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
-                                      &int_src);
+       if (adapter->phy_read)
+               adapter->phy_read(adapter, portno,
+                                 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
+                                 &int_src);
        if (int_src == 0) {
                DPRINTK(INFO, "No phy interrupts for port #%d\n", portno);
                return;
        }
-       if (adapter->ops->disable_phy_interrupts)
-               adapter->ops->disable_phy_interrupts(adapter, portno);
+       if (adapter->disable_phy_interrupts)
+               adapter->disable_phy_interrupts(adapter, portno);
 
        port = adapter->port[portno];
 
        if (netxen_get_phy_int_jabber(int_src))
-               DPRINTK(INFO, "NetXen: %s Jabber interrupt \n",
-                       port->netdev->name);
+               DPRINTK(INFO, "Jabber interrupt \n");
 
        if (netxen_get_phy_int_polarity_changed(int_src))
-               DPRINTK(INFO, "NetXen: %s POLARITY CHANGED int \n",
-                       port->netdev->name);
+               DPRINTK(INFO, "POLARITY CHANGED int \n");
 
        if (netxen_get_phy_int_energy_detect(int_src))
-               DPRINTK(INFO, "NetXen: %s ENERGY DETECT INT \n",
-                       port->netdev->name);
+               DPRINTK(INFO, "ENERGY DETECT INT \n");
 
        if (netxen_get_phy_int_downshift(int_src))
-               DPRINTK(INFO, "NetXen: %s DOWNSHIFT INT \n",
-                       port->netdev->name);
+               DPRINTK(INFO, "DOWNSHIFT INT \n");
        /* write it down later.. */
        if ((netxen_get_phy_int_speed_changed(int_src))
            || (netxen_get_phy_int_link_status_changed(int_src))) {
                __le32 status;
 
-               DPRINTK(INFO, "NetXen: %s SPEED CHANGED OR"
-                       " LINK STATUS CHANGED \n", port->netdev->name);
+               DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n");
 
-               if (adapter->ops->phy_read
-                   && adapter->ops->phy_read(adapter, portno,
-                                             NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-                                             &status) == 0) {
+               if (adapter->phy_read
+                   && adapter->phy_read(adapter, portno,
+                                        NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+                                        &status) == 0) {
                        if (netxen_get_phy_int_link_status_changed(int_src)) {
                                if (netxen_get_phy_link(status)) {
                                        netxen_niu_gbe_init_port(adapter,
@@ -143,8 +137,8 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno,
                        }
                }
        }
-       if (adapter->ops->enable_phy_interrupts)
-               adapter->ops->enable_phy_interrupts(adapter, portno);
+       if (adapter->enable_phy_interrupts)
+               adapter->enable_phy_interrupts(adapter, portno);
 }
 
 void netxen_nic_isr_other(struct netxen_adapter *adapter)
@@ -159,8 +153,7 @@ void netxen_nic_isr_other(struct netxen_adapter *adapter)
 
        qg_linksup = adapter->ahw.qg_linksup;
        adapter->ahw.qg_linksup = val;
-       DPRINTK(1, INFO, "%s: link update 0x%08x\n", netxen_nic_driver_name,
-               val);
+       DPRINTK(INFO, "link update 0x%08x\n", val);
        for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) {
                linkup = val & 1;
                if (linkup != (qg_linksup & 1)) {
index df0bb36..913e814 100644 (file)
@@ -1,25 +1,25 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * 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.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
@@ -32,6 +32,7 @@
  */
 
 #include <linux/vmalloc.h>
+#include <linux/highmem.h>
 #include "netxen_nic_hw.h"
 
 #include "netxen_nic.h"
@@ -48,14 +49,21 @@ MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID);
 
-char netxen_nic_driver_name[] = "netxen";
+char netxen_nic_driver_name[] = "netxen-nic";
 static char netxen_nic_driver_string[] = "NetXen Network Driver version "
     NETXEN_NIC_LINUX_VERSIONID;
 
+struct netxen_adapter *g_adapter = NULL;
+
 #define NETXEN_NETDEV_WEIGHT 120
 #define NETXEN_ADAPTER_UP_MAGIC 777
 #define NETXEN_NIC_PEG_TUNE 0
 
+u8 nx_p2_id = NX_P2_C0;
+
+#define DMA_32BIT_MASK 0x00000000ffffffffULL
+#define DMA_35BIT_MASK 0x00000007ffffffffULL
+
 /* Local functions to NetXen NIC driver */
 static int __devinit netxen_nic_probe(struct pci_dev *pdev,
                                      const struct pci_device_id *ent);
@@ -87,6 +95,9 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
 
 MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
 
+struct workqueue_struct *netxen_workq;
+static void netxen_watchdog(unsigned long);
+
 /*
  * netxen_nic_probe()
  *
@@ -105,20 +116,28 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct net_device *netdev = NULL;
        struct netxen_adapter *adapter = NULL;
        struct netxen_port *port = NULL;
-       u8 *mem_ptr0 = NULL;
-       u8 *mem_ptr1 = NULL;
-       u8 *mem_ptr2 = NULL;
+       void __iomem *mem_ptr0 = NULL;
+       void __iomem *mem_ptr1 = NULL;
+       void __iomem *mem_ptr2 = NULL;
 
-       unsigned long mem_base, mem_len;
+       u8 *db_ptr = NULL;
+       unsigned long mem_base, mem_len, db_base, db_len;
        int pci_using_dac, i, err;
        int ring;
        struct netxen_recv_context *recv_ctx = NULL;
        struct netxen_rcv_desc_ctx *rcv_desc = NULL;
        struct netxen_cmd_buffer *cmd_buf_arr = NULL;
        u64 mac_addr[FLASH_NUM_PORTS + 1];
-       int valid_mac;
+       int valid_mac = 0;
+       static int netxen_cards_found = 0;
 
        printk(KERN_INFO "%s \n", netxen_nic_driver_string);
+       /* In current scheme, we use only PCI function 0 */
+       if (PCI_FUNC(pdev->devfn) != 0) {
+               DPRINTK(ERR, "NetXen function %d will not be enabled.\n",
+                       PCI_FUNC(pdev->devfn));
+               return -ENODEV;
+       }
        if ((err = pci_enable_device(pdev)))
                return err;
        if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
@@ -130,10 +149,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto err_out_disable_pdev;
 
        pci_set_master(pdev);
-       if ((pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) &&
-           (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) == 0))
+       pci_read_config_byte(pdev, PCI_REVISION_ID, &nx_p2_id);
+       if (nx_p2_id == NX_P2_C1 &&
+           (pci_set_dma_mask(pdev, DMA_35BIT_MASK) == 0) &&
+           (pci_set_consistent_dma_mask(pdev, DMA_35BIT_MASK) == 0)) {
                pci_using_dac = 1;
-       else {
+       else {
                if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
                    (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)))
                        goto err_out_free_res;
@@ -153,21 +174,34 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
            ioremap(mem_base + THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
 
        if ((mem_ptr0 == 0UL) || (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) {
-               DPRINTK(1, ERR,
+               DPRINTK(ERR,
                        "Cannot remap adapter memory aborting.:"
                        "0 -> %p, 1 -> %p, 2 -> %p\n",
                        mem_ptr0, mem_ptr1, mem_ptr2);
 
                err = -EIO;
-               if (mem_ptr0)
-                       iounmap(mem_ptr0);
-               if (mem_ptr1)
-                       iounmap(mem_ptr1);
-               if (mem_ptr2)
-                       iounmap(mem_ptr2);
-
-               goto err_out_free_res;
+               goto err_out_iounmap;
+       }
+       db_base = pci_resource_start(pdev, 4);  /* doorbell is on bar 4 */
+       db_len = pci_resource_len(pdev, 4);
+
+       if (db_len == 0) {
+               printk(KERN_ERR "%s: doorbell is disabled\n",
+                      netxen_nic_driver_name);
+               err = -EIO;
+               goto err_out_iounmap;
+       }
+       DPRINTK(INFO, "doorbell ioremap from %lx a size of %lx\n", db_base,
+               db_len);
+
+       db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES);
+       if (db_ptr == 0UL) {
+               printk(KERN_ERR "%s: Failed to allocate doorbell map.",
+                      netxen_nic_driver_name);
+               err = -EIO;
+               goto err_out_iounmap;
        }
+       DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr);
 
 /*
  *      Allocate a adapter structure which will manage all the initialization
@@ -183,17 +217,24 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                       netxen_nic_driver_name,
                       (int)sizeof(struct netxen_adapter));
                err = -ENOMEM;
-               goto err_out_iounmap;
+               goto err_out_dbunmap;
        }
 
+       if (netxen_cards_found == 0) {
+               g_adapter = adapter;
+       }
        adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS;
        adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS;
        adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
+       adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS;
 
        pci_set_drvdata(pdev, adapter);
 
        cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
        if (cmd_buf_arr == NULL) {
+               printk(KERN_ERR
+                      "%s: Could not allocate cmd_buf_arr memory:%d\n",
+                      netxen_nic_driver_name, (int)TX_RINGSIZE);
                err = -ENOMEM;
                goto err_out_free_adapter;
        }
@@ -220,11 +261,23 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                                rcv_desc->skb_size = MAX_RX_JUMBO_BUFFER_LENGTH;
                                break;
 
+                       case RCV_RING_LRO:
+                               rcv_desc->max_rx_desc_count =
+                                   adapter->max_lro_rx_desc_count;
+                               rcv_desc->flags = RCV_DESC_LRO;
+                               rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN;
+                               rcv_desc->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
+                               break;
+
                        }
                        rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *)
                            vmalloc(RCV_BUFFSIZE);
 
                        if (rcv_desc->rx_buf_arr == NULL) {
+                               printk(KERN_ERR "%s: Could not allocate"
+                                      "rcv_desc->rx_buf_arr memory:%d\n",
+                                      netxen_nic_driver_name,
+                                      (int)RCV_BUFFSIZE);
                                err = -ENOMEM;
                                goto err_out_free_rx_buffer;
                        }
@@ -233,30 +286,21 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        }
 
-       adapter->ops = kzalloc(sizeof(struct netxen_drvops), GFP_KERNEL);
-       if (adapter->ops == NULL) {
-               printk(KERN_ERR
-                      "%s: Could not allocate memory for adapter->ops:%d\n",
-                      netxen_nic_driver_name,
-                      (int)sizeof(struct netxen_adapter));
-               err = -ENOMEM;
-               goto err_out_free_rx_buffer;
-       }
-
        adapter->cmd_buf_arr = cmd_buf_arr;
        adapter->ahw.pci_base0 = mem_ptr0;
        adapter->ahw.pci_base1 = mem_ptr1;
        adapter->ahw.pci_base2 = mem_ptr2;
+       adapter->ahw.db_base = db_ptr;
+       adapter->ahw.db_len = db_len;
        spin_lock_init(&adapter->tx_lock);
        spin_lock_init(&adapter->lock);
+       netxen_initialize_adapter_sw(adapter);  /* initialize the buffers in adapter */
 #ifdef CONFIG_IA64
        netxen_pinit_from_rom(adapter, 0);
        udelay(500);
        netxen_load_firmware(adapter);
 #endif
 
-       /* initialize the buffers in adapter */
-       netxen_initialize_adapter_sw(adapter);
        /*
         * Set the CRB window to invalid. If any register in window 0 is
         * accessed it should set the window to 0 and then reset it to 1.
@@ -277,7 +321,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
        adapter->ahw.pdev = pdev;
        adapter->proc_cmd_buf_counter = 0;
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->ahw.revision_id);
+       adapter->ahw.revision_id = nx_p2_id;
 
        if (pci_enable_msi(pdev)) {
                adapter->flags &= ~NETXEN_NIC_MSI_ENABLED;
@@ -299,6 +343,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET));
        writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
 
+       /* do this before waking up pegs so that we have valid dummy dma addr */
+       err = netxen_initialize_adapter_offload(adapter);
+       if (err) {
+               goto err_out_free_dev;
+       }
+
        /* Unlock the HW, prompting the boot sequence */
        writel(1,
               NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
@@ -307,6 +357,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
 
        /* initialize the all the ports */
+       adapter->active_ports = 0;
 
        for (i = 0; i < adapter->ahw.max_ports; i++) {
                netdev = alloc_etherdev(sizeof(struct netxen_port));
@@ -372,10 +423,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                                       netdev->dev_addr[4],
                                       netdev->dev_addr[5]);
                        } else {
-                               if (adapter->ops->macaddr_set)
-                                       adapter->ops->macaddr_set(port,
-                                                                 netdev->
-                                                                 dev_addr);
+                               if (adapter->macaddr_set)
+                                       adapter->macaddr_set(port,
+                                                            netdev->dev_addr);
                        }
                }
                adapter->netdev = netdev;
@@ -391,7 +441,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        goto err_out_free_dev;
                }
                adapter->port_count++;
-               adapter->active_ports = 0;
                adapter->port[i] = port;
        }
 
@@ -412,6 +461,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                break;
        }
 
+       adapter->number = netxen_cards_found;
        adapter->driver_mismatch = 0;
 
        return 0;
@@ -426,7 +476,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        free_netdev(port->netdev);
                }
        }
-       kfree(adapter->ops);
+
+       netxen_free_adapter_offload(adapter);
 
       err_out_free_rx_buffer:
        for (i = 0; i < MAX_RCV_CTX; ++i) {
@@ -439,19 +490,23 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        }
                }
        }
-
        vfree(cmd_buf_arr);
 
-       kfree(adapter->port);
-
       err_out_free_adapter:
        pci_set_drvdata(pdev, NULL);
        kfree(adapter);
 
+      err_out_dbunmap:
+       if (db_ptr)
+               iounmap(db_ptr);
+
       err_out_iounmap:
-       iounmap(mem_ptr0);
-       iounmap(mem_ptr1);
-       iounmap(mem_ptr2);
+       if (mem_ptr0)
+               iounmap(mem_ptr0);
+       if (mem_ptr1)
+               iounmap(mem_ptr1);
+       if (mem_ptr2)
+               iounmap(mem_ptr2);
 
       err_out_free_res:
        pci_release_regions(pdev);
@@ -476,12 +531,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
        netxen_nic_stop_all_ports(adapter);
        /* leave the hw in the same state as reboot */
-       netxen_pinit_from_rom(adapter, 0);
-       udelay(500);
        netxen_load_firmware(adapter);
-
-       if ((adapter->flags & NETXEN_NIC_MSI_ENABLED))
-               netxen_nic_disable_int(adapter);
+       netxen_free_adapter_offload(adapter);
 
        udelay(500);            /* Delay for a while to drain the DMA engines */
        for (i = 0; i < adapter->port_count; i++) {
@@ -498,6 +549,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
        if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
                netxen_free_hw_resources(adapter);
 
+       iounmap(adapter->ahw.db_base);
        iounmap(adapter->ahw.pci_base0);
        iounmap(adapter->ahw.pci_base1);
        iounmap(adapter->ahw.pci_base2);
@@ -524,7 +576,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
        }
 
        vfree(adapter->cmd_buf_arr);
-       kfree(adapter->ops);
        kfree(adapter);
 }
 
@@ -546,6 +597,8 @@ static int netxen_nic_open(struct net_device *netdev)
                        return -EIO;
                }
                netxen_nic_flash_print(adapter);
+               if (adapter->init_niu)
+                       adapter->init_niu(adapter);
 
                /* setup all the resources for the Phantom... */
                /* this include the descriptors for rcv, tx, and status */
@@ -556,32 +609,31 @@ static int netxen_nic_open(struct net_device *netdev)
                               err);
                        return err;
                }
-               if (adapter->ops->init_port
-                   && adapter->ops->init_port(adapter, port->portnum) != 0) {
+               if (adapter->init_port
+                   && adapter->init_port(adapter, port->portnum) != 0) {
                        printk(KERN_ERR "%s: Failed to initialize port %d\n",
                               netxen_nic_driver_name, port->portnum);
                        netxen_free_hw_resources(adapter);
                        return -EIO;
                }
-               if (adapter->ops->init_niu)
-                       adapter->ops->init_niu(adapter);
                for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
                        for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++)
                                netxen_post_rx_buffers(adapter, ctx, ring);
                }
-               adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
-       }
-       adapter->active_ports++;
-       if (adapter->active_ports == 1) {
+               adapter->irq = adapter->ahw.pdev->irq;
                err = request_irq(adapter->ahw.pdev->irq, &netxen_intr,
                                  SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name,
                                  adapter);
                if (err) {
                        printk(KERN_ERR "request_irq failed with: %d\n", err);
-                       adapter->active_ports--;
+                       netxen_free_hw_resources(adapter);
                        return err;
                }
-               adapter->irq = adapter->ahw.pdev->irq;
+
+               adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
+       }
+       adapter->active_ports++;
+       if (adapter->active_ports == 1) {
                if (!adapter->driver_mismatch)
                        mod_timer(&adapter->watchdog_timer, jiffies);
 
@@ -590,11 +642,14 @@ static int netxen_nic_open(struct net_device *netdev)
 
        /* Done here again so that even if phantom sw overwrote it,
         * we set it */
-       if (adapter->ops->macaddr_set)
-               adapter->ops->macaddr_set(port, netdev->dev_addr);
+       if (adapter->macaddr_set)
+               adapter->macaddr_set(port, netdev->dev_addr);
        netxen_nic_set_link_parameters(port);
 
        netxen_nic_set_multi(netdev);
+       if (adapter->set_mtu)
+               adapter->set_mtu(port, netdev->mtu);
+
        if (!adapter->driver_mismatch)
                netif_start_queue(netdev);
 
@@ -647,6 +702,7 @@ static int netxen_nic_close(struct net_device *netdev)
                        }
                        cmd_buff++;
                }
+               FLUSH_SCHEDULED_WORK();
                del_timer_sync(&adapter->watchdog_timer);
        }
 
@@ -667,7 +723,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        struct cmd_desc_type0 *hwdesc;
        int k;
        struct netxen_cmd_buffer *pbuf = NULL;
-       unsigned int tries = 0;
        static int dropped_packet = 0;
        int frag_count;
        u32 local_producer = 0;
@@ -729,7 +784,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                        if (((skb->nh.iph)->ihl * sizeof(u32)) +
                            ((skb->h.th)->doff * sizeof(u32)) +
                            sizeof(struct ethhdr) >
-                           (sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) {
+                           (sizeof(struct cmd_desc_type0) - 2)) {
                                no_of_desc++;
                        }
                }
@@ -740,27 +795,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        if ((k + no_of_desc) >=
            ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count :
             last_cmd_consumer)) {
+               port->stats.nocmddescriptor++;
+               DPRINTK(ERR, "No command descriptors available,"
+                       " producer = %d, consumer = %d count=%llu,"
+                       " dropping packet\n", producer,
+                       adapter->last_cmd_consumer,
+                       port->stats.nocmddescriptor);
+
+               netif_stop_queue(netdev);
+               port->flags |= NETXEN_NETDEV_STATUS;
                spin_unlock_bh(&adapter->tx_lock);
-               if (tries == 0) {
-                       local_bh_disable();
-                       netxen_process_cmd_ring((unsigned long)adapter);
-                       local_bh_enable();
-                       ++tries;
-                       goto retry_getting_window;
-               } else {
-                       port->stats.nocmddescriptor++;
-                       DPRINTK(ERR, "No command descriptors available,"
-                               " producer = %d, consumer = %d count=%llu,"
-                               " dropping packet\n", producer,
-                               adapter->last_cmd_consumer,
-                               port->stats.nocmddescriptor);
-
-                       spin_lock_bh(&adapter->tx_lock);
-                       netif_stop_queue(netdev);
-                       port->flags |= NETXEN_NETDEV_STATUS;
-                       spin_unlock_bh(&adapter->tx_lock);
-                       return NETDEV_TX_BUSY;
-               }
+               return NETDEV_TX_BUSY;
        }
        k = get_index_range(k, max_tx_desc_count, no_of_desc);
        adapter->cmd_producer = k;
@@ -782,7 +827,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                pbuf->mss = 0;
                hwdesc->mss = 0;
        }
-       pbuf->no_of_descriptors = no_of_desc;
        pbuf->total_length = skb->len;
        pbuf->skb = skb;
        pbuf->cmd = TX_ETHER_PKT;
@@ -792,11 +836,11 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        buffrag->dma = pci_map_single(port->pdev, skb->data, first_seg_len,
                                      PCI_DMA_TODEVICE);
        buffrag->length = first_seg_len;
-       CMD_DESC_TOTAL_LENGTH_WRT(hwdesc, skb->len);
-       hwdesc->num_of_buffers = frag_count;
-       hwdesc->opcode = TX_ETHER_PKT;
+       netxen_set_cmd_desc_totallength(hwdesc, skb->len);
+       netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count);
+       netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT);
 
-       CMD_DESC_PORT_WRT(hwdesc, port->portnum);
+       netxen_set_cmd_desc_port(hwdesc, port->portnum);
        hwdesc->buffer1_length = cpu_to_le16(first_seg_len);
        hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
 
@@ -855,12 +899,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        /* For LSO, we need to copy the MAC/IP/TCP headers into
         * the descriptor ring
         */
-       if (hw->cmd_desc_head[saved_producer].opcode == TX_TCP_LSO) {
+       if (netxen_get_cmd_desc_opcode(&hw->cmd_desc_head[saved_producer])
+           == TX_TCP_LSO) {
                int hdr_len, first_hdr_len, more_hdr;
                hdr_len = hw->cmd_desc_head[saved_producer].total_hdr_length;
-               if (hdr_len > (sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) {
-                       first_hdr_len =
-                           sizeof(struct cmd_desc_type0) - NET_IP_ALIGN;
+               if (hdr_len > (sizeof(struct cmd_desc_type0) - 2)) {
+                       first_hdr_len = sizeof(struct cmd_desc_type0) - 2;
                        more_hdr = 1;
                } else {
                        first_hdr_len = hdr_len;
@@ -870,7 +914,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                hwdesc = &hw->cmd_desc_head[producer];
 
                /* copy the first 64 bytes */
-               memcpy(((void *)hwdesc) + NET_IP_ALIGN,
+               memcpy(((void *)hwdesc) + 2,
                       (void *)(skb->data), first_hdr_len);
                producer = get_next_index(producer, max_tx_desc_count);
 
@@ -886,7 +930,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        }
        spin_lock_bh(&adapter->tx_lock);
        port->stats.txbytes +=
-           CMD_DESC_TOTAL_LENGTH(&hw->cmd_desc_head[saved_producer]);
+           netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]);
        /* Code to update the adapter considering how many producer threads
           are currently working */
        if ((--adapter->num_threads) == 0) {
@@ -896,20 +940,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                       NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET));
                wmb();
                adapter->total_threads = 0;
-       } else {
-               u32 crb_producer = 0;
-               crb_producer =
-                   readl(NETXEN_CRB_NORMALIZE
-                         (adapter, CRB_CMD_PRODUCER_OFFSET));
-               if (crb_producer == local_producer) {
-                       crb_producer = get_index_range(crb_producer,
-                                                      max_tx_desc_count,
-                                                      no_of_desc);
-                       writel(crb_producer,
-                              NETXEN_CRB_NORMALIZE(adapter,
-                                                   CRB_CMD_PRODUCER_OFFSET));
-                       wmb();
-               }
        }
 
        port->stats.xmitfinished++;
@@ -926,15 +956,20 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 static void netxen_watchdog(unsigned long v)
 {
        struct netxen_adapter *adapter = (struct netxen_adapter *)v;
-       schedule_work(&adapter->watchdog_task);
+       if (adapter != g_adapter) {
+               printk("%s: ***BUG*** adapter[%p] != g_adapter[%p]\n",
+                      __FUNCTION__, adapter, g_adapter);
+               return;
+       }
+
+       SCHEDULE_WORK(&adapter->watchdog_task);
 }
 
 static void netxen_tx_timeout(struct net_device *netdev)
 {
        struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev);
-       struct netxen_adapter *adapter = port->adapter;
 
-       schedule_work(&adapter->tx_timeout_task);
+       SCHEDULE_WORK(port->adapter->tx_timeout_task + port->portnum);
 }
 
 static void netxen_tx_timeout_task(struct work_struct *work)
@@ -967,6 +1002,11 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
        if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
                int count = 0;
                u32 mask;
+               mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR));
+               if ((mask & 0x80) == 0) {
+                       /* not our interrupt */
+                       return ret;
+               }
                netxen_nic_disable_int(adapter);
                /* Window = 0 or 1 */
                do {
@@ -1026,7 +1066,10 @@ irqreturn_t netxen_intr(int irq, void *data)
                netdev = port->netdev;
 
                /* process our status queue (for all 4 ports) */
-               netxen_handle_int(adapter, netdev);
+               if (netif_running(netdev)) {
+                       netxen_handle_int(adapter, netdev);
+                       break;
+               }
        }
 
        return IRQ_HANDLED;
@@ -1040,11 +1083,12 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget)
        int done = 1;
        int ctx;
        int this_work_done;
+       int work_done = 0;
 
        DPRINTK(INFO, "polling for %d descriptors\n", *budget);
        port->stats.polled++;
 
-       adapter->work_done = 0;
+       work_done = 0;
        for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
                /*
                 * Fairness issue. This will give undue weight to the
@@ -1061,20 +1105,20 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget)
                this_work_done = netxen_process_rcv_ring(adapter, ctx,
                                                         work_to_do /
                                                         MAX_RCV_CTX);
-               adapter->work_done += this_work_done;
+               work_done += this_work_done;
        }
 
-       netdev->quota -= adapter->work_done;
-       *budget -= adapter->work_done;
+       netdev->quota -= work_done;
+       *budget -= work_done;
 
-       if (adapter->work_done >= work_to_do
-           && netxen_nic_rx_has_work(adapter) != 0)
+       if (work_done >= work_to_do && netxen_nic_rx_has_work(adapter) != 0)
                done = 0;
 
-       netxen_process_cmd_ring((unsigned long)adapter);
+       if (netxen_process_cmd_ring((unsigned long)adapter) == 0)
+               done = 0;
 
        DPRINTK(INFO, "new work_done: %d work_to_do: %d\n",
-               adapter->work_done, work_to_do);
+               work_done, work_to_do);
        if (done) {
                netif_rx_complete(netdev);
                netxen_nic_enable_int(adapter);
@@ -1117,8 +1161,9 @@ netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
                if (ifr->ifr_data) {
                        sprintf(dev_name, "%s-%d", NETXEN_NIC_NAME_RSP,
                                port->portnum);
-                       nr_bytes = copy_to_user((char *)ifr->ifr_data, dev_name,
-                                               NETXEN_NIC_NAME_LEN);
+                       nr_bytes =
+                           copy_to_user((char __user *)ifr->ifr_data, dev_name,
+                                        NETXEN_NIC_NAME_LEN);
                        if (nr_bytes)
                                err = -EIO;
 
@@ -1145,6 +1190,9 @@ static struct pci_driver netxen_driver = {
 
 static int __init netxen_init_module(void)
 {
+       if ((netxen_workq = create_singlethread_workqueue("netxen")) == 0)
+               return -ENOMEM;
+
        return pci_module_init(&netxen_driver);
 }
 
@@ -1155,7 +1203,7 @@ static void __exit netxen_exit_module(void)
        /*
         * Wait for some time to allow the dma to drain, if any.
         */
-       mdelay(5);
+       destroy_workqueue(netxen_workq);
        pci_unregister_driver(&netxen_driver);
 }
 
index 7950a04..4987dc7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * 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
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * MA  02111-1307, USA.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
 
 static long phy_lock_timeout = 100000000;
 
-static inline int phy_lock(void)
+static inline int phy_lock(struct netxen_adapter *adapter)
 {
        int i;
        int done = 0, timeout = 0;
 
        while (!done) {
-               done = readl((void __iomem *)NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
+               done =
+                   readl(pci_base_offset
+                         (adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK)));
                if (done == 1)
                        break;
                if (timeout >= phy_lock_timeout) {
@@ -61,13 +63,15 @@ static inline int phy_lock(void)
                }
        }
 
-       writel(NETXEN_PHY_LOCK_ID, (void __iomem *)PHY_LOCK_DRIVER);
+       writel(PHY_LOCK_DRIVER,
+              NETXEN_CRB_NORMALIZE(adapter, NETXEN_PHY_LOCK_ID));
        return 0;
 }
 
-static inline int phy_unlock(void)
+static inline int phy_unlock(struct netxen_adapter *adapter)
 {
-       readl((void __iomem *)NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK));
+       readl(pci_base_offset(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK)));
+
        return 0;
 }
 
@@ -95,7 +99,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy,
        __le32 status;
        __le32 mac_cfg0;
 
-       if (phy_lock() != 0) {
+       if (phy_lock(adapter) != 0) {
                return -1;
        }
 
@@ -162,7 +166,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy,
                                           NETXEN_NIU_GB_MAC_CONFIG_0(0),
                                           &mac_cfg0, 4))
                        return -EIO;
-       phy_unlock();
+       phy_unlock(adapter);
        return result;
 }
 
@@ -399,8 +403,8 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
 {
        int result = 0;
        __le32 status;
-       if (adapter->ops->disable_phy_interrupts)
-               adapter->ops->disable_phy_interrupts(adapter, port);
+       if (adapter->disable_phy_interrupts)
+               adapter->disable_phy_interrupts(adapter, port);
        mdelay(2);
 
        if (0 ==
@@ -612,7 +616,7 @@ int netxen_niu_macaddr_set(struct netxen_port *port,
        __le32 temp = 0;
        struct netxen_adapter *adapter = port->adapter;
        int phy = port->portnum;
-       unsigned char mac_addr[MAX_ADDR_LEN];
+       unsigned char mac_addr[6];
        int i;
 
        for (i = 0; i < 10; i++) {
@@ -631,7 +635,7 @@ int netxen_niu_macaddr_set(struct netxen_port *port,
 
                netxen_niu_macaddr_get(adapter, phy,
                                       (netxen_ethernet_macaddr_t *) mac_addr);
-               if (memcmp(mac_addr, addr, MAX_ADDR_LEN == 0))
+               if (memcmp(mac_addr, addr, 6) == 0)
                        break;
        }
 
index 8181d43..7879f85 100644 (file)
 /* 
  * CRB Registers or queue message done only at initialization time.
  */
+#define NIC_CRB_BASE               NETXEN_CAM_RAM(0x200)
+#define NETXEN_NIC_REG(X)             (NIC_CRB_BASE+(X))
 
-/*
- * The following 2 are the base adresses for the CRB registers and their
- * offsets will be added to get addresses for the index addresses.
- */
-#define NIC_CRB_BASE_PORT1     NETXEN_CAM_RAM(0x200)
-#define NIC_CRB_BASE_PORT2     NETXEN_CAM_RAM(0x250)
+#define CRB_PHAN_CNTRL_LO_OFFSET    NETXEN_NIC_REG(0x00)
+#define CRB_PHAN_CNTRL_HI_OFFSET    NETXEN_NIC_REG(0x04)
+#define CRB_CMD_PRODUCER_OFFSET     NETXEN_NIC_REG(0x08)
+#define CRB_CMD_CONSUMER_OFFSET     NETXEN_NIC_REG(0x0c)
+#define CRB_PAUSE_ADDR_LO           NETXEN_NIC_REG(0x10)       /* C0 EPG BUG  */
+#define CRB_PAUSE_ADDR_HI           NETXEN_NIC_REG(0x14)
+#define CRB_HOST_CMD_ADDR_HI        NETXEN_NIC_REG(0x18)       /* host add:cmd ring */
+#define CRB_HOST_CMD_ADDR_LO        NETXEN_NIC_REG(0x1c)
+#define CRB_CMD_INTR_LOOP           NETXEN_NIC_REG(0x20)       /* 4 regs for perf */
+#define CRB_CMD_DMA_LOOP            NETXEN_NIC_REG(0x24)
+#define CRB_RCV_INTR_LOOP           NETXEN_NIC_REG(0x28)
+#define CRB_RCV_DMA_LOOP            NETXEN_NIC_REG(0x2c)
+#define CRB_ENABLE_TX_INTR          NETXEN_NIC_REG(0x30)       /* phantom init status */
+#define CRB_MMAP_ADDR_3             NETXEN_NIC_REG(0x34)
+#define CRB_CMDPEG_CMDRING          NETXEN_NIC_REG(0x38)
+#define CRB_HOST_DUMMY_BUF_ADDR_HI  NETXEN_NIC_REG(0x3c)
+#define CRB_HOST_DUMMY_BUF_ADDR_LO  NETXEN_NIC_REG(0x40)
+#define CRB_MMAP_ADDR_0             NETXEN_NIC_REG(0x44)
+#define CRB_MMAP_ADDR_1             NETXEN_NIC_REG(0x48)
+#define CRB_MMAP_ADDR_2             NETXEN_NIC_REG(0x4c)
+#define CRB_CMDPEG_STATE            NETXEN_NIC_REG(0x50)
+#define CRB_MMAP_SIZE_0             NETXEN_NIC_REG(0x54)
+#define CRB_MMAP_SIZE_1             NETXEN_NIC_REG(0x58)
+#define CRB_MMAP_SIZE_2             NETXEN_NIC_REG(0x5c)
+#define CRB_MMAP_SIZE_3             NETXEN_NIC_REG(0x60)
+#define CRB_GLOBAL_INT_COAL         NETXEN_NIC_REG(0x64)       /* interrupt coalescing */
+#define CRB_INT_COAL_MODE           NETXEN_NIC_REG(0x68)
+#define CRB_MAX_RCV_BUFS            NETXEN_NIC_REG(0x6c)
+#define CRB_TX_INT_THRESHOLD        NETXEN_NIC_REG(0x70)
+#define CRB_RX_PKT_TIMER            NETXEN_NIC_REG(0x74)
+#define CRB_TX_PKT_TIMER            NETXEN_NIC_REG(0x78)
+#define CRB_RX_PKT_CNT              NETXEN_NIC_REG(0x7c)
+#define CRB_RX_TMR_CNT              NETXEN_NIC_REG(0x80)
+#define CRB_RX_LRO_TIMER            NETXEN_NIC_REG(0x84)
+#define CRB_RX_LRO_MID_TIMER        NETXEN_NIC_REG(0x88)
+#define CRB_DMA_MAX_RCV_BUFS        NETXEN_NIC_REG(0x8c)
+#define CRB_MAX_DMA_ENTRIES         NETXEN_NIC_REG(0x90)
+#define CRB_XG_STATE                NETXEN_NIC_REG(0x94)       /* XG Link status */
+#define CRB_AGENT_GO                NETXEN_NIC_REG(0x98)       /* NIC pkt gen agent */
+#define CRB_AGENT_TX_SIZE           NETXEN_NIC_REG(0x9c)
+#define CRB_AGENT_TX_TYPE           NETXEN_NIC_REG(0xa0)
+#define CRB_AGENT_TX_ADDR           NETXEN_NIC_REG(0xa4)
+#define CRB_AGENT_TX_MSS            NETXEN_NIC_REG(0xa8)
+#define CRB_TX_STATE                NETXEN_NIC_REG(0xac)       /* Debug -performance */
+#define CRB_TX_COUNT                NETXEN_NIC_REG(0xb0)
+#define CRB_RX_STATE                NETXEN_NIC_REG(0xb4)
+#define CRB_RX_PERF_DEBUG_1         NETXEN_NIC_REG(0xb8)
+#define CRB_RX_LRO_CONTROL          NETXEN_NIC_REG(0xbc)       /* LRO On/OFF */
+#define CRB_RX_LRO_START_NUM        NETXEN_NIC_REG(0xc0)
+#define CRB_MPORT_MODE              NETXEN_NIC_REG(0xc4)       /* Multiport Mode */
+#define CRB_CMD_RING_SIZE           NETXEN_NIC_REG(0xc8)
+#define CRB_INT_VECTOR              NETXEN_NIC_REG(0xd4)
+#define CRB_CTX_RESET               NETXEN_NIC_REG(0xd8)
+#define CRB_HOST_STS_PROD           NETXEN_NIC_REG(0xdc)
+#define CRB_HOST_STS_CONS           NETXEN_NIC_REG(0xe0)
+#define CRB_PEG_CMD_PROD            NETXEN_NIC_REG(0xe4)
+#define CRB_PEG_CMD_CONS            NETXEN_NIC_REG(0xe8)
+#define CRB_HOST_BUFFER_PROD        NETXEN_NIC_REG(0xec)
+#define CRB_HOST_BUFFER_CONS        NETXEN_NIC_REG(0xf0)
+#define CRB_JUMBO_BUFFER_PROD       NETXEN_NIC_REG(0xf4)
+#define CRB_JUMBO_BUFFER_CONS       NETXEN_NIC_REG(0xf8)
 
-#define NETXEN_NIC_REG(X)      (NIC_CRB_BASE_PORT1+(X))
+#define CRB_CMD_PRODUCER_OFFSET_1   NETXEN_NIC_REG(0x1ac)
+#define CRB_CMD_CONSUMER_OFFSET_1   NETXEN_NIC_REG(0x1b0)
+#define CRB_TEMP_STATE              NETXEN_NIC_REG(0x1b4)
 
 /*
  * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
  * on the Phantom.
  */
 
-#define CRB_PHAN_CNTRL_LO_OFFSET       NETXEN_NIC_REG(0x00)
-#define CRB_PHAN_CNTRL_HI_OFFSET       NETXEN_NIC_REG(0x04)
-
-/* point to the indexes */
-#define CRB_CMD_PRODUCER_OFFSET                NETXEN_NIC_REG(0x08)
-#define CRB_CMD_CONSUMER_OFFSET                NETXEN_NIC_REG(0x0c)
-
-#define CRB_PAUSE_ADDR_LO              NETXEN_NIC_REG(0x10)
-#define CRB_PAUSE_ADDR_HI              NETXEN_NIC_REG(0x14)
-
-/* address of command descriptors in the host memory */
-#define CRB_HOST_CMD_ADDR_HI           NETXEN_NIC_REG(0x30)
-#define CRB_HOST_CMD_ADDR_LO           NETXEN_NIC_REG(0x34)
-
-/* The following 4 CRB registers are for doing performance coal */
-#define CRB_CMD_INTR_LOOP              NETXEN_NIC_REG(0x38)
-#define CRB_CMD_DMA_LOOP               NETXEN_NIC_REG(0x3c)
-#define CRB_RCV_INTR_LOOP              NETXEN_NIC_REG(0x40)
-#define CRB_RCV_DMA_LOOP               NETXEN_NIC_REG(0x44)
-
-/* Needed by the host to find out the state of Phantom's initialization */
-#define CRB_ENABLE_TX_INTR             NETXEN_NIC_REG(0x4c)
-#define CRB_CMDPEG_STATE               NETXEN_NIC_REG(0x50)
-#define CRB_CMDPEG_CMDRING             NETXEN_NIC_REG(0x54)
-
-/* Interrupt coalescing parameters */
-#define CRB_GLOBAL_INT_COAL            NETXEN_NIC_REG(0x80)
-#define CRB_INT_COAL_MODE              NETXEN_NIC_REG(0x84)
-#define CRB_MAX_RCV_BUFS               NETXEN_NIC_REG(0x88)
-#define CRB_TX_INT_THRESHOLD           NETXEN_NIC_REG(0x8c)
-#define CRB_RX_PKT_TIMER               NETXEN_NIC_REG(0x90)
-#define CRB_TX_PKT_TIMER               NETXEN_NIC_REG(0x94)
-#define CRB_RX_PKT_CNT                 NETXEN_NIC_REG(0x98)
-#define CRB_RX_TMR_CNT                 NETXEN_NIC_REG(0x9c)
-#define CRB_INT_THRESH          NETXEN_NIC_REG(0xa4)
-
-/* Register for communicating XG link status */
-#define CRB_XG_STATE                   NETXEN_NIC_REG(0xa0)
-
-/* Register for communicating card temperature */
-/* Upper 16 bits are temperature value. Lower 16 bits are the state */
-#define CRB_TEMP_STATE          NETXEN_NIC_REG(0xa8)
-#define nx_get_temp_val(x)          ((x) >> 16)
-#define nx_get_temp_state(x)      ((x) & 0xffff)
-#define nx_encode_temp(val, state)     (((val) << 16) | (state))
-
-/* Debug registers for controlling NIC pkt gen agent */
-#define CRB_AGENT_GO                   NETXEN_NIC_REG(0xb0)
-#define CRB_AGENT_TX_SIZE              NETXEN_NIC_REG(0xb4)
-#define CRB_AGENT_TX_TYPE              NETXEN_NIC_REG(0xb8)
-#define CRB_AGENT_TX_ADDR              NETXEN_NIC_REG(0xbc)
-#define CRB_AGENT_TX_MSS               NETXEN_NIC_REG(0xc0)
-
-/* Debug registers for observing NIC performance */
-#define CRB_TX_STATE                   NETXEN_NIC_REG(0xd0)
-#define CRB_TX_COUNT                   NETXEN_NIC_REG(0xd4)
-#define CRB_RX_STATE                   NETXEN_NIC_REG(0xd8)
+#define nx_get_temp_val(x)             ((x) >> 16)
+#define nx_get_temp_state(x)           ((x) & 0xffff)
+#define nx_encode_temp(val, state)     (((val) << 16) | (state))
 
 /* CRB registers per Rcv Descriptor ring */
 struct netxen_rcv_desc_crb {
        u32 crb_rcv_producer_offset __attribute__ ((aligned(512)));
        u32 crb_rcv_consumer_offset;
        u32 crb_globalrcv_ring;
+       u32 crb_rcv_ring_size;
 };
 
 /*
- * CRB registers used by the receive peg logic. One instance of these
- * needs to be instantiated per instance of the receive peg.
+ * CRB registers used by the receive peg logic.
  */
 
 struct netxen_recv_crb {
@@ -127,6 +132,7 @@ struct netxen_recv_crb {
        u32 crb_rcv_status_producer;
        u32 crb_rcv_status_consumer;
        u32 crb_rcvpeg_state;
+       u32 crb_status_ring_size;
 };
 
 #if defined(DEFINE_GLOBAL_RECV_CRB)
@@ -139,30 +145,48 @@ struct netxen_recv_crb recv_crb_registers[] = {
         {
          {
           /* crb_rcv_producer_offset: */
-          NETXEN_NIC_REG(0x18),
+          NETXEN_NIC_REG(0x100),
           /* crb_rcv_consumer_offset: */
-          NETXEN_NIC_REG(0x1c),
+          NETXEN_NIC_REG(0x104),
           /* crb_gloablrcv_ring: */
-          NETXEN_NIC_REG(0x20),
+          NETXEN_NIC_REG(0x108),
+          /* crb_rcv_ring_size */
+          NETXEN_NIC_REG(0x10c),
+
           },
          /* Jumbo frames */
          {
           /* crb_rcv_producer_offset: */
-          NETXEN_NIC_REG(0x100),
+          NETXEN_NIC_REG(0x110),
           /* crb_rcv_consumer_offset: */
-          NETXEN_NIC_REG(0x104),
+          NETXEN_NIC_REG(0x114),
           /* crb_gloablrcv_ring: */
-          NETXEN_NIC_REG(0x108),
+          NETXEN_NIC_REG(0x118),
+          /* crb_rcv_ring_size */
+          NETXEN_NIC_REG(0x11c),
+          },
+         /* LRO */
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x120),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x124),
+          /* crb_gloablrcv_ring: */
+          NETXEN_NIC_REG(0x128),
+          /* crb_rcv_ring_size */
+          NETXEN_NIC_REG(0x12c),
           }
          },
         /* crb_rcvstatus_ring: */
-        NETXEN_NIC_REG(0x24),
+        NETXEN_NIC_REG(0x130),
         /* crb_rcv_status_producer: */
-        NETXEN_NIC_REG(0x28),
+        NETXEN_NIC_REG(0x134),
         /* crb_rcv_status_consumer: */
-        NETXEN_NIC_REG(0x2c),
+        NETXEN_NIC_REG(0x138),
         /* crb_rcvpeg_state: */
-        NETXEN_NIC_REG(0x48),
+        NETXEN_NIC_REG(0x13c),
+        /* crb_status_ring_size */
+        NETXEN_NIC_REG(0x140),
 
         },
        /*
@@ -173,34 +197,66 @@ struct netxen_recv_crb recv_crb_registers[] = {
         {
          {
           /* crb_rcv_producer_offset: */
-          NETXEN_NIC_REG(0x80),
+          NETXEN_NIC_REG(0x144),
           /* crb_rcv_consumer_offset: */
-          NETXEN_NIC_REG(0x84),
+          NETXEN_NIC_REG(0x148),
           /* crb_globalrcv_ring: */
-          NETXEN_NIC_REG(0x88),
+          NETXEN_NIC_REG(0x14c),
+          /* crb_rcv_ring_size */
+          NETXEN_NIC_REG(0x150),
+
           },
          /* Jumbo frames */
          {
           /* crb_rcv_producer_offset: */
-          NETXEN_NIC_REG(0x10C),
+          NETXEN_NIC_REG(0x154),
           /* crb_rcv_consumer_offset: */
-          NETXEN_NIC_REG(0x110),
+          NETXEN_NIC_REG(0x158),
           /* crb_globalrcv_ring: */
-          NETXEN_NIC_REG(0x114),
+          NETXEN_NIC_REG(0x15c),
+          /* crb_rcv_ring_size */
+          NETXEN_NIC_REG(0x160),
+          },
+         /* LRO */
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x164),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x168),
+          /* crb_globalrcv_ring: */
+          NETXEN_NIC_REG(0x16c),
+          /* crb_rcv_ring_size */
+          NETXEN_NIC_REG(0x170),
           }
+
          },
         /* crb_rcvstatus_ring: */
-        NETXEN_NIC_REG(0x8c),
+        NETXEN_NIC_REG(0x174),
         /* crb_rcv_status_producer: */
-        NETXEN_NIC_REG(0x90),
+        NETXEN_NIC_REG(0x178),
         /* crb_rcv_status_consumer: */
-        NETXEN_NIC_REG(0x94),
+        NETXEN_NIC_REG(0x17c),
         /* crb_rcvpeg_state: */
-        NETXEN_NIC_REG(0x98),
+        NETXEN_NIC_REG(0x180),
+        /* crb_status_ring_size */
+        NETXEN_NIC_REG(0x184),
+
         },
 };
+
+u64 ctx_addr_sig_regs[][3] = {
+       {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)},
+       {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)},
+       {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)},
+       {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)}
+};
+
 #else
 extern struct netxen_recv_crb recv_crb_registers[];
+extern u64 ctx_addr_sig_regs[][3];
+#define CRB_CTX_ADDR_REG_LO            (ctx_addr_sig_regs[0][0])
+#define CRB_CTX_ADDR_REG_HI            (ctx_addr_sig_regs[0][2])
+#define CRB_CTX_SIGNATURE_REG       (ctx_addr_sig_regs[0][1])
 #endif                         /* DEFINE_GLOBAL_RECEIVE_CRB */
 
 /*
index 26e42f6..196993a 100644 (file)
@@ -1335,7 +1335,7 @@ int __init init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        unregister_netdev(dev_ni52);
        release_region(dev_ni52->base_addr, NI52_TOTAL_SIZE);
index 340ad0d..1578f4d 100644 (file)
@@ -1259,7 +1259,7 @@ int __init init_module(void)
        return IS_ERR(dev_ni65) ? PTR_ERR(dev_ni65) : 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        unregister_netdev(dev_ni65);
        cleanup_card(dev_ni65);
index 312e0e3..568daeb 100644 (file)
@@ -414,10 +414,10 @@ struct rx_info {
 
        struct sk_buff  *skbs[NR_RX_DESC];
 
-       u32             *next_rx_desc;
+       __le32          *next_rx_desc;
        u16             next_rx, next_empty;
 
-       u32             *descs;
+       __le32          *descs;
        dma_addr_t      phy_descs;
 };
 
@@ -460,7 +460,7 @@ struct ns83820 {
        struct sk_buff  *tx_skbs[NR_TX_DESC];
 
        char            pad[16] __attribute__((aligned(16)));
-       u32             *tx_descs;
+       __le32          *tx_descs;
        dma_addr_t      tx_phy_descs;
 
        struct timer_list       tx_watchdog;
@@ -534,7 +534,7 @@ static void ns83820_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid
  * conditions, still route realtime traffic with as low jitter as
  * possible.
  */
-static inline void build_rx_desc(struct ns83820 *dev, u32 *desc, dma_addr_t link, dma_addr_t buf, u32 cmdsts, u32 extsts)
+static inline void build_rx_desc(struct ns83820 *dev, __le32 *desc, dma_addr_t link, dma_addr_t buf, u32 cmdsts, u32 extsts)
 {
        desc_addr_set(desc + DESC_LINK, link);
        desc_addr_set(desc + DESC_BUFPTR, buf);
@@ -548,7 +548,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
 {
        unsigned next_empty;
        u32 cmdsts;
-       u32 *sg;
+       __le32 *sg;
        dma_addr_t buf;
 
        next_empty = dev->rx_info.next_empty;
@@ -875,7 +875,8 @@ static void fastcall rx_irq(struct net_device *ndev)
        struct rx_info *info = &dev->rx_info;
        unsigned next_rx;
        int rx_rc, len;
-       u32 cmdsts, *desc;
+       u32 cmdsts;
+       __le32 *desc;
        unsigned long flags;
        int nr = 0;
 
@@ -1011,7 +1012,8 @@ static inline void kick_tx(struct ns83820 *dev)
 static void do_tx_done(struct net_device *ndev)
 {
        struct ns83820 *dev = PRIV(ndev);
-       u32 cmdsts, tx_done_idx, *desc;
+       u32 cmdsts, tx_done_idx;
+       __le32 *desc;
 
        dprintk("do_tx_done(%p)\n", ndev);
        tx_done_idx = dev->tx_done_idx;
@@ -1078,7 +1080,7 @@ static void ns83820_cleanup_tx(struct ns83820 *dev)
                struct sk_buff *skb = dev->tx_skbs[i];
                dev->tx_skbs[i] = NULL;
                if (skb) {
-                       u32 *desc = dev->tx_descs + (i * DESC_SIZE);
+                       __le32 *desc = dev->tx_descs + (i * DESC_SIZE);
                        pci_unmap_single(dev->pci_dev,
                                        desc_addr_get(desc + DESC_BUFPTR),
                                        le32_to_cpu(desc[DESC_CMDSTS]) & CMDSTS_LEN_MASK,
@@ -1108,7 +1110,7 @@ static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        skb_frag_t *frag;
        int stopped = 0;
        int do_intr = 0;
-       volatile u32 *first_desc;
+       volatile __le32 *first_desc;
 
        dprintk("ns83820_hard_start_xmit\n");
 
@@ -1181,7 +1183,7 @@ again:
        first_desc = dev->tx_descs + (free_idx * DESC_SIZE);
 
        for (;;) {
-               volatile u32 *desc = dev->tx_descs + (free_idx * DESC_SIZE);
+               volatile __le32 *desc = dev->tx_descs + (free_idx * DESC_SIZE);
 
                dprintk("frag[%3u]: %4u @ 0x%08Lx\n", free_idx, len,
                        (unsigned long long)buf);
@@ -1456,7 +1458,8 @@ static int ns83820_stop(struct net_device *ndev)
 static void ns83820_tx_timeout(struct net_device *ndev)
 {
        struct ns83820 *dev = PRIV(ndev);
-        u32 tx_done_idx, *desc;
+        u32 tx_done_idx;
+       __le32 *desc;
        unsigned long flags;
 
        spin_lock_irqsave(&dev->tx_lock, flags);
index d9d0a3a..0d6c95c 100644 (file)
@@ -750,7 +750,7 @@ int __init init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        unregister_netdev(dev_seeq);
        release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT);
index ab66d80..3e7aa49 100644 (file)
@@ -1319,7 +1319,7 @@ SK_BOOL   AutoNeg)        /* Is Auto-negotiation used ? */
        SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
 
 #ifdef xDEBUG
-       if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) ==
+       if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) ==
                (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
 
                SK_U32  Stat1, Stat2, Stat3;
index 889ef0d..d70bc97 100644 (file)
@@ -593,7 +593,7 @@ static void cleanup_card(struct net_device *dev)
        iounmap(ei_status.mem);
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        int this_dev;
index e10755e..2c5319c 100644 (file)
@@ -437,7 +437,7 @@ int __init init_module(void)
        return -ENXIO;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        int this_dev;
 
index c0d13d6..bd6e845 100644 (file)
@@ -1616,7 +1616,7 @@ int __init init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        unregister_netdev(devSMC9194);
        free_irq(devSMC9194->irq, devSMC9194);
index a864016..9367c57 100644 (file)
@@ -238,7 +238,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 #define SMC_CAN_USE_16BIT      1
 #define SMC_CAN_USE_32BIT      0
 
-#define SMC_inb(a, r)          inb((u32)a) + (r))
+#define SMC_inb(a, r)          inb(((u32)a) + (r))
 #define SMC_inw(a, r)          inw(((u32)a) + (r))
 #define SMC_outb(v, a, r)      outb(v, ((u32)a) + (r))
 #define SMC_outw(v, a, r)      outw(v, ((u32)a) + (r))
@@ -434,6 +434,24 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
 
 #define SMC_IRQ_FLAGS          (0)
 
+#elif  defined(CONFIG_ARCH_VERSATILE)
+
+#define SMC_CAN_USE_8BIT       1
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      1
+#define SMC_NOWAIT             1
+
+#define SMC_inb(a, r)          readb((a) + (r))
+#define SMC_inw(a, r)          readw((a) + (r))
+#define SMC_inl(a, r)          readl((a) + (r))
+#define SMC_outb(v, a, r)      writeb(v, (a) + (r))
+#define SMC_outw(v, a, r)      writew(v, (a) + (r))
+#define SMC_outl(v, a, r)      writel(v, (a) + (r))
+#define SMC_insl(a, r, p, l)   readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l)  writesl((a) + (r), p, l)
+
+#define SMC_IRQ_FLAGS          (0)
+
 #else
 
 #define SMC_CAN_USE_8BIT       1
@@ -1216,7 +1234,7 @@ static const char * chip_ids[ 16 ] =  {
                if (SMC_CAN_USE_32BIT) {                                \
                        void *__ptr = (p);                              \
                        int __len = (l);                                \
-                       void *__ioaddr = ioaddr;                        \
+                       void __iomem *__ioaddr = ioaddr;                \
                        if (__len >= 2 && (unsigned long)__ptr & 2) {   \
                                __len -= 2;                             \
                                SMC_outw(*(u16 *)__ptr, ioaddr, DATA_REG); \
@@ -1240,7 +1258,7 @@ static const char * chip_ids[ 16 ] =  {
                if (SMC_CAN_USE_32BIT) {                                \
                        void *__ptr = (p);                              \
                        int __len = (l);                                \
-                       void *__ioaddr = ioaddr;                        \
+                       void __iomem *__ioaddr = ioaddr;                \
                        if ((unsigned long)__ptr & 2) {                 \
                                /*                                      \
                                 * We want 32bit alignment here.        \
index 47a1c09..c62e85d 100644 (file)
@@ -945,7 +945,7 @@ static void set_multicast_list( struct net_device *dev )
 
 static struct net_device *sun3lance_dev;
 
-int init_module(void)
+int __init init_module(void)
 {
        sun3lance_dev = sun3lance_probe(-1);
        if (IS_ERR(sun3lance_dev))
@@ -953,7 +953,7 @@ int init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        unregister_netdev(sun3lance_dev);
 #ifdef CONFIG_SUN3
index 46dabdb..cec282a 100644 (file)
@@ -5706,7 +5706,7 @@ int __init init_module(void)
         return found ? 0 : -ENODEV;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
         int i;
 
index 41f1d67..7f38012 100644 (file)
@@ -538,7 +538,7 @@ static void cleanup_card(struct net_device *dev)
        iounmap(ei_status.mem);
 }
 
-void
+void __exit
 cleanup_module(void)
 {
        int this_dev;