Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6c80b18df3537d1221ab34555c150bccbfd90260
Commit:     6c80b18df3537d1221ab34555c150bccbfd90260
Parent:     5d512f5594f9f4829b099c87f7bc6f683ef146ca
Author:     Mithlesh Thukral <[EMAIL PROTECTED]>
AuthorDate: Fri Apr 20 07:55:26 2007 -0700
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Sat Apr 28 11:01:06 2007 -0400

    NetXen: Port swap feature for multi port cards
    
    NetXen: Port Swap feature
    This patch will allow a port numbers on the card to be swapped in
    host driver. This feature is applicable to cards having more than
    1 port.
    
    Signed-off by: Milan Bag <[EMAIL PROTECTED]>
    Signed-off by: Mithlesh Thukral <[EMAIL PROTECTED]>
    
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/net/netxen/netxen_nic.h          |   21 ++-
 drivers/net/netxen/netxen_nic_ethtool.c  |  143 ++++++++++-----
 drivers/net/netxen/netxen_nic_hdr.h      |    3 +
 drivers/net/netxen/netxen_nic_hw.c       |   67 ++------
 drivers/net/netxen/netxen_nic_hw.h       |   63 ++++++
 drivers/net/netxen/netxen_nic_init.c     |    2 +-
 drivers/net/netxen/netxen_nic_isr.c      |   29 ++--
 drivers/net/netxen/netxen_nic_main.c     |  306 ++++++++++++++++++------------
 drivers/net/netxen/netxen_nic_niu.c      |   93 ++++++---
 drivers/net/netxen/netxen_nic_phan_reg.h |    7 +
 10 files changed, 468 insertions(+), 266 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 923ae6c..1e944d5 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -205,6 +205,7 @@ enum {
 
 #define MAX_CMD_DESCRIPTORS            1024
 #define MAX_RCV_DESCRIPTORS            16384
+#define MAX_CMD_DESCRIPTORS_HOST       (MAX_CMD_DESCRIPTORS / 4)
 #define MAX_RCV_DESCRIPTORS_1G         (MAX_RCV_DESCRIPTORS / 4)
 #define MAX_JUMBO_RCV_DESCRIPTORS      1024
 #define MAX_LRO_RCV_DESCRIPTORS                64
@@ -303,6 +304,8 @@ struct netxen_ring_ctx {
 
 #define netxen_set_cmd_desc_port(cmd_desc, var)        \
        ((cmd_desc)->port_ctxid |= ((var) & 0x0F))
+#define netxen_set_cmd_desc_ctxid(cmd_desc, var)       \
+       ((cmd_desc)->port_ctxid |= ((var) & 0xF0))
 
 #define netxen_set_cmd_desc_flags(cmd_desc, val)       \
        ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x7f), \
@@ -445,7 +448,7 @@ struct status_desc {
        /* Bit pattern: 0-6 lro_count indicates frag sequence,
           7 last_frag indicates last frag */
        u8 lro;
-} __attribute__ ((aligned(8)));
+} __attribute__ ((aligned(16)));
 
 enum {
        NETXEN_RCV_PEG_0 = 0,
@@ -723,6 +726,18 @@ struct netxen_skb_frag {
        u32 length;
 };
 
+#define _netxen_set_bits(config_word, start, bits, val)        {\
+       unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start));\
+       unsigned long long __tvalue = (val);    \
+       (config_word) &= ~__tmask;      \
+       (config_word) |= (((__tvalue) << (start)) & __tmask); \
+}
+       
+#define _netxen_clear_bits(config_word, start, bits) {\
+       unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start));  \
+       (config_word) &= ~__tmask; \
+}              
+
 /*    Following defines are for the state of the buffers    */
 #define        NETXEN_BUFFER_FREE      0
 #define        NETXEN_BUFFER_BUSY      1
@@ -767,6 +782,8 @@ struct netxen_hardware_context {
        void __iomem *pci_base0;
        void __iomem *pci_base1;
        void __iomem *pci_base2;
+       unsigned long first_page_group_end;
+       unsigned long first_page_group_start;
        void __iomem *db_base;
        unsigned long db_len;
 
@@ -862,6 +879,7 @@ struct netxen_adapter {
        struct netxen_adapter *master;
        struct net_device *netdev;
        struct pci_dev *pdev;
+       struct net_device_stats net_stats;
        unsigned char mac_addr[ETH_ALEN];
        int mtu;
        int portnum;
@@ -1152,4 +1170,5 @@ extern int netxen_rom_fast_read(struct netxen_adapter 
*adapter, int addr,
 
 extern struct ethtool_ops netxen_nic_ethtool_ops;
 
+extern int physical_port[];    /* physical port # from virtual port.*/
 #endif                         /* __NETXEN_NIC_H_ */
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c 
b/drivers/net/netxen/netxen_nic_ethtool.c
index 24c68f4..16fabb3 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -40,8 +40,8 @@
 #include <linux/ethtool.h>
 #include <linux/version.h>
 
-#include "netxen_nic_hw.h"
 #include "netxen_nic.h"
+#include "netxen_nic_hw.h"
 #include "netxen_nic_phan_reg.h"
 
 struct netxen_nic_stats {
@@ -379,7 +379,7 @@ netxen_nic_get_regs(struct net_device *dev, struct 
ethtool_regs *regs, void *p)
                for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) {
                        /* GB: port specific registers */
                        if (mode == 0 && i >= 19)
-                               window = adapter->portnum * 
+                               window = physical_port[adapter->portnum] *
                                        NETXEN_NIC_PORT_WINDOW;
 
                        NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode].
@@ -537,16 +537,43 @@ netxen_nic_get_pauseparam(struct net_device *dev,
 {
        struct netxen_adapter *adapter = netdev_priv(dev);
        __u32 val;
+       int port = physical_port[adapter->portnum];
 
        if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+               if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+                       return;
                /* get flow control settings */
-               netxen_nic_read_w0(adapter,
-                                  NETXEN_NIU_GB_MAC_CONFIG_0(adapter->portnum),
-                                  &val);
+               netxen_nic_read_w0(adapter,NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                               &val);
                pause->rx_pause = netxen_gb_get_rx_flowctl(val);
-               pause->tx_pause = netxen_gb_get_tx_flowctl(val);
-               /* get autoneg settings */
-               pause->autoneg = adapter->link_autoneg;
+               netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
+               switch (port) {
+                       case 0:
+                               pause->tx_pause = 
!(netxen_gb_get_gb0_mask(val));
+                               break;
+                       case 1:
+                               pause->tx_pause = 
!(netxen_gb_get_gb1_mask(val));
+                               break;
+                       case 2:
+                               pause->tx_pause = 
!(netxen_gb_get_gb2_mask(val));
+                               break;
+                       case 3:
+                       default:
+                               pause->tx_pause = 
!(netxen_gb_get_gb3_mask(val));
+                               break;
+               }
+       } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+               if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
+                       return;
+               pause->rx_pause = 1;
+               netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
+               if (port == 0)
+                       pause->tx_pause = !(netxen_xg_get_xg0_mask(val));
+               else
+                       pause->tx_pause = !(netxen_xg_get_xg1_mask(val));
+       } else {
+               printk(KERN_ERR"%s: Unknown board type: %x\n", 
+                               netxen_nic_driver_name, 
adapter->ahw.board_type);
        }
 }
 
@@ -556,39 +583,74 @@ netxen_nic_set_pauseparam(struct net_device *dev,
 {
        struct netxen_adapter *adapter = netdev_priv(dev);
        __u32 val;
-       unsigned int autoneg;
-
+       int port = physical_port[adapter->portnum];
        /* read mode */
        if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+               if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+                       return -EIO;
                /* set flow control */
                netxen_nic_read_w0(adapter,
-                                  NETXEN_NIU_GB_MAC_CONFIG_0(adapter->portnum),
-                                  (u32 *) & val);
-               if (pause->tx_pause)
-                       netxen_gb_tx_flowctl(val);
-               else
-                       netxen_gb_unset_tx_flowctl(val);
+                                       NETXEN_NIU_GB_MAC_CONFIG_0(port), &val);
+               
                if (pause->rx_pause)
                        netxen_gb_rx_flowctl(val);
                else
                        netxen_gb_unset_rx_flowctl(val);
 
-               netxen_nic_write_w0(adapter,
-                                   
NETXEN_NIU_GB_MAC_CONFIG_0(adapter->portnum),
-                                   *&val);
+               netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                               val);
                /* set autoneg */
-               autoneg = pause->autoneg;
-               if (adapter->phy_write
-                   && adapter->phy_write(adapter,
-                                         NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
-                                         autoneg) != 0)
+               netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
+               switch (port) {
+                       case 0:
+                               if (pause->tx_pause)
+                                       netxen_gb_unset_gb0_mask(val);
+                               else
+                                       netxen_gb_set_gb0_mask(val);
+                               break;
+                       case 1:
+                               if (pause->tx_pause)
+                                       netxen_gb_unset_gb1_mask(val);
+                               else
+                                       netxen_gb_set_gb1_mask(val);
+                               break;
+                       case 2:
+                               if (pause->tx_pause)
+                                       netxen_gb_unset_gb2_mask(val);
+                               else
+                                       netxen_gb_set_gb2_mask(val);
+                               break;
+                       case 3:
+                       default:
+                               if (pause->tx_pause)
+                                       netxen_gb_unset_gb3_mask(val);
+                               else
+                                       netxen_gb_set_gb3_mask(val);
+                               break;
+               }
+               netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
+       } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+               if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
                        return -EIO;
-               else {
-                       adapter->link_autoneg = pause->autoneg;
-                       return 0;
+               netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
+               if (port == 0) {
+                       if (pause->tx_pause)
+                               netxen_xg_unset_xg0_mask(val);
+                       else
+                               netxen_xg_set_xg0_mask(val);
+               } else {
+                       if (pause->tx_pause)
+                               netxen_xg_unset_xg1_mask(val);
+                       else
+                               netxen_xg_set_xg1_mask(val);
                }
-       } else
-               return -EOPNOTSUPP;
+               netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);     
                
+       } else {
+               printk(KERN_ERR "%s: Unknown board type: %x\n",
+                               netxen_nic_driver_name, 
+                               adapter->ahw.board_type);
+       }
+       return 0;
 }
 
 static int netxen_nic_reg_test(struct net_device *dev)
@@ -619,23 +681,12 @@ static void
 netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
                     u64 * data)
 {
-       if (eth_test->flags == ETH_TEST_FL_OFFLINE) {   /* offline tests */
-               /* link test */
-               if ((data[1] = (u64) netxen_nic_test_link(dev)))
-                       eth_test->flags |= ETH_TEST_FL_FAILED;
-
-               /* register tests */
-               if ((data[0] = netxen_nic_reg_test(dev)))
-                       eth_test->flags |= ETH_TEST_FL_FAILED;
-       } else {                /* online tests */
-               /* register tests */
-               if((data[0] = netxen_nic_reg_test(dev)))
-                       eth_test->flags |= ETH_TEST_FL_FAILED;
-
-               /* link test */
-               if ((data[1] = (u64) netxen_nic_test_link(dev)))
-                       eth_test->flags |= ETH_TEST_FL_FAILED;
-       }
+       memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN);
+       if ((data[0] = netxen_nic_reg_test(dev)))
+               eth_test->flags |= ETH_TEST_FL_FAILED;
+       /* link test */
+       if ((data[1] = (u64) netxen_nic_test_link(dev)))
+               eth_test->flags |= ETH_TEST_FL_FAILED;
 }
 
 static void
diff --git a/drivers/net/netxen/netxen_nic_hdr.h 
b/drivers/net/netxen/netxen_nic_hdr.h
index b826bca..608e37b 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -467,6 +467,8 @@ enum {
 #define NETXEN_PCI_OCM1                (0x05100000UL)
 #define NETXEN_PCI_OCM1_MAX    (0x051fffffUL)
 #define NETXEN_PCI_CRBSPACE    (0x06000000UL)
+#define NETXEN_PCI_128MB_SIZE  (0x08000000UL)
+#define NETXEN_PCI_32MB_SIZE   (0x02000000UL)
 
 #define NETXEN_CRB_CAM NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_CAM)
 
@@ -528,6 +530,7 @@ enum {
 #define        NETXEN_NIU_XG_PAUSE_CTL         (NETXEN_CRB_NIU + 0x00098)
 #define        NETXEN_NIU_XG_PAUSE_LEVEL       (NETXEN_CRB_NIU + 0x000dc)
 #define        NETXEN_NIU_XG_SEL               (NETXEN_CRB_NIU + 0x00128)
+#define NETXEN_NIU_GB_PAUSE_CTL                (NETXEN_CRB_NIU + 0x0030c)
 
 #define NETXEN_NIU_FULL_LEVEL_XG       (NETXEN_CRB_NIU + 0x00450)
 
diff --git a/drivers/net/netxen/netxen_nic_hw.c 
b/drivers/net/netxen/netxen_nic_hw.c
index 74517b6..3f4853f 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -145,7 +145,7 @@ struct netxen_recv_crb recv_crb_registers[] = {
         NETXEN_NIC_REG(0x184),
         },
        /*
-        * Instance 3,
+        * Instance 2,
         */
        {
          {
@@ -194,7 +194,7 @@ struct netxen_recv_crb recv_crb_registers[] = {
          NETXEN_NIC_REG(0x228),
        },
        /*
-        * Instance 4,
+        * Instance 3,
         */
        {
          {
@@ -310,7 +310,6 @@ void netxen_nic_set_multi(struct net_device *netdev)
 {
        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) {
@@ -318,43 +317,10 @@ void netxen_nic_set_multi(struct net_device *netdev)
                        adapter->set_promisc(adapter,
                                             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,
                                               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));
 }
 
 /*
@@ -390,7 +356,6 @@ 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;
@@ -402,11 +367,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");
@@ -449,7 +409,7 @@ 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 = adapter->portnum;
+       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));
@@ -551,10 +511,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];
@@ -735,7 +691,10 @@ 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)
@@ -1055,18 +1014,18 @@ int netxen_nic_get_board_info(struct netxen_adapter 
*adapter)
 int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
 {
        netxen_nic_write_w0(adapter,
-                           NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->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_adapter *adapter, int new_mtu)
 {
        new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
-       if (adapter->portnum == 0)
+       if (physical_port[adapter->portnum] == 0)
                netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, 
                                new_mtu);
-       else if (adapter->portnum == 1)
+       else 
                netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE,
                                new_mtu);
        return 0;
@@ -1074,7 +1033,7 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter 
*adapter, int new_mtu)
 
 void netxen_nic_init_niu_gb(struct netxen_adapter *adapter)
 {
-       netxen_niu_gbe_init_port(adapter, adapter->portnum);
+       netxen_niu_gbe_init_port(adapter, physical_port[adapter->portnum]);
 }
 
 void
diff --git a/drivers/net/netxen/netxen_nic_hw.h 
b/drivers/net/netxen/netxen_nic_hw.h
index 94459cf..245bf13 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -220,6 +220,69 @@ typedef enum {
                _netxen_crb_get_bit(config_word, 1)
 #define netxen_get_gb_mii_mgmt_notvalid(config_word)   \
                _netxen_crb_get_bit(config_word, 2)
+/*
+ * NIU XG Pause Ctl Register
+ *
+ *      Bit 0       : xg0_mask => 1:disable tx pause frames
+ *      Bit 1       : xg0_request => 1:request single pause frame
+ *      Bit 2       : xg0_on_off => 1:request is pause on, 0:off
+ *      Bit 3       : xg1_mask => 1:disable tx pause frames
+ *      Bit 4       : xg1_request => 1:request single pause frame
+ *      Bit 5       : xg1_on_off => 1:request is pause on, 0:off
+ */
+
+#define netxen_xg_set_xg0_mask(config_word)    \
+       ((config_word) |= 1 << 0)
+#define netxen_xg_set_xg1_mask(config_word)    \
+       ((config_word) |= 1 << 3)
+               
+#define netxen_xg_get_xg0_mask(config_word)    \
+       _netxen_crb_get_bit((config_word), 0)
+#define netxen_xg_get_xg1_mask(config_word)    \
+       _netxen_crb_get_bit((config_word), 3)
+
+#define netxen_xg_unset_xg0_mask(config_word)  \
+       ((config_word) &= ~(1 << 0))
+#define netxen_xg_unset_xg1_mask(config_word)  \
+       ((config_word) &= ~(1 << 3))
+
+/*
+ * NIU XG Pause Ctl Register
+ *
+ *      Bit 0       : xg0_mask => 1:disable tx pause frames
+ *      Bit 1       : xg0_request => 1:request single pause frame
+ *      Bit 2       : xg0_on_off => 1:request is pause on, 0:off
+ *      Bit 3       : xg1_mask => 1:disable tx pause frames
+ *      Bit 4       : xg1_request => 1:request single pause frame
+ *      Bit 5       : xg1_on_off => 1:request is pause on, 0:off
+ */
+#define netxen_gb_set_gb0_mask(config_word)    \
+       ((config_word) |= 1 << 0)
+#define netxen_gb_set_gb1_mask(config_word)    \
+       ((config_word) |= 1 << 2)
+#define netxen_gb_set_gb2_mask(config_word)    \
+       ((config_word) |= 1 << 4)
+#define netxen_gb_set_gb3_mask(config_word)    \
+       ((config_word) |= 1 << 6)
+
+#define netxen_gb_get_gb0_mask(config_word)    \
+       _netxen_crb_get_bit((config_word), 0)
+#define netxen_gb_get_gb1_mask(config_word)    \
+       _netxen_crb_get_bit((config_word), 2)
+#define netxen_gb_get_gb2_mask(config_word)    \
+       _netxen_crb_get_bit((config_word), 4)
+#define netxen_gb_get_gb3_mask(config_word)    \
+       _netxen_crb_get_bit((config_word), 6)
+       
+#define netxen_gb_unset_gb0_mask(config_word)  \
+       ((config_word) &= ~(1 << 0))
+#define netxen_gb_unset_gb1_mask(config_word)  \
+       ((config_word) &= ~(1 << 2))
+#define netxen_gb_unset_gb2_mask(config_word)  \
+       ((config_word) &= ~(1 << 4))
+#define netxen_gb_unset_gb3_mask(config_word)  \
+       ((config_word) &= ~(1 << 6))
+
 
 /*
  * PHY-Specific MII control/status registers.
diff --git a/drivers/net/netxen/netxen_nic_init.c 
b/drivers/net/netxen/netxen_nic_init.c
index 2a3a91d..3cd7e35 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -1033,7 +1033,7 @@ void netxen_watchdog_task(struct work_struct *work)
        struct netxen_adapter *adapter =
                container_of(work, struct netxen_adapter, watchdog_task);
 
-       if (netxen_nic_check_temp(adapter))
+       if ((adapter->portnum  == 0) && netxen_nic_check_temp(adapter))
                return;
 
        netdev = adapter->netdev;
diff --git a/drivers/net/netxen/netxen_nic_isr.c 
b/drivers/net/netxen/netxen_nic_isr.c
index 8510216..b213b06 100644
--- a/drivers/net/netxen/netxen_nic_isr.c
+++ b/drivers/net/netxen/netxen_nic_isr.c
@@ -34,38 +34,38 @@
 #include "netxen_nic_hw.h"
 #include "netxen_nic_phan_reg.h"
 
-#if 0
 /*
  * netxen_nic_get_stats - Get System Network Statistics
  * @netdev: network interface device structure
  */
 struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
 {
-       struct netxen_port *port = netdev_priv(netdev);
+       struct netxen_adapter *adapter = netdev_priv(netdev);
        struct net_device_stats *stats = &adapter->net_stats;
 
        memset(stats, 0, sizeof(*stats));
 
        /* total packets received   */
-       stats->rx_packets = port->stats.no_rcv;
+       stats->rx_packets = adapter->stats.no_rcv;
        /* total packets transmitted    */
-       stats->tx_packets = port->stats.xmitedframes + port->stats.xmitfinished;
+       stats->tx_packets = adapter->stats.xmitedframes + 
+               adapter->stats.xmitfinished;
        /* total bytes received     */
-       stats->rx_bytes = port->stats.rxbytes;
+       stats->rx_bytes = adapter->stats.rxbytes;
        /* total bytes transmitted  */
-       stats->tx_bytes = port->stats.txbytes;
+       stats->tx_bytes = adapter->stats.txbytes;
        /* bad packets received     */
-       stats->rx_errors = port->stats.rcvdbadskb;
+       stats->rx_errors = adapter->stats.rcvdbadskb;
        /* packet transmit problems */
-       stats->tx_errors = port->stats.nocmddescriptor;
+       stats->tx_errors = adapter->stats.nocmddescriptor;
        /* no space in linux buffers    */
-       stats->rx_dropped = port->stats.updropped;
+       stats->rx_dropped = adapter->stats.updropped;
        /* no space available in linux  */
-       stats->tx_dropped = port->stats.txdropped;
+       stats->tx_dropped = adapter->stats.txdropped;
 
        return stats;
 }
-#endif
+
 void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link)
 {
        struct net_device *netdev = adapter->netdev;
@@ -116,9 +116,6 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, 
u32 enable)
                                         &status) == 0) {
                        if (netxen_get_phy_int_link_status_changed(int_src)) {
                                if (netxen_get_phy_link(status)) {
-                                       netxen_niu_gbe_init_port(
-                                                       adapter, 
-                                                       adapter->portnum);
                                        printk(KERN_INFO "%s: %s Link UP\n",
                                               netxen_nic_driver_name,
                                               adapter->netdev->name);
@@ -145,7 +142,7 @@ void netxen_nic_isr_other(struct netxen_adapter *adapter)
 
        /* verify the offset */
        val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
-       val = val >> adapter->portnum;
+       val = val >> physical_port[adapter->portnum];
        if (val == adapter->ahw.qg_linksup)
                return;
 
@@ -179,7 +176,7 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter 
*adapter)
 
        /* WINDOW = 1 */
        val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
-       val >>= (adapter->portnum * 8);
+       val >>= (physical_port[adapter->portnum] * 8);
        val1 = val & 0xff;
 
        if (adapter->ahw.xg_linkup == 1 && val1 != XG_LINK_UP) {
diff --git a/drivers/net/netxen/netxen_nic_main.c 
b/drivers/net/netxen/netxen_nic_main.c
index 137fb57..4e32bb6 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -76,6 +76,8 @@ static void netxen_nic_poll_controller(struct net_device 
*netdev);
 #endif
 static irqreturn_t netxen_intr(int irq, void *data);
 
+int physical_port[] = {0, 1, 2, 3};
+
 /*  PCI Device ID Table  */
 static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
        {PCI_DEVICE(0x4040, 0x0001)},
@@ -174,6 +176,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
        void __iomem *mem_ptr0 = NULL;
        void __iomem *mem_ptr1 = NULL;
        void __iomem *mem_ptr2 = NULL;
+       unsigned long first_page_group_end;
+       unsigned long first_page_group_start;
+
 
        u8 __iomem *db_ptr = NULL;
        unsigned long mem_base, mem_len, db_base, db_len;
@@ -183,11 +188,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
        struct netxen_rcv_desc_ctx *rcv_desc = NULL;
        struct netxen_cmd_buffer *cmd_buf_arr = NULL;
        u64 mac_addr[FLASH_NUM_PORTS + 1];
-       static int valid_mac = 0;
-       static int netxen_probe_flag;
+       int valid_mac = 0;
+       u32 val;
        int pci_func_id = PCI_FUNC(pdev->devfn);
 
        printk(KERN_INFO "%s \n", netxen_nic_driver_string);
+
        if (pdev->class != 0x020000) {
                printk(KERN_ERR"NetXen function %d, class %x will not"
                                "be enabled.\n",pci_func_id, pdev->class);
@@ -234,19 +240,35 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 
        adapter->ahw.pdev = pdev;
        adapter->ahw.pci_func  = pci_func_id;
+       spin_lock_init(&adapter->tx_lock);
+       spin_lock_init(&adapter->lock);
 
        /* remap phys address */
        mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */
        mem_len = pci_resource_len(pdev, 0);
 
        /* 128 Meg of memory */
-       mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
-       mem_ptr1 =
-           ioremap(mem_base + SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_SIZE);
-       mem_ptr2 =
-           ioremap(mem_base + THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
+       if (mem_len == NETXEN_PCI_128MB_SIZE) {
+               mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
+               mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START,
+                               SECOND_PAGE_GROUP_SIZE);
+               mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
+                               THIRD_PAGE_GROUP_SIZE);
+               first_page_group_start = FIRST_PAGE_GROUP_START;
+               first_page_group_end   = FIRST_PAGE_GROUP_END;
+       } else if (mem_len == NETXEN_PCI_32MB_SIZE) {
+               mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
+               mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
+                       SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
+               first_page_group_start = 0;
+               first_page_group_end   = 0;
+       } else {
+               err = -EIO; 
+               goto err_out_free_netdev;
+       }
 
-       if ((mem_ptr0 == 0UL) || (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) {
+       if (((mem_ptr0 == 0UL) && (mem_len == NETXEN_PCI_128MB_SIZE)) ||
+                       (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) {
                DPRINTK(ERR,
                        "Cannot remap adapter memory aborting.:"
                        "0 -> %p, 1 -> %p, 2 -> %p\n",
@@ -276,17 +298,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
        }
        DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr);
 
-       adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS;
-       if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) ||
-                       (adapter->ahw.boardcfg.board_type == 
-                        NETXEN_BRDTYPE_P2_SB31_2G)) 
-               adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
-       else
-               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, netdev);
+       adapter->ahw.pci_base0 = mem_ptr0;
+       adapter->ahw.first_page_group_start = first_page_group_start;
+       adapter->ahw.first_page_group_end   = first_page_group_end;
+       adapter->ahw.pci_base1 = mem_ptr1;
+       adapter->ahw.pci_base2 = mem_ptr2;
+       adapter->ahw.db_base = db_ptr;
+       adapter->ahw.db_len = db_len;
 
        adapter->netdev  = netdev;
        adapter->pdev    = pdev;
@@ -295,6 +313,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
        netdev->open               = netxen_nic_open;
        netdev->stop               = netxen_nic_close;
        netdev->hard_start_xmit    = netxen_nic_xmit_frame;
+       netdev->get_stats          = netxen_nic_get_stats;      
        netdev->set_multicast_list = netxen_nic_set_multi;
        netdev->set_mac_address    = netxen_nic_set_mac;
        netdev->change_mtu         = netxen_nic_change_mtu;
@@ -324,6 +343,42 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
        } else
                adapter->flags |= NETXEN_NIC_MSI_ENABLED;
 
+       netdev->irq = pdev->irq;
+       INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
+
+       /*
+        * 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.
+        */
+       adapter->curr_window = 255;
+
+       /* initialize the adapter */
+       netxen_initialize_adapter_hw(adapter);
+
+#ifdef CONFIG_PPC
+       if ((adapter->ahw.boardcfg.board_type ==
+               NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) &&
+                       (pci_func_id == 2))
+                   goto err_out_free_adapter;
+#endif /* CONFIG_PPC */
+
+       /*
+        *  Adapter in our case is quad port so initialize it before
+        *  initializing the ports
+        */
+
+       netxen_initialize_adapter_ops(adapter);
+
+       adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST;
+       if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) ||
+                       (adapter->ahw.boardcfg.board_type == 
+                        NETXEN_BRDTYPE_P2_SB31_2G)) 
+               adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
+       else
+               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;
+
        cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
        if (cmd_buf_arr == NULL) {
                printk(KERN_ERR
@@ -333,6 +388,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
                goto err_out_free_adapter;
        }
        memset(cmd_buf_arr, 0, TX_RINGSIZE);
+       adapter->cmd_buf_arr = cmd_buf_arr;
 
        for (i = 0; i < MAX_RCV_CTX; ++i) {
                recv_ctx = &adapter->recv_ctx[i];
@@ -380,23 +436,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 
        }
 
-       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);
-       /* initialize the adapter */
-       netxen_initialize_adapter_hw(adapter);
-
-       netxen_initialize_adapter_ops(adapter);
-
        netxen_initialize_adapter_sw(adapter);  /* initialize the buffers in 
adapter */
+
        /* Mezz cards have PCI function 0,2,3 enabled */
-       if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ)
-               if (pci_func_id >= 2)
+       if ((adapter->ahw.boardcfg.board_type == 
NETXEN_BRDTYPE_P2_SB31_10G_IMEZ)
+               && (pci_func_id >= 2))
                        adapter->portnum = pci_func_id - 2;
 
 #ifdef CONFIG_IA64
@@ -407,16 +451,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
        }
 #endif
 
-       /*
-        * 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.
-        */
-       adapter->curr_window = 255;
-       /*
-        *  Adapter in our case is quad port so initialize it before
-        *  initializing the ports
-        */
-
        init_timer(&adapter->watchdog_timer);
        adapter->ahw.xg_linkup = 0;
        adapter->watchdog_timer.function = &netxen_watchdog;
@@ -426,8 +460,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
        adapter->proc_cmd_buf_counter = 0;
        adapter->ahw.revision_id = nx_p2_id;
 
+       /* make sure Window == 1 */
+       netxen_nic_pci_change_crbwindow(adapter, 1);
+
        netxen_nic_update_cmd_producer(adapter, 0);
        netxen_nic_update_cmd_consumer(adapter, 0);
+       writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
 
        if (netxen_is_flash_supported(adapter) == 0 &&
            netxen_get_flash_mac_addr(adapter, mac_addr) == 0)
@@ -463,20 +501,41 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
                }
        }
 
-       /*
-        * Initialize all the CRB registers here.
-        */
-       writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET));
-       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 */
-       if (adapter->portnum == 0)
+       if (adapter->portnum == 0) {
                err = netxen_initialize_adapter_offload(adapter);
-       if (err) 
-               goto err_out_free_dev;
+               if (err) 
+                       goto err_out_free_rx_buffer;
+               val = readl(NETXEN_CRB_NORMALIZE(adapter, 
+                                       NETXEN_CAM_RAM(0x1fc)));
+               if (val == 0x55555555) {
+                   /* This is the first boot after power up */
+                   val = readl(NETXEN_CRB_NORMALIZE(adapter,
+                                       NETXEN_ROMUSB_GLB_SW_RESET));
+                   printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val);
+                   if (val != 0x80000f) {
+                       /* clear the register for future unloads/loads */
+                       writel(0, NETXEN_CRB_NORMALIZE(adapter,
+                                               NETXEN_CAM_RAM(0x1fc)));
+                       printk(KERN_ERR "ERROR in NetXen HW init sequence.\n");
+                       err = -ENODEV;
+                       goto err_out_free_dev;
+                   }
+
+                   /* clear the register for future unloads/loads */
+                   writel(0, NETXEN_CRB_NORMALIZE(adapter, 
+                                           NETXEN_CAM_RAM(0x1fc)));
+               }
+               printk(KERN_INFO "State: 0x%0x\n",
+                       readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));
+
+               /*
+                * Tell the hardware our version number.
+                */
+               i = (_NETXEN_NIC_LINUX_MAJOR << 16) 
+                       | ((_NETXEN_NIC_LINUX_MINOR << 8))
+                       | (_NETXEN_NIC_LINUX_SUBVERSION);
+               writel(i, NETXEN_CRB_NORMALIZE(adapter, CRB_DRIVER_VERSION));
 
-       if (netxen_probe_flag == 0) {
                /* Unlock the HW, prompting the boot sequence */
                writel(1,
                        NETXEN_CRB_NORMALIZE(adapter,
@@ -485,26 +544,25 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
                netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
        }
 
-       if(netxen_probe_flag == 0) {
-               writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
-               netxen_pinit_from_rom(adapter, 0);
-               udelay(500);
-               netxen_load_firmware(adapter);
-               netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
-       }
        /*
-        * delay a while to ensure that the Pegs are up & running.
-        * Otherwise, we might see some flaky behaviour.
+        * See if the firmware gave us a virtual-physical port mapping.
         */
-       udelay(100);
-       INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
-       netxen_nic_erase_pxe(adapter);
+       i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum)));
+       if (i != 0x55555555)
+               physical_port[adapter->portnum] = i;
+
        netif_carrier_off(netdev);
        netif_stop_queue(netdev);
 
-       if((err = register_netdev(netdev)))
-               DPRINTK(1, ERR, "register_netdev failed port #%d"
-                               " aborting\n", i+1);
+       if ((err = register_netdev(netdev))) {
+               printk(KERN_ERR "%s: register_netdev failed port #%d"
+                              " aborting\n", netxen_nic_driver_name,
+                              adapter->portnum);
+               err = -EIO;
+               goto err_out_free_dev;
+       }
+
+       pci_set_drvdata(pdev, adapter);
 
        switch (adapter->ahw.board_type) {
                case NETXEN_NIC_GBE:
@@ -519,21 +577,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
        }
 
        adapter->driver_mismatch = 0;
-       if(netxen_probe_flag == 0)
-               netxen_probe_flag ++;
 
        return 0;
 
-      err_out_free_dev:
-       if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
-               pci_disable_msi(pdev);
-
-       unregister_netdev(adapter->netdev);
-       free_netdev(adapter->netdev);
-
-       netxen_free_adapter_offload(adapter);
+err_out_free_dev:
+       if (adapter->portnum == 0)
+               netxen_free_adapter_offload(adapter);
 
-      err_out_free_rx_buffer:
+err_out_free_rx_buffer:
        for (i = 0; i < MAX_RCV_CTX; ++i) {
                recv_ctx = &adapter->recv_ctx[i];
                for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
@@ -546,14 +597,16 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
        }
        vfree(cmd_buf_arr);
 
-      err_out_free_adapter:
+err_out_free_adapter:
+       if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
+               pci_disable_msi(pdev);
+
        pci_set_drvdata(pdev, NULL);
-       kfree(adapter);
 
        if (db_ptr)
                iounmap(db_ptr);
 
-      err_out_iounmap:
+err_out_iounmap:
        if (mem_ptr0)
                iounmap(mem_ptr0);
        if (mem_ptr1)
@@ -561,9 +614,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
        if (mem_ptr2)
                iounmap(mem_ptr2);
 
-      err_out_free_res:
+err_out_free_netdev:
+       free_netdev(netdev);
+
+err_out_free_res:
        pci_release_regions(pdev);
-      err_out_disable_pdev:
+
+err_out_disable_pdev:
        pci_disable_device(pdev);
        return err;
 }
@@ -578,36 +635,39 @@ static void __devexit netxen_nic_remove(struct pci_dev 
*pdev)
        int i;
        int ctxid, ring;
 
-       netdev = pci_get_drvdata(pdev);
-       adapter = netdev_priv(netdev);
+       adapter = pci_get_drvdata(pdev);
        if (adapter == NULL)
                return;
 
+       netdev = adapter->netdev;
+
+       netxen_nic_disable_int(adapter);
+       if (adapter->irq)
+               free_irq(adapter->irq, adapter);
+       
        if (adapter->stop_port)
                adapter->stop_port(adapter);
 
+       if ((adapter->flags & NETXEN_NIC_MSI_ENABLED))
+               pci_disable_msi(pdev);
+
+       if (adapter->portnum == 0)
+               netxen_free_adapter_offload(adapter);
+
        if (adapter->irq)
                free_irq(adapter->irq, adapter);
        if(adapter->portnum == 0) {
                /* leave the hw in the same state as reboot */
                writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
                netxen_pinit_from_rom(adapter, 0);
+               udelay(500);
                netxen_load_firmware(adapter);
-               netxen_free_adapter_offload(adapter);
+               netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
        }
 
-       udelay(500);
-
-       if ((adapter->flags & NETXEN_NIC_MSI_ENABLED))
-               pci_disable_msi(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);
-
        for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
                recv_ctx = &adapter->recv_ctx[ctxid];
                for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
@@ -626,14 +686,20 @@ static void __devexit netxen_nic_remove(struct pci_dev 
*pdev)
                }
        }
 
-       vfree(adapter->cmd_buf_arr);
        unregister_netdev(netdev);
-       free_netdev(netdev);
+
+       vfree(adapter->cmd_buf_arr);
+
+       iounmap(adapter->ahw.db_base);
+       iounmap(adapter->ahw.pci_base0);
+       iounmap(adapter->ahw.pci_base1);
+       iounmap(adapter->ahw.pci_base2);
 
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
 
+       free_netdev(netdev);
 }
 
 /*
@@ -668,9 +734,9 @@ static int netxen_nic_open(struct net_device *netdev)
                                netxen_post_rx_buffers(adapter, ctx, ring);
                }
                adapter->irq = adapter->ahw.pdev->irq;
-               err = request_irq(adapter->ahw.pdev->irq, &netxen_intr,
-                                 IRQF_SHARED | IRQF_SAMPLE_RANDOM,
-                                 netdev->name, adapter);
+               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);
                        netxen_free_hw_resources(adapter);
@@ -690,10 +756,9 @@ static int netxen_nic_open(struct net_device *netdev)
                adapter->macaddr_set(adapter, netdev->dev_addr);
        if (adapter->init_port
            && adapter->init_port(adapter, adapter->portnum) != 0) {
+           del_timer_sync(&adapter->watchdog_timer);
                printk(KERN_ERR "%s: Failed to initialize port %d\n",
                                netxen_nic_driver_name, adapter->portnum);
-               free_irq(adapter->irq, adapter);
-               netxen_free_hw_resources(adapter);
                return -EIO;
        }
 
@@ -722,10 +787,6 @@ static int netxen_nic_close(struct net_device *netdev)
        netif_carrier_off(netdev);
        netif_stop_queue(netdev);
 
-       netxen_nic_disable_int(adapter);
-       if (adapter->irq)
-               free_irq(adapter->irq, adapter);
-       
        cmd_buff = adapter->cmd_buf_arr;
        for (i = 0; i < adapter->max_tx_desc_count; i++) {
                buffrag = cmd_buff->frag_array;
@@ -879,6 +940,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, 
struct net_device *netdev)
        netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT);
 
        netxen_set_cmd_desc_port(hwdesc, adapter->portnum);
+       netxen_set_cmd_desc_ctxid(hwdesc, adapter->portnum);
        hwdesc->buffer1_length = cpu_to_le16(first_seg_len);
        hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
 
@@ -968,9 +1030,18 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, 
struct net_device *netdev)
                        producer = get_next_index(producer, max_tx_desc_count);
                }
        }
+
+       i = netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]);
+
+       hw->cmd_desc_head[saved_producer].flags_opcode =
+               cpu_to_le16(hw->cmd_desc_head[saved_producer].flags_opcode);
+       hw->cmd_desc_head[saved_producer].num_of_buffers_total_length =
+         cpu_to_le32(hw->cmd_desc_head[saved_producer].
+                         num_of_buffers_total_length);
+
        spin_lock_bh(&adapter->tx_lock);
-       adapter->stats.txbytes +=
-           netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]);
+       adapter->stats.txbytes += i;
+
        /* Code to update the adapter considering how many producer threads
           are currently working */
        if ((--adapter->num_threads) == 0) {
@@ -1010,18 +1081,17 @@ static void netxen_tx_timeout_task(struct work_struct 
*work)
 {
        struct netxen_adapter *adapter = 
                container_of(work, struct netxen_adapter, tx_timeout_task);
-       struct net_device *netdev = adapter->netdev;
        unsigned long flags;
 
        printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
-              netxen_nic_driver_name, netdev->name);
+              netxen_nic_driver_name, adapter->netdev->name);
 
        spin_lock_irqsave(&adapter->lock, flags);
-       netxen_nic_close(netdev);
-       netxen_nic_open(netdev);
+       netxen_nic_close(adapter->netdev);
+       netxen_nic_open(adapter->netdev);
        spin_unlock_irqrestore(&adapter->lock, flags);
-       netdev->trans_start = jiffies;
-       netif_wake_queue(netdev);
+       adapter->netdev->trans_start = jiffies;
+       netif_wake_queue(adapter->netdev);
 }
 
 static int
diff --git a/drivers/net/netxen/netxen_nic_niu.c 
b/drivers/net/netxen/netxen_nic_niu.c
index ad2486f..cef90a7 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -94,7 +94,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, 
long reg,
        long timeout = 0;
        long result = 0;
        long restore = 0;
-       long phy = adapter->portnum;
+       long phy = physical_port[adapter->portnum];
        __u32 address;
        __u32 command;
        __u32 status;
@@ -190,7 +190,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter 
*adapter, long reg,
        long timeout = 0;
        long result = 0;
        long restore = 0;
-       long phy = adapter->portnum;
+       long phy = physical_port[adapter->portnum];
        __u32 address;
        __u32 command;
        __u32 status;
@@ -454,16 +454,18 @@ int netxen_niu_gbe_init_port(struct netxen_adapter 
*adapter, int port)
 
 int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
 {
-       u32 ret = 0;
-       int portnum = adapter->portnum;
-               netxen_crb_writelit_adapter(adapter, 
-                               NETXEN_NIU_XGE_CONFIG_1 +(0x10000 * portnum),
-                               0x1447);
-               netxen_crb_writelit_adapter(adapter,
-                           NETXEN_NIU_XG1_CONFIG_1 + 
-                           (0x10000 * portnum), 0x5);
+       u32 reg;
+       u32 portnum = physical_port[adapter->portnum];
+
+       netxen_crb_writelit_adapter(adapter,
+               NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5);
+       netxen_nic_hw_read_wx(adapter,
+               NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), &reg, 4);
+       reg = (reg & ~0x2000UL);
+       netxen_crb_writelit_adapter(adapter,
+               NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), reg);
 
-       return ret;
+       return 0;
 }
 
 /* 
@@ -571,7 +573,7 @@ int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
 {
        u32 stationhigh;
        u32 stationlow;
-       int phy = adapter->portnum;
+       int phy = physical_port[adapter->portnum];
        u8 val[8];
 
        if (addr == NULL)
@@ -602,7 +604,7 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
 {
        u8 temp[4];
        u32 val;
-       int phy = adapter->portnum;
+       int phy = physical_port[adapter->portnum];
        unsigned char mac_addr[6];
        int i;
 
@@ -724,8 +726,10 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter 
*adapter,
 int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
 {
        __u32 mac_cfg0;
-       int port = adapter->portnum;
+       u32 port = physical_port[adapter->portnum];
 
+       if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+               return -EINVAL;
        mac_cfg0 = 0;
        netxen_gb_soft_reset(mac_cfg0);
        if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
@@ -738,7 +742,10 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter 
*adapter)
 int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
 {
        __u32 mac_cfg;
+       u32 port = physical_port[adapter->portnum];
 
+       if (port != 0)
+               return -EINVAL;
        mac_cfg = 0;
        netxen_xg_soft_reset(mac_cfg);
        if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_CONFIG_0,
@@ -752,7 +759,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter 
*adapter,
                                    netxen_niu_prom_mode_t mode)
 {
        __u32 reg;
-       int port = adapter->portnum;
+       u32 port = physical_port[adapter->portnum];
 
        if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
                return -EINVAL;
@@ -809,21 +816,47 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter 
*adapter,
 int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
                              netxen_ethernet_macaddr_t addr)
 {
+       int phy = physical_port[adapter->portnum];
        u8 temp[4];
        u32 val;
 
+       if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS))
+               return -EIO;
+
        temp[0] = temp[1] = 0;
-       memcpy(temp + 2, addr, 2);
-       val = le32_to_cpu(*(__le32 *)temp);
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
-                                  &val, 4))
+       switch (phy) {
+       case 0:
+           memcpy(temp + 2, addr, 2);
+           val = le32_to_cpu(*(__le32 *)temp);
+           if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
+                               &val, 4))
                return -EIO;
 
-       memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
-       val = le32_to_cpu(*(__le32 *)temp);
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
-                                  &val, 4))
+           memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
+           val = le32_to_cpu(*(__le32 *)temp);
+           if (netxen_nic_hw_write_wx(adapter, 
NETXEN_NIU_XGE_STATION_ADDR_0_HI,
+                               &val, 4))
+               return -EIO;
+           break;
+
+       case 1:
+           memcpy(temp + 2, addr, 2);
+           val = le32_to_cpu(*(__le32 *)temp);
+           if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1,
+                               &val, 4))
+               return -EIO;
+
+           memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
+           val = le32_to_cpu(*(__le32 *)temp);
+           if (netxen_nic_hw_write_wx(adapter, 
NETXEN_NIU_XG1_STATION_ADDR_0_HI,
+                               &val, 4))
                return -EIO;
+           break;
+
+       default:
+           printk(KERN_ERR "Unknown port %d\n", phy);
+           break;
+       }
 
        return 0;
 }
@@ -835,7 +868,7 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter 
*adapter,
 int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
                              netxen_ethernet_macaddr_t * addr)
 {
-       int phy = adapter->portnum;
+       int phy = physical_port[adapter->portnum];
        u32 stationhigh;
        u32 stationlow;
        u8 val[8];
@@ -863,21 +896,21 @@ int netxen_niu_xg_set_promiscuous_mode(struct 
netxen_adapter *adapter,
                                       netxen_niu_prom_mode_t mode)
 {
        __u32 reg;
-       int port = adapter->portnum;
+       u32 port = physical_port[adapter->portnum];
 
        if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
                return -EINVAL;
 
-       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_CONFIG_1 + 
-                                       (0x10000 * port), &reg, 4))
-               return -EIO;
+       if (netxen_nic_hw_read_wx(adapter,
+               NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4))
+                       return -EIO;
        if (mode == NETXEN_NIU_PROMISC_MODE)
                reg = (reg | 0x2000UL);
        else
                reg = (reg & ~0x2000UL);
 
-       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_XGE_CONFIG_1 +
-                                       (0x10000 * port), reg);
+       netxen_crb_writelit_adapter(adapter,
+               NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
 
        return 0;
 }
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h 
b/drivers/net/netxen/netxen_nic_phan_reg.h
index 12bcaf9..9457fc7 100644
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ b/drivers/net/netxen/netxen_nic_phan_reg.h
@@ -108,6 +108,13 @@
 #define CRB_CMD_CONSUMER_OFFSET_3   NETXEN_NIC_REG(0x1d4)
 #define CRB_TEMP_STATE              NETXEN_NIC_REG(0x1b4)
 
+#define CRB_V2P_0                  NETXEN_NIC_REG(0x290)
+#define CRB_V2P_1                  NETXEN_NIC_REG(0x294)
+#define CRB_V2P_2                  NETXEN_NIC_REG(0x298)
+#define CRB_V2P_3                  NETXEN_NIC_REG(0x29c)
+#define CRB_V2P(port)              (CRB_V2P_0+((port)*4))
+#define CRB_DRIVER_VERSION         NETXEN_NIC_REG(0x2a0)
+
 /* used for ethtool tests */
 #define CRB_SCRATCHPAD_TEST        NETXEN_NIC_REG(0x280)
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to