RDMA/cxgb3: Don't add PBL memory to gen_pool in chunks
[safe/jmp/linux-2.6] / drivers / net / netxen / netxen_nic_hw.c
index 7470852..af73564 100644 (file)
 #include "netxen_nic_hw.h"
 #include "netxen_nic_phan_reg.h"
 
+
+#include <net/ip.h>
+
+struct netxen_recv_crb recv_crb_registers[] = {
+       /*
+        * Instance 0.
+        */
+       {
+        /* rcv_desc_crb: */
+        {
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x100),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x104),
+          /* crb_gloablrcv_ring: */
+          NETXEN_NIC_REG(0x108),
+          /* crb_rcv_ring_size */
+          NETXEN_NIC_REG(0x10c),
+
+          },
+         /* Jumbo frames */
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x110),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x114),
+          /* crb_gloablrcv_ring: */
+          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(0x130),
+        /* crb_rcv_status_producer: */
+        NETXEN_NIC_REG(0x134),
+        /* crb_rcv_status_consumer: */
+        NETXEN_NIC_REG(0x138),
+        /* crb_rcvpeg_state: */
+        NETXEN_NIC_REG(0x13c),
+        /* crb_status_ring_size */
+        NETXEN_NIC_REG(0x140),
+
+        },
+       /*
+        * Instance 1,
+        */
+       {
+        /* rcv_desc_crb: */
+        {
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x144),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x148),
+          /* crb_globalrcv_ring: */
+          NETXEN_NIC_REG(0x14c),
+          /* crb_rcv_ring_size */
+          NETXEN_NIC_REG(0x150),
+
+          },
+         /* Jumbo frames */
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x154),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x158),
+          /* crb_globalrcv_ring: */
+          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(0x174),
+        /* crb_rcv_status_producer: */
+        NETXEN_NIC_REG(0x178),
+        /* crb_rcv_status_consumer: */
+        NETXEN_NIC_REG(0x17c),
+        /* crb_rcvpeg_state: */
+        NETXEN_NIC_REG(0x180),
+        /* crb_status_ring_size */
+        NETXEN_NIC_REG(0x184),
+        },
+       /*
+        * Instance 2,
+        */
+       {
+         {
+           {
+           /* crb_rcv_producer_offset: */
+           NETXEN_NIC_REG(0x1d8),
+           /* crb_rcv_consumer_offset: */
+           NETXEN_NIC_REG(0x1dc),
+           /* crb_gloablrcv_ring: */
+           NETXEN_NIC_REG(0x1f0),
+           /* crb_rcv_ring_size */
+           NETXEN_NIC_REG(0x1f4),
+           },
+           /* Jumbo frames */
+           {
+           /* crb_rcv_producer_offset: */
+           NETXEN_NIC_REG(0x1f8),
+           /* crb_rcv_consumer_offset: */
+           NETXEN_NIC_REG(0x1fc),
+           /* crb_gloablrcv_ring: */
+           NETXEN_NIC_REG(0x200),
+           /* crb_rcv_ring_size */
+           NETXEN_NIC_REG(0x204),
+           },
+           /* LRO */
+           {
+           /* crb_rcv_producer_offset: */
+           NETXEN_NIC_REG(0x208),
+           /* crb_rcv_consumer_offset: */
+           NETXEN_NIC_REG(0x20c),
+           /* crb_gloablrcv_ring: */
+           NETXEN_NIC_REG(0x210),
+           /* crb_rcv_ring_size */
+           NETXEN_NIC_REG(0x214),
+           }
+         },
+         /* crb_rcvstatus_ring: */
+         NETXEN_NIC_REG(0x218),
+         /* crb_rcv_status_producer: */
+         NETXEN_NIC_REG(0x21c),
+         /* crb_rcv_status_consumer: */
+         NETXEN_NIC_REG(0x220),
+         /* crb_rcvpeg_state: */
+         NETXEN_NIC_REG(0x224),
+         /* crb_status_ring_size */
+         NETXEN_NIC_REG(0x228),
+       },
+       /*
+        * Instance 3,
+        */
+       {
+         {
+           {
+           /* crb_rcv_producer_offset: */
+           NETXEN_NIC_REG(0x22c),
+           /* crb_rcv_consumer_offset: */
+           NETXEN_NIC_REG(0x230),
+           /* crb_gloablrcv_ring: */
+           NETXEN_NIC_REG(0x234),
+           /* crb_rcv_ring_size */
+           NETXEN_NIC_REG(0x238),
+           },
+           /* Jumbo frames */
+           {
+           /* crb_rcv_producer_offset: */
+           NETXEN_NIC_REG(0x23c),
+           /* crb_rcv_consumer_offset: */
+           NETXEN_NIC_REG(0x240),
+           /* crb_gloablrcv_ring: */
+           NETXEN_NIC_REG(0x244),
+           /* crb_rcv_ring_size */
+           NETXEN_NIC_REG(0x248),
+           },
+           /* LRO */
+           {
+           /* crb_rcv_producer_offset: */
+           NETXEN_NIC_REG(0x24c),
+           /* crb_rcv_consumer_offset: */
+           NETXEN_NIC_REG(0x250),
+           /* crb_gloablrcv_ring: */
+           NETXEN_NIC_REG(0x254),
+           /* crb_rcv_ring_size */
+           NETXEN_NIC_REG(0x258),
+           }
+         },
+         /* crb_rcvstatus_ring: */
+         NETXEN_NIC_REG(0x25c),
+         /* crb_rcv_status_producer: */
+         NETXEN_NIC_REG(0x260),
+         /* crb_rcv_status_consumer: */
+         NETXEN_NIC_REG(0x264),
+         /* crb_rcvpeg_state: */
+         NETXEN_NIC_REG(0x268),
+         /* crb_status_ring_size */
+         NETXEN_NIC_REG(0x26c),
+       },
+};
+
+static 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)}
+};
+#define CRB_CTX_ADDR_REG_LO(FUNC_ID)           (ctx_addr_sig_regs[FUNC_ID][0])
+#define CRB_CTX_ADDR_REG_HI(FUNC_ID)           (ctx_addr_sig_regs[FUNC_ID][2])
+#define CRB_CTX_SIGNATURE_REG(FUNC_ID)         (ctx_addr_sig_regs[FUNC_ID][1])
+
+
 /*  PCI Windowing for DDR regions.  */
 
 #define ADDR_IN_RANGE(addr, low, high) \
        (((addr) <= (high)) && ((addr) >= (low)))
 
-#define NETXEN_FLASH_BASE      (BOOTLD_START)
+#define NETXEN_FLASH_BASE      (NETXEN_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
 
 #define NETXEN_NIC_WINDOW_MARGIN 0x100000
 
-unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter,
-                                       unsigned long long addr);
+static unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter,
+                                              unsigned long long addr);
 void netxen_free_hw_resources(struct netxen_adapter *adapter);
 
 int netxen_nic_set_mac(struct net_device *netdev, void *p)
 {
-       struct netxen_port *port = netdev_priv(netdev);
-       struct netxen_adapter *adapter = port->adapter;
+       struct netxen_adapter *adapter = netdev_priv(netdev);
        struct sockaddr *addr = p;
 
        if (netif_running(netdev))
@@ -82,7 +300,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 
        if (adapter->macaddr_set)
-               adapter->macaddr_set(port, addr->sa_data);
+               adapter->macaddr_set(adapter, addr->sa_data);
 
        return 0;
 }
@@ -92,56 +310,19 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
  */
 void netxen_nic_set_multi(struct net_device *netdev)
 {
-       struct netxen_port *port = netdev_priv(netdev);
-       struct netxen_adapter *adapter = port->adapter;
+       struct netxen_adapter *adapter = netdev_priv(netdev);
        struct dev_mc_list *mc_ptr;
-       __le32 netxen_mac_addr_cntl_data = 0;
 
        mc_ptr = netdev->mc_list;
        if (netdev->flags & IFF_PROMISC) {
                if (adapter->set_promisc)
                        adapter->set_promisc(adapter,
-                                            port->portnum,
                                             NETXEN_NIU_PROMISC_MODE);
        } else {
-               if (adapter->unset_promisc &&
-                   adapter->ahw.boardcfg.board_type
-                   != NETXEN_BRDTYPE_P2_SB31_10G_IMEZ)
+               if (adapter->unset_promisc)
                        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);
-               netxen_nic_mcr_set_id_pool0(netxen_mac_addr_cntl_data, 0x00);
-               netxen_nic_mcr_set_id_pool1(netxen_mac_addr_cntl_data, 0x00);
-               netxen_nic_mcr_set_id_pool2(netxen_mac_addr_cntl_data, 0x00);
-               netxen_nic_mcr_set_id_pool3(netxen_mac_addr_cntl_data, 0x00);
-               netxen_nic_mcr_set_enable_xtnd0(netxen_mac_addr_cntl_data);
-               netxen_nic_mcr_set_enable_xtnd1(netxen_mac_addr_cntl_data);
-               netxen_nic_mcr_set_enable_xtnd2(netxen_mac_addr_cntl_data);
-               netxen_nic_mcr_set_enable_xtnd3(netxen_mac_addr_cntl_data);
-       } else {
-               netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x00);
-               netxen_nic_mcr_set_id_pool0(netxen_mac_addr_cntl_data, 0x00);
-               netxen_nic_mcr_set_id_pool1(netxen_mac_addr_cntl_data, 0x01);
-               netxen_nic_mcr_set_id_pool2(netxen_mac_addr_cntl_data, 0x02);
-               netxen_nic_mcr_set_id_pool3(netxen_mac_addr_cntl_data, 0x03);
-       }
-       writel(netxen_mac_addr_cntl_data,
-              NETXEN_CRB_NORMALIZE(adapter, NETXEN_MAC_ADDR_CNTL_REG));
-       if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
-               writel(netxen_mac_addr_cntl_data,
-                      NETXEN_CRB_NORMALIZE(adapter,
-                                           NETXEN_MULTICAST_ADDR_HI_0));
-       } else {
-               writel(netxen_mac_addr_cntl_data,
-                      NETXEN_CRB_NORMALIZE(adapter,
-                                           NETXEN_MULTICAST_ADDR_HI_1));
-       }
-       netxen_mac_addr_cntl_data = 0;
-       writel(netxen_mac_addr_cntl_data,
-              NETXEN_CRB_NORMALIZE(adapter, NETXEN_NIU_GB_DROP_WRONGADDR));
 }
 
 /*
@@ -150,8 +331,7 @@ void netxen_nic_set_multi(struct net_device *netdev)
  */
 int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
 {
-       struct netxen_port *port = netdev_priv(netdev);
-       struct netxen_adapter *adapter = port->adapter;
+       struct netxen_adapter *adapter = netdev_priv(netdev);
        int eff_mtu = mtu + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE;
 
        if ((eff_mtu > NETXEN_MAX_MTU) || (eff_mtu < NETXEN_MIN_MTU)) {
@@ -161,7 +341,7 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
        }
 
        if (adapter->set_mtu)
-               adapter->set_mtu(port, mtu);
+               adapter->set_mtu(adapter, mtu);
        netdev->mtu = mtu;
 
        return 0;
@@ -176,13 +356,11 @@ 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;
+       int func_id = adapter->portnum;
 
        DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE,
                PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE));
@@ -191,11 +369,6 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
        DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE,
                pci_base_offset(adapter, NETXEN_CAM_RAM_BASE));
 
-       /* Window 1 call */
-       card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING));
-
-       DPRINTK(INFO, "Command Peg sends 0x%x for cmdring base\n",
-               card_cmdring);
 
        for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
                DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n");
@@ -206,7 +379,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
                                                   recv_crb_registers[ctx].
                                                   crb_rcvpeg_state));
                while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) {
-                       udelay(100);
+                       msleep(1);
                        /* Window 1 call */
                        state = readl(NETXEN_CRB_NORMALIZE(adapter,
                                                           recv_crb_registers
@@ -221,36 +394,54 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
                        return err;
                }
        }
-       DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n");
+       adapter->intr_scheme = readl(
+               NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW));
+       printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name,
+                       adapter->intr_scheme);
+       adapter->msi_mode = readl(
+               NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW));
+       DPRINTK(INFO, "Receive 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(KERN_INFO "ctx_desc_phys_addr: 0x%llx\n",
+              (unsigned long long) 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->ctx_id = cpu_to_le32(adapter->portnum);
+       adapter->ctx_desc->cmd_consumer_offset =
+           cpu_to_le64(adapter->ctx_desc_phys_addr +
+                       sizeof(struct netxen_ring_ctx));
+       adapter->cmd_consumer = (__le32 *) (((char *)addr) +
+                                             sizeof(struct netxen_ring_ctx));
+
+       addr = netxen_alloc(adapter->ahw.pdev,
+                           sizeof(struct cmd_desc_type0) *
+                           adapter->max_tx_desc_count,
+                           (dma_addr_t *) & hw->cmd_desc_phys_addr,
+                           &adapter->ahw.cmd_desc_pdev);
+       printk(KERN_INFO "cmd_desc_phys_addr: 0x%llx\n",
+              (unsigned long long) 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 =
+               cpu_to_le64(hw->cmd_desc_phys_addr);
+       adapter->ctx_desc->cmd_ring_size =
+               cpu_to_le32(adapter->max_tx_desc_count);
 
        hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
 
@@ -271,6 +462,10 @@ 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 =
+                           cpu_to_le64(rcv_desc->phys_addr);
+                       adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
+                           cpu_to_le32(rcv_desc->max_rx_desc_count);
                }
 
                addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE,
@@ -284,47 +479,20 @@ 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 =
+                   cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
+               adapter->ctx_desc->sts_ring_size =
+                   cpu_to_le32(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(func_id)));
+       writel(upper32(adapter->ctx_desc_phys_addr),
+              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI(func_id)));
+       writel(NETXEN_CTX_SIGNATURE | func_id,
+              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG(func_id)));
        return err;
 }
 
@@ -334,6 +502,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) *
@@ -342,12 +519,6 @@ 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;
-       }
 
        for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
                recv_ctx = &adapter->recv_ctx[ctx];
@@ -378,23 +549,20 @@ void netxen_tso_check(struct netxen_adapter *adapter,
                      struct cmd_desc_type0 *desc, struct sk_buff *skb)
 {
        if (desc->mss) {
-               desc->total_hdr_length = sizeof(struct ethhdr) +
-                   ((skb->nh.iph)->ihl * sizeof(u32)) +
-                   ((skb->h.th)->doff * sizeof(u32));
-               desc->opcode = TX_TCP_LSO;
-       } else if (skb->ip_summed == CHECKSUM_COMPLETE) {
-               if (skb->nh.iph->protocol == IPPROTO_TCP) {
-                       desc->opcode = TX_TCP_PKT;
-               } else if (skb->nh.iph->protocol == IPPROTO_UDP) {
-                       desc->opcode = TX_UDP_PKT;
+               desc->total_hdr_length = (sizeof(struct ethhdr) +
+                                         ip_hdrlen(skb) + tcp_hdrlen(skb));
+               netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO);
+       } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               if (ip_hdr(skb)->protocol == IPPROTO_TCP) {
+                       netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT);
+               } else if (ip_hdr(skb)->protocol == IPPROTO_UDP) {
+                       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->ip_hdr_offset = skb->nh.raw - skb->data;
+       desc->tcp_hdr_offset = skb_transport_offset(skb);
+       desc->ip_hdr_offset = skb_network_offset(skb);
 }
 
 int netxen_is_flash_supported(struct netxen_adapter *adapter)
@@ -405,7 +573,7 @@ int netxen_is_flash_supported(struct netxen_adapter *adapter)
        /* if the flash size less than 4Mb, make huge war cry and die */
        for (j = 1; j < 4; j++) {
                addr = j * NETXEN_NIC_WINDOW_MARGIN;
-               for (i = 0; i < (sizeof(locs) / sizeof(locs[0])); i++) {
+               for (i = 0; i < ARRAY_SIZE(locs); i++) {
                        if (netxen_rom_fast_read(adapter, locs[i], &val01) == 0
                            && netxen_rom_fast_read(adapter, (addr + locs[i]),
                                                    &val02) == 0) {
@@ -420,50 +588,52 @@ int netxen_is_flash_supported(struct netxen_adapter *adapter)
 }
 
 static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
-                                 int size, u32 * buf)
+                                 int size, __le32 * buf)
 {
        int i, addr;
-       u32 *ptr32;
+       __le32 *ptr32;
+       u32 v;
 
        addr = base;
        ptr32 = buf;
        for (i = 0; i < size / sizeof(u32); i++) {
-               if (netxen_rom_fast_read(adapter, addr, ptr32) == -1)
+               if (netxen_rom_fast_read(adapter, addr, &v) == -1)
                        return -1;
+               *ptr32 = cpu_to_le32(v);
                ptr32++;
                addr += sizeof(u32);
        }
        if ((char *)buf + size > (char *)ptr32) {
-               u32 local;
-
-               if (netxen_rom_fast_read(adapter, addr, &local) == -1)
+               __le32 local;
+               if (netxen_rom_fast_read(adapter, addr, &v) == -1)
                        return -1;
+               local = cpu_to_le32(v);
                memcpy(ptr32, &local, (char *)buf + size - (char *)ptr32);
        }
 
        return 0;
 }
 
-int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[])
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[])
 {
-       u32 *pmac = (u32 *) & mac[0];
+       __le32 *pmac = (__le32 *) & mac[0];
 
        if (netxen_get_flash_block(adapter,
-                                  USER_START +
+                                  NETXEN_USER_START +
                                   offsetof(struct netxen_new_user_info,
                                            mac_addr),
                                   FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) {
                return -1;
        }
-       if (*mac == ~0ULL) {
+       if (*mac == cpu_to_le64(~0ULL)) {
                if (netxen_get_flash_block(adapter,
-                                          USER_START_OLD +
+                                          NETXEN_USER_START_OLD +
                                           offsetof(struct netxen_user_old_info,
                                                    mac_addr),
                                           FLASH_NUM_PORTS * sizeof(u64),
                                           pmac) == -1)
                        return -1;
-               if (*mac == ~0ULL)
+               if (*mac == cpu_to_le64(~0ULL))
                        return -1;
        }
        return 0;
@@ -480,7 +650,30 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
 
        if (adapter->curr_window == wndw)
                return;
-
+       switch(adapter->ahw.pci_func) {
+               case 0:
+                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
+                                       NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW));
+                       break;
+               case 1:
+                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
+                                       NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F1));
+                       break;
+               case 2:
+                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
+                                       NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F2));
+                       break;
+               case 3:
+                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
+                                       NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F3));
+                       break;
+               default:
+                       printk(KERN_INFO "Changing the window for PCI function "
+                                       "%d\n", adapter->ahw.pci_func);
+                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
+                                       NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW));
+                       break;
+       }
        /*
         * Move the CRB window.
         * We need to write to the "direct access" region of PCI
@@ -489,9 +682,6 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
         * register address is received by PCI. The direct region bypasses
         * the CRB bus.
         */
-       offset =
-           PCI_OFFSET_SECOND_RANGE(adapter,
-                                   NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW));
 
        if (wndw & 0x1)
                wndw = NETXEN_WINDOW_ONE;
@@ -509,14 +699,17 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
                count++;
        }
 
-       adapter->curr_window = wndw;
+       if (wndw == NETXEN_WINDOW_ONE)
+               adapter->curr_window = 1;
+       else
+               adapter->curr_window = 0;
 }
 
-void netxen_load_firmware(struct netxen_adapter *adapter)
+int netxen_load_firmware(struct netxen_adapter *adapter)
 {
        int i;
-       long data, size = 0;
-       long flashaddr = NETXEN_FLASH_BASE, memaddr = NETXEN_PHANTOM_MEM_BASE;
+       u32 data, size = 0;
+       u32 flashaddr = NETXEN_FLASH_BASE, memaddr = NETXEN_PHANTOM_MEM_BASE;
        u64 off;
        void __iomem *addr;
 
@@ -524,15 +717,24 @@ void netxen_load_firmware(struct netxen_adapter *adapter)
        writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));
 
        for (i = 0; i < size; i++) {
-               if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) {
-                       DPRINTK(ERR,
-                               "Error in netxen_rom_fast_read(). Will skip"
-                               "loading flash image\n");
-                       return;
-               }
+               int retries = 10;
+               if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0)
+                       return -EIO;
+
                off = netxen_nic_pci_set_window(adapter, memaddr);
                addr = pci_base_offset(adapter, off);
                writel(data, addr);
+               do {
+                       if (readl(addr) == data)
+                               break;
+                       msleep(100);
+                       writel(data, addr);
+               } while (--retries);
+               if (!retries) {
+                       printk(KERN_ERR "%s: firmware load aborted, write failed at 0x%x\n",
+                                       netxen_nic_driver_name, memaddr);
+                       return -EIO;
+               }
                flashaddr += 4;
                memaddr += 4;
        }
@@ -542,7 +744,7 @@ void netxen_load_firmware(struct netxen_adapter *adapter)
               NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL));
        writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));
 
-       udelay(100);
+       return 0;
 }
 
 int
@@ -688,11 +890,10 @@ void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value)
        netxen_nic_pci_change_crbwindow(adapter, 1);
 }
 
-int netxen_pci_set_window_warning_count = 0;
+static int netxen_pci_set_window_warning_count;
 
-unsigned long
-netxen_nic_pci_set_window(struct netxen_adapter *adapter,
-                         unsigned long long addr)
+static  unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter,
+                                               unsigned long long addr)
 {
        static int ddr_mn_window = -1;
        static int qdr_sn_window = -1;
@@ -706,11 +907,11 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter,
                        ddr_mn_window = window;
                        writel(window, PCI_OFFSET_SECOND_RANGE(adapter,
                                                               NETXEN_PCIX_PH_REG
-                                                              (PCIX_MN_WINDOW)));
+                                                              (PCIX_MN_WINDOW(adapter->ahw.pci_func))));
                        /* MUST make sure window is set before we forge on... */
                        readl(PCI_OFFSET_SECOND_RANGE(adapter,
                                                      NETXEN_PCIX_PH_REG
-                                                     (PCIX_MN_WINDOW)));
+                                                     (PCIX_MN_WINDOW(adapter->ahw.pci_func))));
                }
                addr -= (window * NETXEN_WINDOW_ONE);
                addr += NETXEN_PCI_DDR_NET;
@@ -731,11 +932,11 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter,
                        writel((window << 22),
                               PCI_OFFSET_SECOND_RANGE(adapter,
                                                       NETXEN_PCIX_PH_REG
-                                                      (PCIX_SN_WINDOW)));
+                                                      (PCIX_SN_WINDOW(adapter->ahw.pci_func))));
                        /* MUST make sure window is set before we forge on... */
                        readl(PCI_OFFSET_SECOND_RANGE(adapter,
                                                      NETXEN_PCIX_PH_REG
-                                                     (PCIX_SN_WINDOW)));
+                                                     (PCIX_SN_WINDOW(adapter->ahw.pci_func))));
                }
                addr -= (window * 0x400000);
                addr += NETXEN_PCI_QDR_NET;
@@ -754,10 +955,23 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter,
        return addr;
 }
 
+#if 0
+int
+netxen_nic_erase_pxe(struct netxen_adapter *adapter)
+{
+       if (netxen_rom_fast_write(adapter, NETXEN_PXE_START, 0) == -1) {
+               printk(KERN_ERR "%s: erase pxe failed\n",
+                       netxen_nic_driver_name);
+               return -1;
+       }
+       return 0;
+}
+#endif  /*  0  */
+
 int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 {
        int rv = 0;
-       int addr = BRDCFG_START;
+       int addr = NETXEN_BRDCFG_START;
        struct netxen_board_info *boardinfo;
        int index;
        u32 *ptr32;
@@ -815,40 +1029,29 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 
 /* NIU access sections */
 
-int netxen_nic_set_mtu_gb(struct netxen_port *port, int new_mtu)
+int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
 {
-       struct netxen_adapter *adapter = port->adapter;
        netxen_nic_write_w0(adapter,
-                           NETXEN_NIU_GB_MAX_FRAME_SIZE(port->portnum),
-                           new_mtu);
+                       NETXEN_NIU_GB_MAX_FRAME_SIZE(
+                               physical_port[adapter->portnum]), new_mtu);
        return 0;
 }
 
-int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu)
+int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
 {
-       struct netxen_adapter *adapter = port->adapter;
        new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
-       netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
+       if (physical_port[adapter->portnum] == 0)
+               netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
+                               new_mtu);
+       else
+               netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE,
+                               new_mtu);
        return 0;
 }
 
 void netxen_nic_init_niu_gb(struct netxen_adapter *adapter)
 {
-       int portno;
-       for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++)
-               netxen_niu_gbe_init_port(adapter, portno);
-}
-
-void netxen_nic_stop_all_ports(struct netxen_adapter *adapter)
-{
-       int port_nr;
-       struct netxen_port *port;
-
-       for (port_nr = 0; port_nr < adapter->ahw.max_ports; port_nr++) {
-               port = adapter->port[port_nr];
-               if (adapter->stop_port)
-                       adapter->stop_port(adapter, port->portnum);
-       }
+       netxen_niu_gbe_init_port(adapter, physical_port[adapter->portnum]);
 }
 
 void
@@ -867,58 +1070,57 @@ netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off,
        }
 }
 
-void netxen_nic_set_link_parameters(struct netxen_port *port)
+void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
 {
-       struct netxen_adapter *adapter = port->adapter;
-       __le32 status;
-       u16 autoneg;
-       __le32 mode;
+       __u32 status;
+       __u32 autoneg;
+       __u32 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->phy_read
                    && adapter->
-                   phy_read(adapter, port->portnum,
+                   phy_read(adapter,
                             NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
                             &status) == 0) {
                        if (netxen_get_phy_link(status)) {
                                switch (netxen_get_phy_speed(status)) {
                                case 0:
-                                       port->link_speed = SPEED_10;
+                                       adapter->link_speed = SPEED_10;
                                        break;
                                case 1:
-                                       port->link_speed = SPEED_100;
+                                       adapter->link_speed = SPEED_100;
                                        break;
                                case 2:
-                                       port->link_speed = SPEED_1000;
+                                       adapter->link_speed = SPEED_1000;
                                        break;
                                default:
-                                       port->link_speed = -1;
+                                       adapter->link_speed = -1;
                                        break;
                                }
                                switch (netxen_get_phy_duplex(status)) {
                                case 0:
-                                       port->link_duplex = DUPLEX_HALF;
+                                       adapter->link_duplex = DUPLEX_HALF;
                                        break;
                                case 1:
-                                       port->link_duplex = DUPLEX_FULL;
+                                       adapter->link_duplex = DUPLEX_FULL;
                                        break;
                                default:
-                                       port->link_duplex = -1;
+                                       adapter->link_duplex = -1;
                                        break;
                                }
                                if (adapter->phy_read
                                    && adapter->
-                                   phy_read(adapter, port->portnum,
+                                   phy_read(adapter,
                                             NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
-                                            (__le32 *) & autoneg) != 0)
-                                       port->link_autoneg = autoneg;
+                                            &autoneg) != 0)
+                                       adapter->link_autoneg = autoneg;
                        } else
                                goto link_down;
                } else {
                      link_down:
-                       port->link_speed = -1;
-                       port->link_duplex = -1;
+                       adapter->link_speed = -1;
+                       adapter->link_duplex = -1;
                }
        }
 }
@@ -930,9 +1132,9 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
        u32 fw_minor = 0;
        u32 fw_build = 0;
        char brd_name[NETXEN_MAX_SHORT_NAME];
-       struct netxen_new_user_info user_info;
-       int i, addr = USER_START;
-       u32 *ptr32;
+       char serial_num[32];
+       int i, addr;
+       __le32 *ptr32;
 
        struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
        if (board_info->magic != NETXEN_BDINFO_MAGIC) {
@@ -948,10 +1150,10 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
                valid = 0;
        }
        if (valid) {
-               ptr32 = (u32 *) & user_info;
-               for (i = 0;
-                    i < sizeof(struct netxen_new_user_info) / sizeof(u32);
-                    i++) {
+               ptr32 = (u32 *)&serial_num;
+               addr = NETXEN_USER_START +
+                      offsetof(struct netxen_new_user_info, serial_num);
+               for (i = 0; i < 8; i++) {
                        if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
                                printk("%s: ERROR reading %s board userarea.\n",
                                       netxen_nic_driver_name,
@@ -961,10 +1163,11 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
                        ptr32++;
                        addr += sizeof(u32);
                }
+
                get_brd_name_by_type(board_info->board_type, brd_name);
 
                printk("NetXen %s Board S/N %s  Chip id 0x%x\n",
-                      brd_name, user_info.serial_num, board_info->chip_id);
+                      brd_name, serial_num, board_info->chip_id);
 
                printk("NetXen %s Board #%d, Chip id 0x%x\n",
                       board_info->board_type == 0x0b ? "XGB" : "GBE",
@@ -987,7 +1190,8 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
                       _NETXEN_NIC_LINUX_MAJOR, fw_major);
                adapter->driver_mismatch = 1;
        }
-       if (fw_minor != _NETXEN_NIC_LINUX_MINOR) {
+       if (fw_minor != _NETXEN_NIC_LINUX_MINOR &&
+                       fw_minor != (_NETXEN_NIC_LINUX_MINOR + 1)) {
                printk(KERN_ERR "The mismatch in driver version and firmware "
                       "version minor number\n"
                       "Driver version minor number = %d \t"
@@ -1000,9 +1204,3 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
                       fw_major, fw_minor);
 }
 
-int netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off)
-{
-       int data;
-       netxen_nic_hw_read_wx(adapter, off, &data, 4);
-       return data;
-}