diff -Naru linux-2.6.16_orig/drivers/net/netxen/netxen_nic_hw.c 
linux-2.6.16/drivers/net/netxen/netxen_nic_hw.c
--- linux-2.6.16_orig/drivers/net/netxen/netxen_nic_hw.c        1969-12-31 
16:00:00.000000000 -0800
+++ linux-2.6.16/drivers/net/netxen/netxen_nic_hw.c     2006-03-24 
14:13:57.000000000 -0800
@@ -0,0 +1,1077 @@
+/*
+ * Copyright (C) 2003 - 2006 NetXen Inc.
+ * All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *                            
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *                                   
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ * 
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.
+ * 
+ * Contact Information:
+ *    [EMAIL PROTECTED]
+ * NetXen, 3965 Freedom Circle, Fourth Floor,
+ * Santa Clara, CA 95054
+ */
+/*
+ * Source file for NIC routines to access the Phantom hardware
+ *
+ * $Id: netxen_nic_hw.c,v 1.66.6.15 2006/03/21 00:31:29 vijo Exp $
+ *
+ */
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/version.h>
+#include "netxen_nic.h"
+#include "netxen_nic_hw.h"
+#include "nic_cmn.h"
+#include "netxen_version.h"
+#include "netxen_brdcfg.h"
+
+/* static unsigned long netxen_nic_pci_set_crbwindow(netxen_adapter *adapter,
+                                                    u64 off); */
+static unsigned long netxen_nic_pci_set_window (unsigned long long pci_base,
+                                                    unsigned long long addr);
+extern struct netxen_adapter_s  *g_adapter;
+extern spinlock_t            hal_lock;
+
+/*
+ * Changes the CRB window to the specified window.
+ */
+void
+netxen_nic_pci_change_crbwindow(netxen_adapter *adapter, uint32_t wndw)
+{
+        netxen_pcix_crb_window_t        window;
+        unsigned long                offset;
+        uint32_t                     tmp;
+
+        if (adapter->curr_window == wndw) {
+                return;
+        }
+
+        /*
+         * Move the CRB window.
+         * We need to write to the "direct access" region of PCI
+         * to avoid a race condition where the window register has
+         * not been successfully written across CRB before the target
+         * register address is received by PCI. The direct region bypasses
+         * the CRB bus.
+         */
+        /*
+         * NOTE: When B0 arrives, we can use direct access registers for
+         * better performance
+         */
+        offset = adapter->ahw.pci_base + NetXen_PCIX_PH_REG(PCIX_CRB_WINDOW);
+
+        *(netxen_crbword_t *)&window = 0;
+        window.addrbit = wndw;
+        NetXen_NIC_PCI_WRITE_32(*(unsigned int *)&window, (void*)(offset));
+
+        //printk("set crbw : 0x%08x\n",off);
+        /* MUST make sure window is set before we forge on... */
+        while ((tmp = NetXen_NIC_PCI_READ_32((void*)offset)) != 
+            *(uint32_t *)&window) {
+                printk(KERN_WARNING "%s: %s WARNING: CRB window value not "
+                                    "registered properly: 0x%08x.\n",
+                                    netxen_nic_driver_name, __FUNCTION__, tmp);
+        }
+
+        adapter->curr_window = wndw;
+        return;
+}
+
+/*
+ * Set the CRB window based on the offset.
+ */
+static inline unsigned long
+netxen_nic_pci_set_crbwindow(netxen_adapter *adapter, u64 off)
+{
+        /*
+         * See if we are currently pointing to the region we want to use next.
+         */
+       
+        if ((off >= NetXen_CRB_PCIX_HOST) && (off < NetXen_CRB_DDR_NET)) {
+                /*
+                 * No need to change window. PCIX and PCIE regs are in both
+                 * windows.
+                 */
+                return (off);
+        }
+
+        if ((off >= NetXen_CRB_PCIX_HOST) && (off < NetXen_CRB_PCIX_HOST2)) {
+                /* We are in first CRB window */
+                if (adapter->curr_window != 0) {
+                        netxen_nic_pci_change_crbwindow(adapter, 0);
+                }
+                return (off);
+        }
+
+        if ((off > NetXen_CRB_PCIX_HOST2) && (off < NetXen_CRB_MAX)) {
+                /* We are in second CRB window */
+                off = off - NetXen_CRB_PCIX_HOST2 + NetXen_CRB_PCIX_HOST;
+
+                if (adapter->curr_window != 1) {
+                        netxen_nic_pci_change_crbwindow(adapter, 1);
+                }
+                return (off);
+        }
+
+        if ((off >= NetXen_PCI_DIRECT_CRB) && (off < NetXen_PCI_CAMQM_MAX)) {
+                /*
+                 * We are in the QM or direct access register region - do
+                 * nothing
+                 */
+                return (off);
+        }
+
+        /* strange address given */
+        dump_stack();
+        printk(KERN_WARNING"%s: Warning: netxen_nic_pci_set_crbwindow called 
with"
+                " an unknown address(%llx)\n", netxen_nic_driver_name, off);
+
+        return (off);
+}
+
+int
+netxen_nic_hw_write_wx(netxen_adapter *adapter, u64 off, void *data, int len)
+{//This is modified from _netxen_nic_hw_write()._netxen_nic_hw_write does not 
exist now.
+        void *addr;
+        unsigned long        flags=0;
+       
+        if(ADDR_IN_WINDOW1(off))
+        {//Window 1
+                addr = CRB_NORMALIZE(adapter, off);
+                read_lock(&adapter->adapter_lock);
+        }
+        else{//Window 0
+                addr = (void *)(uptr_t)(adapter->ahw.pci_base + off);
+                write_lock_irqsave(&adapter->adapter_lock, flags);
+                netxen_nic_pci_change_crbwindow(adapter, 0);
+        }
+
+
+        DPRINTK(1, INFO, "writing to base %lx offset %llx addr %p"
+                            " data %llx len %d\n",
+                            adapter->ahw.pci_base, off, addr,
+                            *(unsigned long long *)data, len);
+        switch (len) {
+        case 1:
+                NetXen_NIC_PCI_WRITE_8 (*(__uint8_t *)data, addr);
+                break;
+        case 2:
+                NetXen_NIC_PCI_WRITE_16 (*(__uint16_t *)data, addr);
+                break;
+        case 4:
+                NetXen_NIC_PCI_WRITE_32 (*(__uint32_t *)data, addr);
+                break;
+        case 8:
+                NetXen_NIC_PCI_WRITE_64 (*(__uint64_t *)data, addr);
+                break;
+        default:
+#if !defined(NDEBUG)
+                if ((len & 0x7) != 0)
+                        printk("%s: %s len(%d) not multiple of 8.\n",
+                                netxen_nic_driver_name, __FUNCTION__, len);
+#endif
+                DPRINTK(1, INFO, "writing data %lx to offset %llx, num 
words=%d\n",
+                            *(unsigned long *)data, off, (len>>3));
+
+                NetXen_NIC_HW_BLOCK_WRITE_64(data, addr, (len>>3));
+                break;
+        }
+        if(ADDR_IN_WINDOW1(off))
+        {//Window 1
+                read_unlock(&adapter->adapter_lock);
+        }
+        else{//Window 0
+                netxen_nic_pci_change_crbwindow(adapter, 1);
+                write_unlock_irqrestore(&adapter->adapter_lock, flags);
+        }
+
+        return 0;
+}
+
+int
+netxen_nic_hw_read_wx (netxen_adapter *adapter, u64 off, void *data, int len)
+{
+        void *addr;
+        unsigned long        flags=0;
+
+        if(ADDR_IN_WINDOW1(off))
+        {//Window 1
+                addr = CRB_NORMALIZE(adapter, off);
+                read_lock(&adapter->adapter_lock);
+        }
+        else{//Window 0
+                addr = (void *)(uptr_t)(adapter->ahw.pci_base + off);
+                write_lock_irqsave(&adapter->adapter_lock, flags);
+                netxen_nic_pci_change_crbwindow(adapter, 0);
+        }
+
+        DPRINTK(1, INFO, "reading from base %lx offset %llx addr %p\n",
+                            adapter->ahw.pci_base, off, addr);
+        switch (len) {
+        case 1:
+                *(__uint8_t  *)data = NetXen_NIC_PCI_READ_8(addr);
+                break;
+        case 2:
+                *(__uint16_t *)data = NetXen_NIC_PCI_READ_16(addr);
+                break;
+        case 4:
+                *(__uint32_t *)data = NetXen_NIC_PCI_READ_32(addr);
+                break;
+        case 8:
+                *(__uint64_t *)data = NetXen_NIC_PCI_READ_64(addr);
+                break;
+        default:
+#if !defined(NDEBUG)
+                if ((len & 0x7) != 0)
+                        printk("%s: %s len(%d) not multiple of 8.\n",
+                                netxen_nic_driver_name, __FUNCTION__, len);
+#endif
+                NetXen_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
+                break;
+        }
+        DPRINTK(1, INFO, "read %lx\n", *(unsigned long *)data);
+
+        if(ADDR_IN_WINDOW1(off))
+        {//Window 1
+                read_unlock(&adapter->adapter_lock);
+        }
+        else{//Window 0
+                netxen_nic_pci_change_crbwindow(adapter, 1);
+                write_unlock_irqrestore(&adapter->adapter_lock, flags);
+        }
+
+        return 0;
+}
+
+/*  PCI Windowing for DDR regions.  */
+
+#define ADDR_IN_RANGE(addr, low, high)            \
+        (((addr) <= (high)) && ((addr) >= (low)))
+
+int netxen_pci_set_window_warning_count = 0;
+
+static unsigned long
+netxen_nic_pci_set_window (unsigned long long pci_base, unsigned long long 
addr)
+{
+        static int ddr_mn_window=-1;
+        static int qdr_sn_window=-1;
+        int window;
+
+        /* printk("addr: %lx\n", addr); */
+        if (ADDR_IN_RANGE(addr, NetXen_ADDR_DDR_NET, NetXen_ADDR_DDR_NET_MAX)) 
{
+                /* DDR network side */
+                /* printk("MN DDR\n"); */
+                addr -= NetXen_ADDR_DDR_NET;
+                window = (addr >> 25 )  & 0x3ff;
+                if (ddr_mn_window != window) {
+                        /* printk("Change the MN window!!! \n"); */
+                        ddr_mn_window = window;
+                        NetXen_NIC_PCI_WRITE_32(window, (void 
*)(uptr_t)(pci_base +
+                                            
NetXen_PCIX_PH_REG(PCIX_MN_WINDOW)));
+                        /* MUST make sure window is set before we forge on... 
*/
+                        NetXen_NIC_PCI_READ_32((void *)(uptr_t)(pci_base +
+                                            
NetXen_PCIX_PH_REG(PCIX_MN_WINDOW)));
+                }
+                addr -= (window * 0x2000000);
+                addr+= NetXen_PCI_DDR_NET;
+        } else if (ADDR_IN_RANGE(addr, NetXen_ADDR_OCM0, 
NetXen_ADDR_OCM0_MAX)) {
+                addr -= NetXen_ADDR_OCM0;
+                addr += NetXen_PCI_OCM0;
+        } else if (ADDR_IN_RANGE(addr, NetXen_ADDR_OCM1, 
NetXen_ADDR_OCM1_MAX)) {
+                addr -= NetXen_ADDR_OCM1;
+                addr += NetXen_PCI_OCM1;
+        } else if (ADDR_IN_RANGE(addr, NetXen_ADDR_QDR_NET, 
NetXen_ADDR_QDR_NET_MAX)) {
+                /* printk("SN QDR\n"); */
+                /* QDR network side */
+                addr -= NetXen_ADDR_QDR_NET;
+                window = (addr >> 22 )  & 0x3f;
+                if (qdr_sn_window != window) {
+                        /* printk("Change the SN window!!! \n"); */
+                        qdr_sn_window = window;
+                        NetXen_NIC_PCI_WRITE_32((window << 22), 
+                                            (void *)(uptr_t)(pci_base +
+                                            
NetXen_PCIX_PH_REG(PCIX_SN_WINDOW)));
+                        /* MUST make sure window is set before we forge on... 
*/
+                        NetXen_NIC_PCI_READ_32((void *)(uptr_t)(pci_base +
+                                            
NetXen_PCIX_PH_REG(PCIX_SN_WINDOW)));
+                }
+                addr -= (window * 0x400000);
+                addr+= NetXen_PCI_QDR_NET;
+        } else {
+                /*
+                 * peg gdb frequently accesses memory that doesn't exist,
+                 * this limits the chit chat so debugging isn't slowed down.
+                 */
+                if((netxen_pci_set_window_warning_count++ < 8)
+                    || (netxen_pci_set_window_warning_count%64 == 0)) {
+                        printk("%s: Warning:netxen_nic_pci_set_window()"
+                                " Unknown address range!\n", 
netxen_nic_driver_name);
+                }
+        }
+        /* printk("New address: 0x%08lx\n",addr); */
+        return addr;
+}
+
+/* read num_words from hardware (num_words in 64 bits    */
+void
+netxen_nic_mem_block_read(struct netxen_adapter_s *adapter, u64 off,
+                        void *data, int num_words)
+{
+        void *addr;
+        unsigned long flags;
+
+        write_lock_irqsave(&adapter->adapter_lock, flags);
+        off  = netxen_nic_pci_set_window(adapter->ahw.pci_base, off);
+        addr = (void *)(uptr_t)(adapter->ahw.pci_base + off);
+        DPRINTK(1, INFO, "reading from base %lx offset %lx addr %p\n",
+                        adapter->ahw.pci_base, (unsigned long)off, addr);
+        NetXen_NIC_HW_BLOCK_READ_64(data, addr, num_words);
+        write_unlock_irqrestore(&adapter->adapter_lock, flags);
+
+        return;
+}
+
+/* Write num_words (in 64 bits) in the phantom memory    */
+/*void
+netxen_nic_mem_block_write(struct netxen_adapter_s *adapter, u64 off,
+                            void *data, int num_words)
+{
+        void *addr;
+        unsigned long    flags;
+
+        write_lock_irqsave(&adapter->adapter_lock, flags);
+        off  = netxen_nic_pci_set_window(adapter->ahw.pci_base, off);
+        addr = (void *)(uptr_t)(off + adapter->ahw.pci_base);
+        DPRINTK(1, INFO, "writing data %lx to offset %lx\n",
+                        *(unsigned long *)data, (unsigned long)off);
+        NetXen_NIC_HW_BLOCK_WRITE_64(data, addr, num_words);
+        write_unlock_irqrestore(&adapter->adapter_lock, flags);
+
+        return;
+}*/
+int
+netxen_nic_pci_mem_write(struct netxen_adapter_s *adapter, u64 off,
+                        void *data, int size)
+{
+        unsigned long   flags;
+        void           *addr;
+        int             ret = 0;
+
+        write_lock_irqsave(&adapter->adapter_lock, flags);
+        off = netxen_nic_pci_set_window(adapter->ahw.pci_base, off);
+        addr = (void *)(uptr_t)(adapter->ahw.pci_base  + off);
+        DPRINTK(1, INFO, "writing data %llx to offset %llx\n",
+                            *(unsigned long long *)data, off);
+        switch (size) {
+        case 1:
+                NetXen_NIC_PCI_WRITE_8( *(__uint8_t  *)data, addr);
+                break;
+        case 2:
+                NetXen_NIC_PCI_WRITE_16(*(__uint16_t *)data, addr);
+                break;
+        case 4:
+                NetXen_NIC_PCI_WRITE_32(*(__uint32_t *)data, addr);
+                break;
+        case 8:
+                NetXen_NIC_PCI_WRITE_64(*(__uint64_t *)data, addr);
+                break;
+        default:
+                ret = 1;
+                break;
+        }
+        write_unlock_irqrestore(&adapter->adapter_lock, flags);
+        DPRINTK(1, INFO, "wrote %llx\n", *(unsigned long long*)data);
+
+        return ret;
+}
+
+int
+netxen_nic_pci_mem_read(struct netxen_adapter_s *adapter,
+                        u64 off, void *data, int size)
+{
+        unsigned long   flags;
+        void           *addr;
+        int             ret = 0;
+
+        write_lock_irqsave(&adapter->adapter_lock, flags);
+        off = netxen_nic_pci_set_window(adapter->ahw.pci_base, off);
+        addr = (void *)(uptr_t)(adapter->ahw.pci_base + off);
+        switch (size) {
+        case 1: 
+                *(__uint8_t  *)data = NetXen_NIC_PCI_READ_8(addr);
+                break;
+        case 2:
+                *(__uint16_t *)data = NetXen_NIC_PCI_READ_16(addr);
+                break;
+        case 4:
+                *(__uint32_t *)data = NetXen_NIC_PCI_READ_32(addr);
+                break;
+        case 8:
+                *(__uint64_t *)data = NetXen_NIC_PCI_READ_64(addr);
+                break;
+        default:
+                ret = 1;
+                break;
+        }
+        write_unlock_irqrestore(&adapter->adapter_lock, flags);
+        DPRINTK(1, INFO, "read %llx\n", *(unsigned long long*)data);
+
+        return ret;
+}
+/*
+ *static void
+ *netxen_load_cam_ram(struct netxen_adapter_s *adapter)
+ *{
+ *       DPRINTK(1, INFO, "writing to  LOAD CAM RAM.....START \n");
+ *       netxen_nic_reg_write(adapter, NetXen_CRB_CAM + 0x2000, 0);
+ *       // may be we need to have some value for bootpeg - IND
+ *
+ *       // Hw bug - needs an extra write after reset
+ *       netxen_nic_reg_write(adapter, NetXen_CRB_CAM + 0x2000, 0);
+ *       // one more for good measure
+ *       netxen_nic_reg_write(adapter, NetXen_CRB_CAM + 0x2000, 0);
+ *
+ *       return;
+ *}
+*/
+
+int
+netxen_nic_get_board_info(struct netxen_adapter_s *adapter)
+{
+        int                rv=0;
+        netxen_board_info_t  *boardinfo;
+        int                i;
+        int                addr = 0x4000;
+        uint32_t          *ptr32;
+
+        boardinfo = &adapter->ahw.boardcfg;
+        ptr32 = (uint32_t *)boardinfo;
+
+        for (i=0;i<sizeof(netxen_board_info_t)/sizeof(uint32_t);i++) {
+                *ptr32++ = rom_fast_read(adapter, addr);
+                //printk("ROM: %x\n",*ptr32);
+                addr+= sizeof(uint32_t);
+        }
+        if (boardinfo->magic != NetXen_BDINFO_MAGIC) {
+                printk("%s: ERROR reading %s board config."
+                        " Read %x, expected %x\n", netxen_nic_driver_name,
+                       netxen_nic_driver_name,
+                        boardinfo->magic, NetXen_BDINFO_MAGIC);
+                rv=-1;
+        }
+        if (boardinfo->header_version != NetXen_BDINFO_VERSION) {
+                printk("%s: Unknown board config version."
+                        " Read %x, expected %x\n", netxen_nic_driver_name,
+                        boardinfo->header_version, NetXen_BDINFO_VERSION);
+                rv=-1;
+        }
+
+        DPRINTK(1, INFO, "Discovered board type:0x%x  ",boardinfo->board_type);
+        switch((netxen_brdtype_t)boardinfo->board_type){
+        case NetXen_BRDTYPE_P2_SB35_4G:
+                adapter->ahw.board_type = NetXen_NIC_GBE;
+                break;
+        case NetXen_BRDTYPE_P2_SB31_10G:
+        case NetXen_BRDTYPE_P2_SB31_10G_IMEZ:
+        case NetXen_BRDTYPE_P2_SB31_10G_HMEZ:
+        case NetXen_BRDTYPE_P2_SB31_10G_CX4:
+                adapter->ahw.board_type = NetXen_NIC_XGBE;
+                break;
+        case NetXen_BRDTYPE_P1_BD:
+        case NetXen_BRDTYPE_P1_SB:
+        case NetXen_BRDTYPE_P1_SMAX:
+        case NetXen_BRDTYPE_P1_SOCK:
+                adapter->ahw.board_type = NetXen_NIC_GBE;
+                break;
+        default:
+                printk("%s: Unknown(%x)\n", netxen_nic_driver_name,
+                       boardinfo->board_type);
+                break;
+        }
+
+        return rv;
+}
+
+int
+netxen_nic_get_board_num(netxen_adapter *adapter)
+{
+        return adapter->ahw.boardcfg.board_num;
+}
+
+/* NIU access sections */
+
+/* Set the MAC address for a port */
+int
+netxen_nic_macaddr_set(struct netxen_port *port, __uint8_t *addr)
+{
+        struct netxen_adapter_s   *adapter = port->adapter;
+        int                     phy = port->portnum, ret = 0;
+       unsigned long           flags;
+
+        if ((phy < 0) || (phy > 3))
+                return -1;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+               spin_lock_irqsave(&hal_lock, flags);
+               g_adapter = adapter;
+                ret = netxen_niu_macaddr_set(phy, addr);
+               spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        case NetXen_NIC_XGBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                ret = netxen_niu_xg_macaddr_set(phy, addr);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        default:
+                dump_stack();
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return ret;
+}
+
+/* Return the current MAC address of the given port. */
+int
+netxen_nic_macaddr_get(struct netxen_port *port, __uint8_t **addr)
+{
+        struct netxen_adapter_s *adapter = port->adapter;
+        int                   phy = port->portnum;
+        int                   ret = 0;
+       unsigned long         flags;
+
+        if (addr == NULL)
+                return -1;
+        if ((phy < 0) || (phy > 3))
+                return -1;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                ret = netxen_niu_macaddr_get(phy, (netxen_ethernet_macaddr_t 
*)*addr);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        case NetXen_NIC_XGBE:
+                printk(KERN_ERR "%s: Function %s is not implemented for XG\n",
+                                netxen_nic_driver_name,__FUNCTION__);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+                ret = -1;
+        }
+
+        return ret;
+}
+
+int
+netxen_nic_set_mtu(struct netxen_port *port, int new_mtu)
+{
+        struct netxen_adapter_s *adapter = port->adapter;
+        int                   ret = 0;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                /*netxen_nic_hw_write(adapter,
+                                    
NetXen_NIU_GB_MAX_FRAME_SIZE(port->portnum),
+                                    &new_mtu, 4);*/
+                netxen_nic_write_w0 (
+                        adapter,NetXen_NIU_GB_MAX_FRAME_SIZE(port->portnum),
+                        new_mtu);
+
+                break;
+
+        case NetXen_NIC_XGBE:
+                new_mtu += 100; /* so that MAC accepts frames > MTU */
+                /*netxen_nic_hw_write(adapter, NetXen_NIU_XGE_MAX_FRAME_SIZE,
+                                    &new_mtu, 4);*/
+               netxen_nic_write_w0 (adapter, NetXen_NIU_XGE_MAX_FRAME_SIZE, 
new_mtu);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return ret;
+}
+
+int
+netxen_nic_set_promisc_mode(struct netxen_port *port)
+{
+        struct netxen_adapter_s *adapter = port->adapter;
+        int                   phy = port->portnum;
+        int                   ret = 0;
+       unsigned long         flags;
+        if ((phy < 0) || (phy > 3))
+                return -1;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                ret = netxen_niu_set_promiscuous_mode(phy,
+                                                    
NetXen_NIU_PROMISCOUS_MODE); 
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        case NetXen_NIC_XGBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                ret = netxen_niu_xg_set_promiscuous_mode(phy,
+                                                    
NetXen_NIU_PROMISCOUS_MODE);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return ret;
+}
+
+int
+netxen_nic_unset_promisc_mode(struct netxen_port *port)
+{
+        struct netxen_adapter_s *adapter = port->adapter;
+        int                   phy = port->portnum;
+        int                   ret = -1;
+       unsigned long         flags;
+
+        if ((phy < 0) || (phy > 3))
+                return -1;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                ret = netxen_niu_set_promiscuous_mode(phy,
+                                                
NetXen_NIU_NON_PROMISCOUS_MODE);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        case NetXen_NIC_XGBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                ret = netxen_niu_xg_set_promiscuous_mode(phy,
+                                                
NetXen_NIU_NON_PROMISCOUS_MODE);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return ret;
+}
+
+long
+netxen_nic_phy_read (netxen_adapter *adapter, long phy, long reg,
+                    __uint32_t *readval)
+{
+        long        ret = 0;
+       unsigned long flags;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                ret = netxen_niu_gbe_phy_read (phy, reg, readval);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        case NetXen_NIC_XGBE:
+                printk(KERN_ERR "%s: Function %s is not implemented for XG\n",
+                        netxen_nic_driver_name,__FUNCTION__);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return ret;
+}
+
+long
+netxen_nic_phy_write (netxen_adapter *adapter, long phy, long reg, __uint32_t 
val)
+{
+        long ret = 0;
+       unsigned long flags;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                ret = netxen_niu_gbe_phy_write (phy, reg, val);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        case NetXen_NIC_XGBE:
+                printk(KERN_ERR "%s: Function %s is not implemented for XG\n",
+                            netxen_nic_driver_name, __FUNCTION__);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return ret;
+}
+
+long
+netxen_nic_init_port (struct netxen_port *port)
+{
+        struct netxen_adapter_s *adapter = port->adapter;
+        long                  portnum = port->portnum;
+        long                  ret = 0;
+       unsigned long         flags;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                netxen_nic_disable_phy_interrupts (adapter, portnum);
+                udelay(20000);
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                netxen_niu_gbe_init_port(portnum);
+                spin_unlock_irqrestore(&hal_lock, flags);
+
+
+                break;
+
+        case NetXen_NIC_XGBE:
+                /* Nothing to be done for XG */
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return ret;
+}
+
+void
+netxen_nic_init_niu (struct netxen_adapter_s *adapter)
+{
+        long        rv;
+        int         portno;
+        unsigned long         flags;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                for (portno = 0; portno < NetXen_NIU_MAX_GBE_PORTS; portno++)
+                        netxen_niu_gbe_init_port(portno);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        case NetXen_NIC_XGBE:
+                /* DO niu_init also, for HW bug workaround */
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                xge_mdio_init();
+                netxen_niu_xginit();
+                rv = xge_mdio_init();
+                if ((rv & 2) != 0) {
+                        /* XG link is down. Need to do additional init
+                        when INT comes */
+                        adapter->ahw.xg_linkup=0;
+                } else {
+                        adapter->ahw.xg_linkup=1;
+                }
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return;
+}
+
+void
+netxen_nic_stop_port(struct netxen_port *port)
+{
+        long                  portnum = port->portnum;
+        struct netxen_adapter_s *adapter = port->adapter;
+        unsigned long         flags;
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                netxen_niu_disable_gbe_port(portnum);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        case NetXen_NIC_XGBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                netxen_niu_disable_xg_port(portnum);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return;
+}
+
+void
+netxen_nic_stop_all_ports(struct netxen_adapter_s *adapter)
+{
+        int              i;
+        struct netxen_port *port;
+
+        for (i=0; i < adapter->ahw.max_ports; i++) {
+                port = adapter->port[i];
+                netxen_nic_stop_port(port);
+        }
+
+         return;
+}
+
+/* Functions required by NetXen Hal routines */
+unsigned long
+netxen_xport_lock(void)
+{
+        /* No lock necessary */
+        return 0;
+}
+
+void
+netxen_xport_unlock(unsigned long unused)
+{
+        /* No lock/unlock necessary */
+        return;
+}
+
+int
+netxen_crb_writelit_adapter (unsigned long off, int data, struct 
netxen_adapter_s *adapter)
+{       //Modified. All the direct calls to this func are changed.
+        //This gets called only thru' some macros like NetXen_CRB_WRITELIT
+        unsigned long flags;
+        void *addr;
+
+        if(ADDR_IN_WINDOW1(off))
+        {
+                read_lock(&adapter->adapter_lock);
+                NetXen_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
+                read_unlock(&adapter->adapter_lock);
+        }
+        else{
+                //netxen_nic_write_w0 (adapter, off, data);
+                write_lock_irqsave(&adapter->adapter_lock, flags);
+                netxen_nic_pci_change_crbwindow(adapter, 0);
+                addr = (void *)(adapter->ahw.pci_base + off);
+                NetXen_NIC_PCI_WRITE_32(data, addr);
+                netxen_nic_pci_change_crbwindow(adapter, 1);
+                write_unlock_irqrestore(&adapter->adapter_lock, flags);
+        }
+
+        return 0;
+}
+int
+netxen_crb_write (unsigned long off, void *data)
+{
+        return  netxen_nic_hw_write_wx (g_adapter, off, data, 4);
+}
+
+int 
+netxen_crb_writelit(unsigned long off, int data)
+{
+       return netxen_crb_writelit_adapter(off, data, g_adapter);
+}
+int
+netxen_crb_read (unsigned long off, void *data)
+{
+        return netxen_nic_hw_read_wx (g_adapter, off, data, 4);
+}
+
+native_t
+netxen_crb_read_val (unsigned long off)
+{
+        int        data;
+
+        netxen_nic_hw_read_wx (g_adapter, off, &data, 4);
+        return data;
+}
+
+int
+netxen_crb_write_adapter (unsigned long off, void *data, struct 
netxen_adapter_s *adapter)
+{
+        return  netxen_nic_hw_write_wx (adapter, off, data, 4);
+}
+
+int
+netxen_crb_read_adapter (unsigned long off, void *data, struct 
netxen_adapter_s *adapter)
+{
+        return netxen_nic_hw_read_wx (adapter, off, data, 4);
+}
+
+int
+netxen_crb_read_val_adapter (unsigned long off, struct netxen_adapter_s 
*adapter)
+{
+        int        data;
+
+        netxen_nic_hw_read_wx (adapter, off, &data, 4);
+        return data;
+}
+
+
+void DELAY(A)
+{
+        unsigned long remainder;
+
+        remainder = A/50000;
+        do {
+                if (remainder > 1000) {
+                        udelay(1000);
+                        remainder -= 1000;
+                } else {
+                        udelay(remainder + 1);
+                        remainder = 0;
+                }
+        } while (remainder > 0);
+}
+
+void netxen_nic_set_link_parameters(struct netxen_port *port)
+{
+        struct netxen_adapter_s *adapter = port->adapter;
+        netxen_niu_phy_status_t status;
+        uint16_t autoneg;
+        netxen_niu_control_t mode;
+
+       netxen_nic_read_w0(adapter, NetXen_NIU_MODE, (uint32_t *)&mode);
+        if(mode.enable_ge) { // Gb 10/100/1000 Mbps mode
+                if (netxen_nic_phy_read(port->adapter,port->portnum,
+                        NetXen_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+                        (netxen_crbword_t *)&status) == 0) {
+                        if(status.link) {
+                                port->state = 1;
+                                switch(status.speed) {
+                                case 0: port->link_speed = SPEED_10;
+                                        break;
+                                case 1: port->link_speed = SPEED_100;
+                                        break;
+                                case 2: port->link_speed = SPEED_1000;
+                                        break;
+                                default:
+                                        port->link_speed = -1; // unknown speed
+                                        break;
+                                }
+                                switch(status.duplex) {
+                                case 0: port->link_duplex = DUPLEX_HALF;
+                                        break;
+                                case 1: port->link_duplex = DUPLEX_FULL;
+                                        break;
+                                default:
+                                        port->link_duplex = -1; // unknown mode
+                                        break;
+                                }
+                                if (netxen_nic_phy_read(port->adapter,
+                                    port->portnum,
+                                    NetXen_NIU_GB_MII_MGMT_ADDR_AUTONEG, 
+                                    (netxen_crbword_t *)&autoneg)!= 0)
+                                        port->link_autoneg = autoneg;
+                        } else {
+                                port->state = -1;
+                                port->link_speed = -1;
+                                port->link_duplex = -1;
+                        }
+                } else {
+                        port->state = -1;
+                        port->link_speed = -1;
+                        port->link_duplex = -1;
+                }
+        }
+}
+
+#define FLASH_SIZE      (0x100000)
+
+int
+netxen_nic_get_flash_size(void)
+{
+        return FLASH_SIZE;
+}
+
+void
+netxen_nic_flash_print(struct netxen_adapter_s* adapter)
+{
+       int valid = 1;
+       uint32_t fw_major = 0;
+       uint32_t fw_minor = 0;
+       uint32_t fw_build = 0;
+
+       netxen_board_info_t* board_info = &(adapter->ahw.boardcfg);
+       if (board_info->magic != NetXen_BDINFO_MAGIC) {
+               printk("NetXen Unknown board config, Read 0x%x expected as 
0x%x\n", board_info->magic,
+                       NetXen_BDINFO_MAGIC);
+               valid = 0;
+       }
+       if (board_info->header_version != NetXen_BDINFO_VERSION) {
+               printk("NetXen Unknown board config version."
+                       " Read %x, expected %x\n",
+                       board_info->header_version, NetXen_BDINFO_VERSION);
+               valid = 0;
+       }
+       if(valid) {
+               printk("NetXen %s Board #%d, Chip id 0x%x\n",
+                       board_info->board_type == 0x0b ? "XGB" : "GBE",
+                       board_info->board_num, board_info->chip_id);
+               read_lock(&adapter->adapter_lock);
+               fw_major = NetXen_NIC_PCI_READ_32(CRB_NORMALIZE(adapter,
+                               NetXen_FW_VERSION_MAJOR));
+               fw_minor = NetXen_NIC_PCI_READ_32(CRB_NORMALIZE(adapter,
+                               NetXen_FW_VERSION_MINOR));
+               fw_build = NetXen_NIC_PCI_READ_32(CRB_NORMALIZE(adapter,
+                               NetXen_FW_VERSION_SUB));
+               read_unlock(&adapter->adapter_lock);
+
+               printk("NetXen Firmware version %d.%d.%d\n", fw_major, fw_minor,
+                       fw_build);
+       }
+       if(fw_major != _NetXen_NIC_LINUX_MAJOR) {
+               printk(KERN_ERR"The mismatch in driver version and firmware "
+                       "version major number\n"
+                       "Driver version major number = %d \t"
+                       "Firmware version major number = %d \n",
+                       _NetXen_NIC_LINUX_MAJOR, fw_major);
+               adapter->driver_mismatch = 1;
+       }
+       if(fw_minor != _NetXen_NIC_LINUX_MINOR) {
+               printk(KERN_ERR"The mismatch in driver version and firmware "
+                       "version minor number\n"
+                       "Driver version minor number = %d \t"
+                       "Firmware version minor number = %d \n",
+                       _NetXen_NIC_LINUX_MINOR, fw_minor);
+               adapter->driver_mismatch = 1;
+       }
+       if(adapter->driver_mismatch) {
+               printk(KERN_INFO"Use the driver with version no %d.%d.xxx\n"
+                       ,fw_major,fw_minor);
+       } else {
+               DPRINTK(1, INFO,"The major and minor number of driver and "
+                       "firmware versions match\n");
+       }
+}

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to