diff -Naru linux-2.6.16_orig/drivers/net/netxen/netxen_nic_main.c 
linux-2.6.16/drivers/net/netxen/netxen_nic_main.c
--- linux-2.6.16_orig/drivers/net/netxen/netxen_nic_main.c      1969-12-31 
16:00:00.000000000 -0800
+++ linux-2.6.16/drivers/net/netxen/netxen_nic_main.c   2006-03-24 
14:19:19.000000000 -0800
@@ -0,0 +1,3847 @@
+/*
+ * 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
+ */
+/*
+ *  Main source file for NetXen NIC Driver on Linux
+ *
+ *  $Id: netxen_nic_main.c,v 1.179.4.36 2006/03/21 00:31:29 vijo Exp $
+ */
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+//#include <linux/kgdb-defs.h>
+#include <linux/compiler.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/version.h>
+
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/proc_fs.h>
+
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+#include "netxen_nic_hw.h"
+#include "netxen_nic_config.h"
+
+#undef NetXen_LOOPBACK
+#undef SINGLE_DMA_BUF
+#define NetXen_NIC_HW_CSUM
+#define NetXen_NIC_NAPI
+// #undef NetXen_NIC_NAPI
+
+#define NetXen_NETIF_F_TSO
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+//#define NetXen_NIC_HW_VLAN 1
+#else
+#define NetXen_NIC_HW_VLAN 0
+#endif
+
+#ifdef NetXen_NETIF_F_TSO
+#define NetXen_DO_TSO    1
+#else
+#define NetXen_DO_TSO    0
+#endif
+
+#include "netxen_nic.h"
+
+#define DEFINE_GLOBAL_RECV_CRB
+#include "nic_phan_reg.h"
+
+#include "netxen_nic_ioctl.h"
+#include "nic_cmn.h"
+#include "netxen_nic_config.h"
+
+#include "netxen_nic_hw.h"
+#include "netxen_version.h"
+
+// for cmd line parameteres----------
+#define NetXen_PARAM(X,S) \
+static int X=0; \
+MODULE_PARM(X,"i"); \
+MODULE_PARM_DESC(X,S);
+
+
+/*
+ * Disable this for now.
+ * NetXen_PARAM(MaxTxCount,"No of TX descriptors");
+ * NetXen_PARAM(MaxRxCount,"No of Rx descriptors");
+ */
+
+//----------- cmd line parameters-------
+
+
+
+MODULE_AUTHOR("NetXen");
+MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
+MODULE_LICENSE("GPL");
+
+/*static int netxen_nic_debug = NETIF_MSG_DRV | NETIF_MSG_PROBE; TODO */
+int netxen_nic_debug;
+
+MODULE_PARM(netxen_nic_debug, "i");
+MODULE_PARM_DESC(netxen_nic_debug, "Debug level (0=none,...,16=all)");
+
+
+char netxen_nic_driver_name[]   = "netxen";
+char netxen_nic_driver_string[] = "NetXen Network Driver version "
+                               NetXen_NIC_LINUX_VERSIONID
+                               "-"
+                               NetXen_NIC_BUILD_NO
+                               " generated "
+                               NetXen_NIC_TIMESTAMP;
+
+#ifndef ARCH_KMALLOC_MINALIGN
+#define ARCH_KMALLOC_MINALIGN 0
+#endif
+#ifndef ARCH_KMALLOC_FLAGS
+#define ARCH_KMALLOC_FLAGS SLAB_HWCACHE_ALIGN
+#endif
+
+#define NetXen_NETDEV_WEIGHT 120
+#define ADAPTER_UP_MAGIC 777
+
+kmem_cache_t           *cmd_desc_cache = NULL;
+kmem_cache_t           *cmd_buff_cache = NULL;
+cmdDescType0_t         *cmd_desc_array[NR_CPUS];
+struct netxen_cmd_buffer  *cmd_buff_array[NR_CPUS];
+
+static int netxen_nic_probe_err = 0;
+
+#define RCV_DESC_RINGSIZE         (sizeof(rcvDesc_t) * adapter->MaxRxDescCount)
+#define STATUS_DESC_RINGSIZE    (sizeof(statusDesc_t)* adapter->MaxRxDescCount)
+#define JUMBO_DESC_RINGSIZE  (sizeof(rcvDesc_t) * adapter->MaxJumboRxDescCount)
+#define TX_RINGSIZE   (sizeof(struct netxen_cmd_buffer) * 
adapter->MaxTxDescCount)
+#define RCV_BUFFSIZE  (sizeof(struct netxen_rx_buffer) * 
rcv_desc->MaxRxDescCount)
+
+#define NetXen_NIC_INT_RESET 0x2004
+
+/* Local functions to NetXen NIC driver */
+static int  __devinit netxen_nic_probe(struct pci_dev *pdev,
+                                    const struct pci_device_id *ent);
+static void __devexit netxen_nic_remove(struct pci_dev *pdev);
+static void   netxen_nic_hw_reset (struct netxen_adapter_s *adapter);
+static int    netxen_nic_open(struct net_device *netdev);
+static int    netxen_nic_close(struct net_device *netdev);
+static int    netxen_nic_xmit_frame(struct sk_buff *, struct net_device *);
+static int    netxen_nic_set_mac(struct net_device *netdev, void *p);
+static int    netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
+static int    netxen_nic_hw_resources(struct netxen_adapter_s *adapter);
+static void   netxen_nic_set_multi(struct net_device *netdev);
+static void   initialize_adapter_sw(struct netxen_adapter_s *adapter);
+static void   netxen_post_rx_buffers(struct netxen_adapter_s *adapter, 
uint32_t ctx,
+                                    uint32_t num, uint32_t type);
+static void   netxen_process_rcv(struct netxen_adapter_s *adapter,int ctx,
+                                statusDesc_t *desc);
+static void   netxen_tx_timeout(struct net_device *netdev);
+static void   netxen_tx_timeout_task(struct net_device *netdev);
+static void   netxen_process_cmd_ring(unsigned long data);
+static void   netxen_nic_down(struct netxen_port *port);
+static int    netxen_nic_do_ioctl(struct netxen_adapter_s *adapter, 
void*u_data,
+                               struct netxen_port *port);
+static int    initialize_adapter_hw(struct netxen_adapter_s *adapter);
+static void   netxen_watchdog(unsigned long);
+static void   netxen_watchdog_task(unsigned long adapter);
+static void   netxen_nic_tune_phantom(struct pci_dev *pdev,
+                                    struct netxen_adapter_s*);
+static void   netxen_nic_enable_int(netxen_adapter *adapter);
+static void   netxen_nic_disable_int(netxen_adapter *adapter);
+static uint32_t netxen_process_rcv_ring(struct netxen_adapter_s *, int, int);
+static void   netxen_nic_clear_stats(struct netxen_adapter_s *);
+static struct net_device_stats *netxen_nic_get_stats(struct net_device 
*netdev);
+static void   netxen_nic_irq_enable(struct netxen_adapter_s *adapter);
+static int    netxen_handle_int(netxen_adapter *, struct net_device *);
+static int    netxen_nic_ioctl(struct net_device *netdev,
+                            struct ifreq *ifr, int cmd);
+static int    netxen_nic_read_proc(char *buf, char **start, off_t offset,
+                                int count, int *eof, void *data);
+static int    netxen_nic_port_read_proc(char *buf, char **start, off_t offset,
+                                        int count, int *eof, void *data);
+#ifdef NetXen_NIC_NAPI
+static int    netxen_nic_rx_has_work(struct netxen_adapter_s *adapter);
+static int    netxen_nic_tx_has_work(struct netxen_adapter_s *adapter);
+static int    netxen_nic_poll(struct net_device *dev, int *budget);
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void netxen_nic_poll_controller(struct net_device *netdev);
+#endif
+#ifdef NetXen_NIC_HW_CSUM
+static int    netxen_tx_csum(struct netxen_adapter_s *adapter, cmdDescType0_t 
*desc,
+                            struct sk_buff *skb);
+#endif
+static irqreturn_t netxen_intr(int irq, void *data, struct pt_regs *regs);
+
+extern void set_ethtool_ops(struct net_device *netdev);
+struct netxen_adapter_s  *g_adapter;
+spinlock_t            hal_lock;
+
+unsigned int            loopback_start = 0;
+
+static struct           proc_dir_entry *netxen_proc_dir_entry;
+
+static unsigned char *tx_user_packet_data = NULL, *rx_user_packet_data;
+static unsigned int tx_user_packet_length = 0, rx_datalen, rx_user_pos = 0;
+static int capture_input = 0, captured = 0;
+
+#define DIDX_DIF(p, c) \
+   ((p >= c) ? (p - c) : (MAX_CMD_DESCRIPTORS - p + c))
+
+#define CIS_WATERMARK  0x60
+
+#define PEG_LOOP       1000  /* loop to pegstuck? */
+
+#define QMAJ(hdr)      ((hdr >> 19) & 0xF)
+#define QMIN(hdr)      (hdr & 0x3ffff)
+#define QSUB(hdr)      ((hdr >> 18) & 0x1)
+
+extern void xge_loopback(int on);
+extern long xge_link_status (void);
+
+void __devinit
+netxen_check_options(netxen_adapter *adapter)
+{
+        adapter->MaxTxDescCount      = MAX_CMD_DESCRIPTORS;
+        adapter->MaxRxDescCount      = MAX_RCV_DESCRIPTORS;
+        adapter->MaxJumboRxDescCount = MAX_JUMBO_RCV_DESCRIPTORS;
+        return;
+}
+
+/*  PCI Device ID Table  */
+static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
+        {PCI_VENDOR_ID_NetXen,PCI_DEVICE_ID_NetXen_4PORT,PCI_ANY_ID,
+                PCI_ANY_ID,0,0,0UL},
+        {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
+
+struct netxen_adapter_s *adapterlist[MAX_NUM_CARDS];
+
+/*
+netxen_nic_probe()
+
+Linux system will invoke this after identifying the vendor ID and device Id
+in the pci_tbl where this module will search for NetXen vedonr and device ID 
for
+quad port adapter.
+
+Even though there are 4 seperate devices (functions) on the quad port NIC, but
+the probe will be invoked for the first device (function) only. This will
+initialize the adapter, and setup the global parameters along with the port's
+specific structure.
+*/
+static int __devinit
+netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+        struct net_device     *netdev  = NULL;
+        struct netxen_adapter_s  *adapter = NULL;
+        struct netxen_port       *port    = NULL;
+        uint8_t               *mem_ptr = NULL;
+        unsigned long          mem_base, mem_len;
+        int                    pci_using_dac, i, err;
+        int                    boardno = 0;
+        int                    ring;
+        netdev_list_t         *netlist     = NULL;
+        netxen_recv_context_t    *recv_ctx    = NULL;
+        netxen_rcv_desc_ctx_t    *rcv_desc    = NULL;
+        struct netxen_cmd_buffer *cmd_buf_arr = NULL;
+        struct proc_dir_entry *procfile;
+       static int             netxen_cards_found = 0;
+
+       printk("NetXen: adapter %d\n", netxen_cards_found);
+
+        if((err = pci_enable_device(pdev))) {
+                DPRINTK(1, ERR, "Cannot enable PCI device, aborting. %d\n",
+                                    err);
+                netxen_nic_probe_err = err;
+                return err;
+        }
+
+        if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+                DPRINTK(1, ERR, "Cannot find proper PCI device "
+                                    "base address, aborting. %p\n", pdev);
+                err = -ENODEV;
+                goto err_out_disable_pdev;
+        }
+
+        if((err = pci_request_regions(pdev, netxen_nic_driver_name))) {
+                DPRINTK(1, ERR, "Cannot find proper PCI resources"
+                                    " aborting:%d\n", err);
+                goto err_out_disable_pdev;
+        }
+
+        pci_set_master(pdev);
+
+        if(!(err = pci_set_dma_mask(pdev, PCI_DMA_64BIT)) &&
+           !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
+                pci_using_dac = 1;
+        } else {
+                if((err = pci_set_dma_mask(pdev, PCI_DMA_32BIT)) ||
+                   (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
+                        DPRINTK(1, ERR, "No usable DMA configuration,"
+                                        " aborting:%d\n", err);
+                        goto err_out_free_res;
+                }
+                pci_using_dac = 0;
+        }
+        DPRINTK(1, INFO, "pci_using_dac: %d\n", pci_using_dac);
+
+        /* 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 */
+        DPRINTK(1, INFO, "ioremap from %lx a size of %lx\n", mem_base,
+                            mem_len);
+        mem_ptr = ioremap(mem_base, NetXen_PCI_MAPSIZE_BYTES);
+        if (mem_ptr == 0UL) {
+                DPRINTK(1, ERR, "Cannot remap adapter memory aborting.:%p\n",
+                                    mem_ptr);
+                err = -EIO;
+                goto err_out_free_res;
+        }
+        DPRINTK(1, ERR, "ioremaped at %p\n", mem_ptr);
+
+/*
+ *      Allocate a adapter structure which will manage all the initialization
+ *      as well as the common resources for all ports...
+ *      all the ports will have pointer to this adapter as well as Adapter
+ *      will have pointers of all the ports structures.
+ */
+
+        /* One adapter structure for all 4 ports....   */
+        adapter = (struct netxen_adapter_s *)kmalloc(sizeof(struct 
netxen_adapter_s),
+                                                    GFP_KERNEL);
+        if (adapter == NULL) {
+                DPRINTK(1, ERR, "Could not allocate adapter memory:%d\n",
+                                    (int)sizeof(struct netxen_adapter_s));
+                err = -ENOMEM;
+                goto err_out_iounmap;
+        }
+
+       if (netxen_cards_found == 0) {
+               g_adapter = adapter;
+               spin_lock_init(&hal_lock);
+       }
+
+        /* Initialize to 0 */
+        memset(adapter, 0 , sizeof(struct netxen_adapter_s));
+        DPRINTK(1, INFO, "malloced memory at %p\n", adapter);
+
+        netxen_check_options(adapter);
+
+        cmd_buf_arr = (struct netxen_cmd_buffer*) vmalloc(TX_RINGSIZE);
+        if (cmd_buf_arr == NULL) {
+                DPRINTK(1, ERR, "Could not allocate command buffer array,"
+                                    " order :%d\n", get_order(TX_RINGSIZE));
+                err = -ENOMEM;
+                goto err_out_free_adapter;
+        }
+        memset (cmd_buf_arr, 0, TX_RINGSIZE);
+
+        for (i = 0; i < MAX_RCV_CTX; ++i) {
+                recv_ctx = &adapter->recv_ctx[i];
+                for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+                        rcv_desc = &recv_ctx->rcv_desc[ring];
+                        switch (RCV_DESC_TYPE(ring)) {
+                        case RCV_RING_STD:
+                                rcv_desc->MaxRxDescCount =
+                                                adapter->MaxRxDescCount;
+                                rcv_desc->flags = RCV_DESC_NORMAL;
+                                rcv_desc->dma_size = RX_DMA_MAP_LEN;
+                                rcv_desc->skb_size = MAX_RX_BUFFER_LENGTH;
+                                break;
+
+                        case RCV_RING_JUMBO:
+                                rcv_desc->MaxRxDescCount =
+                                                adapter->MaxJumboRxDescCount;
+                                rcv_desc->flags = RCV_DESC_JUMBO;
+                                rcv_desc->dma_size = RX_JUMBO_DMA_MAP_LEN;
+                                rcv_desc->skb_size =
+                                                MAX_RX_JUMBO_BUFFER_LENGTH;
+                                break;
+
+                        default:
+                                printk("%s: netxen_nic_probe: bad receive "
+                                       "descriptor type %d\n",
+                                       netxen_nic_driver_name,
+                                        RCV_DESC_TYPE(ring));
+                                break;
+                        }
+                        rcv_desc->rx_buf_arr = (struct netxen_rx_buffer*)
+                                                    pci_alloc_consistent(pdev,
+                                                    RCV_BUFFSIZE,
+                                                    &rcv_desc->rx_buf_phys);
+
+                        if(rcv_desc->rx_buf_arr == NULL) {
+                                DPRINTK(1, ERR, "Could not allocate rx"
+                                                " buffer array ring %d,"
+                                                " size:%u\n", ring,
+                                                (unsigned int)RCV_BUFFSIZE);
+                                err = -ENOMEM;
+                                goto err_out_free_rx_buffer;
+                        }
+                        memset (rcv_desc->rx_buf_arr, 0, RCV_BUFFSIZE);
+               }
+
+        }
+
+        adapter->cmd_buf_arr = cmd_buf_arr;
+        adapter->ahw.pci_base  = (unsigned long)mem_ptr;
+        adapter->ahw.pci_len   = mem_len;
+        adapter->ahw.crb_base  = adapter->ahw.pci_base + NetXen_PCI_CRBSPACE;
+        rwlock_init(&adapter->adapter_lock);
+        spin_lock_init(&adapter->tx_lock);
+        spin_lock_init(&adapter->lock);
+        initialize_adapter_sw(adapter); /* initialize the buffers in adapter */
+        /*
+         * Set the CRB window to invalid. If any register in window 0 is
+         * accessed it should set the window to 0 and then reset it to 1.
+         */
+        adapter->curr_window = 255;
+        /*
+         *  Adapter in our case is quad port so initialize it beofore
+         *  initializing the ports
+         */
+        initialize_adapter_hw(adapter);    /* initialize the adapter */
+        adapter->port =
+                (struct netxen_port**) kmalloc(sizeof(struct netxen_adapter_s)*
+                                                    (adapter->ahw.max_ports),
+                                                    GFP_KERNEL);
+        if (adapter->port == NULL) {
+                DPRINTK(1, ERR, "Could not allocate port-array memory:%d\n",
+                                    (int)sizeof(struct netxen_adapter_s) *
+                                    (adapter->ahw.max_ports));
+                err = -ENOMEM;
+                goto err_out_free_rx_buffer;
+        }
+        init_timer(&adapter->watchdog_timer);
+        adapter->ahw.xg_linkup = 0;
+        adapter->watchdog_timer.function = &netxen_watchdog;
+        adapter->watchdog_timer.data = (unsigned long) adapter;
+        INIT_WORK(&adapter->watchdog_task,
+                 (void (*)(void *))netxen_watchdog_task, adapter);
+        adapter->ahw.vendor_id = pdev->vendor;
+        adapter->ahw.device_id = pdev->device;
+        adapter->ahw.pdev      = pdev;
+        adapter->procCmdBufCounter = 0;
+        pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->ahw.revision_id);
+        pci_read_config_word(pdev, PCI_COMMAND, &adapter->ahw.pci_cmd_word);
+
+#if defined(CONFIG_PCI_MSI)
+        adapter->flags |= NetXen_NIC_MSI_ENABLED;
+        if (pci_enable_msi(pdev)) {
+                adapter->flags &= ~NetXen_NIC_MSI_ENABLED;
+                printk(KERN_WARNING "%s: unable to allocate MSI interrupt"
+                                    " error\n",netxen_nic_driver_name);
+        }
+#endif
+        netxen_nic_tune_phantom(pdev, adapter);
+
+        /* initialize the all the ports */
+        DPRINTK(1, INFO, "about to allocate all the %d net devs.\n",
+                            adapter->ahw.max_ports);
+        for (i = 0; i < adapter->ahw.max_ports; i ++) {
+                netlist = kmalloc(sizeof(netdev_list_t), GFP_KERNEL);
+                if (netlist == NULL) {
+                        goto err_out_free_dev;
+                }
+                netlist->netdev = alloc_etherdev(sizeof(struct netxen_port));
+                if(!netlist->netdev) {
+                        DPRINTK(1, ERR, " could not allocate netdev for port"
+                                        " %d\n",i+1);
+                        kfree(netlist);
+                        goto err_out_free_dev;
+                }
+                netdev = netlist->netdev;
+
+                SET_MODULE_OWNER(netdev);
+
+                port          = netdev->priv;
+                port->netdev  = netdev;
+                port->pdev    = pdev;
+                port->hw.port = port;
+                port->adapter = adapter;
+                port->portnum = i;  /* Gigabit port number starting from 0-3 */
+                port->flags   &= ~NETDEV_STATUS;
+
+                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;
+                netdev->do_ioctl           = netxen_nic_ioctl;
+                netdev->tx_timeout         = netxen_tx_timeout;
+                set_ethtool_ops(netdev);
+                /* FIXME: maybe 
SET_ETHTOOL_OPS(netdev,&netxen_nic_ethtool_ops);*/
+                netdev->irq                = pdev->irq;
+#ifdef NetXen_NIC_NAPI
+                netdev->poll               = netxen_nic_poll;
+                netdev->weight             = NetXen_NETDEV_WEIGHT;
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+               netdev->poll_controller    = netxen_nic_poll_controller;
+#endif
+#ifdef NetXen_NIC_HW_CSUM
+                /* ScatterGather support */
+                netdev->features           = NETIF_F_SG ;
+                netdev->features          |= NETIF_F_IP_CSUM;
+#endif
+#ifdef NetXen_NIC_HW_VLAN
+                netdev->features          |= NETIF_F_HW_VLAN_TX;
+                netdev->features          |= NETIF_F_HW_VLAN_RX;
+#endif
+#ifdef NetXen_NETIF_F_TSO
+                netdev->features          |= NETIF_F_TSO;
+#endif
+
+                if(pci_using_dac)
+                        netdev->features  |= NETIF_F_HIGHDMA;
+                DPRINTK(1, INFO, "setting mac address: %p\n", port);
+
+                /*
+                 * Allocate h/w address and set in h/w.
+                 * Eventually, we will read from the flash and set the mac
+                 * address.
+                 * For now set the lower 3 bytes to be same as board number
+                 */
+                boardno = netxen_nic_get_board_num(adapter);
+                port->hw.mac_addr[0] = 0x00;
+                port->hw.mac_addr[1] = 0x0e;
+                port->hw.mac_addr[2] = 0x1e;
+                port->hw.mac_addr[3] = ((boardno & (0xff << 16)) >> 16) + i;
+                port->hw.mac_addr[4] = (boardno  & (0xff << 8)) >> 8;
+                port->hw.mac_addr[5] = boardno & 0xff;
+                netxen_nic_macaddr_set (port, port->hw.mac_addr);
+                memcpy(netdev->dev_addr, port->hw.mac_addr, netdev->addr_len);
+                if(!is_valid_ether_addr(netdev->dev_addr)) {
+                        DPRINTK(1, ERR, "BAD MAC :is_valid_ether_addr"
+                                        " aborting:%d\n", err);
+                        break;
+                }
+                INIT_WORK(adapter->tx_timeout_task + i,
+                                (void (*)(void *))netxen_tx_timeout_task, 
netdev);
+                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);
+                        break;
+                }
+                procfile = create_proc_entry(netdev->name, S_IRUGO,
+                                                netxen_proc_dir_entry);
+                if (procfile) {
+                        procfile->data = netdev;
+                        procfile->owner = THIS_MODULE;
+                        procfile->read_proc = netxen_nic_port_read_proc;
+                }
+                adapter->activePorts = 0;
+                adapter->portCount ++;        /* number of ports allocated */
+                adapter->port[i] = port;
+                netlist->next = pci_get_drvdata(pdev);
+                pci_set_drvdata(pdev, netlist);
+        } /* For loop added by for number of ports  */
+
+        /*
+         * check how many ports were configured. If due to some errors,
+         * the port count == NULL, then free up the adapter structure,
+         * do ionetxenap() else add the adapter to the global adapter list
+         */
+
+        if (!adapter->portCount) {
+                /* unable to configure any port */
+                err = -EIO;
+                goto err_out_free_dev;
+        }
+
+        adapter->netlist = netlist;
+
+        /*
+         * Initialize all the CRB registers here.
+         */
+        /* Window = 1 */
+        read_lock(&adapter->adapter_lock);
+        NetXen_NIC_PCI_WRITE_32(0, CRB_NORMALIZE(adapter,
+                                                CRB_CMD_PRODUCER_OFFSET));
+        NetXen_NIC_PCI_WRITE_32(0, CRB_NORMALIZE(adapter, 
CRB_CMD_CONSUMER_OFFSET));
+        NetXen_NIC_PCI_WRITE_32(0, CRB_NORMALIZE(adapter, 
CRB_HOST_CMD_ADDR_LO));
+        read_unlock(&adapter->adapter_lock);
+
+
+//      tasklet_init(&adapter->tx_tasklet, netxen_process_cmd_ring,
+//                       (unsigned long)adapter);
+//      tasklet_disable(&adapter->tx_tasklet);
+        if (create_proc_read_entry(PROC_ENTRY_NAME, 0, netxen_proc_dir_entry,
+                                    netxen_nic_read_proc, adapter) == NULL) {
+                DPRINTK(1,INFO,"Error in creating proc entry.\n");
+        }
+
+        phantom_init(adapter);
+        /*
+         * delay a while to ensure that the Pegs are up & running.
+         * Otherwise, we might see some flaky behaviour.
+         */
+        mdelay(1000);
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_BRDTYPE_P2_SB35_4G:
+                printk("%s: QUAD GbE board 
initialized\n",netxen_nic_driver_name);
+                break;
+
+        case NetXen_BRDTYPE_P2_SB31_10G:
+        case NetXen_BRDTYPE_P2_SB31_10G_CX4:
+        case NetXen_BRDTYPE_P2_SB31_10G_IMEZ:
+        case NetXen_BRDTYPE_P2_SB31_10G_HMEZ:
+                printk("%s: XGbE board initialized\n",netxen_nic_driver_name);
+                break;
+        }
+
+       adapter->driver_mismatch = 0;
+        netxen_nic_flash_print(adapter);
+
+       adapterlist[netxen_cards_found++] = adapter;
+       adapter->number = netxen_cards_found;
+        netxen_nic_probe_err = 0;
+        return 0;
+
+err_out_free_dev:
+        for (netlist = pci_get_drvdata(pdev);  netlist != NULL; ) {
+                netdev_list_t *prev;
+                unregister_netdev(netlist->netdev);
+                free_netdev(netlist->netdev);
+                prev = netlist;
+                netlist = netlist->next;
+                kfree(prev);
+        }
+        kfree(netlist);
+        pci_set_drvdata(pdev, NULL);
+
+
+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++) {
+                        rcv_desc = &recv_ctx->rcv_desc[ring];
+                        if (rcv_desc->rx_buf_arr != NULL) {
+                                pci_free_consistent(pdev, RCV_BUFFSIZE,
+                                                       rcv_desc->rx_buf_arr,
+                                                       rcv_desc->rx_buf_phys);
+                                rcv_desc->rx_buf_arr = NULL;
+                        }
+                }
+        }
+
+        vfree (cmd_buf_arr);
+
+        kfree(adapter->port);
+
+err_out_free_adapter:
+        kfree (adapter);
+
+err_out_iounmap:
+        iounmap ((uint8_t *)mem_ptr) ;
+err_out_free_res:
+        pci_release_regions(pdev);
+err_out_disable_pdev:
+        pci_disable_device(pdev);
+        pci_set_drvdata(pdev, NULL);
+        netxen_nic_probe_err = err;
+        return err;
+}
+
+static void
+initialize_adapter_sw (struct netxen_adapter_s    *adapter)
+{
+        int                ctx, ring;
+        uint32_t           i;
+        uint32_t           num_rx_bufs = 0;
+        netxen_rcv_desc_ctx_t *rcv_desc;
+
+        adapter->freeCmdCount = adapter->MaxTxDescCount;
+        DPRINTK(1, INFO, "initializing some queues: %p\n", adapter);
+        for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+                for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+                        struct netxen_rx_buffer *rxBuf;
+                        rcv_desc    = &adapter->recv_ctx[ctx].rcv_desc[ring];
+                        rcv_desc->rcv_free = rcv_desc->MaxRxDescCount;
+                        /* Initialize the queues for both receive and
+                           command buffers */
+                        (&rcv_desc->free_rxbuf_list)->tqh_first = NULL;
+                        (&rcv_desc->free_rxbuf_list)->tqh_last =
+                                &(&rcv_desc->free_rxbuf_list)->tqh_first;
+                        (&rcv_desc->busy_rxbuf_list)->tqh_first = NULL;
+                        (&rcv_desc->busy_rxbuf_list)->tqh_last =
+                                &(&rcv_desc->busy_rxbuf_list)->tqh_first;
+
+                        rxBuf       = rcv_desc->rx_buf_arr;
+                        num_rx_bufs = rcv_desc->MaxRxDescCount;
+                        /*
+                         * Now go through all of them, set reference handles
+                         * and put them in the queues.
+                         */
+                        for (i=0; i < num_rx_bufs; i ++) {
+                                rxBuf->refHandle = i;
+
+                               rxBuf->link.tqe_next = NULL;
+                               rxBuf->link.tqe_prev =
+                                       (&rcv_desc->free_rxbuf_list)->tqh_last;
+                               *(&rcv_desc->free_rxbuf_list)->tqh_last =rxBuf;
+                               (&rcv_desc->free_rxbuf_list)->tqh_last =
+                                       &(rxBuf)->link.tqe_next;
+
+                                DPRINTK(1, INFO, "Rx buf:ctx%d i(%d) rxBuf:"
+                                                    "%p\n", ctx, i,rxBuf);
+                                rxBuf ++;
+                        }
+                }
+        }
+        DPRINTK(1, INFO, "initialized buffers for %s and %s\n",
+                            "adapter->free_cmd_buf_list",
+                            "adapter->free_rxbuf");
+        return;
+}
+
+static int
+initialize_adapter_hw(struct netxen_adapter_s *adapter)
+{
+        uint32_t value = 0;
+
+        if (netxen_nic_get_board_info(adapter) != 0) {
+            printk("%s: Error getting board config info.\n",
+                   netxen_nic_driver_name);
+        }
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                adapter->ahw.max_ports = 4;
+                break;
+
+        case NetXen_NIC_XGBE:
+                adapter->ahw.max_ports = 1;
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+
+        /* now we do the loadimage...so wait before doing anytining alselll */
+
+        return value;
+}
+
+/* Tuning for performance */
+static void
+netxen_nic_tune_phantom(struct pci_dev *pdev, struct netxen_adapter_s *adapter)
+{
+        struct pci_dev *bdev;
+        uint16_t dcr_word;
+        uint32_t netxen_dcr_word;
+        int cap, maxpayload;
+
+        bdev = pdev->bus->self;
+        if (bdev) {
+
+                /* override minimum read request, payload size settings */
+                netxen_nic_write_w0 (adapter, 
NetXen_PCIE_REG(PCIE_IMBUS_CONTROL),
+                                   0);
+
+                /* DMA transfer size */
+                netxen_nic_write_w0 (adapter,
+                                   NetXen_PCIE_REG(PCIE_MAX_DMA_XFER_SIZE),
+                                   0x201);
+
+                cap = pci_find_capability(bdev, PCI_CAP_ID_EXP);
+
+                if (cap) {
+                        if (pci_read_config_word(bdev, cap + PCI_EXP_DEVCTL,
+                                                    &dcr_word)) {
+                                printk(KERN_ERR "%s: could not read PCI EXP"
+                                    " device 
control.\n",netxen_nic_driver_name);
+                                return;
+                        }
+                } else {
+                        printk(KERN_ERR "%s: could not find bridge express"
+                                    " cpability .\n",netxen_nic_driver_name);
+                        return;
+                }
+                maxpayload = ((dcr_word & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+                printk(KERN_ERR "%s: got maxpayload = %x from dcr_word:%x\n",
+                        netxen_nic_driver_name, maxpayload, dcr_word);
+
+                /* enable error reporting, read requst size = 256 */
+                netxen_dcr_word = PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_FERE
+                                    | (1<<12);
+
+                /*match max payload size of the bridge, but no more than 512*/
+                if ((dcr_word & PCI_EXP_DEVCTL_PAYLOAD) <= (2 << 5)) {
+                        /* set equal to bridge's payload size */
+                        netxen_dcr_word |= (dcr_word & PCI_EXP_DEVCTL_PAYLOAD);
+                } else {
+                        /* set to 512 byte payload size */
+                        netxen_dcr_word |=  (2<<5);
+                }
+
+                printk(KERN_ERR "%s: Writing 0x%x to NetXen PCIE_DCR\n",
+                               netxen_nic_driver_name,netxen_dcr_word);
+                netxen_nic_write_w0 (adapter, NetXen_PCIE_REG(PCIE_DCR),
+                                    netxen_dcr_word);
+                switch (maxpayload) {
+                case 0:
+                        printk(KERN_INFO "%s: 128 Byte Max payload size\n",
+                               netxen_nic_driver_name);
+                        /* DMA transfer size */
+                        netxen_nic_write_w0 (adapter,
+                                           
NetXen_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN),
+                                           0x08b000ba);
+                        /* max splits = 8 */
+                        netxen_nic_write_w0 (adapter,
+                                          
NetXen_PCIE_REG(PCIE_MAX_MASTER_SPLIT),
+                                          0x844);
+                        break;
+
+                case 1:
+                        printk(KERN_INFO "%s: 256 Byte max payload size\n",
+                                       netxen_nic_driver_name);
+                        /* DMA transfer size */
+                        netxen_nic_write_w0 (adapter,
+                                           
NetXen_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN),
+                                           0x08b010ba);
+                        /* max splits = 4 */
+                        netxen_nic_write_w0 (adapter,
+                                          
NetXen_PCIE_REG(PCIE_MAX_MASTER_SPLIT),
+                                          0x422);
+                        break;
+
+                default:
+                        printk(KERN_INFO "%s: default(128B) max payload 
size\n",
+                                       netxen_nic_driver_name);
+                        /* DMA transfer size */
+                        netxen_nic_write_w0 (adapter,
+                                           
NetXen_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN),
+                                           0x08b000ba);
+                        /* max splits = 8 */
+                        netxen_nic_write_w0 (adapter,
+                                          
NetXen_PCIE_REG(PCIE_MAX_MASTER_SPLIT),
+                                          0x844);
+                        break;
+
+                }
+
+        }
+
+        return;
+}
+
+static void
+netxen_free_hw_resources(struct netxen_adapter_s *adapter)
+{
+        netxen_recv_context_t *recv_ctx;
+        netxen_rcv_desc_ctx_t *rcv_desc;
+        int                 ctx, ring;
+
+        if (adapter->ahw.cmdDescHead != NULL) {
+                pci_free_consistent(adapter->ahw.pdev,
+                                    sizeof(cmdDescType0_t) *
+                                    adapter->MaxTxDescCount,
+                                    adapter->ahw.cmdDescHead,
+                                    adapter->ahw.cmdDesc_physAddr);
+                adapter->ahw.cmdDescHead = NULL;
+        }
+
+        for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+                recv_ctx = &adapter->recv_ctx[ctx];
+                for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+                        rcv_desc = &recv_ctx->rcv_desc[ring];
+
+                        if (rcv_desc->desc_head != NULL) {
+                                pci_free_consistent(adapter->ahw.pdev,
+                                                    RCV_DESC_RINGSIZE,
+                                                    rcv_desc->desc_head,
+                                                    rcv_desc->phys_addr);
+                                rcv_desc->desc_head = NULL;
+                        }
+                }
+
+                if (recv_ctx->rcvStatusDescHead != NULL) {
+                        pci_free_consistent(adapter->ahw.pdev,
+                                            STATUS_DESC_RINGSIZE,
+                                            recv_ctx->rcvStatusDescHead,
+                                            recv_ctx->rcvStatusDesc_physAddr);
+                        recv_ctx->rcvStatusDescHead = NULL;
+                }
+        }
+
+        return;
+}
+
+static void __devexit
+netxen_nic_remove(struct pci_dev *pdev)
+{
+        struct netxen_adapter_s *adapter;
+        netdev_list_t        *netlist;
+        struct netxen_rx_buffer *buffer;
+        netxen_recv_context_t   *recv_ctx;
+        netxen_rcv_desc_ctx_t   *rcv_desc;
+        int                   i;
+        int                   ctx, ring;
+
+        remove_proc_entry(PROC_ENTRY_NAME, netxen_proc_dir_entry);
+        netlist = pci_get_drvdata(pdev);
+        if (netlist == NULL || netlist->netdev == NULL) {
+                return;
+        }
+        adapter = ((struct netxen_port *)(netlist->netdev->priv))->adapter;
+        if (adapter == NULL) {
+                return;
+        }
+
+        netxen_nic_stop_all_ports(adapter);
+        /* leave the hw in the same state as reboot */
+        pinit_from_rom(adapter, 0);
+        udelay(500);
+        load_firmware(adapter);
+
+#ifndef SINGLE_DMA_BUF
+        if ((adapter->flags & NetXen_NIC_MSI_ENABLED)) {
+               read_lock(&adapter->adapter_lock);
+                netxen_nic_disable_int(adapter);
+               read_unlock(&adapter->adapter_lock);
+        }
+#endif
+        udelay(500);    /* Delay for a while to drain the DMA engines */
+
+        netlist = pci_get_drvdata(pdev);
+        if (netlist != NULL) {
+#ifndef SINGLE_DMA_BUF
+                free_irq(netlist->netdev->irq, adapter);
+#endif
+                if ((adapter->flags & NetXen_NIC_MSI_ENABLED)) {
+                        pci_disable_msi(pdev);
+                }
+        }
+        while (netlist != NULL) {
+                netdev_list_t *prev;
+
+                remove_proc_entry(netlist->netdev->name, 
netxen_proc_dir_entry);
+                unregister_netdev(netlist->netdev);
+                free_netdev(netlist->netdev);
+                prev = netlist;
+                netlist = netlist->next;
+                kfree(prev);
+        }
+        adapter->netlist = NULL;
+        pci_set_drvdata(pdev, NULL);
+
+        netxen_free_hw_resources(adapter);
+
+        iounmap((uint8_t*)adapter->ahw.pci_base);
+
+        pci_release_regions(pdev);
+        pci_disable_device(pdev);
+

-
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