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 7195af3..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 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE
 #define NETXEN_MIN_MTU         64
 
 #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;
-       __u32 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;
@@ -178,9 +358,9 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
        void *addr;
        int loops = 0, err = 0;
        int ctx, ring;
-       u32 card_cmdring = 0;
        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));
@@ -189,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");
@@ -204,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
@@ -219,7 +394,13 @@ 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 netxen_ring_ctx) +
@@ -227,8 +408,8 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
                            (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);
+       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");
                err = -ENOMEM;
@@ -236,17 +417,20 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
        }
        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 = (uint32_t *) (((char *)addr) +
+       adapter->cmd_consumer = (__le32 *) (((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);
+       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);
 
        if (addr == NULL) {
                DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
@@ -304,11 +488,11 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
        /* Window = 1 */
 
        writel(lower32(adapter->ctx_desc_phys_addr),
-              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO));
+              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));
-       writel(NETXEN_CTX_SIGNATURE,
-              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG));
+              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;
 }
 
@@ -335,10 +519,6 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
                                    adapter->ahw.cmd_desc_phys_addr);
                adapter->ahw.cmd_desc_head = 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) {
                recv_ctx = &adapter->recv_ctx[ctx];
@@ -369,22 +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->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 (skb->nh.iph->protocol == IPPROTO_TCP) {
+               if (ip_hdr(skb)->protocol == IPPROTO_TCP) {
                        netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT);
-               } else if (skb->nh.iph->protocol == IPPROTO_UDP) {
+               } else if (ip_hdr(skb)->protocol == IPPROTO_UDP) {
                        netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT);
                } else {
                        return;
                }
        }
-       adapter->stats.xmitcsummed++;
-       desc->tcp_hdr_offset = skb->h.raw - skb->data;
-       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)
@@ -395,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) {
@@ -410,52 +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(*ptr32);
+               *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(local);
+               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;
@@ -472,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
@@ -481,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;
@@ -501,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;
 
@@ -516,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;
        }
@@ -534,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
@@ -680,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;
@@ -698,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;
@@ -723,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;
@@ -746,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;
@@ -807,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
@@ -859,9 +1070,8 @@ 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;
        __u32 status;
        __u32 autoneg;
        __u32 mode;
@@ -870,47 +1080,47 @@ void netxen_nic_set_link_parameters(struct netxen_port *port)
        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,
                                             &autoneg) != 0)
-                                       port->link_autoneg = autoneg;
+                                       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;
                }
        }
 }
@@ -922,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) {
@@ -940,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,
@@ -953,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",