Netdev List
 help / color / mirror / Atom feed
* [PATCH 8/9] NetXen 1G/10G ethernet driver patch with corrections
From: Linsys Contractor Amit S. Kale @ 2006-06-07  9:55 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, unmproj

2006-06-07 Amit S. Kale <amitkale@unminc.com>
 	* Add netxen driver main routines: module initialization, probe,
 	  xmit, receive, interrupt handler

diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_main.c linux-2.6.16.20/drivers/net/netxen/netxen_nic_main.c
--- linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_main.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/netxen_nic_main.c	2006-06-06 06:58:11.000000000 -0700
@@ -0,0 +1,1228 @@
+/*
+ * 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:
+ *    info@netxen.com
+ * NetXen,
+ * 3965 Freedom Circle, Fourth floor,
+ * Santa Clara, CA 95054
+ *
+ *
+ *  Main source file for NetXen NIC Driver on Linux
+ *
+ */
+
+#include "netxen_nic.h"
+
+#define DEFINE_GLOBAL_RECV_CRB
+#include "netxen_nic_phan_reg.h"
+#include "netxen_nic_ioctl.h"
+
+MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID);
+
+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;
+
+#define NETXEN_NETDEV_WEIGHT 120
+#define NETXEN_ADAPTER_UP_MAGIC 777
+
+static int netxen_nic_probe_err = 0;
+
+/* 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 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 void netxen_tx_timeout(struct net_device *netdev);
+static void netxen_tx_timeout_task(struct net_device *netdev);
+static void netxen_watchdog(unsigned long);
+static int netxen_handle_int(struct netxen_adapter *, struct net_device *);
+static int netxen_nic_ioctl(struct net_device *netdev,
+			    struct ifreq *ifr, int cmd);
+static int netxen_nic_poll(struct net_device *dev, int *budget);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void netxen_nic_poll_controller(struct net_device *netdev);
+#endif
+static irqreturn_t netxen_intr(int irq, void *data, struct pt_regs *regs);
+
+/*  PCI Device ID Table  */
+static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
+	NETXEN_PCI_ID(PCI_DEVICE_ID_NX_QG),
+	NETXEN_PCI_ID(PCI_DEVICE_ID_NX_XG),
+	NETXEN_PCI_ID(PCI_DEVICE_ID_NX_CX4),
+	NETXEN_PCI_ID(PCI_DEVICE_ID_NX_IMEZ),
+	NETXEN_PCI_ID(PCI_DEVICE_ID_NX_HMEZ),
+	{0,}
+};
+
+MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
+
+struct netxen_adapter *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 vendor 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 *adapter = NULL;
+	struct netxen_port *port = NULL;
+	u8 *mem_ptr = NULL;
+	u8 *db_ptr = NULL;
+	unsigned long mem_base, mem_len, db_base, db_len;
+	int pci_using_dac, i, err;
+	int boardno = 0;
+	int ring;
+	struct netxen_recv_context *recv_ctx = NULL;
+	struct netxen_rcv_desc_ctx *rcv_desc = NULL;
+	struct netxen_cmd_buffer *cmd_buf_arr[MAX_RING_CTX] = { NULL };
+	struct netxen_ring_context *ctx;
+	static int netxen_cards_found = 0;
+	u64 mac_addr[FLASH_NUM_PORTS + 1];
+	int valid_mac;
+
+	if ((err = pci_enable_device(pdev))) {
+		netxen_nic_probe_err = err;
+		return err;
+	}
+	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+		err = -ENODEV;
+		goto err_out_disable_pdev;
+	}
+
+	if ((err = pci_request_regions(pdev, netxen_nic_driver_name)))
+		goto err_out_disable_pdev;
+
+	pci_set_master(pdev);
+	if ((pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) &&
+	    (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) == 0))
+		pci_using_dac = 1;
+	else {
+		if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
+		    (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)))
+			goto err_out_free_res;
+
+		pci_using_dac = 0;
+	}
+
+	/* 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_ptr = ioremap(mem_base, NETXEN_PCI_MAPSIZE_BYTES);
+	if (mem_ptr == 0UL) {
+		printk(KERN_ERR "%s: Cannot ioremap adapter memory aborting."
+		       ":%p\n", netxen_nic_driver_name, mem_ptr);
+		err = -EIO;
+		goto err_out_free_res;
+	}
+	db_base = pci_resource_start(pdev, 4);	/* doorbell is on bar 4 */
+	db_len = pci_resource_len(pdev, 4);
+
+	if (db_len == 0) {
+		printk(KERN_ERR "%s: doorbell is disabled\n",
+		       netxen_nic_driver_name);
+		err = -EIO;
+		goto err_out_free_res;
+	}
+
+	DPRINTK(1, INFO, "doorbell ioremap from %lx a size of %lx\n", db_base,
+		db_len);
+
+	db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES);
+	if (db_ptr == 0UL) {
+		printk(KERN_ERR "%s: Failed to allocate doorbell map.",
+		       netxen_nic_driver_name);
+		err = -EIO;
+		goto err_out_free_res;
+	}
+	DPRINTK(1, INFO, "doorbell ioremaped at %p\n", db_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 = kzalloc(sizeof(struct netxen_adapter), GFP_KERNEL);
+	if (adapter == NULL) {
+		printk(KERN_ERR "%s: Could not allocate adapter memory:%d\n",
+		       netxen_nic_driver_name,
+		       (int)sizeof(struct netxen_adapter));
+		err = -ENOMEM;
+		goto err_out_iounmap;
+	}
+
+	netxen_check_options(adapter);
+	for (i = 0; i < MAX_RING_CTX; i++) {
+		cmd_buf_arr[i] =
+		    (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE(i));
+		if (cmd_buf_arr[i] == NULL) {
+			printk(KERN_ERR "%s: Failed to allocate memory for the"
+			       "device block.Check system memory resource "
+			       "usage.\n", netxen_nic_driver_name);
+			err = -ENOMEM;
+			goto err_out_free_adapter;
+		}
+		memset(cmd_buf_arr[i], 0, TX_RINGSIZE(i));
+	}
+
+	for (i = 0; i < MAX_RING_CTX; ++i) {
+		ctx = &adapter->ring_ctx[i];
+		recv_ctx = &ctx->recv_ctx;
+		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+			switch (RCV_DESC_TYPE(ring)) {
+			case RCV_DESC_NORMAL:
+				rcv_desc->max_rx_desc_count =
+				    ctx->max_rx_desc_count;
+				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_DESC_JUMBO:
+				rcv_desc->max_rx_desc_count =
+				    ctx->max_jumbo_rx_desc_count;
+				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) {
+				err = -ENOMEM;
+				goto err_out_free_rx_buffer;
+			}
+			memset(rcv_desc->rx_buf_arr, 0, RCV_BUFFSIZE);
+		}
+
+	}
+
+	for (i = 0; i < MAX_RING_CTX; ++i) {
+		ctx = &adapter->ring_ctx[i];
+		ctx->cmd_buf_arr = cmd_buf_arr[i];
+	}
+	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;
+	adapter->ahw.db_base = (unsigned long)db_ptr;
+	adapter->ahw.db_len = db_len;
+	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 = kcalloc(adapter->ahw.max_ports,
+				sizeof(struct netxen_adapter), GFP_KERNEL);
+	if (adapter->port == NULL) {
+		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;
+	for (i = 0; i < MAX_RING_CTX; i++) {
+		adapter->ring_ctx[i].proc_cmd_buf_counter = 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 (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);
+	} else
+		adapter->flags |= NETXEN_NIC_MSI_ENABLED;
+
+	if (is_flash_supported(adapter) == 0 &&
+	    get_flash_mac_addr(adapter, mac_addr) == 0)
+		valid_mac = 1;
+	else
+		valid_mac = 0;
+
+	/* initialize the all the ports */
+
+	for (i = 0; i < adapter->ahw.max_ports; i++) {
+		netdev = alloc_etherdev(sizeof(struct netxen_port));
+		if (netdev) {
+			printk(KERN_ERR "%s: could not allocate netdev for port"
+			       " %d\n", netxen_nic_driver_name, i + 1);
+			goto err_out_free_dev;
+		}
+
+		SET_MODULE_OWNER(netdev);
+
+		port = netdev_priv(netdev);
+		port->netdev = netdev;
+		port->pdev = pdev;
+		port->adapter = adapter;
+		port->portnum = i;	/* Gigabit port number starting from 0-3 */
+		port->flags &= ~NETXEN_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, &netxen_nic_ethtool_ops);
+
+		netdev->irq = pdev->irq;
+		netdev->poll = netxen_nic_poll;
+		netdev->weight = NETXEN_NETDEV_WEIGHT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+		netdev->poll_controller = netxen_nic_poll_controller;
+#endif
+		/* ScatterGather support */
+		netdev->features = NETIF_F_SG;
+		netdev->features |= NETIF_F_IP_CSUM;
+		netdev->features |= NETIF_F_TSO;
+
+		if (pci_using_dac)
+			netdev->features |= NETIF_F_HIGHDMA;
+
+		boardno = netxen_nic_get_board_num(adapter);
+		if (valid_mac) {
+			unsigned char *p = (unsigned char *)&mac_addr[i];
+			netdev->dev_addr[0] = *(p + 5);
+			netdev->dev_addr[1] = *(p + 4);
+			netdev->dev_addr[2] = *(p + 3);
+			netdev->dev_addr[3] = *(p + 2);
+			netdev->dev_addr[4] = *(p + 1);
+			netdev->dev_addr[5] = *(p + 0);
+
+			memcpy(netdev->perm_addr, netdev->dev_addr,
+				netdev->addr_len); 
+			if (!is_valid_ether_addr(netdev->perm_addr)) {
+				printk(KERN_ERR "%s: Bad MAC address "
+					"%02x:%02x:%02x:%02x:%02x:%02x.\n",
+				       netxen_nic_driver_name,
+				       netdev->dev_addr[0],
+				       netdev->dev_addr[1],
+				       netdev->dev_addr[2],
+				       netdev->dev_addr[3],
+				       netdev->dev_addr[4],
+				       netdev->dev_addr[5]);
+			} else {
+				netxen_nic_macaddr_set(port, netdev->dev_addr);
+			}
+		}
+		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))) {
+			printk(KERN_ERR "%s: register_netdev failed port #%d"
+			       " aborting\n", netxen_nic_driver_name, i + 1);
+			break;
+		}
+		adapter->active_ports = 0;
+		adapter->port_count++;	/* number of ports allocated */
+		adapter->port[i] = port;
+		pci_set_drvdata(pdev, port);
+	}
+
+	/*
+	 * check how many ports were configured. If due to some errors,
+	 * the port count == NULL, then free up the adapter structure,
+	 * do iounmap() else add the adapter to the global adapter list
+	 */
+
+	if (!adapter->port_count) {
+		/* unable to configure any port */
+		err = -EIO;
+		goto err_out_free_dev;
+	}
+
+	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;
+
+	adapterlist[netxen_cards_found++] = adapter;
+	adapter->number = netxen_cards_found;
+	netxen_nic_probe_err = 0;
+	return 0;
+
+      err_out_free_dev:
+	for (port = pci_get_drvdata(pdev); port != NULL;) {
+		unregister_netdev(port->netdev);
+		free_netdev(port->netdev);
+		if (port->portnum <= 0)
+			break;
+		port = adapter->port[port->portnum - 1];
+	}
+	pci_set_drvdata(pdev, NULL);
+
+      err_out_free_rx_buffer:
+	for (i = 0; i < MAX_RING_CTX; ++i) {
+		ctx = &adapter->ring_ctx[i];
+		recv_ctx = &ctx->recv_ctx;
+		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:
+	for (i = 0; i < MAX_RING_CTX; i++) {
+		if (cmd_buf_arr[i] != NULL)
+			vfree(cmd_buf_arr[i]);
+	}
+
+	kfree(adapter);
+
+      err_out_iounmap:
+	iounmap((u8 *) 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 __devexit netxen_nic_remove(struct pci_dev *pdev)
+{
+	struct netxen_adapter *adapter;
+	struct netxen_port *port;
+	struct netxen_rx_buffer *buffer;
+	struct netxen_recv_context *recv_ctx;
+	struct netxen_rcv_desc_ctx *rcv_desc;
+	struct netxen_ring_context *ctx;
+	int i;
+	int ctxid, ring;
+
+	port = pci_get_drvdata(pdev);
+	if (port == NULL || port->netdev == NULL)
+		return;
+	adapter = ((struct netxen_port *)(netdev_priv(port->netdev)))->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);
+
+	if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+		read_lock(&adapter->adapter_lock);
+		netxen_nic_disable_int(adapter);
+		read_unlock(&adapter->adapter_lock);
+	}
+	udelay(500);		/* Delay for a while to drain the DMA engines */
+
+	port = pci_get_drvdata(pdev);
+	if (adapter->irq)
+		free_irq(adapter->irq, adapter);
+	if ((adapter->flags & NETXEN_NIC_MSI_ENABLED))
+		pci_disable_msi(pdev);
+	while (port != NULL) {
+		unregister_netdev(port->netdev);
+		free_netdev(port->netdev);
+		if (port->portnum <= 0)
+			break;
+		port = adapter->port[port->portnum - 1];
+	}
+	pci_set_drvdata(pdev, NULL);
+
+	netxen_free_hw_resources(adapter);
+
+	iounmap((u8 *) adapter->ahw.pci_base);
+
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+
+	for (ctxid = 0; ctxid < MAX_RING_CTX; ++ctxid) {
+		ctx = &adapter->ring_ctx[ctxid];
+		recv_ctx = &ctx->recv_ctx;
+		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+			for (i = 0; i < rcv_desc->max_rx_desc_count; ++i) {
+				buffer = &(rcv_desc->rx_buf_arr[i]);
+				if (buffer->state == NETXEN_BUFFER_FREE)
+					continue;
+				pci_unmap_single(pdev, buffer->dma,
+						 rcv_desc->dma_size,
+						 PCI_DMA_FROMDEVICE);
+				if (buffer->skb != NULL)
+					dev_kfree_skb_any(buffer->skb);
+			}
+			pci_free_consistent(pdev, RCV_BUFFSIZE,
+					    rcv_desc->rx_buf_arr,
+					    rcv_desc->rx_buf_phys);
+		}
+		vfree(ctx->cmd_buf_arr);
+	}
+
+	kfree(adapter->port);
+	kfree(adapter);
+}
+
+/*
+ * Called when a network interface is made active
+ * @returns 0 on success, negative value on failure
+ */
+static int netxen_nic_open(struct net_device *netdev)
+{
+	struct netxen_port *port = netdev_priv(netdev);
+	struct netxen_adapter *adapter = port->adapter;
+	int err = 0;
+	int ctxid, ring;
+	static int opencount = 0;
+
+	if (!try_module_get(THIS_MODULE))
+		return -ENODEV;
+
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
+		err = init_firmware(adapter);
+		if (err != 0) {
+			printk(KERN_ERR "Failed to init firmware\n");
+			module_put(THIS_MODULE);
+			return -EIO;
+		}
+		netxen_nic_flash_print(adapter);
+
+		printk("NetXen adapter %d\n", opencount);
+		adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
+		/* setup all the resources for the Phantom... */
+		/* this include the descriptors for rcv, tx, and status */
+		netxen_nic_clear_stats(adapter);
+		err = netxen_nic_hw_resources(adapter);
+		if (err) {
+			printk(KERN_ERR "Error in setting hw resources:%d\n",
+			       err);
+			module_put(THIS_MODULE);
+			return err;
+		}
+		if (netxen_nic_init_port(port) != 0) {
+			printk(KERN_ERR "%s: Failed to initialize port %d\n",
+			       netxen_nic_driver_name, port->portnum);
+			module_put(THIS_MODULE);
+			netxen_free_hw_resources(adapter);
+			return -EIO;
+		}
+		netxen_nic_init_niu(adapter);
+		for (ctxid = 0; ctxid < MAX_RING_CTX; ++ctxid) {
+			for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+				netxen_post_rx_buffers(adapter, ctxid, ring);
+			}
+		}
+
+		err = request_irq(netdev->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);
+			module_put(THIS_MODULE);
+			return err;
+		}
+		adapter->irq = netdev->irq;
+		mod_timer(&adapter->watchdog_timer, jiffies);
+	}
+	++opencount;
+	adapter->active_ports++;
+	if (adapter->active_ports == 1) {
+		read_lock(&adapter->adapter_lock);
+		netxen_nic_enable_int(adapter);
+		read_unlock(&adapter->adapter_lock);
+	}
+
+	spin_lock_init(&port->stats_lock);
+
+	/* Done here again so that even if phantom sw overwrote it,
+	   we set it */
+	netxen_nic_macaddr_set(port, netdev->dev_addr);
+	netxen_nic_set_link_parameters(port);
+
+	netxen_nic_set_multi(netdev);
+	if (!adapter->driver_mismatch)
+		netif_start_queue(netdev);
+
+	return 0;
+}
+
+/**
+ * netxen_nic_close - Disables a network interface entry point
+ **/
+static int netxen_nic_close(struct net_device *netdev)
+{
+	struct netxen_port *port = netdev_priv(netdev);
+
+	netif_carrier_off(netdev);
+	netif_stop_queue(netdev);
+
+	netxen_nic_down(port);
+
+	module_put(THIS_MODULE);
+	return 0;
+}
+
+static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct netxen_port *port = netdev_priv(netdev);
+	unsigned int nr_frags = 0;
+	struct netxen_adapter *adapter = port->adapter;
+	struct pci_dev *pdev;
+	unsigned int first_seg_len = skb->len - skb->data_len;
+	struct netxen_skb_frag *buffrag;
+	unsigned int i;
+	int ctxid = 0;
+	u32 producer = 0;
+	u32 saved_producer = 0;
+	struct cmd_desc_type0_t *hwdesc;
+	int k;
+	struct netxen_cmd_buffer *pbuf = NULL;
+	unsigned int tries = 0;
+	static int dropped_packet = 0;
+	struct netxen_skb_frag *frag;
+	int frag_count;
+	u32 local_producer = 0;
+	u32 max_tx_desc_count = 0;
+	u32 last_cmd_consumer = 0;
+	struct netxen_ring_context *ctx = &adapter->ring_ctx[0];
+	struct netxen_hardware_ring_context *hw_ring_ctx = &(ctx->hw_ring_ctx);
+	int no_of_desc;
+
+	port->stats.xmitcalled++;
+	nr_frags = skb_shinfo(skb)->nr_frags;
+	frag_count = 1 + nr_frags;
+
+	if (unlikely(skb->len <= 0)) {
+		dev_kfree_skb_any(skb);
+		port->stats.badskblen++;
+		return 0;
+	}
+
+	if (frag_count > MAX_BUFFERS_PER_CMD) {
+		printk
+		    ("%s: %s netxen_nic_xmit_frame: frag_count (%d) too large, "
+		     "can handle only %d frags\n", netxen_nic_driver_name,
+		     netdev->name, frag_count, MAX_BUFFERS_PER_CMD);
+		goto drop_packet;
+	}
+
+	/*
+	 * Everything is set up. Now, we just need to transmit it out.
+	 * Note that we have to copy the contents of buffer over to
+	 * right place. Later on, this can be optimized out by de-coupling the
+	 * producer index from the buffer index.
+	 */
+      retry_getting_window:
+	spin_lock_bh(&adapter->tx_lock);
+	if (adapter->total_threads == MAX_XMIT_PRODUCERS) {
+		spin_unlock_bh(&adapter->tx_lock);
+		/*
+		 * Yield CPU
+		 */
+		if (!in_atomic())
+			schedule();
+		else {
+			for (i = 0; i < 20; i++)
+				cpu_relax();	/*This a nop instr on i386 */
+		}
+		goto retry_getting_window;
+	}
+	local_producer = ctx->cmd_producer;
+	/* There 4 fragments per descriptor */
+	no_of_desc = (frag_count + 3) >> 2;
+	if (skb_shinfo(skb)->tso_size > 0) {
+		no_of_desc++;
+		if (((skb->nh.iph)->ihl * sizeof(u32)) +
+		    ((skb->h.th)->doff * sizeof(u32)) +
+		    sizeof(struct ethhdr) >
+		    (sizeof(struct cmd_desc_type0_t) - NET_IP_ALIGN)) {
+			no_of_desc++;
+		}
+	}
+	k = ctx->cmd_producer;
+	max_tx_desc_count = ctx->max_tx_desc_count;
+	last_cmd_consumer = ctx->last_cmd_consumer;
+	if ((k + no_of_desc) >=
+	    ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count :
+	     last_cmd_consumer)) {
+		spin_unlock_bh(&adapter->tx_lock);
+		if (tries == 0) {
+			local_bh_disable();
+			for (ctxid = 0; ctxid < MAX_RING_CTX; ++ctxid) {
+				netxen_process_cmd_ring((unsigned long)adapter,
+							ctxid);
+			}
+			local_bh_enable();
+			++tries;
+			goto retry_getting_window;
+		} else {
+			port->stats.nocmddescriptor++;
+			DPRINTK(ERR, "No command descriptors available,"
+				" producer = %d, consumer = %d count=%llu,"
+				" dropping packet\n", producer,
+				ctx->last_cmd_consumer,
+				port->stats.nocmddescriptor);
+			goto requeue_packet;
+		}
+	}
+	k = get_index_range(k, max_tx_desc_count, no_of_desc);
+	ctx->cmd_producer = k;
+	adapter->total_threads++;
+	adapter->num_threads++;
+
+	spin_unlock_bh(&adapter->tx_lock);
+	/* Copy the descriptors into the hardware    */
+	producer = local_producer;
+	saved_producer = producer;
+	hwdesc = &ctx->hw_ring_ctx.cmd_desc_head[producer];
+	memset(hwdesc, 0, sizeof(struct cmd_desc_type0_t));
+	/* Take skb->data itself */
+	pbuf = &ctx->cmd_buf_arr[producer];
+	if (skb_shinfo(skb)->tso_size > 0) {
+		pbuf->mss = skb_shinfo(skb)->tso_size;
+		hwdesc->mss = skb_shinfo(skb)->tso_size;
+	} else {
+		pbuf->mss = 0;
+		hwdesc->mss = 0;
+	}
+	pbuf->no_of_descriptors = no_of_desc;
+	pbuf->total_length = skb->len;
+	pbuf->skb = skb;
+	pbuf->cmd = TX_ETHER_PKT;
+	pbuf->frag_count = frag_count;
+	pbuf->port = port->portnum;
+	buffrag = &pbuf->frag_array[0];
+	buffrag->dma = pci_map_single(port->pdev, skb->data, first_seg_len,
+				      PCI_DMA_TODEVICE);
+	buffrag->length = first_seg_len;
+	hwdesc->total_length = skb->len;
+	hwdesc->num_of_buffers = frag_count;
+	hwdesc->opcode = TX_ETHER_PKT;
+
+	hwdesc->port = port->portnum;
+	hwdesc->buffer1_length = first_seg_len;
+	hwdesc->addr_buffer1 = buffrag->dma;
+
+	for (i = 1, k = 1; i < frag_count; i++, k++) {
+		struct skb_frag_struct *frag;
+		int len, temp_len;
+		unsigned long offset;
+		dma_addr_t temp_dma;
+
+		/* move to next desc. if there is a need */
+		if ((i & 0x3) == 0) {
+			k = 0;
+			producer = get_next_index(producer,
+						  ctx->max_tx_desc_count);
+			hwdesc = &ctx->hw_ring_ctx.cmd_desc_head[producer];
+			memset(hwdesc, 0, sizeof(struct cmd_desc_type0_t));
+		}
+		frag = &skb_shinfo(skb)->frags[i - 1];
+		len = frag->size;
+		offset = frag->page_offset;
+
+		temp_len = len;
+		temp_dma = pci_map_page(port->pdev, frag->page, offset,
+					len, PCI_DMA_TODEVICE);
+
+		buffrag++;
+		buffrag->dma = temp_dma;
+		buffrag->length = temp_len;
+
+		DPRINTK(INFO, "for loop. i=%d k=%d\n", i, k);
+		switch (k) {
+		case 0:
+			hwdesc->buffer1_length = temp_len;
+			hwdesc->addr_buffer1 = temp_dma;
+			break;
+		case 1:
+			hwdesc->buffer2_length = temp_len;
+			hwdesc->addr_buffer2 = temp_dma;
+			break;
+		case 2:
+			hwdesc->buffer3_length = temp_len;
+			hwdesc->addr_buffer3 = temp_dma;
+			break;
+		case 3:
+			hwdesc->buffer4_length = temp_len;
+			hwdesc->addr_buffer4 = temp_dma;
+			break;
+		}
+		frag++;
+	}
+	producer = get_next_index(producer, ctx->max_tx_desc_count);
+
+	/* might change opcode to TX_TCP_LSO */
+	netxen_tso_check(adapter, &hw_ring_ctx->cmd_desc_head[saved_producer],
+			 skb);
+
+	/* For LSO, we need to copy the MAC/IP/TCP headers into
+	 * the descriptor ring
+	 */
+	if (hw_ring_ctx->cmd_desc_head[saved_producer].opcode == TX_TCP_LSO) {
+		int hdr_len, first_hdr_len, more_hdr;
+		hdr_len =
+		    hw_ring_ctx->cmd_desc_head[saved_producer].total_hdr_length;
+		if (hdr_len > (sizeof(struct cmd_desc_type0_t) - NET_IP_ALIGN)) {
+			first_hdr_len =
+			    sizeof(struct cmd_desc_type0_t) - NET_IP_ALIGN;
+			more_hdr = 1;
+		} else {
+			first_hdr_len = hdr_len;
+			more_hdr = 0;
+		}
+		/* copy the MAC/IP/TCP headers to the cmd descriptor list */
+		hwdesc = &hw_ring_ctx->cmd_desc_head[producer];
+
+		/* copy the first 64 bytes */
+		memcpy(((void *)hwdesc) + NET_IP_ALIGN,
+		       (void *)(skb->data), first_hdr_len);
+		producer = get_next_index(producer, max_tx_desc_count);
+
+		if (more_hdr) {
+			hwdesc = &hw_ring_ctx->cmd_desc_head[producer];
+			/* copy the next 64 bytes - should be enough except
+			 * for pathological case
+			 */
+			memcpy((void *)hwdesc, (void *)(skb->data) +
+			       first_hdr_len, hdr_len - first_hdr_len);
+			producer = get_next_index(producer, max_tx_desc_count);
+		}
+	}
+	spin_lock_bh(&adapter->tx_lock);
+	port->stats.txbytes +=
+	    hw_ring_ctx->cmd_desc_head[saved_producer].total_length;
+	/* Code to update the adapter considering how many producer threads
+	   are currently working */
+	if ((--adapter->num_threads) == 0) {
+		/* This is the last thread */
+		u32 crb_producer = ctx->cmd_producer;
+		struct ctx_msg msg = { 0 };
+		hw_ring_ctx->cmd_producer = ctx->cmd_producer;
+		msg.PegId = NETXEN_XMIT_PEG_DB_ID;
+		msg.Count = crb_producer;
+		msg.CtxId = 0;
+		msg.Opcode = NETXEN_CMD_PRODUCER;
+		read_lock(&adapter->adapter_lock);
+		writel(*(u32 *) & msg,
+		       DB_NORMALIZE(adapter, NETXEN_CMD_PRODUCER_OFFSET(0)));
+		read_unlock(&adapter->adapter_lock);
+
+		adapter->total_threads = 0;
+	} else {
+		u32 crb_producer = 0;
+		struct ctx_msg msg = { 0 };
+		read_lock(&adapter->adapter_lock);
+		*(u32 *) & msg =
+		    readl(DB_NORMALIZE(adapter, NETXEN_CMD_PRODUCER_OFFSET(0)));
+		read_unlock(&adapter->adapter_lock);
+		crb_producer = msg.Count;
+
+		if (crb_producer == local_producer) {
+			crb_producer = get_index_range(crb_producer,
+						       max_tx_desc_count,
+						       no_of_desc);
+			msg.PegId = NETXEN_XMIT_PEG_DB_ID;
+			msg.Count = crb_producer;
+			msg.CtxId = 0;
+			msg.Opcode = NETXEN_CMD_PRODUCER;
+			read_lock(&adapter->adapter_lock);
+			writel(*(u32 *) & msg,
+			       DB_NORMALIZE(adapter,
+					    NETXEN_CMD_PRODUCER_OFFSET(0)));
+			read_unlock(&adapter->adapter_lock);
+
+			hw_ring_ctx->cmd_producer = crb_producer;
+		}
+	}
+
+	port->stats.xmitfinished++;
+	spin_unlock_bh(&adapter->tx_lock);
+
+	netdev->trans_start = jiffies;
+
+	DPRINTK(INFO, "wrote CMD producer %x to phantom\n", producer);
+
+	DPRINTK(INFO, "Done. Send\n");
+	goto netxen_nic_xmit_success;
+
+      requeue_packet:
+	spin_lock_bh(&adapter->tx_lock);
+	netif_stop_queue(netdev);
+	port->flags |= NETXEN_NETDEV_STATUS;
+	spin_unlock_bh(&adapter->tx_lock);
+	return NETDEV_TX_BUSY;
+
+      drop_packet:
+	pbuf = &ctx->cmd_buf_arr[producer];
+	frag = &pbuf->frag_array[0];
+	pdev = port->pdev;
+	pci_unmap_single(pdev, frag->dma, frag->length, PCI_DMA_TODEVICE);
+	for (i = 1; i < frag_count; i++) {
+		frag++;		/* Get the next frag */
+		pci_unmap_page(pdev, frag->dma, frag->length, PCI_DMA_TODEVICE);
+	}
+
+	port->stats.txdropped++;
+	dev_kfree_skb_any(pbuf->skb);
+	pbuf->skb = NULL;
+	if ((++dropped_packet & 0xff) == 0xff)
+		printk("%s: %s droppped packets = %d\n", netxen_nic_driver_name,
+		       netdev->name, dropped_packet);
+
+      netxen_nic_xmit_success:
+	return NETDEV_TX_OK;
+}
+
+static void netxen_watchdog(unsigned long v)
+{
+	struct netxen_adapter *adapter = (struct netxen_adapter *)v;
+	schedule_work(&adapter->watchdog_task);
+}
+
+static void netxen_tx_timeout(struct net_device *netdev)
+{
+	struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev);
+	struct netxen_adapter *adapter = port->adapter;
+
+	schedule_work(adapter->tx_timeout_task + port->portnum);
+}
+
+static void netxen_tx_timeout_task(struct net_device *netdev)
+{
+	struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev);
+	unsigned long flags;
+
+	printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
+	       netxen_nic_driver_name, netdev->name);
+
+	spin_lock_irqsave(&port->adapter->lock, flags);
+	netxen_nic_close(netdev);
+	netxen_nic_open(netdev);
+	spin_unlock_irqrestore(&port->adapter->lock, flags);
+	netdev->trans_start = jiffies;
+	netif_wake_queue(netdev);
+}
+
+static int
+netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+	u32 ret = 0;
+
+	DPRINTK(INFO, "Entered handle ISR\n");
+
+	adapter->stats.ints++;
+
+	if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+		int count = 0;
+		u32 mask;
+		read_lock(&adapter->adapter_lock);
+		netxen_nic_disable_int(adapter);
+		/* Window = 0 or 1 */
+		do {
+			writel(0xffffffff, (void *)
+			       (adapter->ahw.pci_base + ISR_INT_TARGET_STATUS));
+			mask = readl((void *)
+				     (adapter->ahw.pci_base + ISR_INT_VECTOR));
+		} while (((mask & 0x80) != 0) && (++count < 32));
+		if ((mask & 0x80) != 0)
+			printk("Could not disable interrupt completely\n");
+
+		read_unlock(&adapter->adapter_lock);
+	}
+	adapter->stats.hostints++;
+
+	if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) {
+		if (netif_rx_schedule_prep(netdev)) {
+			/*
+			 * Interrupts are already disabled.
+			 */
+			__netif_rx_schedule(netdev);
+		} else {
+			static unsigned int intcount = 0;
+			if ((++intcount & 0xfff) == 0xfff)
+				printk(KERN_ERR
+				       "%s: %s interrupt %d while in poll\n",
+				       netxen_nic_driver_name, netdev->name,
+				       intcount);
+		}
+		ret = 1;
+	}
+
+	if (ret == 0) {
+		read_lock(&adapter->adapter_lock);
+		netxen_nic_enable_int(adapter);
+		read_unlock(&adapter->adapter_lock);
+	}
+
+	return ret;
+}
+
+/**
+ * netxen_intr - Interrupt Handler
+ * @irq: interrupt number
+ * data points to adapter stucture (which may be handling more than 1 port
+ **/
+irqreturn_t netxen_intr(int irq, void *data, struct pt_regs * regs)
+{
+	struct netxen_adapter *adapter;
+	struct netxen_port *port;
+	struct net_device *netdev;
+
+	if (unlikely(!irq)) {
+		return IRQ_NONE;	/* Not our interrupt */
+	}
+
+	adapter = (struct netxen_adapter *)data;
+	port = adapter->port[0];
+	netdev = port->netdev;
+
+	/* process our status queue (for all 4 ports) */
+	netxen_handle_int(adapter, netdev);
+
+	return IRQ_HANDLED;
+}
+
+static int netxen_nic_poll(struct net_device *netdev, int *budget)
+{
+	struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev);
+	struct netxen_adapter *adapter = port->adapter;
+	int work_to_do = min(*budget, netdev->quota);
+	int done = 1;
+	int ctxid;
+	int this_work_done;
+
+	DPRINTK(INFO, "polling for %d descriptors\n", *budget);
+	port->stats.polled++;
+
+	adapter->work_done = 0;
+	for (ctxid = 0; ctxid < MAX_RING_CTX; ++ctxid) {
+		/*
+		 * Fairness issue. This will give undue weight to the
+		 * receive context 0.
+		 */
+
+		/*
+		 * To avoid starvation, we give each of our receivers,
+		 * a fraction of the quota. Sometimes, it might happen that we
+		 * have enough quota to process every packet, but since all the
+		 * packets are on one context, it gets only half of the quota,
+		 * and ends up not processing it.
+		 */
+		this_work_done = netxen_process_rcv_ring(adapter, ctxid,
+							 work_to_do /
+							 MAX_RING_CTX);
+		adapter->work_done += this_work_done;
+	}
+
+	netdev->quota -= adapter->work_done;
+	*budget -= adapter->work_done;
+
+	if (adapter->work_done >= work_to_do
+	    && netxen_nic_rx_has_work(adapter) != 0)
+		done = 0;
+
+	for (ctxid = 0; ctxid < MAX_RING_CTX; ++ctxid) {
+		netxen_process_cmd_ring((unsigned long)adapter, ctxid);
+	}
+
+	DPRINTK(INFO, "new work_done: %d work_to_do: %d\n",
+		adapter->work_done, work_to_do);
+	if (done) {
+		netif_rx_complete(netdev);
+		read_lock(&adapter->adapter_lock);
+		netxen_nic_enable_int(adapter);
+		read_unlock(&adapter->adapter_lock);
+	}
+
+	return (done ? 0 : 1);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void netxen_nic_poll_controller(struct net_device *netdev)
+{
+	struct netxen_port *port = netdev_priv(netdev);
+	struct netxen_adapter *adapter = port->adapter;
+	disable_irq(netdev->irq);
+	netxen_intr(netdev->irq, adapter, NULL);
+	enable_irq(netdev->irq);
+}
+#endif
+
+/*
+ * netxen_nic_ioctl ()    We provide the tcl/phanmon support through these
+ * ioctls.
+ */
+static int
+netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	int err = 0;
+	struct netxen_port *port = netdev_priv(netdev);
+	struct netxen_adapter *adapter = port->adapter;
+
+	DPRINTK(INFO, "doing ioctl for %s\n", netdev->name);
+	switch (cmd) {
+	case NETXEN_NIC_CMD:
+		err = netxen_nic_do_ioctl(adapter, (void *)ifr->ifr_data, port);
+		break;
+
+	case NETXEN_NIC_NAME:
+		DPRINTK(INFO, "ioctl cmd for NetXen\n");
+		if (ifr->ifr_data) {
+			put_user(port->portnum, (u16 *) ifr->ifr_data);
+		}
+		break;
+
+	default:
+		DPRINTK(INFO, "ioctl cmd %x not supported\n", cmd);
+		err = -EOPNOTSUPP;
+		break;
+	}
+
+	return err;
+}
+
+static struct pci_driver netxen_driver = {
+	.name = netxen_nic_driver_name,
+	.id_table = netxen_pci_tbl,
+	.probe = netxen_nic_probe,
+	.remove = __devexit_p(netxen_nic_remove),
+	.suspend = netxen_nic_suspend,
+	.resume = netxen_nic_resume
+};
+
+/* Driver Registration on NetXen card    */
+
+static int __init netxen_init_module(void)
+{
+	printk(KERN_INFO "%s \n", netxen_nic_driver_string);
+
+	netxen_check_cmdline_params();
+	pci_module_init(&netxen_driver);
+
+	return netxen_nic_probe_err;
+}
+
+module_init(netxen_init_module);
+
+static void __exit netxen_exit_module(void)
+{
+	int i;
+	struct netxen_adapter *adapter;
+
+	for (i = 0; i < MAX_NUM_CARDS; i++) {
+		adapter = adapterlist[i];
+		if (adapter == NULL)
+			continue;
+		if (adapter->port != NULL && adapter->port[0]->netdev != NULL) {
+			read_lock(&adapter->adapter_lock);
+			netxen_nic_disable_int(adapter);
+			read_unlock(&adapter->adapter_lock);
+			pinit_from_rom(adapter, 0);
+		}
+	}
+
+	/*
+	 * Wait for some time to allow the dma to drain, if any.
+	 */
+	mdelay(5);
+	pci_unregister_driver(&netxen_driver);
+}
+
+module_exit(netxen_exit_module);

^ permalink raw reply

* [PATCH 7/9] NetXen 1G/10G ethernet driver patch with corrections
From: Linsys Contractor Amit S. Kale @ 2006-06-07  9:53 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, unmproj

2006-06-07 Amit S. Kale <amitkale@unminc.com>
 	* Add netxen ioctl interface
 	* Add netxen interrupt related routines

diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_ioctl.h linux-2.6.16.20/drivers/net/netxen/netxen_nic_ioctl.h
--- linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_ioctl.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/netxen_nic_ioctl.h	2006-06-06 06:58:11.000000000 -0700
@@ -0,0 +1,75 @@
+/*
+ * 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:
+ *    info@netxen.com
+ * NetXen,
+ * 3965 Freedom Circle, Fourth floor,
+ * Santa Clara, CA 95054
+ */
+
+#ifndef __NETXEN_NIC_IOCTL_H__
+#define __NETXEN_NIC_IOCTL_H__
+
+#include <linux/sockios.h>
+
+#define NETXEN_CMD_START        SIOCDEVPRIVATE
+#define NETXEN_NIC_CMD          (NETXEN_CMD_START + 1)
+#define NETXEN_NIC_NAME         (NETXEN_CMD_START + 2)
+
+typedef enum {
+	netxen_nic_cmd_none = 0,
+	netxen_nic_cmd_pci_read,
+	netxen_nic_cmd_pci_write,
+	netxen_nic_cmd_pci_mem_read,
+	netxen_nic_cmd_pci_mem_write,
+	netxen_nic_cmd_pci_config_read,
+	netxen_nic_cmd_pci_config_write,
+	netxen_nic_cmd_get_stats,
+	netxen_nic_cmd_clear_stats,
+	netxen_nic_cmd_get_version
+} netxen_nic_ioctl_cmd_t;
+
+struct netxen_nic_ioctl_data {
+	u32 cmd;
+	u32 unused1;
+	u64 off;
+	u32 size;
+	u32 rv;
+	char u[64];
+	void *ptr;
+};
+
+struct netxen_statistics {
+	u64 rx_packets;
+	u64 tx_packets;
+	u64 rx_bytes;
+	u64 rx_errors;
+	u64 tx_bytes;
+	u64 tx_errors;
+	u64 rx_crc_errors;
+	u64 rx_short_length_error;
+	u64 rx_long_length_error;
+	u64 rx_mac_errors;
+};
+
+#endif				/* __NETXEN_NIC_IOCTL_H_ */
diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_isr.c linux-2.6.16.20/drivers/net/netxen/netxen_nic_isr.c
--- linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_isr.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/netxen_nic_isr.c	2006-06-06 06:58:11.000000000 -0700
@@ -0,0 +1,430 @@
+/*
+ * 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:
+ *    info@netxen.com
+ * NetXen,
+ * 3965 Freedom Circle, Fourth floor,
+ * Santa Clara, CA 95054
+ */
+
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+
+#include "netxen_nic.h"
+#include "netxen_nic_hw.h"
+#include "netxen_nic_phan_reg.h"
+
+/*
+ * This will be called when all the ports of the adapter are removed.
+ * This will cleanup and disable interrupts and irq.
+ */
+void netxen_nic_down(struct netxen_port *port)
+{
+	struct netxen_adapter *adapter = port->adapter;
+	int i, j, ctxid;
+	struct netxen_cmd_buffer *cmd_buff;
+	struct netxen_skb_frag *buffrag;
+	struct netxen_ring_context *ctx;
+
+	/* disable phy_ints */
+	netxen_nic_disable_phy_interrupts(adapter, (long)port->portnum);
+
+	adapter->active_ports--;
+
+	if (!adapter->active_ports) {
+		read_lock(&adapter->adapter_lock);
+		netxen_nic_disable_int(adapter);
+		read_unlock(&adapter->adapter_lock);
+
+		for (ctxid = 0; ctxid < MAX_RING_CTX; ++ctxid) {
+			ctx = &adapter->ring_ctx[ctxid];
+			cmd_buff = ctx->cmd_buf_arr;
+
+			for (i = 0; i < ctx->max_tx_desc_count; i++) {
+				buffrag = cmd_buff->frag_array;
+				if (buffrag->dma) {
+					pci_unmap_single(port->pdev,
+							 buffrag->dma,
+							 buffrag->length,
+							 PCI_DMA_TODEVICE);
+					buffrag->dma = (u64) NULL;
+				}
+				for (j = 1; j < cmd_buff->frag_count; j++) {
+					buffrag++;
+					if (buffrag->dma) {
+						pci_unmap_page(port->pdev,
+							       buffrag->dma,
+							       buffrag->length,
+							       PCI_DMA_TODEVICE);
+						buffrag->dma = (u64) NULL;
+					}
+				}
+				/* Free the skb we received in
+				   netxen_nic_xmit_frame */
+				if (cmd_buff->skb) {
+					dev_kfree_skb_any(cmd_buff->skb);
+					cmd_buff->skb = NULL;
+				}
+				cmd_buff++;
+			}
+		}
+	}
+	del_timer_sync(&adapter->watchdog_timer);
+}
+
+int netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct netxen_port *port = netdev_priv(netdev);
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev)) {
+		netif_carrier_off(netdev);
+		netif_stop_queue(netdev);
+		netxen_nic_down(port);
+	}
+
+	return 0;
+}
+
+int netxen_nic_resume(struct pci_dev *pdev)
+{
+	u32 ret;
+	struct net_device *netdev = pci_get_drvdata(pdev);
+
+	ret = pci_enable_device(pdev);
+	netif_device_attach(netdev);
+	return ret;
+}
+
+/*
+ * 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 net_device_stats *stats = &port->net_stats;
+
+	memset(stats, 0, sizeof(*stats));
+
+	/* total packets received   */
+	stats->rx_packets = port->stats.no_rcv;
+	/* total packets transmitted    */
+	stats->tx_packets = port->stats.xmitedframes + port->stats.xmitfinished;
+	/* total bytes received     */
+	stats->rx_bytes = port->stats.rxbytes;
+	/* total bytes transmitted  */
+	stats->tx_bytes = port->stats.txbytes;
+	/* bad packets received     */
+	stats->rx_errors = port->stats.rcvdbadskb;
+	/* packet transmit problems */
+	stats->tx_errors = port->stats.nocmddescriptor;
+	/* no space in linux buffers    */
+	stats->rx_dropped = port->stats.updropped;
+	/* no space available in linux  */
+	stats->tx_dropped = port->stats.txdropped;
+
+	return stats;
+}
+
+long netxen_nic_enable_phy_interrupts(struct netxen_adapter *adapter,
+				      long portno)
+{
+	long result = 0;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		result = netxen_niu_gbe_enable_phy_interrupts(adapter, portno);
+		break;
+
+	case NETXEN_NIC_XGBE:
+		netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x3f);
+		break;
+
+	default:
+		printk(KERN_ERR "%s: Unknown board type\n",
+		       netxen_nic_driver_name);
+		result = -1;
+	}
+
+	return result;
+}
+
+long netxen_nic_disable_phy_interrupts(struct netxen_adapter *adapter,
+				       long portno)
+{
+	long result = 0;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		result = netxen_niu_gbe_disable_phy_interrupts(adapter, portno);
+		break;
+
+	case NETXEN_NIC_XGBE:
+		netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x7f);
+		break;
+
+	default:
+		printk(KERN_ERR "%s: Unknown board type\n",
+		       netxen_nic_driver_name);
+		result = -1;
+	}
+
+	return result;
+}
+
+long netxen_nic_clear_phy_interrupts(struct netxen_adapter *adapter,
+				     long portno)
+{
+	long result = 0;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		result = netxen_niu_gbe_clear_phy_interrupts(adapter, portno);
+		break;
+
+	case NETXEN_NIC_XGBE:
+		netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1);
+		break;
+
+	default:
+		printk(KERN_ERR "%s: Unknown board type\n",
+		       netxen_nic_driver_name);
+		result = -1;
+	}
+
+	return result;
+}
+
+void netxen_nic_set_mii_mode(struct netxen_adapter *adapter, long portno,
+			     long enable)
+{
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		netxen_niu_gbe_set_mii_mode(adapter, portno, enable);
+		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);
+	}
+}
+
+void
+netxen_nic_set_gmii_mode(struct netxen_adapter *adapter, long portno,
+			 long enable)
+{
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		netxen_niu_gbe_set_gmii_mode(adapter, portno, enable);
+		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);
+	}
+}
+
+void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno,
+				 u32 link)
+{
+	struct netxen_port *pport = adapter->port[portno];
+	struct net_device *netdev = pport->netdev;
+
+	if (link)
+		netif_carrier_on(netdev);
+	else
+		netif_carrier_off(netdev);
+}
+
+void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno,
+			    u32 enable)
+{
+	u32 intr;
+	struct netxen_niu_phy_interrupt *int_src;
+	struct netxen_port *port;
+
+	/*  This should clear the interrupt source */
+	netxen_nic_phy_read(adapter, portno,
+			    NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, &intr);
+	if (intr == 0) {
+		DPRINTK(INFO, "No phy interrupts for port #%d\n", portno);
+		return;
+	}
+	int_src = (struct netxen_niu_phy_interrupt *)&intr;
+	netxen_nic_disable_phy_interrupts(adapter, portno);
+
+	port = adapter->port[portno];
+
+	if (int_src->jabber)
+		DPRINTK(INFO, "NetXen: %s Jabber interrupt \n",
+			port->netdev->name);
+
+	if (int_src->polarity_changed)
+		DPRINTK(INFO, "NetXen: %s POLARITY CHANGED int \n",
+			port->netdev->name);
+
+	if (int_src->energy_detect)
+		DPRINTK(INFO, "NetXen: %s ENERGY DETECT INT \n",
+			port->netdev->name);
+
+	if (int_src->downshift)
+		DPRINTK(INFO, "NetXen: %s DOWNSHIFT INT \n",
+			port->netdev->name);
+	/* write it down later.. */
+	if ((int_src->speed_changed) || (int_src->link_status_changed)) {
+		struct netxen_niu_phy_status status;
+
+		DPRINTK(INFO, "NetXen: %s SPEED CHANGED OR"
+			" LINK STATUS CHANGED \n", port->netdev->name);
+
+		if (netxen_nic_phy_read(adapter, portno,
+					NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+					(netxen_crbword_t *) & status) == 0) {
+			if (int_src->link_status_changed) {
+				if (status.link) {
+					netxen_niu_gbe_init_port(adapter,
+								 portno);
+					printk("%s: %s Link UP\n",
+					       netxen_nic_driver_name,
+					       port->netdev->name);
+
+				} else {
+					printk("%s: %s Link DOWN\n",
+					       netxen_nic_driver_name,
+					       port->netdev->name);
+				}
+				netxen_indicate_link_status(adapter, portno,
+							    status.link);
+			}
+		}
+	}
+	netxen_nic_enable_phy_interrupts(adapter, portno);
+}
+
+void netxen_nic_isr_other(struct netxen_adapter *adapter)
+{
+	u32 enable, portno;
+	u32 i2qhi;
+
+	/*
+	 * bit 3 is for i2qInt, if high its enabled
+	 * check for phy interrupts
+	 * read vector and check for bit 45 for phy
+	 * clear int by writing the same value into ISR_INT_VECTOR REG
+	 */
+
+	DPRINTK(INFO, "I2Q is the source of INT \n");
+
+	/* verify the offset */
+	read_lock(&adapter->adapter_lock);
+	i2qhi = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_I2Q_CLR_PCI_HI));
+	read_unlock(&adapter->adapter_lock);
+
+	DPRINTK(INFO, "isr NETXEN_I2Q_CLR_PCI_HI = 0x%x \n", i2qhi);
+
+	if (i2qhi & 0x4000) {
+		for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) {
+			DPRINTK(INFO, "External PHY interrupt ON PORT %d\n",
+				portno);
+
+			enable = 1;
+			netxen_handle_port_int(adapter, portno, enable);
+		}
+
+		/* Clear the interrupt on I2Q */
+		read_lock(&adapter->adapter_lock);
+		writel((u32) i2qhi,
+		       NETXEN_CRB_NORMALIZE(adapter, NETXEN_I2Q_CLR_PCI_HI));
+		read_unlock(&adapter->adapter_lock);
+
+	}
+}
+
+void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
+{
+	u32 val, val1;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		val = readl(NETXEN_CRB_NORMALIZE(adapter, ISR_INT_VECTOR));
+		if (val & 0x4) {
+			adapter->stats.otherints++;
+			netxen_nic_isr_other(adapter);
+		}
+		break;
+
+	case NETXEN_NIC_XGBE:
+		{
+			struct net_device *netdev = adapter->port[0]->netdev;
+
+			/* WINDOW = 1 */
+			read_lock(&adapter->adapter_lock);
+			val1 =
+			    readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
+			read_unlock(&adapter->adapter_lock);
+
+			if (adapter->ahw.xg_linkup == 1 && val1 != XG_LINK_UP) {
+				printk(KERN_INFO "%s: %s NIC Link is down\n",
+				       netxen_nic_driver_name, netdev->name);
+				adapter->ahw.xg_linkup = 0;
+				/* read twice to clear sticky bits */
+				/* WINDOW = 0 */
+				netxen_nic_read_w0(adapter,
+						   NETXEN_NIU_XG_STATUS, &val1);
+				netxen_nic_read_w0(adapter,
+						   NETXEN_NIU_XG_STATUS, &val1);
+
+				if ((val1 & 0xffb) != 0xffb) {
+					printk(KERN_INFO
+					       "%s ISR: Sync/Align BAD: 0x%08x\n",
+					       netxen_nic_driver_name, val1);
+				}
+
+			} else if (adapter->ahw.xg_linkup == 0
+				   && val1 == XG_LINK_UP) {
+				printk(KERN_INFO "%s: %s NIC Link is up\n",
+				       netxen_nic_driver_name, netdev->name);
+				adapter->ahw.xg_linkup = 1;
+			}
+
+		}
+		break;
+
+	default:
+		printk(KERN_ERR "%s ISR: Unknown board type\n",
+		       netxen_nic_driver_name);
+	}
+}

^ permalink raw reply

* [PATCH 6/9] NetXen 1G/10G ethernet driver patch with corrections
From: Linsys Contractor Amit S. Kale @ 2006-06-07  9:50 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, unmproj

2006-06-07 Amit S. Kale <amitkale@unminc.com>
 	* Add netxen hardware initialization routines

diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_init.c linux-2.6.16.20/drivers/net/netxen/netxen_nic_init.c
--- linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_init.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/netxen_nic_init.c	2006-06-06 06:58:11.000000000 -0700
@@ -0,0 +1,1263 @@
+/*
+ * 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:
+ *    info@netxen.com
+ * NetXen,
+ * 3965 Freedom Circle, Fourth floor,
+ * Santa Clara, CA 95054
+ *
+ *
+ * Source file for NIC routines to initialize the Phantom Hardware
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include "netxen_nic.h"
+#include "netxen_nic_hw.h"
+#include "netxen_nic_ioctl.h"
+#include "netxen_nic_phan_reg.h"
+
+struct crb_addr_pair {
+	long addr;
+	long data;
+};
+
+#define NETXEN_MAX_CRB_XFORM 60
+static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
+#define NETXEN_ADDR_ERROR ((unsigned long ) 0xffffffff )
+
+#define crb_addr_transform(name) \
+        crb_addr_xform[NETXEN_HW_PX_MAP_CRB_##name] = \
+        NETXEN_HW_CRB_HUB_AGT_ADR_##name << 20
+
+#define NETXEN_FLASH_BASE	(BOOTLD_START)
+#define NETXEN_PHANTOM_MEM_BASE	(NETXEN_FLASH_BASE)
+
+static void crb_addr_transform_setup(void)
+{
+	crb_addr_transform(XDMA);
+	crb_addr_transform(TIMR);
+	crb_addr_transform(SRE);
+	crb_addr_transform(SQN3);
+	crb_addr_transform(SQN2);
+	crb_addr_transform(SQN1);
+	crb_addr_transform(SQN0);
+	crb_addr_transform(SQS3);
+	crb_addr_transform(SQS2);
+	crb_addr_transform(SQS1);
+	crb_addr_transform(SQS0);
+	crb_addr_transform(RPMX7);
+	crb_addr_transform(RPMX6);
+	crb_addr_transform(RPMX5);
+	crb_addr_transform(RPMX4);
+	crb_addr_transform(RPMX3);
+	crb_addr_transform(RPMX2);
+	crb_addr_transform(RPMX1);
+	crb_addr_transform(RPMX0);
+	crb_addr_transform(ROMUSB);
+	crb_addr_transform(SN);
+	crb_addr_transform(QMN);
+	crb_addr_transform(QMS);
+	crb_addr_transform(PGNI);
+	crb_addr_transform(PGND);
+	crb_addr_transform(PGN3);
+	crb_addr_transform(PGN2);
+	crb_addr_transform(PGN1);
+	crb_addr_transform(PGN0);
+	crb_addr_transform(PGSI);
+	crb_addr_transform(PGSD);
+	crb_addr_transform(PGS3);
+	crb_addr_transform(PGS2);
+	crb_addr_transform(PGS1);
+	crb_addr_transform(PGS0);
+	crb_addr_transform(PS);
+	crb_addr_transform(PH);
+	crb_addr_transform(NIU);
+	crb_addr_transform(I2Q);
+	crb_addr_transform(EG);
+	crb_addr_transform(MN);
+	crb_addr_transform(MS);
+	crb_addr_transform(CAS2);
+	crb_addr_transform(CAS1);
+	crb_addr_transform(CAS0);
+	crb_addr_transform(CAM);
+	crb_addr_transform(C2C1);
+	crb_addr_transform(C2C0);
+}
+
+static int cmdline_max_cmd_desc = 1024;
+static int cmdline_max_rcv_desc = 16384;
+static int cmdline_max_jumbo_rcv_desc = 512;
+
+module_param(cmdline_max_cmd_desc, int, S_IRUGO);
+module_param(cmdline_max_rcv_desc, int, S_IRUGO);
+module_param(cmdline_max_jumbo_rcv_desc, int, S_IRUGO);
+
+void inline netxen_check_cmdline_params(void)
+{
+	if (cmdline_max_cmd_desc < 1024)
+		cmdline_max_cmd_desc = MAX_CMD_DESCRIPTORS;
+	if (cmdline_max_rcv_desc < 16384)
+		cmdline_max_rcv_desc = MAX_RCV_DESCRIPTORS;
+	if (cmdline_max_jumbo_rcv_desc < 512)
+		cmdline_max_jumbo_rcv_desc = MAX_JUMBO_RCV_DESCRIPTORS;
+}
+
+void __devinit netxen_check_options(struct netxen_adapter *adapter)
+{
+	struct netxen_ring_context *ctx;
+	int i;
+
+	for (i = 0; i < MAX_RING_CTX; i++) {
+		ctx = &adapter->ring_ctx[i];
+		ctx->max_tx_desc_count = cmdline_max_cmd_desc;
+		ctx->max_rx_desc_count = cmdline_max_rcv_desc;
+		ctx->max_jumbo_rx_desc_count = cmdline_max_jumbo_rcv_desc;
+	}
+}
+
+int init_firmware(struct netxen_adapter *adapter)
+{
+	u32 state = 0, loops = 0, err = 0;
+
+	/* Window 1 call */
+	read_lock(&adapter->adapter_lock);
+	state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+	read_unlock(&adapter->adapter_lock);
+
+	while (state != PHAN_INITIALIZE_COMPLETE && loops < 200000) {
+		udelay(100);
+		/* Window 1 call */
+		read_lock(&adapter->adapter_lock);
+		state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+		read_unlock(&adapter->adapter_lock);
+
+		loops++;
+	}
+	if (loops >= 200000) {
+		printk(KERN_ERR "Cmd Peg initialization not complete:%x.\n",
+		       state);
+		err = -EIO;
+		return err;
+	}
+	/* Window 1 call */
+	read_lock(&adapter->adapter_lock);
+	writel(PHAN_INITIALIZE_ACK,
+	       NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+	read_unlock(&adapter->adapter_lock);
+
+	return err;
+}
+
+void initialize_adapter_sw(struct netxen_adapter *adapter)
+{
+	int ctxid, ring;
+	u32 i;
+	u32 num_rx_bufs = 0;
+	struct netxen_rcv_desc_ctx *rcv_desc;
+	struct netxen_ring_context *ctx;
+
+	DPRINTK(INFO, "initializing some queues: %p\n", adapter);
+	for (ctxid = 0; ctxid < MAX_RING_CTX; ++ctxid) {
+		ctx = &adapter->ring_ctx[ctxid];
+		ctx->free_cmd_count = ctx->max_tx_desc_count;
+		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+			struct netxen_rx_buffer *rx_buf;
+			rcv_desc = &ctx->recv_ctx.rcv_desc[ring];
+			rcv_desc->rcv_free = rcv_desc->max_rx_desc_count;
+			rcv_desc->begin_alloc = 0;
+			rx_buf = rcv_desc->rx_buf_arr;
+			num_rx_bufs = rcv_desc->max_rx_desc_count;
+			/*
+			 * Now go through all of them, set reference handles
+			 * and put them in the queues.
+			 */
+			for (i = 0; i < num_rx_bufs; i++) {
+				rx_buf->ref_handle = i;
+				rx_buf->state = NETXEN_BUFFER_FREE;
+
+				DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:"
+					"%p\n", ctxid, i, rx_buf);
+				rx_buf++;
+			}
+		}
+	}
+	DPRINTK(INFO, "initialized buffers for %s and %s\n",
+		"adapter->free_cmd_buf_list", "adapter->free_rxbuf");
+}
+
+int initialize_adapter_hw(struct netxen_adapter *adapter)
+{
+	u32 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);
+	}
+
+	return value;
+}
+
+/*
+ * netxen_decode_crb_addr(0 - utility to translate from internal Phantom CRB
+ * address to external PCI CRB address.
+ */
+unsigned long netxen_decode_crb_addr(unsigned long addr)
+{
+	int i;
+	unsigned long base_addr, offset, pci_base;
+
+	crb_addr_transform_setup();
+
+	pci_base = NETXEN_ADDR_ERROR;
+	base_addr = addr & 0xfff00000;
+	offset = addr & 0x000fffff;
+
+	for (i = 0; i < NETXEN_MAX_CRB_XFORM; i++) {
+		if (crb_addr_xform[i] == base_addr) {
+			pci_base = i << 20;
+			break;
+		}
+	}
+	if (pci_base == NETXEN_ADDR_ERROR)
+		return pci_base;
+	else
+		return (pci_base + offset);
+}
+
+static long rom_max_timeout = 10000;
+static long rom_lock_timeout = 100000000;
+
+int rom_lock(struct netxen_adapter *adapter)
+{
+	int iter;
+	int done = 0, timeout = 0;
+
+	while (!done) {
+		/* acquire semaphore2 from PCI HW block */
+		netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK),
+				   &done);
+		if (done == 1)
+			break;
+		if (timeout >= rom_lock_timeout)
+			return -1;
+
+		timeout++;
+		/*
+		 * Yield CPU
+		 */
+		if (!in_atomic())
+			schedule();
+		else {
+			for (iter = 0; iter < 20; iter++)
+				cpu_relax();	/*This a nop instr on i386 */
+		}
+	}
+	netxen_nic_reg_write(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
+	return 0;
+}
+
+void rom_unlock(struct netxen_adapter *adapter)
+{
+	int val;
+
+	/* release semaphore2 */
+	netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val);
+
+}
+
+int netxen_wait_rom_done(struct netxen_adapter *adapter)
+{
+	long timeout = 0;
+	long done = 0;
+
+	while (done == 0) {
+		done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS);
+		done &= 2;
+		timeout++;
+		if (timeout >= rom_max_timeout) {
+			printk("Timeout reached  waiting for rom done");
+			return -1;
+		}
+	}
+	return 0;
+}
+
+int do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
+{
+	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
+	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
+	udelay(100);		/* prevent bursting on CRB */
+	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
+	if (netxen_wait_rom_done(adapter)) {
+		printk("Error waiting for rom done\n");
+		return -1;
+	}
+	/* reset abyte_cnt and dummy_byte_cnt */
+	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
+	udelay(100);		/* prevent bursting on CRB */
+	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+
+	*valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
+	return 0;
+}
+
+int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
+{
+	int ret;
+
+	if (rom_lock(adapter) != 0)
+		return -1;
+
+	ret = do_rom_fast_read(adapter, addr, valp);
+	rom_unlock(adapter);
+	return ret;
+}
+
+int pinit_from_rom(struct netxen_adapter *adapter, int verbose)
+{
+	int addr, val, status;
+	int n, i;
+	int init_delay = 0;
+	struct crb_addr_pair *buf;
+	unsigned long off;
+	unsigned long flags;
+
+	/* resetall */
+	status = netxen_nic_get_board_info(adapter);
+	if (status)
+		printk("%s: pinit_from_rom: Error getting board info\n",
+		       netxen_nic_driver_name);
+
+	netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
+				    0xffffffff);
+
+	if (verbose) {
+		int val;
+		if (netxen_rom_fast_read(adapter, 0x4008, &val) == 0)
+			printk("P2 ROM board type: 0x%08x\n", val);
+		else
+			printk("Could not read board type\n");
+		if (netxen_rom_fast_read(adapter, 0x400c, &val) == 0)
+			printk("P2 ROM board  num: 0x%08x\n", val);
+		else
+			printk("Could not read board number\n");
+		if (netxen_rom_fast_read(adapter, 0x4010, &val) == 0)
+			printk("P2 ROM chip   num: 0x%08x\n", val);
+		else
+			printk("Could not read chip number\n");
+	}
+
+	if (netxen_rom_fast_read(adapter, 0, &n) == 0 && (n & 0x800000000ULL)) {
+		n &= ~0x80000000ULL;
+		if (n < 1024) {
+			if (verbose)
+				printk("%s: %d CRB init values found"
+				       " in ROM.\n", netxen_nic_driver_name, n);
+		} else {
+			printk("%s:n=0x%x Error! NetXen card flash not"
+			       " initialized.\n", __FUNCTION__, n);
+			return -1;
+		}
+		buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
+		if (buf == NULL) {
+			printk("%s: pinit_from_rom: Unable to calloc memory.\n",
+			       netxen_nic_driver_name);
+			return -1;
+		}
+		for (i = 0; i < n; i++) {
+			if (netxen_rom_fast_read(adapter, 8 * i + 4, &val) != 0
+			    || netxen_rom_fast_read(adapter, 8 * i + 8,
+						    &addr) != 0)
+				goto error_ret;
+
+			buf[i].addr = addr;
+			buf[i].data = val;
+
+			if (verbose)
+				printk("%s: PCI:     0x%08x == 0x%08x\n",
+				       netxen_nic_driver_name, (unsigned int)
+				       netxen_decode_crb_addr((unsigned long)
+							      addr), val);
+		}
+		for (i = 0; i < n; i++) {
+
+			off =
+			    netxen_decode_crb_addr((unsigned long)buf[i].addr) +
+			    NETXEN_PCI_CRBSPACE;
+			/* skipping cold reboot MAGIC */
+			if (off == NETXEN_CAM_RAM(0x1fc))
+				continue;
+
+			/* After writing this register, HW needs time for CRB */
+			/* to quiet down (else crb_window returns 0xffffffff) */
+			if (off == NETXEN_ROMUSB_GLB_SW_RESET) {
+				init_delay = 1;
+				/* hold xdma in reset also */
+				buf[i].data = 0x8000ff;
+			}
+
+			if (ADDR_IN_WINDOW1(off)) {
+				read_lock(&adapter->adapter_lock);
+				writel(buf[i].data,
+				       NETXEN_CRB_NORMALIZE(adapter, off));
+				read_unlock(&adapter->adapter_lock);
+			} else {
+				write_lock_irqsave(&adapter->adapter_lock,
+						   flags);
+				netxen_nic_pci_change_crbwindow(adapter, 0);
+				off = adapter->ahw.pci_base + off;
+				writel(buf[i].data, (void *)off);
+				netxen_nic_pci_change_crbwindow(adapter, 1);
+				write_unlock_irqrestore(&adapter->adapter_lock,
+							flags);
+			}
+			if (init_delay == 1) {
+				msleep(1000);
+				init_delay = 0;
+			}
+			msleep(1);
+		}
+		kfree(buf);
+
+		/* disable_peg_cache_all */
+
+		/* unreset_net_cache */
+		netxen_nic_hw_read_wx(adapter, NETXEN_ROMUSB_GLB_SW_RESET, &val,
+				      4);
+		netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
+					    (val & 0xffffff0f));
+		/* p2dn replyCount */
+		netxen_crb_writelit_adapter(adapter,
+					    NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
+		/* disable_peg_cache 0 */
+		netxen_crb_writelit_adapter(adapter,
+					    NETXEN_CRB_PEG_NET_D + 0x4c, 8);
+		/* disable_peg_cache 1 */
+		netxen_crb_writelit_adapter(adapter,
+					    NETXEN_CRB_PEG_NET_I + 0x4c, 8);
+
+		/* peg_clr_all */
+
+		/* peg_clr 0 */
+		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8,
+					    0);
+		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc,
+					    0);
+		/* peg_clr 1 */
+		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8,
+					    0);
+		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc,
+					    0);
+		/* peg_clr 2 */
+		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8,
+					    0);
+		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc,
+					    0);
+		/* peg_clr 3 */
+		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8,
+					    0);
+		netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc,
+					    0);
+	}
+	return 0;
+      error_ret:
+	return -1;
+}
+
+void phantom_init(struct netxen_adapter *adapter)
+{
+	u32 val = 0;
+	int loops = 0;
+
+	read_lock(&adapter->adapter_lock);
+	netxen_nic_hw_read_wx(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE, &val, 4);
+	writel(1,
+	       NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
+
+	if (0 == val) {
+		while (val != PHAN_INITIALIZE_COMPLETE && loops < 2000000) {
+			udelay(100);
+			val =
+			    readl(NETXEN_CRB_NORMALIZE
+				  (adapter, CRB_CMDPEG_STATE));
+			loops++;
+		}
+		if (val != PHAN_INITIALIZE_COMPLETE)
+			printk("WARNING: Initial boot wait loop failed...\n");
+	}
+	read_unlock(&adapter->adapter_lock);
+}
+
+void load_firmware(struct netxen_adapter *adapter)
+{
+	int i;
+	long data, size = 0;
+	long flashaddr = NETXEN_FLASH_BASE, memaddr = NETXEN_PHANTOM_MEM_BASE;
+
+	size = (16 * 1024) / 4;
+	read_lock(&adapter->adapter_lock);
+	writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));
+	read_unlock(&adapter->adapter_lock);
+
+	for (i = 0; i < size; i++) {
+		if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) {
+			DPRINTK(ERR,
+				"Error in netxen_rom_fast_read(). Will skip"
+				"loading flash image\n");
+			return;
+		}
+		netxen_nic_pci_mem_write(adapter, memaddr, &data, 4);
+		flashaddr += 4;
+		memaddr += 4;
+	}
+	udelay(100);
+	read_lock(&adapter->adapter_lock);
+	/* make sure Casper is powered on */
+	writel(0x3fff,
+	       NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL));
+	writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));
+	read_unlock(&adapter->adapter_lock);
+
+	udelay(10000);
+}
+
+int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
+{
+	int ctxid;
+
+	for (ctxid = 0; ctxid < MAX_RING_CTX; ++ctxid) {
+		struct netxen_ring_context *ctx = &adapter->ring_ctx[ctxid];
+		struct netxen_recv_context *recv_ctx = &(ctx->recv_ctx);
+		u32 consumer;
+		struct status_desc_t *desc_head;
+		struct status_desc_t *desc;	/* used to read status desc here */
+
+		consumer = recv_ctx->status_rx_consumer;
+		desc_head = recv_ctx->rcv_status_desc_head;
+		desc = &desc_head[consumer];
+
+		if ((desc->owner & STATUS_OWNER_HOST))
+			return 1;
+	}
+
+	return 0;
+}
+
+void netxen_watchdog_task(unsigned long v)
+{
+	int port_num;
+	struct netxen_port *port;
+	struct net_device *netdev;
+	struct netxen_adapter *adapter = (struct netxen_adapter *)v;
+	unsigned long flags;
+
+	if (adapter->driver_mismatch) {
+		/* We return without turning on the netdev queue as there
+		 * was a mismatch in driver and firmware version
+		 */
+		return;
+	}
+	for (port_num = 0; port_num < adapter->ahw.max_ports; port_num++) {
+		port = adapter->port[port_num];
+		netdev = port->netdev;
+
+		if ((netdev->flags & IFF_UP) && !netif_carrier_ok(netdev)) {
+			printk(KERN_INFO "%s port %d, %s carrier is now ok\n",
+			       netxen_nic_driver_name, port_num, netdev->name);
+			netif_carrier_on(netdev);
+		}
+
+		if (netif_queue_stopped(netdev))
+			netif_wake_queue(netdev);
+	}
+
+	write_lock_irqsave(&adapter->adapter_lock, flags);
+	netxen_nic_pci_change_crbwindow(adapter, 1);
+	write_unlock_irqrestore(&adapter->adapter_lock, flags);
+
+	netxen_nic_handle_phy_intr(adapter);
+	mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+}
+
+/*
+ * netxen_process_rcv() send the received packet to the protocol stack.
+ * and if the number of receives exceeds RX_BUFFERS_REFILL, then we
+ * invoke the routine to send more rx buffers to the Phantom...
+ */
+inline void
+netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
+		   struct status_desc_t *desc)
+{
+	struct netxen_port *port = adapter->port[desc->port];
+	struct pci_dev *pdev = port->pdev;
+	struct net_device *netdev = port->netdev;
+	int index = desc->reference_handle;
+	struct netxen_recv_context *recv_ctx =
+	    &(adapter->ring_ctx[ctxid].recv_ctx);
+	struct netxen_rx_buffer *buffer;
+	struct sk_buff *skb;
+	u32 length = desc->total_length;
+	u32 desc_ctx;
+	struct netxen_rcv_desc_ctx *rcv_desc;
+	int ret;
+
+	desc_ctx = desc->type;
+	if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
+		printk("%s: %s Bad Rcv descriptor ring\n",
+		       netxen_nic_driver_name, netdev->name);
+		return;
+	}
+
+	rcv_desc = &recv_ctx->rcv_desc[desc_ctx];
+	buffer = &rcv_desc->rx_buf_arr[index];
+
+	pci_unmap_single(pdev, buffer->dma, rcv_desc->dma_size,
+			 PCI_DMA_FROMDEVICE);
+
+	skb = (struct sk_buff *)buffer->skb;
+
+	if (unlikely(skb == NULL)) {
+		/*
+		 * This should not happen and if it does, it is serious,
+		 * catch it
+		 */
+		u32 temp1, temp2;
+		/* Window = 0 or 1 */
+		read_lock(&adapter->adapter_lock);
+		temp1 = readl((void *)(adapter->ahw.pci_base
+				       + (NETXEN_CRB_PCIE + 0x20000)));
+		temp2 = readl((void *)(adapter->ahw.pci_base
+				       + (NETXEN_CRB_PCIE + 0x20008)));
+
+		read_unlock(&adapter->adapter_lock);
+
+		/* Window = 0 */
+		netxen_nic_write_w0(adapter, NETXEN_CRB_PEG_NET_0 + 0x3c, 1);
+		netxen_nic_write_w0(adapter, NETXEN_CRB_PEG_NET_1 + 0x3c, 1);
+		netxen_nic_write_w0(adapter, NETXEN_CRB_PEG_NET_2 + 0x3c, 1);
+		netxen_nic_write_w0(adapter, NETXEN_CRB_PEG_NET_3 + 0x3c, 1);
+		netxen_nic_write_w0(adapter, NETXEN_CRB_NIU + 0x70000, 0);
+
+		printk("%s: %s Halted the pegs and stopped the NIU consumer\n",
+		       netxen_nic_driver_name, netdev->name);
+		printk("Curr DMA Addr: 0x%x, status:0x%x\n", temp1, temp2);
+		printk("got NULL skb for index %d  desc %p\n", index, desc);
+		printk("prev desc %p: refh:%x\n", desc - 1,
+		       (desc - 1)->reference_handle);
+		printk("next desc %p: refh:%x\n", desc + 1,
+		       (desc + 1)->reference_handle);
+		printk("next desc %p: refh:%x\n", desc + 2,
+		       (desc + 2)->reference_handle);
+		printk("and mine again %p: refh:%x\n", desc,
+		       (desc)->reference_handle);
+
+		port->stats.rcvdbadskb++;
+		return;
+	}
+
+	if (likely(desc->status == STATUS_CKSUM_OK)) {
+		port->stats.csummed++;
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	} else
+		skb->ip_summed = CHECKSUM_NONE;
+	skb->dev = netdev;
+	skb_put(skb, length);
+	skb->protocol = eth_type_trans(skb, netdev);
+
+	ret = netif_receive_skb(skb);
+
+	/*
+	 * RH: Do we need these stats on a regular basis. Can we get it from
+	 * Linux stats.
+	 */
+	switch (ret) {
+	case NET_RX_SUCCESS:
+		port->stats.uphappy++;
+		break;
+
+	case NET_RX_CN_LOW:
+		port->stats.uplcong++;
+		break;
+
+	case NET_RX_CN_MOD:
+		port->stats.upmcong++;
+		break;
+
+	case NET_RX_CN_HIGH:
+		port->stats.uphcong++;
+		break;
+
+	case NET_RX_DROP:
+		port->stats.updropped++;
+		break;
+
+	default:
+		port->stats.updunno++;
+		break;
+	}
+
+	netdev->last_rx = jiffies;
+
+	rcv_desc->rcv_free++;
+	rcv_desc->rcv_pending--;
+
+	/*
+	 * We just consumed one buffer so post a buffer.
+	 */
+	adapter->stats.post_called++;
+	buffer->skb = NULL;
+	buffer->state = NETXEN_BUFFER_FREE;
+
+	port->stats.no_rcv++;
+	port->stats.rxbytes += length;
+}
+
+/* Process Receive status ring */
+u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
+{
+	struct netxen_ring_context *ctx = &adapter->ring_ctx[ctxid];
+	struct netxen_recv_context *recv_ctx = &(ctx->recv_ctx);
+	struct status_desc_t *desc_head = recv_ctx->rcv_status_desc_head;
+	struct status_desc_t *desc;	/* used to read status desc here */
+	u32 producer = 0;	/* will be read from phantom */
+	u32 consumer = recv_ctx->status_rx_consumer;
+	int count = 0, ring;
+	DPRINTK(INFO, "procesing receive\n");
+	/*
+	 * we assume in this case that there is only one port and that is
+	 * port #1...changes need to be done in firmware to indicate port
+	 * number as part of the descriptor. This way we will be able to get
+	 * the netdev which is associated with that device.
+	 */
+	while (count < max) {
+		desc = &desc_head[consumer];
+		if (!(desc->owner & STATUS_OWNER_HOST)) {
+			DPRINTK(ERR, "desc %p ownedby %x\n", desc, desc->owner);
+			break;
+		}
+		netxen_process_rcv(adapter, ctxid, desc);
+		consumer = (consumer + 1) & (ctx->max_rx_desc_count - 1);
+		count++;
+	}
+	if (count) {
+		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+			netxen_post_rx_buffers(adapter, ctxid, ring);
+		}
+	}
+
+	/* update the consumer index in phantom */
+	if (count) {
+		struct ctx_msg msg = { 0 };
+		adapter->stats.process_rcv++;
+		recv_ctx->status_rx_consumer = consumer;
+		recv_ctx->status_rx_producer = producer;
+
+		msg.PegId = NETXEN_RCV_PEG_DB_ID;
+		msg.Count = consumer;
+		msg.CtxId = ctxid;
+		msg.Opcode = NETXEN_RCV_STATUS_CONSUMER;
+
+		/* Window = 1 */
+		read_lock(&adapter->adapter_lock);
+		writel(*((u32 *) & msg),
+		       DB_NORMALIZE(adapter, recv_crb_registers[ctxid].
+				    crb_rcv_status_consumer));
+		read_unlock(&adapter->adapter_lock);
+	}
+
+	return count;
+}
+
+/* Process Command status ring */
+void netxen_process_cmd_ring(unsigned long data, int ctxid)
+{
+	u32 last_consumer;
+	u32 consumer;
+	struct netxen_adapter *adapter = (struct netxen_adapter *)data;
+	int count = 0;
+	struct netxen_cmd_buffer *buffer;
+	struct netxen_port *port;	/* port #1 */
+	struct netxen_port *nport;
+	struct pci_dev *pdev;
+	struct netxen_skb_frag *frag;
+	u32 i;
+	struct sk_buff *skb = NULL;
+	int p;
+	struct netxen_ring_context *ctx = &adapter->ring_ctx[ctxid];
+
+	spin_lock(&adapter->tx_lock);
+	last_consumer = ctx->last_cmd_consumer;
+	DPRINTK(INFO, "procesing xmit complete\n");
+	/* we assume in this case that there is only one port and that is
+	 * port #1...changes need to be done in firmware to indicate port
+	 * number as part of the descriptor. This way we will be able to get
+	 * the netdev which is associated with that device.
+	 */
+	/* Window = 1 */
+	consumer = *(ctx->cmd_consumer);
+
+	if (last_consumer == consumer) {	/* Ring is empty    */
+		DPRINTK(INFO, "last_consumer %d == consumer %d\n",
+			last_consumer, consumer);
+		spin_unlock(&adapter->tx_lock);
+		return;
+	}
+
+	ctx->proc_cmd_buf_counter++;
+	adapter->stats.process_xmit++;
+	/*
+	 * Not needed - does not seem to be used anywhere.
+	 * adapter->cmd_consumer = consumer;
+	 */
+	spin_unlock(&adapter->tx_lock);
+
+	while ((last_consumer != consumer) && (count < MAX_STATUS_HANDLE)) {
+		buffer = &ctx->cmd_buf_arr[last_consumer];
+		port = adapter->port[buffer->port];
+		pdev = port->pdev;
+		frag = &buffer->frag_array[0];
+		skb = buffer->skb;
+		if (skb && (cmpxchg(&buffer->skb, skb, 0) == skb)) {
+			pci_unmap_single(pdev, frag->dma, frag->length,
+					 PCI_DMA_TODEVICE);
+			for (i = 1; i < buffer->frag_count; i++) {
+				DPRINTK(INFO, "getting fragment no %d\n", i);
+				frag++;	/* Get the next frag */
+				pci_unmap_page(pdev, frag->dma, frag->length,
+					       PCI_DMA_TODEVICE);
+			}
+
+			port->stats.skbfreed++;
+			dev_kfree_skb_any(skb);
+			skb = NULL;
+		} else if (ctx->proc_cmd_buf_counter == 1) {
+			port->stats.txnullskb++;
+		}
+		if (unlikely(netif_queue_stopped(port->netdev)
+			     && netif_carrier_ok(port->netdev))
+		    && ((jiffies - port->netdev->trans_start) >
+			port->netdev->watchdog_timeo)) {
+			schedule_work(port->adapter->tx_timeout_task +
+				      port->portnum);
+		}
+
+		last_consumer = get_next_index(last_consumer,
+					       ctx->max_tx_desc_count);
+		count++;
+	}
+	adapter->stats.noxmitdone += count;
+
+	count = 0;
+	spin_lock(&adapter->tx_lock);
+	if ((--ctx->proc_cmd_buf_counter) == 0) {
+		ctx->last_cmd_consumer = last_consumer;
+		while ((ctx->last_cmd_consumer != consumer)
+		       && (count < MAX_STATUS_HANDLE)) {
+			buffer = &ctx->cmd_buf_arr[ctx->last_cmd_consumer];
+			count++;
+			if (buffer->skb)
+				break;
+			else
+				ctx->last_cmd_consumer =
+				    get_next_index(ctx->last_cmd_consumer,
+						   ctx->max_tx_desc_count);
+		}
+	}
+	if (count) {
+		for (p = 0; p < adapter->ahw.max_ports; p++) {
+			nport = adapter->port[p];
+			if (netif_queue_stopped(nport->netdev)
+			    && (nport->flags & NETXEN_NETDEV_STATUS)) {
+				netif_wake_queue(nport->netdev);
+				nport->flags &= ~NETXEN_NETDEV_STATUS;
+			}
+		}
+	}
+
+	spin_unlock(&adapter->tx_lock);
+	DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer,
+		__FUNCTION__);
+}
+
+/**
+ * netxen_post_rx_buffers puts buffer in the Phantom memory
+ **/
+void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctxid,
+			    u32 ringid)
+{
+	struct pci_dev *pdev = adapter->ahw.pdev;
+	struct sk_buff *skb;
+	struct netxen_recv_context *recv_ctx =
+	    &(adapter->ring_ctx[ctxid].recv_ctx);
+	struct netxen_rcv_desc_ctx *rcv_desc = NULL;
+	u32 producer;
+	struct rcv_desc_t *pdesc;
+	struct netxen_rx_buffer *buffer;
+	int count = 0;
+	int index = 0;
+	struct ctx_msg msg = { 0 };
+
+	adapter->stats.post_called++;
+	rcv_desc = &recv_ctx->rcv_desc[ringid];
+
+	producer = rcv_desc->producer;
+	buffer = &rcv_desc->rx_buf_arr[index];
+	/* We can start writing rx descriptors into the phantom memory. */
+	while (buffer->state == NETXEN_BUFFER_FREE) {
+		skb = dev_alloc_skb(rcv_desc->skb_size);
+		if (unlikely(!skb)) {
+			/*
+			 * We need to schedule the posting of buffers to the pegs.
+			 */
+			rcv_desc->begin_alloc = index;
+			DPRINTK(ERR, "netxen_post_rx_buffers: "
+				" allocated only %d buffers\n", count);
+			break;
+		}
+		count++;	/* now there should be no failure */
+		pdesc = &rcv_desc->desc_head[producer];
+		skb_reserve(skb, NET_IP_ALIGN);
+		/* 
+		 * This will be setup when we receive the
+		 * buffer after it has been filled
+		 * skb->dev = netdev;
+		 */
+		buffer->skb = skb;
+		buffer->state = NETXEN_BUFFER_BUSY;
+		buffer->dma = pci_map_single(pdev, skb->data,
+					     rcv_desc->dma_size,
+					     PCI_DMA_FROMDEVICE);
+		/* make a rcv descriptor  */
+		pdesc->reference_handle = buffer->ref_handle;
+		pdesc->buffer_length = rcv_desc->dma_size;
+		pdesc->addr_buffer = buffer->dma;
+		DPRINTK(INFO, "done writing descripter\n");
+		producer =
+		    get_next_index(producer, rcv_desc->max_rx_desc_count);
+		index = get_next_index(index, rcv_desc->max_rx_desc_count);
+		buffer = &rcv_desc->rx_buf_arr[index];
+	}
+	rcv_desc->begin_alloc = index;
+
+	/* if we did allocate buffers, then write the count to Phantom */
+	if (count) {
+		rcv_desc->begin_alloc = index;
+		rcv_desc->rcv_pending += count;
+		adapter->stats.lastposted = count;
+		adapter->stats.posted += count;
+		rcv_desc->producer = producer;
+		if (rcv_desc->rcv_free >= 32) {
+			rcv_desc->rcv_free = 0;
+			/*
+			 * Write a doorbell msg to tell phanmon of change in
+			 * receive ring producer
+			 */
+			msg.PegId = NETXEN_RCV_PEG_DB_ID;
+			msg.Count =
+			    (producer - 1) & (rcv_desc->max_rx_desc_count - 1);
+			msg.CtxId = ctxid;
+			msg.Opcode = NETXEN_RCV_PRODUCER(ringid);
+			/* Window = 1 */
+			read_lock(&adapter->adapter_lock);
+			writel(*((u32 *) & msg),
+			       DB_NORMALIZE(adapter,
+					    NETXEN_RCV_PRODUCER_OFFSET(ctxid,
+								       ringid)));
+			read_unlock(&adapter->adapter_lock);
+
+		}
+	}
+}
+
+int netxen_nic_tx_has_work(struct netxen_adapter *adapter)
+{
+	int ctxid;
+	struct netxen_ring_context *ctx;
+	for (ctxid = 0; ctxid < MAX_RING_CTX; ++ctxid) {
+		ctx = &adapter->ring_ctx[ctxid];
+		if (find_diff_among(ctx->last_cmd_consumer,
+				    ctx->cmd_producer,
+				    ctx->max_tx_desc_count) > 0)
+			return 1;
+	}
+	return 0;
+}
+
+int
+netxen_nic_fill_statistics(struct netxen_adapter *adapter,
+			   struct netxen_port *port,
+			   struct netxen_statistics *netxen_stats)
+{
+	unsigned long flags;
+	void *addr;
+
+	if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+		write_lock_irqsave(&adapter->adapter_lock, flags);
+		netxen_nic_pci_change_crbwindow(adapter, 0);
+		NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_BYTE_CNT,
+					   &(netxen_stats->tx_bytes));
+		NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_FRAME_CNT,
+					   &(netxen_stats->tx_packets));
+		NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_BYTE_CNT,
+					   &(netxen_stats->rx_bytes));
+		NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_FRAME_CNT,
+					   &(netxen_stats->rx_packets));
+		NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_AGGR_ERROR_CNT,
+					   &(netxen_stats->rx_errors));
+		NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_CRC_ERROR_CNT,
+					   &(netxen_stats->rx_crc_errors));
+		NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR,
+					   &(netxen_stats->
+					     rx_long_length_error));
+		NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR,
+					   &(netxen_stats->
+					     rx_short_length_error));
+
+		netxen_nic_pci_change_crbwindow(adapter, 1);
+		write_unlock_irqrestore(&adapter->adapter_lock, flags);
+	} else {
+		spin_lock_bh(&adapter->tx_lock);
+		netxen_stats->tx_bytes = port->stats.txbytes;
+		netxen_stats->tx_packets = port->stats.xmitedframes +
+		    port->stats.xmitfinished;
+		netxen_stats->rx_bytes = port->stats.rxbytes;
+		netxen_stats->rx_packets = port->stats.no_rcv;
+		netxen_stats->rx_errors = port->stats.rcvdbadskb;
+		netxen_stats->tx_errors = port->stats.nocmddescriptor;
+		netxen_stats->rx_short_length_error = port->stats.uplcong;
+		netxen_stats->rx_long_length_error = port->stats.uphcong;
+		netxen_stats->rx_crc_errors = 0;
+		netxen_stats->rx_mac_errors = 0;
+		spin_unlock_bh(&adapter->tx_lock);
+	}
+	return 0;
+}
+
+void netxen_nic_clear_stats(struct netxen_adapter *adapter)
+{
+	struct netxen_port *port;
+	int port_num;
+
+	memset(&adapter->stats, 0, sizeof(adapter->stats));
+	for (port_num = 0; port_num < adapter->ahw.max_ports; port_num++) {
+		port = adapter->port[port_num];
+		memset(&port->stats, 0, sizeof(port->stats));
+	}
+}
+
+int
+netxen_nic_clear_statistics(struct netxen_adapter *adapter,
+			    struct netxen_port *port)
+{
+	unsigned long flags;
+	void *addr;
+	int data = 0;
+
+	write_lock_irqsave(&adapter->adapter_lock, flags);
+	netxen_nic_pci_change_crbwindow(adapter, 0);
+
+	NETXEN_NIC_LOCKED_WRITE_REG(NETXEN_NIU_XGE_TX_BYTE_CNT, &data);
+	NETXEN_NIC_LOCKED_WRITE_REG(NETXEN_NIU_XGE_TX_FRAME_CNT, &data);
+	NETXEN_NIC_LOCKED_WRITE_REG(NETXEN_NIU_XGE_RX_BYTE_CNT, &data);
+	NETXEN_NIC_LOCKED_WRITE_REG(NETXEN_NIU_XGE_RX_FRAME_CNT, &data);
+	NETXEN_NIC_LOCKED_WRITE_REG(NETXEN_NIU_XGE_AGGR_ERROR_CNT, &data);
+	NETXEN_NIC_LOCKED_WRITE_REG(NETXEN_NIU_XGE_CRC_ERROR_CNT, &data);
+	NETXEN_NIC_LOCKED_WRITE_REG(NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR, &data);
+	NETXEN_NIC_LOCKED_WRITE_REG(NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR, &data);
+
+	netxen_nic_pci_change_crbwindow(adapter, 1);
+	write_unlock_irqrestore(&adapter->adapter_lock, flags);
+	netxen_nic_clear_stats(adapter);
+	return 0;
+}
+
+int
+netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
+		    struct netxen_port *port)
+{
+	struct netxen_nic_ioctl_data data;
+	struct netxen_nic_ioctl_data *up_data;
+	int retval = 0;
+	struct netxen_statistics netxen_stats;
+
+	up_data = (void *)u_data;
+
+	DPRINTK(INFO, "doing ioctl for %p\n", adapter);
+	if (copy_from_user(&data, up_data, sizeof(data))) {
+		/* evil user tried to crash the kernel */
+		DPRINTK(ERR, "bad copy from userland: %d\n", (int)sizeof(data));
+		retval = -EFAULT;
+		goto error_out;
+	}
+
+	/* Shouldn't access beyond legal limits of  "char u[64];" member */
+	if (!data.ptr && (data.size > sizeof(data.u))) {
+		/* evil user tried to crash the kernel */
+		DPRINTK(ERR, "bad size: %d\n", data.size);
+		retval = -EFAULT;
+		goto error_out;
+	}
+
+	switch (data.cmd) {
+	case netxen_nic_cmd_pci_read:
+		if ((retval = netxen_nic_hw_read_wx(adapter, data.off,
+						    &(data.u), data.size)))
+			goto error_out;
+		if (copy_to_user((void *)&(up_data->u), &(data.u), data.size)) {
+			DPRINTK(ERR, "bad copy to userland: %d\n",
+				(int)sizeof(data));
+			retval = -EFAULT;
+			goto error_out;
+		}
+		data.rv = 0;
+		break;
+
+	case netxen_nic_cmd_pci_write:
+		data.rv = netxen_nic_hw_write_wx(adapter, data.off, &(data.u),
+						 data.size);
+		break;
+
+	case netxen_nic_cmd_pci_mem_read:
+		DPRINTK(INFO, "doing %s for %p\n",
+			"netxen_nic_cmd_pci_mm_rd", adapter);
+		netxen_nic_pci_mem_read(adapter, data.off, &(data.u),
+					data.size);
+		if (copy_to_user((void *)&(up_data->u), &(data.u), data.size)) {
+			DPRINTK(ERR, "bad copy to userland: %d\n",
+				(int)sizeof(data));
+			retval = -EFAULT;
+			goto error_out;
+		}
+		data.rv = 0;
+		DPRINTK(INFO, "read %lx\n", (unsigned long)data.u);
+		break;
+
+	case netxen_nic_cmd_pci_mem_write:
+		netxen_nic_pci_mem_write(adapter, data.off, &(data.u),
+					 data.size);
+		data.rv = 0;	/* write always succeeds */
+		break;
+
+	case netxen_nic_cmd_pci_config_read:
+		switch (data.size) {
+		case 1:
+			data.rv = pci_read_config_byte(adapter->ahw.pdev,
+						       data.off,
+						       (char *)&(data.u));
+			break;
+		case 2:
+			data.rv = pci_read_config_word(adapter->ahw.pdev,
+						       data.off,
+						       (short *)&(data.u));
+			break;
+		case 4:
+			data.rv = pci_read_config_dword(adapter->ahw.pdev,
+							data.off,
+							(u32 *) & (data.u));
+			break;
+		}
+		if (copy_to_user((void *)&(up_data->u), &(data.u), data.size)) {
+			DPRINTK(ERR, "bad copy to userland: %d\n",
+				(int)sizeof(data));
+			retval = -EFAULT;
+			goto error_out;
+		}
+		break;
+
+	case netxen_nic_cmd_pci_config_write:
+		switch (data.size) {
+		case 1:
+			data.rv = pci_write_config_byte(adapter->ahw.pdev,
+							data.off,
+							*(char *)&(data.u));
+			break;
+		case 2:
+			data.rv = pci_write_config_word(adapter->ahw.pdev,
+							data.off,
+							*(short *)&(data.u));
+			break;
+		case 4:
+			data.rv = pci_write_config_dword(adapter->ahw.pdev,
+							 data.off,
+							 *(u32 *) & (data.u));
+			break;
+		}
+		break;
+
+	case netxen_nic_cmd_get_stats:
+		data.rv =
+		    netxen_nic_fill_statistics(adapter, port, &netxen_stats);
+		if (copy_to_user
+		    ((void *)(up_data->ptr), (void *)&netxen_stats,
+		     sizeof(struct netxen_statistics))) {
+			DPRINTK(ERR, "bad copy to userland: %d\n",
+				(int)sizeof(netxen_stats));
+			retval = -EFAULT;
+			goto error_out;
+		}
+		up_data->rv = data.rv;
+		break;
+
+	case netxen_nic_cmd_clear_stats:
+		data.rv = netxen_nic_clear_statistics(adapter, port);
+		up_data->rv = data.rv;
+		break;
+
+	case netxen_nic_cmd_get_version:
+		if (copy_to_user
+		    ((void *)&(up_data->u), NETXEN_NIC_LINUX_VERSIONID,
+		     sizeof(NETXEN_NIC_LINUX_VERSIONID))) {
+			DPRINTK(ERR, "bad copy to userland: %d\n",
+				(int)sizeof(data));
+			retval = -EFAULT;
+			goto error_out;
+		}
+		break;
+
+	default:
+		DPRINTK(INFO, "bad command %d for %p\n", data.cmd, adapter);
+		retval = -EOPNOTSUPP;
+		goto error_out;
+	}
+	put_user(data.rv, &(up_data->rv));
+	DPRINTK(INFO, "done ioctl for %p well.\n", adapter);
+
+      error_out:
+	return retval;
+}

^ permalink raw reply

* Re: [PATCH 1/9] NetXen 1G/10G ethernet driver patch with corrections
From: Andi Kleen @ 2006-06-07  9:49 UTC (permalink / raw)
  To: Linsys Contractor Amit S. Kale; +Cc: netdev, sanjeev, unmproj
In-Reply-To: <Pine.LNX.4.64.0606070237220.10031@unmsrvr>

On Wednesday 07 June 2006 11:39, Linsys Contractor Amit S. Kale wrote:

> +	switch (mode) {

... You could save a lot of code by using a table and a loop over the registers.


> +	case 4:{		/* XGB Mode */
> +			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_SINGLE_TERM,
> +						   &regs_buff[3]);


-Andi

^ permalink raw reply

* [PATCH 5/9] NetXen 1G/10G ethernet driver patch with corrections
From: Linsys Contractor Amit S. Kale @ 2006-06-07  9:49 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, unmproj

2006-06-07 Amit S. Kale <amitkale@unminc.com>
 	* Add a header file containing netxen hardware access routines

diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_hw.h linux-2.6.16.20/drivers/net/netxen/netxen_nic_hw.h
--- linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_hw.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/netxen_nic_hw.h	2006-06-06 06:58:11.000000000 -0700
@@ -0,0 +1,346 @@
+/*
+ * 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:
+ *    info@netxen.com
+ * NetXen,
+ * 3965 Freedom Circle, Fourth floor,
+ * Santa Clara, CA 95054
+ *
+ *
+ * Structures, enums, and macros for the MAC
+ *
+ */
+
+#ifndef __NETXEN_NIC_HW_H_
+#define __NETXEN_NIC_HW_H_
+
+#include "netxen_nic_hdr.h"
+
+/* Hardware memory size of 128 meg */
+#define NETXEN_MEMADDR_MAX (128 * 1024 * 1024)
+
+#ifndef readq
+static inline u64 readq(void __iomem * addr)
+{
+	return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(u64 val, void __iomem * addr)
+{
+	writel(((u32) (val)), (addr));
+	writel(((u32) (val >> 32)), (addr + 4));
+}
+#endif
+
+#define NETXEN_NIC_HW_BLOCK_WRITE_64(DATA_PTR, ADDR, NUM_WORDS)     \
+        do {                                                        \
+                int num;                                            \
+                u64 *a = (u64 *) (DATA_PTR);                        \
+                u64 *b = (u64 *) (ADDR);                            \
+                for (num = 0; num < (NUM_WORDS); num++) {           \
+                        writeq(readq(a), b);                        \
+                        b++;                                        \
+                        a++;                                        \
+                }                                                   \
+        } while (0)
+
+#define NETXEN_NIC_HW_BLOCK_READ_64(DATA_PTR, ADDR, NUM_WORDS)        \
+        do {                                                          \
+                int num;                                              \
+                u64 *a = (u64 *) (DATA_PTR);                          \
+                u64 *b = (u64 *) (ADDR);                              \
+                for (num = 0; num < (NUM_WORDS); num++) {             \
+                        writeq(readq(b), a);                          \
+                        b++;                                          \
+                        a++;                                          \
+                }                                                     \
+        } while (0)
+
+#define NETXEN_PCI_MAPSIZE_BYTES  (NETXEN_PCI_MAPSIZE << 20)
+#define NETXEN_DB_MAPSIZE_BYTES    0x4000
+
+#define NETXEN_NIC_LOCKED_READ_REG(X, Y)   		\
+        addr = (void *)(adapter->ahw.pci_base + X);     \
+        *(u32 *)Y = readl(addr);
+
+#define NETXEN_NIC_LOCKED_WRITE_REG(X, Y)   		\
+	addr = (void *)(adapter->ahw.pci_base + X); 	\
+	writel(*(u32 *)Y, addr);
+
+struct netxen_port;
+void netxen_nic_set_link_parameters(struct netxen_port *port);
+struct netxen_adapter;
+void netxen_nic_flash_print(struct netxen_adapter *adapter);
+
+int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off,
+			   void *data, int len);
+void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
+				 unsigned long off, int data);
+int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off,
+			  void *data, int len);
+
+typedef u8 netxen_ethernet_macaddr_t[6];
+
+/* Nibble or Byte mode for phy interface (GbE mode only) */
+typedef enum {
+	NETXEN_NIU_10_100_MB = 0,
+	NETXEN_NIU_1000_MB
+} netxen_niu_gbe_ifmode_t;
+
+/*
+ * NIU GB MAC Config Register 0 (applies to GB0, GB1, GB2, GB3)
+ */
+struct netxen_niu_gb_mac_config_0_t {
+	netxen_crbword_t tx_enable:1,	/* 1:enable frame xmit, 0:disable */
+	 tx_synched:1,		/* R/O: xmit enable synched to xmit stream */
+	 rx_enable:1,		/* 1:enable frame recv, 0:disable */
+	 rx_synched:1,		/* R/O: recv enable synched to recv stream */
+	 tx_flowctl:1,		/* 1:enable pause frame generation, 0:disable*/
+	 rx_flowctl:1,		/* 1:act on recv'd pause frames, 0:ignore */
+	 rsvd1:2,
+	 loopback:1,		/* 1:loop MAC xmits to MAC recvs, 0:normal */
+	 rsvd2:7,
+	 tx_reset_pb:1,		/* 1:reset frame xmit protocol blk, 0:no-op */
+	 rx_reset_pb:1,		/* 1:reset frame recv protocol blk, 0:no-op */
+	 tx_reset_mac:1,	/* 1:reset data/ctl multiplexer blk, 0:no-op */
+	 rx_reset_mac:1,	/* 1:reset ctl frames & timers blk, 0:no-op */
+	 rsvd3:11,
+	 soft_reset:1;	/* 1:reset the MAC and the SERDES, 0:no-op */
+};
+
+/*
+ * NIU GB MAC Config Register 1 (applies to GB0, GB1, GB2, GB3)
+ */
+struct netxen_niu_gb_mac_config_1_t {
+	netxen_crbword_t duplex:1,	/* 1:full duplex mode, 0:half duplex */
+	 crc_enable:1,	/* 1:append CRC to xmit frames, 0:dont append */
+	 padshort:1,	/* 1:pad short frames and add CRC, 0:dont pad */
+	 rsvd1:1,
+	 checklength:1,	/* 1:check framelen with actual, 0:dont check */
+	 hugeframes:1,	/* 1:allow oversize xmit frames, 0:dont allow */
+	 rsvd2:2,
+	 intfmode:2,	/* 01:nibble (10/100), 10:byte (1000) */
+	 rsvd3:2,
+	 preamblelen:4,	/* preamble field length in bytes, default 7 */
+	 rsvd4:16;
+};
+
+/*
+ * NIU GB Station Address High Register
+ * NOTE: this value is in network byte order.
+ */
+struct netxen_niu_gb_station_address_high {
+	netxen_crbword_t address:32;	/* station address [47:16] */
+};
+
+/*
+ * NIU GB Station Address Low Register
+ * NOTE: this value is in network byte order.
+ */
+struct netxen_niu_gb_station_address_low {
+	netxen_crbword_t rsvd:16, address:16;	/* station address [15:0] */
+};
+
+/*
+ * NIU GB MII Mgmt Config Register (applies to GB0, GB1, GB2, GB3)
+ */
+struct netxen_niu_gb_mii_mgmt_config {
+	netxen_crbword_t clockselect:3,
+	    /* 0:clk/4,  1:clk/4,  2:clk/6,  3:clk/8 */
+	    /* 4:clk/10, 5:clk/14, 6:clk/20, 7:clk/28 */
+	 rsvd1:1, nopreamble:1,	/* 1:suppress preamble generation, 0:normal */
+	 scanauto:1, rsvd2:25, reset:1;	/* 1:reset MII mgmt, 0:no-op */
+};
+
+/*
+ * NIU GB MII Mgmt Command Register (applies to GB0, GB1, GB2, GB3)
+ */
+struct netxen_niu_gb_mii_mgmt_command {
+	/* 1:perform single read cycle, 0:no-op */
+	netxen_crbword_t read_cycle:1,
+	 scan_cycle:1,		/* 1:perform continuous read cycles, 0:no-op */
+	 rsvd:30;
+};
+
+/*
+ * NIU GB MII Mgmt Address Register (applies to GB0, GB1, GB2, GB3)
+ */
+struct netxen_niu_gb_mii_mgmt_address {
+	/* which mgmt register we want to talk to */
+	netxen_crbword_t reg_addr:5,
+	 rsvd1:3, phy_addr:5,	/* which PHY to talk to (0 is reserved) */
+	 rsvd:19;
+};
+
+/*
+ * NIU GB MII Mgmt Indicators Register (applies to GB0, GB1, GB2, GB3)
+ * Read-only register.
+ */
+struct netxen_niu_gb_mii_mgmt_indicators {
+	/* 1:performing an MII mgmt cycle, 0:idle */
+	netxen_crbword_t busy:1,
+	 scanning:1,		/* 1:scan operation in progress, 0:idle */
+	 notvalid:1,		/* 1:mgmt result data not yet valid, 0:idle */
+	 rsvd:29;
+};
+
+/*
+ * PHY-Specific MII control/status registers.
+ */
+typedef enum {
+	NETXEN_NIU_GB_MII_MGMT_ADDR_CONTROL = 0,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_STATUS = 1,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_0 = 2,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_1 = 3,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG = 4,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART = 5,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE = 6,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT = 7,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE = 8,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL = 9,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS = 10,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS = 15,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL = 16,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS = 17,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE = 18,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS = 19,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE = 20,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT = 21,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_LED_CONTROL = 24,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE = 25,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET = 26,
+	NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE = 27
+} netxen_niu_phy_register_t;
+
+/*
+ * PHY-Specific Status Register (reg 17).
+ */
+struct netxen_niu_phy_status {
+	netxen_crbword_t jabber:1,	/* 1:jabber detected, 0:not */
+	 polarity:1,		/* 1:polarity reversed, 0:normal */
+	 recvpause:1,		/* 1:receive pause enabled, 0:disabled */
+	 xmitpause:1,		/* 1:transmit pause enabled, 0:disabled */
+	 energydetect:1,	/* 1:sleep, 0:active */
+	 downshift:1,		/* 1:downshift, 0:no downshift */
+	 crossover:1,		/* 1:MDIX (crossover), 0:MDI (no crossover) */
+	 cablelen:3,		/* not valid in 10Mb/s mode */
+	    /* 0:<50m, 1:50-80m, 2:80-110m, 3:110-140m, 4:>140m */
+	 link:1,		/* 1:link up, 0:link down */
+	 resolved:1,		/* 1:speed and duplex resolved, 0:not yet */
+	 pagercvd:1,		/* 1:page received, 0:page not received */
+	 duplex:1,		/* 1:full duplex, 0:half duplex */
+	 speed:2,		/* 0:10Mb/s, 1:100Mb/s, 2:1000Mb/s, 3:rsvd */
+	 rsvd:16;
+};
+
+/*
+ * Interrupt Register definition
+ * This definition applies to registers 18 and 19 (int enable and int status).
+ */
+struct netxen_niu_phy_interrupt {
+	netxen_crbword_t
+	    jabber:1,
+	    polarity_changed:1,
+	    reserved:2,
+	    energy_detect:1,
+	    downshift:1,
+	    mdi_xover_changed:1,
+	    fifo_over_underflow:1,
+	    false_carrier:1,
+	    symbol_error:1,
+	    link_status_changed:1,
+	    autoneg_completed:1,
+	    page_received:1,
+	    duplex_changed:1, speed_changed:1, autoneg_error:1, rsvd:16;
+};
+
+/*
+ * NIU Mode Register.
+ */
+struct netxen_niu_control {
+	netxen_crbword_t enable_fc:1,	/* enable FibreChannel */
+	 enable_ge:1,		/* enable 10/100/1000 Ethernet */
+	 enable_xgb:1,		/* enable 10Gb Ethernet */
+	 rsvd:29;
+};
+
+/* Promiscous mode options (GbE mode only) */
+typedef enum {
+	NETXEN_NIU_PROMISCOUS_MODE = 0,
+	NETXEN_NIU_NON_PROMISCOUS_MODE
+} netxen_niu_prom_mode_t;
+
+/*
+ * NIU GB Drop CRC Register
+ */
+struct netxen_niu_gb_drop_crc {
+	/* 1:drop pkts with bad CRCs, 0:pass them on */
+	netxen_crbword_t drop_gb0:1,
+	 drop_gb1:1,		/* 1:drop pkts with bad CRCs, 0:pass them on */
+	 drop_gb2:1,		/* 1:drop pkts with bad CRCs, 0:pass them on */
+	 drop_gb3:1,		/* 1:drop pkts with bad CRCs, 0:pass them on */
+	 rsvd:28;
+};
+
+/*
+ * NIU XG MAC Config Register
+ */
+struct netxen_niu_xg_mac_config_0_t {
+	netxen_crbword_t tx_enable:1,	/* 1:enable frame xmit, 0:disable */
+	 rsvd1:1, rx_enable:1,	/* 1:enable frame recv, 0:disable */
+	 rsvd2:1, soft_reset:1,	/* 1:reset the MAC , 0:no-op */
+	 rsvd3:22,
+	    xaui_framer_reset:1,
+	    xaui_rx_reset:1,
+	    xaui_tx_reset:1, xg_ingress_afifo_reset:1, xg_egress_afifo_reset:1;
+};
+
+/* Set promiscuous mode for a GbE interface */
+long netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, long port,
+				     netxen_niu_prom_mode_t mode);
+long netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
+					long port, netxen_niu_prom_mode_t mode);
+
+/* get/set the MAC address for a given MAC */
+int netxen_niu_macaddr_get(struct netxen_adapter *adapter, int port,
+			   netxen_ethernet_macaddr_t * addr);
+int netxen_niu_macaddr_set(struct netxen_adapter *adapter, int port,
+			   netxen_ethernet_macaddr_t addr);
+
+/* XG versons */
+int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int port,
+			      netxen_ethernet_macaddr_t * addr);
+int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, int port,
+			      netxen_ethernet_macaddr_t addr);
+
+/* Generic enable for GbE ports. Will detect the speed of the link. */
+long netxen_niu_gbe_init_port(struct netxen_adapter *adapter, long port);
+
+/* Disable a GbE interface */
+long netxen_niu_disable_gbe_port(struct netxen_adapter *adapter, long port);
+
+long netxen_niu_disable_xg_port(struct netxen_adapter *adapter, long port);
+
+#endif				/* __NETXEN_NIC_HW_H_ */

^ permalink raw reply

* [PATCH 4/9] NetXen 1G/10G ethernet driver patch with corrections
From: Linsys Contractor Amit S. Kale @ 2006-06-07  9:47 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, unmproj

2006-06-07 Amit S. Kale <amitkale@unminc.com>
 	* Add netxen driver hardware access routines

diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_hw.c linux-2.6.16.20/drivers/net/netxen/netxen_nic_hw.c
--- linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_hw.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/netxen_nic_hw.c	2006-06-06 06:58:11.000000000 -0700
@@ -0,0 +1,1308 @@
+/*
+ * 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:
+ *    info@netxen.com
+ * NetXen,
+ * 3965 Freedom Circle, Fourth floor,
+ * Santa Clara, CA 95054
+ *
+ *
+ * Source file for NIC routines to access the Phantom hardware
+ *
+ */
+
+#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 "netxen_nic_phan_reg.h"
+
+/*  PCI Windowing for DDR regions.  */
+
+#define ADDR_IN_RANGE(addr, low, high)	\
+	(((addr) <= (high)) && ((addr) >= (low)))
+
+static unsigned long netxen_nic_pci_set_window(unsigned long long pci_base,
+					       unsigned long long addr);
+void netxen_free_hw_resources(struct netxen_adapter *adapter);
+
+int netxen_nic_set_mac(struct net_device *netdev, void *p)
+{
+	struct netxen_port *port = netdev_priv(netdev);
+	struct sockaddr *addr = p;
+#ifdef NETXEN_DEBUG
+	struct netxen_adapter *adapter = port->adapter;
+#endif
+
+	if (netif_running(netdev))
+		return -EBUSY;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	DPRINTK(INFO, "valid ether addr\n");
+	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+
+	netxen_nic_macaddr_set(port, addr->sa_data);
+
+	return 0;
+}
+
+/**
+ * netxen_nic_set_multi - Multicast
+ **/
+void netxen_nic_set_multi(struct net_device *netdev)
+{
+	struct netxen_port *port = netdev_priv(netdev);
+	struct dev_mc_list *mc_ptr;
+
+	mc_ptr = netdev->mc_list;
+	if (netdev->flags & IFF_PROMISC)
+		netxen_nic_set_promisc_mode(port);
+	else
+		netxen_nic_unset_promisc_mode(port);
+}
+
+/*
+ * netxen_nic_change_mtu - Change the Maximum Transfer Unit
+ * @returns 0 on success, negative on failure
+ */
+int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	struct netxen_port *port = netdev_priv(netdev);
+
+	if (new_mtu & 0xffff0000)
+		return -EINVAL;
+
+	if (new_mtu > 8000) {
+		printk(KERN_ERR "%s: %s MTU > 8000 is not supported\n",
+		       netxen_nic_driver_name, netdev->name);
+		return -EINVAL;
+	}
+
+	netxen_nic_set_mtu(port, new_mtu);
+	netdev->mtu = new_mtu;
+
+	return 0;
+}
+
+/*
+ * check if the firmware has been downloaded and ready to run  and
+ * setup the address for the descriptors in the adapter
+ */
+int netxen_nic_hw_resources(struct netxen_adapter *adapter)
+{
+	int i;
+	u32 state = 0;
+	void *addr;
+	int loops = 0, err = 0;
+	int ring;
+	u32 card_cmdring = 0;
+	struct netxen_recv_context *recv_ctx;
+	struct netxen_rcv_desc_ctx *rcv_desc;
+	u32 ring_size;
+	struct netxen_ring_context *ctx;
+
+	DPRINTK(INFO, "pci_base: %lx\n", adapter->ahw.pci_base);
+	DPRINTK(INFO, "crb_base: %lx %lx", NETXEN_PCI_CRBSPACE,
+		adapter->ahw.pci_base + NETXEN_PCI_CRBSPACE);
+	DPRINTK(INFO, "cam base: %lx %lx", NETXEN_CRB_CAM,
+		adapter->ahw.pci_base + NETXEN_CRB_CAM);
+	DPRINTK(INFO, "cam RAM: %lx %lx", NETXEN_CAM_RAM_BASE,
+		adapter->ahw.pci_base + NETXEN_CAM_RAM_BASE);
+	DPRINTK(INFO, "NIC base:%lx %lx\n", NIC_CRB_BASE_PORT1,
+		adapter->ahw.pci_base + NIC_CRB_BASE_PORT1);
+
+	/* Window 1 call */
+	read_lock(&adapter->adapter_lock);
+	card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING));
+	read_unlock(&adapter->adapter_lock);
+
+	DPRINTK(INFO, "Command Peg sends 0x%x for cmdring base\n",
+		card_cmdring);
+
+	DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n");
+	loops = 0;
+	do {
+		/* Window 1 call */
+		read_lock(&adapter->adapter_lock);
+		state = readl(NETXEN_CRB_NORMALIZE(adapter,
+						   recv_crb_registers[0].
+						   crb_rcvpeg_state));
+		read_unlock(&adapter->adapter_lock);
+
+		loops++;
+		udelay(100);
+	} while (state != PHAN_INITIALIZE_COMPLETE && loops < 21);
+	if (loops >= 21) {
+		DPRINTK(1, ERR, "Rcv Peg initialization not complete:"
+			"%x.\n", state);
+		return -EIO;
+	}
+	DPRINTK(1, INFO, "Recieve Peg ready too. starting stuff\n");
+	for (i = 0; i < MAX_RING_CTX; i++) {
+		ctx = &adapter->ring_ctx[i];
+		/*
+		 * Alloc command ring consumer location and ring context
+		 * which phanmon will dma to card
+		 */
+		addr = pci_alloc_consistent(adapter->ahw.pdev,
+					    sizeof(struct ring_context) +
+					    sizeof(u32),
+					    (dma_addr_t *) & ctx->
+					    ctx_desc_phys_addr);
+		DPRINTK(1, INFO, "ctx_desc_phys_addr: 0x%08x\n",
+			ctx->ctx_desc_phys_addr);
+		if (addr == NULL) {
+			DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
+			netxen_free_hw_resources(adapter);
+			err = -ENOMEM;
+			return err;
+		}
+		memset(addr, 0, sizeof(struct ring_context));
+		ctx->ctx_desc = (struct ring_context *)addr;
+		ctx->ctx_desc->CMD_CONSUMER_OFFSET = ctx->ctx_desc_phys_addr
+		    + sizeof(struct ring_context);
+		ctx->cmd_consumer =
+		    (u32 *) ((char *)addr) + sizeof(struct ring_context);
+		/*
+		 * Alloc command ring shared between host and phantom
+		 */
+		ring_size =
+		    sizeof(struct cmd_desc_type0_t) * ctx->max_tx_desc_count;
+		addr =
+		    pci_alloc_consistent(adapter->ahw.pdev, ring_size,
+					 (dma_addr_t *) & ctx->hw_ring_ctx.
+					 cmd_desc_phys_addr);
+		DPRINTK(1, INFO, "cmd_desc_phys_addr: 0x%08x, size 0x%08x\n",
+			ctx->hw_ring_ctx.cmd_desc_phys_addr, ring_size);
+		if (addr == NULL) {
+			DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
+			netxen_free_hw_resources(adapter);
+			err = -ENOMEM;
+			return err;
+		}
+		ctx->hw_ring_ctx.cmd_desc_head =
+		    (struct cmd_desc_type0_t *)addr;
+		ctx->ctx_desc->CmdRingAddrLo =
+		    ctx->hw_ring_ctx.cmd_desc_phys_addr;
+		ctx->ctx_desc->CmdRingSize = ctx->max_tx_desc_count;
+		DPRINTK(1, INFO, "CMD_RING, ctx %d, val 0x%x, virt%p,"
+			"size %d\n", i,
+			ctx->hw_ring_ctx.cmd_desc_phys_addr,
+			ctx->hw_ring_ctx.cmd_desc_head, ring_size);
+		/*
+		 * Alloc receive rings shared between host and phantom
+		 */
+		recv_ctx = &ctx->recv_ctx;
+
+		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+			ring_size = (sizeof(struct rcv_desc_t) *
+					rcv_desc->max_rx_desc_count);
+			addr = pci_alloc_consistent(adapter->ahw.pdev,
+						    ring_size, (dma_addr_t *)
+						    & rcv_desc->phys_addr);
+			DPRINTK(1, INFO,
+				"rcv %d physAddr: 0x%08x, size 0x%08x\n", ring,
+				rcv_desc->phys_addr, ring_size);
+			if (addr == NULL) {
+				DPRINTK(ERR, "bad return from "
+					"pci_alloc_consistent\n");
+				netxen_free_hw_resources(adapter);
+				err = -ENOMEM;
+				return err;
+			}
+			rcv_desc->desc_head = (struct rcv_desc_t *)addr;
+			ctx->ctx_desc->RcvContext[ring].RcvRingAddrLo =
+			    rcv_desc->phys_addr;
+			ctx->ctx_desc->RcvContext[ring].RcvRingSize =
+			    rcv_desc->max_rx_desc_count;
+			DPRINTK(1, INFO, "GLOBAL_RCV_RING ctx %d, ring #%d,"
+				" val 0x%x, virt %p, size %d\n",
+				i, ring, rcv_desc->phys_addr,
+				rcv_desc->desc_head, ring_size);
+		}
+
+		addr = pci_alloc_consistent(adapter->ahw.pdev,
+					    ring_size, (dma_addr_t *)
+					    & recv_ctx->
+					    rcv_status_desc_phys_addr);
+		DPRINTK(1, INFO,
+			"rcvStatusDesc_physAddr: 0x%08x, size 0x%08x\n",
+			recv_ctx->rcvStatusDesc_physAddr, ring_size);
+		if (addr == NULL) {
+			DPRINTK(ERR, "bad return from"
+				" pci_alloc_consistent\n");
+			netxen_free_hw_resources(adapter);
+			err = -ENOMEM;
+			return err;
+		}
+		recv_ctx->rcv_status_desc_head = (struct status_desc_t *)addr;
+
+		ctx->ctx_desc->StsRingAddrLo =
+		    recv_ctx->rcv_status_desc_phys_addr;
+		ctx->ctx_desc->StsRingSize = ctx->max_rx_desc_count;
+		DPRINTK(1, INFO, "RCVSTATUS_RING, ctx %d,"
+			" val 0x%x, virt %p, size %d\n", i,
+			recv_ctx->rcvStatusDesc_physAddr,
+			recv_ctx->rcvStatusDescHead, ring_size);
+	}
+	/* Window = 1 */
+	read_lock(&adapter->adapter_lock);
+	writel(ctx->ctx_desc_phys_addr,
+	       NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG));
+	writel(NETXEN_CTX_SIGNATURE,
+	       NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG));
+
+	read_unlock(&adapter->adapter_lock);
+
+	return err;
+}
+
+void netxen_free_hw_resources(struct netxen_adapter *adapter)
+{
+	struct netxen_recv_context *recv_ctx;
+	struct netxen_rcv_desc_ctx *rcv_desc;
+	int ring, i;
+	struct netxen_ring_context *ctx;
+
+	for (i = 0; i < MAX_RING_CTX; i++) {
+		ctx = &adapter->ring_ctx[i];
+
+		if (ctx->ctx_desc != NULL) {
+			pci_free_consistent(adapter->ahw.pdev,
+					    sizeof(struct ring_context) +
+					    sizeof(u32),
+					    ctx->ctx_desc,
+					    ctx->ctx_desc_phys_addr);
+			ctx->ctx_desc = NULL;
+		}
+
+		if (ctx->hw_ring_ctx.cmd_desc_head != NULL) {
+			pci_free_consistent(adapter->ahw.pdev,
+					    sizeof(struct cmd_desc_type0_t) *
+					    ctx->max_tx_desc_count,
+					    ctx->hw_ring_ctx.cmd_desc_head,
+					    ctx->hw_ring_ctx.
+					    cmd_desc_phys_addr);
+			ctx->hw_ring_ctx.cmd_desc_head = NULL;
+		}
+		recv_ctx = &ctx->recv_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(i),
+						    rcv_desc->desc_head,
+						    rcv_desc->phys_addr);
+				rcv_desc->desc_head = NULL;
+			}
+		}
+
+		if (recv_ctx->rcv_status_desc_head != NULL) {
+			pci_free_consistent(adapter->ahw.pdev,
+					    STATUS_DESC_RINGSIZE(i),
+					    recv_ctx->rcv_status_desc_head,
+					    recv_ctx->
+					    rcv_status_desc_phys_addr);
+			recv_ctx->rcv_status_desc_head = NULL;
+		}
+	}
+}
+
+void netxen_tso_check(struct netxen_adapter *adapter,
+		      struct cmd_desc_type0_t *desc, struct sk_buff *skb)
+{
+	if (desc->mss) {
+		desc->total_hdr_length = sizeof(struct ethhdr) +
+		    ((skb->nh.iph)->ihl * sizeof(u32)) +
+		    ((skb->h.th)->doff * sizeof(u32));
+		desc->opcode = TX_TCP_LSO;
+	} else if (skb->ip_summed == CHECKSUM_HW) {
+		if (skb->nh.iph->protocol == IPPROTO_TCP) {
+			desc->opcode = TX_TCP_PKT;
+		} else if (skb->nh.iph->protocol == IPPROTO_UDP) {
+			desc->opcode = TX_UDP_PKT;
+		} else {
+			return;
+		}
+	}
+	desc->tcp_hdr_offset = skb->h.raw - skb->data;
+	desc->ip_hdr_offset = skb->nh.raw - skb->data;
+	adapter->stats.xmitcsummed++;
+}
+
+int is_flash_supported(struct netxen_adapter *adapter)
+{
+	int locs[] = { 0, 0x4, 0x100, 0x4000, 0x4128 };
+	int addr, val01, val02, i, j;
+
+	/* if the flash size less than 4Mb, make huge war cry and die */
+	for (j = 1; j < 4; j++) {
+		addr = j * 0x100000;
+		for (i = 0; i < (sizeof(locs) / sizeof(locs[0])); i++) {
+			if (netxen_rom_fast_read(adapter, locs[i], &val01) == 0
+			    && netxen_rom_fast_read(adapter, (addr + locs[i]),
+						    &val02) == 0) {
+				if (val01 == val02)
+					return -1;
+			} else
+				return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
+				  int size, u32 * buf)
+{
+	int i, addr;
+	u32 *ptr32;
+
+	addr = base;
+	ptr32 = buf;
+	for (i = 0; i < size / sizeof(u32); i++) {
+		if (netxen_rom_fast_read(adapter, addr, ptr32) == -1)
+			return -1;
+		ptr32++;
+		addr += sizeof(u32);
+	}
+	if ((char *)buf + size > (char *)ptr32) {
+		u32 local;
+
+		if (netxen_rom_fast_read(adapter, addr, &local) == -1)
+			return -1;
+		memcpy(ptr32, &local, (char *)buf + size - (char *)ptr32);
+	}
+
+	return 0;
+}
+
+int get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[])
+{
+	u32 *pmac = (u32 *) & mac[0];
+
+	if (netxen_get_flash_block(adapter,
+				   USER_START +
+				   offsetof(struct netxen_new_user_info,
+					    mac_addr),
+				   FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) {
+		return -1;
+	}
+	if (*mac == ~0ULL) {
+		if (netxen_get_flash_block(adapter,
+					   USER_START_OLD +
+					   offsetof(struct netxen_user_info,
+						    mac_addr),
+					   FLASH_NUM_PORTS * sizeof(u64),
+					   pmac) == -1)
+			return -1;
+		if (*mac == ~0ULL)
+			return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Changes the CRB window to the specified window.
+ */
+void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
+{
+	struct netxen_pcix_crb_window window;
+	unsigned long offset;
+	u32 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.
+	 */
+	offset = adapter->ahw.pci_base + NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW);
+
+	*(netxen_crbword_t *) & window = 0;
+	window.addrbit = wndw;
+	writel(*(unsigned int *)&window, (void *)(offset));
+
+	/* MUST make sure window is set before we forge on... */
+	while ((tmp = readl((void *)offset)) != *(u32 *) & 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;
+}
+
+/*
+ * Set the CRB window based on the offset.
+ */
+static inline unsigned long
+netxen_nic_pci_set_crbwindow(struct 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(struct netxen_adapter *adapter, u64 off, void *data,
+		       int len)
+{
+	void *addr;
+	unsigned long flags = 0;
+
+	if (ADDR_IN_WINDOW1(off)) {
+		addr = NETXEN_CRB_NORMALIZE(adapter, off);
+		read_lock(&adapter->adapter_lock);
+	} else {		/* Window 0 */
+		addr = (void *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+		write_lock_irqsave(&adapter->adapter_lock, flags);
+		netxen_nic_pci_change_crbwindow(adapter, 0);
+	}
+
+	DPRINTK(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:
+		writeb(*(u8 *) data, addr);
+		break;
+	case 2:
+		writew(*(u16 *) data, addr);
+		break;
+	case 4:
+		writel(*(u32 *) data, addr);
+		break;
+	case 8:
+		writeq(*(u64 *) data, addr);
+		break;
+	default:
+		DPRINTK(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))
+		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(struct netxen_adapter *adapter, u64 off, void *data,
+		      int len)
+{
+	void *addr;
+	unsigned long flags = 0;
+
+	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
+		addr = NETXEN_CRB_NORMALIZE(adapter, off);
+		read_lock(&adapter->adapter_lock);
+	} else {		/* Window 0 */
+		addr = (void *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+		write_lock_irqsave(&adapter->adapter_lock, flags);
+		netxen_nic_pci_change_crbwindow(adapter, 0);
+	}
+
+	DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
+		adapter->ahw.pci_base, off, addr);
+	switch (len) {
+	case 1:
+		*(u8 *) data = readb(addr);
+		break;
+	case 2:
+		*(u16 *) data = readw(addr);
+		break;
+	case 4:
+		*(u32 *) data = readl(addr);
+		break;
+	case 8:
+		*(u64 *) data = readq(addr);
+		break;
+	default:
+		NETXEN_NIC_HW_BLOCK_READ_64(data, addr, (len >> 3));
+		break;
+	}
+	DPRINTK(INFO, "read %lx\n", *(unsigned long *)data);
+
+	if (ADDR_IN_WINDOW1(off))
+		read_unlock(&adapter->adapter_lock);
+	else {			/* Window 0 */
+		netxen_nic_pci_change_crbwindow(adapter, 1);
+		write_unlock_irqrestore(&adapter->adapter_lock, flags);
+	}
+
+	return 0;
+}
+
+void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
+{				/* Only for window 1 */
+	void *addr;
+
+	read_lock(&adapter->adapter_lock);
+
+	if (adapter->curr_window != 1)
+		netxen_nic_pci_change_crbwindow(adapter, 1);
+	addr = NETXEN_CRB_NORMALIZE(adapter, off);
+	DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n",
+		adapter->ahw.pci_base, off, addr, val);
+	writel(val, addr);
+
+	read_unlock(&adapter->adapter_lock);
+}
+
+int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
+{				/* Only for window 1 */
+	void *addr;
+	int val;
+
+	read_lock(&adapter->adapter_lock);
+	addr = NETXEN_CRB_NORMALIZE(adapter, off);
+	DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
+		adapter->ahw.pci_base, off, addr);
+	val = readl(addr);
+	writel(val, addr);
+	read_unlock(&adapter->adapter_lock);
+
+	return val;
+}
+
+/* Change the window to 0, write and change back to window 1. */
+void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value)
+{
+	unsigned long flags;
+	void *addr;
+
+	write_lock_irqsave(&adapter->adapter_lock, flags);
+	netxen_nic_pci_change_crbwindow(adapter, 0);
+	addr = (void *)(adapter->ahw.pci_base + index);
+	writel(value, addr);
+	netxen_nic_pci_change_crbwindow(adapter, 1);
+	write_unlock_irqrestore(&adapter->adapter_lock, flags);
+}
+
+/* Change the window to 0, read and change back to window 1. */
+void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value)
+{
+	unsigned long flags;
+	void *addr;
+
+	addr = (void *)(adapter->ahw.pci_base + index);
+
+	write_lock_irqsave(&adapter->adapter_lock, flags);
+	netxen_nic_pci_change_crbwindow(adapter, 0);
+	*value = readl(addr);
+	netxen_nic_pci_change_crbwindow(adapter, 1);
+	write_unlock_irqrestore(&adapter->adapter_lock, flags);
+}
+
+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;
+
+	if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+		/* DDR network side */
+		addr -= NETXEN_ADDR_DDR_NET;
+		window = (addr >> 25) & 0x3ff;
+		if (ddr_mn_window != window) {
+			ddr_mn_window = window;
+			writel(window, (void *)(ptrdiff_t) (pci_base +
+							    NETXEN_PCIX_PH_REG
+							    (PCIX_MN_WINDOW)));
+			/* MUST make sure window is set before we forge on... */
+			readl((void *)(ptrdiff_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)) {
+		/* QDR network side */
+		addr -= NETXEN_ADDR_QDR_NET;
+		window = (addr >> 22) & 0x3f;
+		if (qdr_sn_window != window) {
+			qdr_sn_window = window;
+			writel((window << 22),
+			       (void *)(ptrdiff_t) (pci_base +
+						    NETXEN_PCIX_PH_REG
+						    (PCIX_SN_WINDOW)));
+			/* MUST make sure window is set before we forge on... */
+			readl((void *)(ptrdiff_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);
+
+	}
+	return addr;
+}
+
+/* read num_words from hardware (num_words in 64 bits    */
+void
+netxen_nic_mem_block_read(struct netxen_adapter *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 *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+	DPRINTK(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);
+}
+
+int
+netxen_nic_pci_mem_write(struct netxen_adapter *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 *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+	DPRINTK(INFO, "writing data %llx to offset %llx\n",
+		*(unsigned long long *)data, off);
+	switch (size) {
+	case 1:
+		writeb(*(u8 *) data, addr);
+		break;
+	case 2:
+		writew(*(u16 *) data, addr);
+		break;
+	case 4:
+		writel(*(u32 *) data, addr);
+		break;
+	case 8:
+		writeq(*(u64 *) data, addr);
+		break;
+	default:
+		ret = 1;
+		break;
+	}
+	write_unlock_irqrestore(&adapter->adapter_lock, flags);
+	DPRINTK(INFO, "wrote %llx\n", *(unsigned long long *)data);
+
+	return ret;
+}
+
+int
+netxen_nic_pci_mem_read(struct netxen_adapter *adapter,
+			u64 off, void *data, int size)
+{
+	unsigned long flags;
+	void *addr;
+	int ret = 0;
+
+	if (data == NULL || off > NETXEN_MEMADDR_MAX) {
+		printk(KERN_ERR "data: %p off:%llx\n", data, off);
+		return 1;
+	}
+	write_lock_irqsave(&adapter->adapter_lock, flags);
+	off = netxen_nic_pci_set_window(adapter->ahw.pci_base, off);
+	addr = (void *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+	switch (size) {
+	case 1:
+		*(u8 *) data = readb(addr);
+		break;
+	case 2:
+		*(u16 *) data = readw(addr);
+		break;
+	case 4:
+		*(u32 *) data = readl(addr);
+		break;
+	case 8:
+		*(u64 *) data = readq(addr);
+		break;
+	default:
+		ret = 1;
+		break;
+	}
+	write_unlock_irqrestore(&adapter->adapter_lock, flags);
+	DPRINTK(INFO, "read %llx\n", *(unsigned long long *)data);
+
+	return ret;
+}
+
+int netxen_nic_get_board_info(struct netxen_adapter *adapter)
+{
+	int rv = 0;
+	int addr = BRDCFG_START;
+	struct netxen_board_info *boardinfo;
+	int index;
+	u32 *ptr32;
+
+	boardinfo = &adapter->ahw.boardcfg;
+	ptr32 = (u32 *) boardinfo;
+
+	for (index = 0; index < sizeof(struct netxen_board_info) / sizeof(u32);
+	     index++) {
+		if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
+			rv = -1;
+			return rv;
+		}
+		ptr32++;
+		addr += sizeof(u32);
+	}
+	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(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;
+}
+
+inline int netxen_nic_get_board_num(struct 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, u8 * addr)
+{
+	struct netxen_adapter *adapter = port->adapter;
+	int phy = port->portnum, ret = 0;
+
+	if ((phy < 0) || (phy > 3))
+		return -1;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		ret = netxen_niu_macaddr_set(adapter, phy, addr);
+		break;
+
+	case NETXEN_NIC_XGBE:
+		ret = netxen_niu_xg_macaddr_set(adapter, phy, addr);
+		break;
+
+	default:
+		dump_stack();
+		printk(KERN_ERR "%s: Unknown board type\n",
+		       netxen_nic_driver_name);
+		ret = -1;
+	}
+
+	return ret;
+}
+
+/* Return the current MAC address of the given port. */
+int netxen_nic_macaddr_get(struct netxen_port *port, u8 ** addr)
+{
+	struct netxen_adapter *adapter = port->adapter;
+	int phy = port->portnum;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+	if ((phy < 0) || (phy > 3))
+		return -1;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		ret = netxen_niu_macaddr_get(adapter, phy,
+					     (netxen_ethernet_macaddr_t *) *
+					     addr);
+		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 *adapter = port->adapter;
+	int ret = 0;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		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_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);
+		ret = -1;
+	}
+
+	return ret;
+}
+
+int netxen_nic_set_promisc_mode(struct netxen_port *port)
+{
+	struct netxen_adapter *adapter = port->adapter;
+	int phy = port->portnum;
+	int ret = 0;
+
+	if ((phy < 0) || (phy > 3))
+		return -1;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		ret = netxen_niu_set_promiscuous_mode(adapter, phy,
+						      NETXEN_NIU_PROMISCOUS_MODE);
+		break;
+
+	case NETXEN_NIC_XGBE:
+		ret = netxen_niu_xg_set_promiscuous_mode(adapter, phy,
+							 NETXEN_NIU_PROMISCOUS_MODE);
+
+		break;
+
+	default:
+		printk(KERN_ERR "%s: Unknown board type\n",
+		       netxen_nic_driver_name);
+		ret = -1;
+	}
+
+	return ret;
+}
+
+int netxen_nic_unset_promisc_mode(struct netxen_port *port)
+{
+	struct netxen_adapter *adapter = port->adapter;
+	int phy = port->portnum;
+	int ret = 0;
+
+	if ((phy < 0) || (phy > 3))
+		return -1;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		ret = netxen_niu_set_promiscuous_mode(adapter, phy,
+						      NETXEN_NIU_NON_PROMISCOUS_MODE);
+		break;
+
+	case NETXEN_NIC_XGBE:
+		ret = netxen_niu_xg_set_promiscuous_mode(adapter, phy,
+							 NETXEN_NIU_NON_PROMISCOUS_MODE);
+
+		break;
+
+	default:
+		printk(KERN_ERR "%s: Unknown board type\n",
+		       netxen_nic_driver_name);
+		ret = -1;
+	}
+
+	return ret;
+}
+
+long
+netxen_nic_phy_read(struct netxen_adapter *adapter, long phy, long reg,
+		    u32 * readval)
+{
+	long ret = 0;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		ret = netxen_niu_gbe_phy_read(adapter, phy, reg, readval);
+		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;
+}
+
+long netxen_nic_phy_write(struct netxen_adapter *adapter, long phy, long reg,
+			  u32 val)
+{
+	long ret = 0;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		ret = netxen_niu_gbe_phy_write(adapter, phy, reg, val);
+		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;
+}
+
+long netxen_nic_init_port(struct netxen_port *port)
+{
+	struct netxen_adapter *adapter = port->adapter;
+	long portnum = port->portnum;
+	long ret = 0;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		netxen_nic_disable_phy_interrupts(adapter, portnum);
+		udelay(20000);
+		netxen_niu_gbe_init_port(adapter, portnum);
+
+		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);
+		ret = -1;
+	}
+
+	return ret;
+}
+
+void netxen_nic_init_niu(struct netxen_adapter *adapter)
+{
+	int portno;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++)
+			netxen_niu_gbe_init_port(adapter, portno);
+		break;
+
+	case NETXEN_NIC_XGBE:
+		/* Do nothing */
+		break;
+
+	default:
+		printk(KERN_ERR "%s: Unknown board type\n",
+		       netxen_nic_driver_name);
+	}
+}
+
+void netxen_nic_stop_port(struct netxen_port *port)
+{
+	long portnum = port->portnum;
+	struct netxen_adapter *adapter = port->adapter;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		netxen_niu_disable_gbe_port(adapter, portnum);
+		break;
+
+	case NETXEN_NIC_XGBE:
+		netxen_niu_disable_xg_port(adapter, portnum);
+		break;
+
+	default:
+		printk(KERN_ERR "%s: Unknown board type\n",
+		       netxen_nic_driver_name);
+	}
+}
+
+void netxen_nic_stop_all_ports(struct netxen_adapter *adapter)
+{
+	int port_nr;
+	struct netxen_port *port;
+
+	for (port_nr = 0; port_nr < adapter->ahw.max_ports; port_nr++) {
+		port = adapter->port[port_nr];
+		netxen_nic_stop_port(port);
+	}
+}
+
+void
+netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off,
+			    int data)
+{
+	unsigned long flags;
+	void *addr;
+
+	if (ADDR_IN_WINDOW1(off)) {
+		read_lock(&adapter->adapter_lock);
+		writel(data, NETXEN_CRB_NORMALIZE(adapter, off));
+		read_unlock(&adapter->adapter_lock);
+	} else {
+		write_lock_irqsave(&adapter->adapter_lock, flags);
+		netxen_nic_pci_change_crbwindow(adapter, 0);
+		addr = (void *)(adapter->ahw.pci_base + off);
+		writel(data, addr);
+		netxen_nic_pci_change_crbwindow(adapter, 1);
+		write_unlock_irqrestore(&adapter->adapter_lock, flags);
+	}
+}
+
+void netxen_nic_set_link_parameters(struct netxen_port *port)
+{
+	struct netxen_adapter *adapter = port->adapter;
+	struct netxen_niu_phy_status status;
+	u16 autoneg;
+	struct netxen_niu_control mode;
+
+	netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, (u32 *) & 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) {
+				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
+				goto link_down;
+		} else {
+		      link_down:
+			port->link_speed = -1;
+			port->link_duplex = -1;
+		}
+	}
+}
+
+void netxen_nic_flash_print(struct netxen_adapter *adapter)
+{
+	int valid = 1;
+	u32 fw_major = 0;
+	u32 fw_minor = 0;
+	u32 fw_build = 0;
+
+	struct netxen_board_info *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 = readl(NETXEN_CRB_NORMALIZE(adapter,
+						      NETXEN_FW_VERSION_MAJOR));
+		fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter,
+						      NETXEN_FW_VERSION_MINOR));
+		fw_build =
+		    readl(NETXEN_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);
+}

^ permalink raw reply

* [PATCH 3/9] NetXen 1G/10G ethernet driver patch with corrections
From: Linsys Contractor Amit S. Kale @ 2006-06-07  9:46 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, unmproj

2006-06-07 Amit S. Kale <amitkale@unminc.com>
 	* Add a header file containing netxen registers info

diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_hdr.h linux-2.6.16.20/drivers/net/netxen/netxen_nic_hdr.h
--- linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_hdr.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/netxen_nic_hdr.h	2006-06-06 06:58:11.000000000 -0700
@@ -0,0 +1,684 @@
+/*
+ * 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:
+ *    info@netxen.com
+ * NetXen,
+ * 3965 Freedom Circle, Fourth floor,
+ * Santa Clara, CA 95054
+ */
+
+#ifndef __NETXEN_NIC_HDR_H_
+#define __NETXEN_NIC_HDR_H_
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/version.h>
+
+#include <asm/semaphore.h>
+#include <linux/spinlock.h>
+#include <asm/irq.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <asm/string.h>		/* for memset */
+
+extern struct netxen_adapter *g_adapter;
+
+/*
+ * The basic unit of access when reading/writing control registers.
+ */
+
+typedef u32 netxen_crbword_t;	/* single word in CRB space */
+
+#define NETXEN_HW_H0_CH_HUB_ADR	0x05
+#define NETXEN_HW_H1_CH_HUB_ADR	0x0E
+#define NETXEN_HW_H2_CH_HUB_ADR	0x03
+#define NETXEN_HW_H3_CH_HUB_ADR	0x01
+#define NETXEN_HW_H4_CH_HUB_ADR	0x06
+#define NETXEN_HW_H5_CH_HUB_ADR	0x07
+#define NETXEN_HW_H6_CH_HUB_ADR	0x08
+
+/*  Hub 0 */
+#define NETXEN_HW_MN_CRB_AGT_ADR	0x15
+#define NETXEN_HW_MS_CRB_AGT_ADR	0x25
+
+/*  Hub 1 */
+#define NETXEN_HW_PS_CRB_AGT_ADR	0x73
+#define NETXEN_HW_SS_CRB_AGT_ADR	0x20
+#define NETXEN_HW_RPMX3_CRB_AGT_ADR	0x0b
+#define NETXEN_HW_QMS_CRB_AGT_ADR	0x00
+#define NETXEN_HW_SQGS0_CRB_AGT_ADR	0x01
+#define NETXEN_HW_SQGS1_CRB_AGT_ADR	0x02
+#define NETXEN_HW_SQGS2_CRB_AGT_ADR	0x03
+#define NETXEN_HW_SQGS3_CRB_AGT_ADR	0x04
+#define NETXEN_HW_C2C0_CRB_AGT_ADR	0x58
+#define NETXEN_HW_C2C1_CRB_AGT_ADR	0x59
+#define NETXEN_HW_C2C2_CRB_AGT_ADR	0x5a
+#define NETXEN_HW_RPMX2_CRB_AGT_ADR	0x0a
+#define NETXEN_HW_RPMX4_CRB_AGT_ADR	0x0c
+#define NETXEN_HW_RPMX7_CRB_AGT_ADR	0x0f
+#define NETXEN_HW_RPMX9_CRB_AGT_ADR	0x12
+#define NETXEN_HW_SMB_CRB_AGT_ADR	0x18
+
+/*  Hub 2 */
+#define NETXEN_HW_NIU_CRB_AGT_ADR	0x31
+#define NETXEN_HW_I2C0_CRB_AGT_ADR	0x19
+#define NETXEN_HW_I2C1_CRB_AGT_ADR	0x29
+
+#define NETXEN_HW_SN_CRB_AGT_ADR	0x10
+#define NETXEN_HW_I2Q_CRB_AGT_ADR	0x20
+#define NETXEN_HW_LPC_CRB_AGT_ADR	0x22
+#define NETXEN_HW_ROMUSB_CRB_AGT_ADR	0x21
+#define NETXEN_HW_QM_CRB_AGT_ADR	0x66
+#define NETXEN_HW_SQG0_CRB_AGT_ADR	0x60
+#define NETXEN_HW_SQG1_CRB_AGT_ADR	0x61
+#define NETXEN_HW_SQG2_CRB_AGT_ADR	0x62
+#define NETXEN_HW_SQG3_CRB_AGT_ADR	0x63
+#define NETXEN_HW_RPMX1_CRB_AGT_ADR	0x09
+#define NETXEN_HW_RPMX5_CRB_AGT_ADR	0x0d
+#define NETXEN_HW_RPMX6_CRB_AGT_ADR	0x0e
+#define NETXEN_HW_RPMX8_CRB_AGT_ADR	0x11
+
+/*  Hub 3 */
+#define NETXEN_HW_PH_CRB_AGT_ADR	0x1A
+#define NETXEN_HW_SRE_CRB_AGT_ADR	0x50
+#define NETXEN_HW_EG_CRB_AGT_ADR	0x51
+#define NETXEN_HW_RPMX0_CRB_AGT_ADR	0x08
+
+/*  Hub 4 */
+#define NETXEN_HW_PEGN0_CRB_AGT_ADR	0x40
+#define NETXEN_HW_PEGN1_CRB_AGT_ADR	0x41
+#define NETXEN_HW_PEGN2_CRB_AGT_ADR	0x42
+#define NETXEN_HW_PEGN3_CRB_AGT_ADR	0x43
+#define NETXEN_HW_PEGNI_CRB_AGT_ADR	0x44
+#define NETXEN_HW_PEGND_CRB_AGT_ADR	0x45
+#define NETXEN_HW_PEGNC_CRB_AGT_ADR	0x46
+#define NETXEN_HW_PEGR0_CRB_AGT_ADR	0x47
+#define NETXEN_HW_PEGR1_CRB_AGT_ADR	0x48
+#define NETXEN_HW_PEGR2_CRB_AGT_ADR	0x49
+#define NETXEN_HW_PEGR3_CRB_AGT_ADR	0x4a
+
+/*  Hub 5 */
+#define NETXEN_HW_PEGS0_CRB_AGT_ADR	0x40
+#define NETXEN_HW_PEGS1_CRB_AGT_ADR	0x41
+#define NETXEN_HW_PEGS2_CRB_AGT_ADR	0x42
+#define NETXEN_HW_PEGS3_CRB_AGT_ADR	0x43
+#define NETXEN_HW_PEGSI_CRB_AGT_ADR	0x44
+#define NETXEN_HW_PEGSD_CRB_AGT_ADR	0x45
+#define NETXEN_HW_PEGSC_CRB_AGT_ADR	0x46
+
+/*  Hub 6 */
+#define NETXEN_HW_CAS0_CRB_AGT_ADR	0x46
+#define NETXEN_HW_CAS1_CRB_AGT_ADR	0x47
+#define NETXEN_HW_CAS2_CRB_AGT_ADR	0x48
+#define NETXEN_HW_CAS3_CRB_AGT_ADR	0x49
+#define NETXEN_HW_NCM_CRB_AGT_ADR	0x16
+#define NETXEN_HW_TMR_CRB_AGT_ADR	0x17
+#define NETXEN_HW_XDMA_CRB_AGT_ADR	0x05
+#define NETXEN_HW_OCM0_CRB_AGT_ADR	0x06
+#define NETXEN_HW_OCM1_CRB_AGT_ADR	0x07
+
+/*  Floaters - non existent modules */
+#define NETXEN_HW_EFC_RPMX0_CRB_AGT_ADR	0x67
+
+/*  This field defines PCI/X adr [25:20] of agents on the CRB */
+#define NETXEN_HW_PX_MAP_CRB_PH		0
+#define NETXEN_HW_PX_MAP_CRB_PS		1
+#define NETXEN_HW_PX_MAP_CRB_MN		2
+#define NETXEN_HW_PX_MAP_CRB_MS		3
+#define NETXEN_HW_PX_MAP_CRB_SRE	5
+#define NETXEN_HW_PX_MAP_CRB_NIU	6
+#define NETXEN_HW_PX_MAP_CRB_QMN	7
+#define NETXEN_HW_PX_MAP_CRB_SQN0	8
+#define NETXEN_HW_PX_MAP_CRB_SQN1	9
+#define NETXEN_HW_PX_MAP_CRB_SQN2	10
+#define NETXEN_HW_PX_MAP_CRB_SQN3	11
+#define NETXEN_HW_PX_MAP_CRB_QMS	12
+#define NETXEN_HW_PX_MAP_CRB_SQS0	13
+#define NETXEN_HW_PX_MAP_CRB_SQS1	14
+#define NETXEN_HW_PX_MAP_CRB_SQS2	15
+#define NETXEN_HW_PX_MAP_CRB_SQS3	16
+#define NETXEN_HW_PX_MAP_CRB_PGN0	17
+#define NETXEN_HW_PX_MAP_CRB_PGN1	18
+#define NETXEN_HW_PX_MAP_CRB_PGN2	19
+#define NETXEN_HW_PX_MAP_CRB_PGN3	20
+#define NETXEN_HW_PX_MAP_CRB_PGND	21
+#define NETXEN_HW_PX_MAP_CRB_PGNI	22
+#define NETXEN_HW_PX_MAP_CRB_PGS0	23
+#define NETXEN_HW_PX_MAP_CRB_PGS1	24
+#define NETXEN_HW_PX_MAP_CRB_PGS2	25
+#define NETXEN_HW_PX_MAP_CRB_PGS3	26
+#define NETXEN_HW_PX_MAP_CRB_PGSD	27
+#define NETXEN_HW_PX_MAP_CRB_PGSI	28
+#define NETXEN_HW_PX_MAP_CRB_SN		29
+#define NETXEN_HW_PX_MAP_CRB_EG		31
+#define NETXEN_HW_PX_MAP_CRB_PH2	32
+#define NETXEN_HW_PX_MAP_CRB_PS2	33
+#define NETXEN_HW_PX_MAP_CRB_CAM	34
+#define NETXEN_HW_PX_MAP_CRB_CAS0	35
+#define NETXEN_HW_PX_MAP_CRB_CAS1	36
+#define NETXEN_HW_PX_MAP_CRB_CAS2	37
+#define NETXEN_HW_PX_MAP_CRB_C2C0	38
+#define NETXEN_HW_PX_MAP_CRB_C2C1	39
+#define NETXEN_HW_PX_MAP_CRB_TIMR	40
+#define NETXEN_HW_PX_MAP_CRB_RPMX1	42
+#define NETXEN_HW_PX_MAP_CRB_RPMX2	43
+#define NETXEN_HW_PX_MAP_CRB_RPMX3	44
+#define NETXEN_HW_PX_MAP_CRB_RPMX4	45
+#define NETXEN_HW_PX_MAP_CRB_RPMX5	46
+#define NETXEN_HW_PX_MAP_CRB_RPMX6	47
+#define NETXEN_HW_PX_MAP_CRB_RPMX7	48
+#define NETXEN_HW_PX_MAP_CRB_XDMA	49
+#define NETXEN_HW_PX_MAP_CRB_I2Q	50
+#define NETXEN_HW_PX_MAP_CRB_ROMUSB	51
+#define NETXEN_HW_PX_MAP_CRB_CAS3	52
+#define NETXEN_HW_PX_MAP_CRB_RPMX0	53
+#define NETXEN_HW_PX_MAP_CRB_RPMX8	54
+#define NETXEN_HW_PX_MAP_CRB_RPMX9	55
+#define NETXEN_HW_PX_MAP_CRB_OCM0	56
+#define NETXEN_HW_PX_MAP_CRB_OCM1	57
+#define NETXEN_HW_PX_MAP_CRB_SMB	58
+#define NETXEN_HW_PX_MAP_CRB_I2C0	59
+#define NETXEN_HW_PX_MAP_CRB_I2C1	60
+#define NETXEN_HW_PX_MAP_CRB_LPC	61
+#define NETXEN_HW_PX_MAP_CRB_PGNC	62
+#define NETXEN_HW_PX_MAP_CRB_PGR0	63
+#define NETXEN_HW_PX_MAP_CRB_PGR1	4
+#define NETXEN_HW_PX_MAP_CRB_PGR2	30
+#define NETXEN_HW_PX_MAP_CRB_PGR3	41
+
+/*  This field defines CRB adr [31:20] of the agents */
+
+#define NETXEN_HW_CRB_HUB_AGT_ADR_MN	\
+	((NETXEN_HW_H0_CH_HUB_ADR << 7) | NETXEN_HW_MN_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PH	\
+	((NETXEN_HW_H0_CH_HUB_ADR << 7) | NETXEN_HW_PH_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_MS	\
+	((NETXEN_HW_H0_CH_HUB_ADR << 7) | NETXEN_HW_MS_CRB_AGT_ADR)
+
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PS	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_PS_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SS	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_SS_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_RPMX3	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_RPMX3_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_QMS	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_QMS_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SQS0	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_SQGS0_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SQS1	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_SQGS1_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SQS2	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_SQGS2_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SQS3	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_SQGS3_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_C2C0	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_C2C0_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_C2C1	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_C2C1_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_RPMX2	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_RPMX2_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_RPMX4	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_RPMX4_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_RPMX7	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_RPMX7_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_RPMX9	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_RPMX9_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SMB	\
+	((NETXEN_HW_H1_CH_HUB_ADR << 7) | NETXEN_HW_SMB_CRB_AGT_ADR)
+
+#define NETXEN_HW_CRB_HUB_AGT_ADR_NIU	\
+	((NETXEN_HW_H2_CH_HUB_ADR << 7) | NETXEN_HW_NIU_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_I2C0	\
+	((NETXEN_HW_H2_CH_HUB_ADR << 7) | NETXEN_HW_I2C0_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_I2C1	\
+	((NETXEN_HW_H2_CH_HUB_ADR << 7) | NETXEN_HW_I2C1_CRB_AGT_ADR)
+
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SRE	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_SRE_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_EG	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_EG_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_RPMX0	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_RPMX0_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_QMN	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_QM_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SQN0	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_SQG0_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SQN1	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_SQG1_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SQN2	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_SQG2_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SQN3	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_SQG3_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_RPMX1	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_RPMX1_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_RPMX5	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_RPMX5_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_RPMX6	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_RPMX6_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_RPMX8	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_RPMX8_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_CAS0	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_CAS0_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_CAS1	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_CAS1_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_CAS2	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_CAS2_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_CAS3	\
+	((NETXEN_HW_H3_CH_HUB_ADR << 7) | NETXEN_HW_CAS3_CRB_AGT_ADR)
+
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGNI	\
+	((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGNI_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGND	\
+	((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGND_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGN0	\
+	((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN0_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGN1	\
+	((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN1_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGN2	\
+	((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN2_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGN3	\
+	((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN3_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGNC	\
+	((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGNC_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGR0	\
+	((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGR0_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGR1	\
+	((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGR1_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGR2	\
+	((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGR2_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGR3	\
+	((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGR3_CRB_AGT_ADR)
+
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGSI	\
+	((NETXEN_HW_H5_CH_HUB_ADR << 7) | NETXEN_HW_PEGSI_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGSD	\
+	((NETXEN_HW_H5_CH_HUB_ADR << 7) | NETXEN_HW_PEGSD_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGS0	\
+	((NETXEN_HW_H5_CH_HUB_ADR << 7) | NETXEN_HW_PEGS0_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGS1	\
+	((NETXEN_HW_H5_CH_HUB_ADR << 7) | NETXEN_HW_PEGS1_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGS2	\
+	((NETXEN_HW_H5_CH_HUB_ADR << 7) | NETXEN_HW_PEGS2_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGS3	\
+	((NETXEN_HW_H5_CH_HUB_ADR << 7) | NETXEN_HW_PEGS3_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGSC	\
+	((NETXEN_HW_H5_CH_HUB_ADR << 7) | NETXEN_HW_PEGSC_CRB_AGT_ADR)
+
+#define NETXEN_HW_CRB_HUB_AGT_ADR_CAM	\
+	((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_NCM_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_TIMR	\
+	((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_TMR_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_XDMA	\
+	((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_XDMA_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_SN	\
+	((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_SN_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_I2Q	\
+	((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_I2Q_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB	\
+	((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_ROMUSB_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_OCM0	\
+	((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_OCM0_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_OCM1	\
+	((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_OCM1_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_LPC	\
+	((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_LPC_CRB_AGT_ADR)
+
+/* ------------------------------------------------------------------------ */
+/*  NCM IMBus Port Tag Defines */
+/* ------------------------------------------------------------------------ */
+#define NETXEN_HW_PH_CAM_TAG	0x3
+#define NETXEN_HW_CAS_CAM_TAG	0x4
+#define NETXEN_HW_PS_CAM_TAG	0x5
+#define NETXEN_HW_PEGN0_CAM_TAG	0x6
+#define NETXEN_HW_PEGN1_CAM_TAG	0x7
+#define NETXEN_HW_PEGN2_CAM_TAG	0x9
+#define NETXEN_HW_PEGN3_CAM_TAG	0xa
+#define NETXEN_HW_PEGS0_CAM_TAG	0xb
+#define NETXEN_HW_PEGS1_CAM_TAG	0xc
+#define NETXEN_HW_PEGS2_CAM_TAG	0xd
+#define NETXEN_HW_PEGS3_CAM_TAG	0xe
+
+/* ------------------------------------------------------------------------ */
+/*  Network QM IMBus Port Tag Defines */
+/* ------------------------------------------------------------------------ */
+#define NETXEN_HW_EG_QM_REQ_TAG		0x4
+#define NETXEN_HW_PEGN0_QM_REQ_TAG	0x5
+#define NETXEN_HW_PEGN1_QM_REQ_TAG	0x6
+#define NETXEN_HW_PEGN2_QM_REQ_TAG	0x7
+#define NETXEN_HW_PEGN3_QM_REQ_TAG	0xE
+#define NETXEN_HW_I2Q_QM_REQ_TAG	0x8
+#define NETXEN_HW_PS_DMA_QMN_REQ_TAG	0x9
+#define NETXEN_HW_PS_QMN_REQ_TAG	0xA
+#define NETXEN_HW_XDMA_QMN_REQ_TAG	0xB
+#define NETXEN_HW_PCIX_QM_REQ_TAG	0xC
+#define NETXEN_HW_CAS_QMN_REQ_TAG	0xD
+#define NETXEN_HW_TMR_QMN_REQ_TAG	0xF
+#define NETXEN_HW_QMS_QMN_REQ_TAG	0xB
+#define NETXEN_HW_C2C0_QM_REQ_TAG	0x9
+
+/* ------------------------------------------------------------------------ */
+/*  Storage QM IMBus Port Tag Defines */
+/* ------------------------------------------------------------------------ */
+#define NETXEN_HW_PEGS0_QMS_REQ_TAG	0x0
+#define NETXEN_HW_PEGS1_QMS_REQ_TAG	0x1
+#define NETXEN_HW_PEGS2_QMS_REQ_TAG	0x2
+#define NETXEN_HW_PEGS3_QMS_REQ_TAG	0xf
+#define NETXEN_HW_C2C1_QMS_REQ_TAG	0x4
+#define NETXEN_HW_PS_QMS_REQ_TAG	0x5
+#define NETXEN_HW_PH_QMS_REQ_TAG	0x6
+#define NETXEN_HW_XDMA_QMS_REQ_TAG	0x9
+#define NETXEN_HW_QMN_QMS_REQ_TAG	0xE
+
+/* ------------------------------------------------------------------------ */
+/*  OCM0 IMBus Port Tag Defines */
+/* ------------------------------------------------------------------------ */
+#define NETXEN_HW_MN_OCM0_PORT_TAG	0x00
+#define NETXEN_HW_SN_OCM0_PORT_TAG	0x01
+#define NETXEN_HW_P2D0_OCM0_PORT_TAG	0x02
+#define NETXEN_HW_P2D1_OCM0_PORT_TAG	0x03
+#define NETXEN_HW_XDMA_OCM0_PORT_TAG	0x04
+
+/* ------------------------------------------------------------------------ */
+/*  OCM0 IMBus Port Tag Defines */
+/* ------------------------------------------------------------------------ */
+#define NETXEN_HW_MN_OCM1_PORT_TAG	0x00
+#define NETXEN_HW_SN_OCM1_PORT_TAG	0x01
+#define NETXEN_HW_P2D0_OCM1_PORT_TAG	0x02
+#define NETXEN_HW_P2D1_OCM1_PORT_TAG	0x03
+#define NETXEN_HW_XDMA_OCM1_PORT_TAG	0x04
+
+/*  Q SubAgent Field for Locking */
+
+#define NETXEN_HW_NPEG0_VPEG0_SUB_AGNT	0x0
+#define NETXEN_HW_NPEG0_VPEG1_SUB_AGNT	0x1
+#define NETXEN_HW_NPEG1_VPEG0_SUB_AGNT	0x2
+#define NETXEN_HW_NPEG1_VPEG1_SUB_AGNT	0x3
+#define NETXEN_HW_NPEG2_VPEG0_SUB_AGNT	0x4
+#define NETXEN_HW_NPEG2_VPEG1_SUB_AGNT	0x5
+#define NETXEN_HW_CAS_SUB_AGNT		0x6
+#define NETXEN_HW_PCI_SUB_AGNT		0x7
+#define NETXEN_HW_SPEG0_VPEG0_SUB_AGNT	0x8
+#define NETXEN_HW_SPEG0_VPEG1_SUB_AGNT	0x9
+#define NETXEN_HW_SPEG1_VPEG0_SUB_AGNT	0xa
+#define NETXEN_HW_SPEG1_VPEG1_SUB_AGNT	0xb
+#define NETXEN_HW_SPEG2_VPEG0_SUB_AGNT	0xc
+#define NETXEN_HW_SPEG2_VPEG1_SUB_AGNT	0xd
+
+/*
+ * MAX_RCV_CTX : The number of receive contexts that are available on
+ * the phantom.
+ */
+#define MAX_RCV_CTX		1
+
+#define NETXEN_SRE_INT_STATUS		(NETXEN_CRB_SRE + 0x00034)
+#define NETXEN_SRE_PBI_ACTIVE_STATUS	(NETXEN_CRB_SRE + 0x01014)
+#define NETXEN_SRE_L1RE_CTL		(NETXEN_CRB_SRE + 0x03000)
+#define NETXEN_SRE_L2RE_CTL		(NETXEN_CRB_SRE + 0x05000)
+#define NETXEN_SRE_BUF_CTL		(NETXEN_CRB_SRE + 0x01000)
+
+#define	NETXEN_DMA_BASE(U)	(NETXEN_CRB_PCIX_MD + 0x20000 + ((U)<<16))
+#define	NETXEN_DMA_COMMAND(U)	(NETXEN_DMA_BASE(U) + 0x00008)
+
+#define NETXEN_I2Q_CLR_PCI_HI	(NETXEN_CRB_I2Q + 0x00034)
+
+#define PEG_NETWORK_BASE(N)	(NETXEN_CRB_PEG_NET_0 + (((N)&3) << 20))
+#define CRB_REG_EX_PC		0x3c
+
+#define ROMUSB_GLB	(NETXEN_CRB_ROMUSB + 0x00000)
+#define ROMUSB_ROM	(NETXEN_CRB_ROMUSB + 0x10000)
+
+#define NETXEN_ROMUSB_GLB_STATUS	(ROMUSB_GLB + 0x0004)
+#define NETXEN_ROMUSB_GLB_SW_RESET	(ROMUSB_GLB + 0x0008)
+#define NETXEN_ROMUSB_GLB_PAD_GPIO_I	(ROMUSB_GLB + 0x000c)
+#define NETXEN_ROMUSB_GLB_CAS_RST	(ROMUSB_GLB + 0x0038)
+#define NETXEN_ROMUSB_GLB_TEST_MUX_SEL	(ROMUSB_GLB + 0x0044)
+#define NETXEN_ROMUSB_GLB_PEGTUNE_DONE	(ROMUSB_GLB + 0x005c)
+#define NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL	(ROMUSB_GLB + 0x00A8)
+
+#define NETXEN_ROMUSB_GPIO(n)		(ROMUSB_GLB + 0x60 + (4 * (n)))
+
+#define NETXEN_ROMUSB_ROM_INSTR_OPCODE	(ROMUSB_ROM + 0x0004)
+#define NETXEN_ROMUSB_ROM_ADDRESS	(ROMUSB_ROM + 0x0008)
+#define NETXEN_ROMUSB_ROM_ABYTE_CNT	(ROMUSB_ROM + 0x0010)
+#define NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT (ROMUSB_ROM + 0x0014)
+#define NETXEN_ROMUSB_ROM_RDATA		(ROMUSB_ROM + 0x0018)
+
+/* Lock IDs for ROM lock */
+#define ROM_LOCK_DRIVER	0x0d417340
+
+#define NETXEN_PCI_CRB_WINDOWSIZE	0x00100000	/* all are 1MB windows */
+#define NETXEN_PCI_CRB_WINDOW(A)	\
+	(NETXEN_PCI_CRBSPACE + (A)*NETXEN_PCI_CRB_WINDOWSIZE)
+
+#define NETXEN_CRB_NIU		NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_NIU)
+#define NETXEN_CRB_SRE		NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_SRE)
+#define NETXEN_CRB_ROMUSB	\
+	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_ROMUSB)
+#define NETXEN_CRB_I2Q		NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_I2Q)
+#define NETXEN_CRB_MAX		NETXEN_PCI_CRB_WINDOW(64)
+
+#define NETXEN_CRB_PCIX_HOST	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PH)
+#define NETXEN_CRB_PCIX_HOST2	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PH2)
+#define NETXEN_CRB_PEG_NET_0	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN0)
+#define NETXEN_CRB_PEG_NET_1	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN1)
+#define NETXEN_CRB_PEG_NET_2	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN2)
+#define NETXEN_CRB_PEG_NET_3	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN3)
+#define NETXEN_CRB_PEG_NET_D	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGND)
+#define NETXEN_CRB_PEG_NET_I	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGNI)
+#define NETXEN_CRB_DDR_NET	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_MN)
+
+#define NETXEN_CRB_PCIX_MD	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PS)
+#define NETXEN_CRB_PCIE		NETXEN_CRB_PCIX_MD
+
+#define ISR_INT_VECTOR		(NETXEN_PCIX_PS_REG(PCIX_INT_VECTOR))
+#define ISR_INT_MASK		(NETXEN_PCIX_PS_REG(PCIX_INT_MASK))
+#define ISR_INT_MASK_SLOW	(NETXEN_PCIX_PS_REG(PCIX_INT_MASK))
+#define ISR_INT_TARGET_STATUS	(NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS))
+#define ISR_INT_TARGET_MASK	(NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK))
+
+#define NETXEN_PCI_MAPSIZE	128
+#define NETXEN_PCI_DDR_NET	(unsigned long)0x00000000
+#define NETXEN_PCI_QDR_NET	(unsigned long)0x04000000
+#define NETXEN_PCI_DIRECT_CRB	(unsigned long)0x04400000
+#define NETXEN_PCI_CAMQM_MAX	(unsigned long)0x04ffffff
+#define NETXEN_PCI_OCM0		(unsigned long)0x05000000
+#define NETXEN_PCI_OCM0_MAX	(unsigned long)0x050fffff
+#define NETXEN_PCI_OCM1		(unsigned long)0x05100000
+#define NETXEN_PCI_OCM1_MAX	(unsigned long)0x051fffff
+#define NETXEN_PCI_CRBSPACE	(unsigned long)0x06000000
+
+#define NETXEN_CRB_CAM	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_CAM)
+
+#define NETXEN_ADDR_DDR_NET	(0x0000000000000000ULL)
+#define NETXEN_ADDR_DDR_NET_MAX (0x000000000fffffffULL)
+#define NETXEN_ADDR_OCM0	(0x0000000200000000ULL)
+#define NETXEN_ADDR_OCM0_MAX	(0x00000002000fffffULL)
+#define NETXEN_ADDR_OCM1	(0x0000000200400000ULL)
+#define NETXEN_ADDR_OCM1_MAX	(0x00000002004fffffULL)
+#define NETXEN_ADDR_QDR_NET	(0x0000000300000000ULL)
+#define NETXEN_ADDR_QDR_NET_MAX (0x00000003003fffffULL)
+
+	/* 200ms delay in each loop */
+#define	NETXEN_NIU_PHY_WAITLEN		200000
+	/* 10 seconds before we give up */
+#define	NETXEN_NIU_PHY_WAITMAX		50
+#define	NETXEN_NIU_MAX_GBE_PORTS	4
+
+#define	NETXEN_NIU_MODE			(NETXEN_CRB_NIU + 0x00000)
+
+#define	NETXEN_NIU_XG_SINGLE_TERM	(NETXEN_CRB_NIU + 0x00004)
+#define	NETXEN_NIU_XG_DRIVE_HI		(NETXEN_CRB_NIU + 0x00008)
+#define	NETXEN_NIU_XG_DRIVE_LO		(NETXEN_CRB_NIU + 0x0000c)
+#define	NETXEN_NIU_XG_DTX		(NETXEN_CRB_NIU + 0x00010)
+#define	NETXEN_NIU_XG_DEQ		(NETXEN_CRB_NIU + 0x00014)
+#define	NETXEN_NIU_XG_WORD_ALIGN	(NETXEN_CRB_NIU + 0x00018)
+#define	NETXEN_NIU_XG_RESET		(NETXEN_CRB_NIU + 0x0001c)
+#define	NETXEN_NIU_XG_POWER_DOWN	(NETXEN_CRB_NIU + 0x00020)
+#define	NETXEN_NIU_XG_RESET_PLL		(NETXEN_CRB_NIU + 0x00024)
+#define	NETXEN_NIU_XG_SERDES_LOOPBACK	(NETXEN_CRB_NIU + 0x00028)
+#define	NETXEN_NIU_XG_DO_BYTE_ALIGN	(NETXEN_CRB_NIU + 0x0002c)
+#define	NETXEN_NIU_XG_TX_ENABLE		(NETXEN_CRB_NIU + 0x00030)
+#define	NETXEN_NIU_XG_RX_ENABLE		(NETXEN_CRB_NIU + 0x00034)
+#define	NETXEN_NIU_XG_STATUS		(NETXEN_CRB_NIU + 0x00038)
+#define	NETXEN_NIU_XG_PAUSE_THRESHOLD	(NETXEN_CRB_NIU + 0x0003c)
+#define	NETXEN_NIU_INT_MASK		(NETXEN_CRB_NIU + 0x00040)
+#define	NETXEN_NIU_ACTIVE_INT		(NETXEN_CRB_NIU + 0x00044)
+#define	NETXEN_NIU_MASKABLE_INT		(NETXEN_CRB_NIU + 0x00048)
+
+#define NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER	(NETXEN_CRB_NIU + 0x0004c)
+
+#define	NETXEN_NIU_GB_SERDES_RESET	(NETXEN_CRB_NIU + 0x00050)
+#define	NETXEN_NIU_GB0_GMII_MODE	(NETXEN_CRB_NIU + 0x00054)
+#define	NETXEN_NIU_GB0_MII_MODE		(NETXEN_CRB_NIU + 0x00058)
+#define	NETXEN_NIU_GB1_GMII_MODE	(NETXEN_CRB_NIU + 0x0005c)
+#define	NETXEN_NIU_GB1_MII_MODE		(NETXEN_CRB_NIU + 0x00060)
+#define	NETXEN_NIU_GB2_GMII_MODE	(NETXEN_CRB_NIU + 0x00064)
+#define	NETXEN_NIU_GB2_MII_MODE		(NETXEN_CRB_NIU + 0x00068)
+#define	NETXEN_NIU_GB3_GMII_MODE	(NETXEN_CRB_NIU + 0x0006c)
+#define	NETXEN_NIU_GB3_MII_MODE		(NETXEN_CRB_NIU + 0x00070)
+#define	NETXEN_NIU_REMOTE_LOOPBACK	(NETXEN_CRB_NIU + 0x00074)
+#define	NETXEN_NIU_GB0_HALF_DUPLEX	(NETXEN_CRB_NIU + 0x00078)
+#define	NETXEN_NIU_GB1_HALF_DUPLEX	(NETXEN_CRB_NIU + 0x0007c)
+#define	NETXEN_NIU_RESET_SYS_FIFOS	(NETXEN_CRB_NIU + 0x00088)
+#define	NETXEN_NIU_GB_CRC_DROP		(NETXEN_CRB_NIU + 0x0008c)
+#define	NETXEN_NIU_GB_DROP_WRONGADDR	(NETXEN_CRB_NIU + 0x00090)
+#define	NETXEN_NIU_TEST_MUX_CTL		(NETXEN_CRB_NIU + 0x00094)
+#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_MAC_CONFIG_0(I)		\
+	(NETXEN_CRB_NIU + 0x30000 + (I)*0x10000)
+#define	NETXEN_NIU_GB_MAC_CONFIG_1(I)		\
+	(NETXEN_CRB_NIU + 0x30004 + (I)*0x10000)
+#define	NETXEN_NIU_GB_MAC_IPG_IFG(I)		\
+	(NETXEN_CRB_NIU + 0x30008 + (I)*0x10000)
+#define	NETXEN_NIU_GB_HALF_DUPLEX_CTRL(I)	\
+	(NETXEN_CRB_NIU + 0x3000c + (I)*0x10000)
+#define	NETXEN_NIU_GB_MAX_FRAME_SIZE(I)		\
+	(NETXEN_CRB_NIU + 0x30010 + (I)*0x10000)
+#define	NETXEN_NIU_GB_TEST_REG(I)		\
+	(NETXEN_CRB_NIU + 0x3001c + (I)*0x10000)
+#define	NETXEN_NIU_GB_MII_MGMT_CONFIG(I)	\
+	(NETXEN_CRB_NIU + 0x30020 + (I)*0x10000)
+#define	NETXEN_NIU_GB_MII_MGMT_COMMAND(I)	\
+	(NETXEN_CRB_NIU + 0x30024 + (I)*0x10000)
+#define	NETXEN_NIU_GB_MII_MGMT_ADDR(I)		\
+	(NETXEN_CRB_NIU + 0x30028 + (I)*0x10000)
+#define	NETXEN_NIU_GB_MII_MGMT_CTRL(I)		\
+	(NETXEN_CRB_NIU + 0x3002c + (I)*0x10000)
+#define	NETXEN_NIU_GB_MII_MGMT_STATUS(I)	\
+	(NETXEN_CRB_NIU + 0x30030 + (I)*0x10000)
+#define	NETXEN_NIU_GB_MII_MGMT_INDICATE(I)	\
+	(NETXEN_CRB_NIU + 0x30034 + (I)*0x10000)
+#define	NETXEN_NIU_GB_INTERFACE_CTRL(I)		\
+	(NETXEN_CRB_NIU + 0x30038 + (I)*0x10000)
+#define	NETXEN_NIU_GB_INTERFACE_STATUS(I)	\
+	(NETXEN_CRB_NIU + 0x3003c + (I)*0x10000)
+#define	NETXEN_NIU_GB_STATION_ADDR_0(I)		\
+	(NETXEN_CRB_NIU + 0x30040 + (I)*0x10000)
+#define	NETXEN_NIU_GB_STATION_ADDR_1(I)		\
+	(NETXEN_CRB_NIU + 0x30044 + (I)*0x10000)
+
+#define	NETXEN_NIU_XGE_CONFIG_0			(NETXEN_CRB_NIU + 0x70000)
+#define	NETXEN_NIU_XGE_CONFIG_1			(NETXEN_CRB_NIU + 0x70004)
+#define	NETXEN_NIU_XGE_IPG			(NETXEN_CRB_NIU + 0x70008)
+#define	NETXEN_NIU_XGE_STATION_ADDR_0_HI	(NETXEN_CRB_NIU + 0x7000c)
+#define	NETXEN_NIU_XGE_STATION_ADDR_0_1		(NETXEN_CRB_NIU + 0x70010)
+#define	NETXEN_NIU_XGE_STATION_ADDR_1_LO	(NETXEN_CRB_NIU + 0x70014)
+#define	NETXEN_NIU_XGE_STATUS			(NETXEN_CRB_NIU + 0x70018)
+#define	NETXEN_NIU_XGE_MAX_FRAME_SIZE		(NETXEN_CRB_NIU + 0x7001c)
+#define	NETXEN_NIU_XGE_PAUSE_FRAME_VALUE	(NETXEN_CRB_NIU + 0x70020)
+#define	NETXEN_NIU_XGE_TX_BYTE_CNT		(NETXEN_CRB_NIU + 0x70024)
+#define	NETXEN_NIU_XGE_TX_FRAME_CNT		(NETXEN_CRB_NIU + 0x70028)
+#define	NETXEN_NIU_XGE_RX_BYTE_CNT		(NETXEN_CRB_NIU + 0x7002c)
+#define	NETXEN_NIU_XGE_RX_FRAME_CNT		(NETXEN_CRB_NIU + 0x70030)
+#define	NETXEN_NIU_XGE_AGGR_ERROR_CNT		(NETXEN_CRB_NIU + 0x70034)
+#define	NETXEN_NIU_XGE_MULTICAST_FRAME_CNT 	(NETXEN_CRB_NIU + 0x70038)
+#define	NETXEN_NIU_XGE_UNICAST_FRAME_CNT	(NETXEN_CRB_NIU + 0x7003c)
+#define	NETXEN_NIU_XGE_CRC_ERROR_CNT		(NETXEN_CRB_NIU + 0x70040)
+#define	NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR	(NETXEN_CRB_NIU + 0x70044)
+#define	NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR	(NETXEN_CRB_NIU + 0x70048)
+#define	NETXEN_NIU_XGE_LOCAL_ERROR_CNT		(NETXEN_CRB_NIU + 0x7004c)
+#define	NETXEN_NIU_XGE_REMOTE_ERROR_CNT		(NETXEN_CRB_NIU + 0x70050)
+#define	NETXEN_NIU_XGE_CONTROL_CHAR_CNT		(NETXEN_CRB_NIU + 0x70054)
+#define	NETXEN_NIU_XGE_PAUSE_FRAME_CNT		(NETXEN_CRB_NIU + 0x70058)
+
+/* XG Link status */
+#define XG_LINK_UP	0x10
+#define XG_LINK_DOWN	0x20
+
+#define NETXEN_CAM_RAM_BASE	(NETXEN_CRB_CAM + 0x02000)
+#define NETXEN_CAM_RAM(reg)	(NETXEN_CAM_RAM_BASE + (reg))
+#define NETXEN_FW_VERSION_MAJOR (NETXEN_CAM_RAM(0x150))
+#define NETXEN_FW_VERSION_MINOR (NETXEN_CAM_RAM(0x154))
+#define NETXEN_FW_VERSION_SUB	(NETXEN_CAM_RAM(0x158))
+#define NETXEN_ROM_LOCK_ID	(NETXEN_CAM_RAM(0x100))
+
+/*
+ * CRB window register.
+ */
+struct netxen_pcix_crb_window {
+	netxen_crbword_t rsvd1:25, addrbit:1,	/* bit 25 of CRB address */
+	 rsvd2:6;
+};
+
+#define PCIX_PS_OP_ADDR_LO	(0x10000) /* Used for PS PCI Memory access */
+#define PCIX_PS_OP_ADDR_HI	(0x10004) /*   via CRB  (PS side only)     */
+
+#define PCIX_INT_VECTOR		(0x10100)
+#define PCIX_INT_MASK		(0x10104)
+
+#define PCIX_MN_WINDOW		(0x10200)
+#define PCIX_MS_WINDOW		(0x10204)
+#define PCIX_SN_WINDOW		(0x10208)
+#define PCIX_CRB_WINDOW		(0x10210)
+
+#define PCIX_TARGET_STATUS	(0x10118)
+#define PCIX_TARGET_MASK	(0x10128)
+
+#define PCIX_MSI_F0		(0x13000)
+
+#define PCIX_PS_MEM_SPACE	(0x90000)
+
+#define NETXEN_PCIX_PH_REG(reg)	(NETXEN_CRB_PCIE + (reg))
+#define NETXEN_PCIX_PS_REG(reg)	(NETXEN_CRB_PCIX_MD + (reg))
+
+#define NETXEN_PCIE_REG(reg)	(NETXEN_CRB_PCIE + (reg))
+
+#define PCIE_MAX_DMA_XFER_SIZE	(0x1404c)
+
+#define PCIE_DCR		0x00d8
+
+#define PCIE_SEM2_LOCK		(0x1c010)	/* Flash lock   */
+#define PCIE_SEM2_UNLOCK	(0x1c014)	/* Flash unlock */
+
+#define PCIE_TGT_SPLIT_CHICKEN	(0x12080)
+
+#define PCIE_MAX_MASTER_SPLIT	(0x14048)
+
+#endif				/* __NETXEN_NIC_HDR_H_ */

^ permalink raw reply

* [PATCH 2/9] NetXen 1G/10G ethernet driver patch with corrections
From: Linsys Contractor Amit S. Kale @ 2006-06-07  9:42 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, unmproj

2006-06-07 Amit S. Kale <amitkale@unminc.com>
 	* Add netxen driver main header file
diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic.h linux-2.6.16.20/drivers/net/netxen/netxen_nic.h
--- linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/netxen_nic.h	2006-06-06 06:58:11.000000000 -0700
@@ -0,0 +1,998 @@
+/*
+ * 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:
+ *    info@netxen.com
+ * NetXen,
+ * 3965 Freedom Circle, Fourth floor,
+ * Santa Clara, CA 95054
+ */
+
+#ifndef _NETXEN_NIC_H_
+#define _NETXEN_NIC_H_
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.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/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 <linux/skbuff.h>
+
+#include "netxen_nic_hw.h"
+#include "netxen_nic_hdr.h"
+
+#define NETXEN_NIC_BUILD_NO     "231"
+#define _NETXEN_NIC_LINUX_MAJOR 2
+#define _NETXEN_NIC_LINUX_MINOR 1
+#define _NETXEN_NIC_LINUX_SUBVERSION 39
+#define NETXEN_NIC_LINUX_VERSIONID  "2.1.39"
+#define NETXEN_NIC_FW_VERSIONID "2.1.39"
+#define NETXEN_NIC_TIMESTAMP "Mon May  1 01:34:07 PDT 2006"
+
+#define RCV_DESC_RINGSIZE(ctxid)	\
+	(sizeof(struct rcv_desc_t) * adapter->ring_ctx[ctxid].max_rx_desc_count)
+#define STATUS_DESC_RINGSIZE(i)	\
+	(sizeof(struct status_desc_t)* adapter->ring_ctx[i].max_rx_desc_count)
+#define TX_RINGSIZE(i)	(sizeof(struct netxen_cmd_buffer)	\
+	* adapter->ring_ctx[i].max_tx_desc_count)
+#define JUMBO_DESC_RINGSIZE	\
+	(sizeof(rcvDesc_t) * adapter->ring_ctx[i].MaxJumboRxDescCount)
+#define RCV_BUFFSIZE	\
+	(sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count)
+
+#define DB_PAGE_SIZE    0x1000
+#define NETXEN_CMD_PRODUCER_OFFSET(ctx) \
+	((NETXEN_CMD_PRODUCER_DB_PAGE(ctx)) * DB_PAGE_SIZE)
+#define NETXEN_RCV_STATUS_CONSUMER_OFFSET(ctx) \
+	((NETXEN_RCV_STATUS_CONSUMER_DB_PAGE(ctx)) * DB_PAGE_SIZE)
+#define NETXEN_RCV_PRODUCER_OFFSET(ctx,ring) \
+	((NETXEN_RCV_PRODUCER_DB_PAGE(ctx,ring)) * DB_PAGE_SIZE)
+
+#define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
+
+#define NETXEN_NETDEV_STATUS 0x1
+
+#define ADDR_IN_WINDOW1(off)	\
+	((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0
+
+/* 
+ * normalize a 64MB crb address to 32MB PCI window 
+ * To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1
+ */
+#define NETXEN_CRB_NORMALIZE(adapter, reg) \
+	(void *)(ptrdiff_t)(adapter->ahw.pci_base+ (reg)	\
+	- NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST)
+
+#define DB_NORMALIZE(adapter, off) \
+	(void *)(ptrdiff_t)(adapter->ahw.db_base + (off))
+
+#define MAX_RX_BUFFER_LENGTH		2000
+#define MAX_RX_JUMBO_BUFFER_LENGTH 	9046
+#define RX_DMA_MAP_LEN 		(MAX_RX_BUFFER_LENGTH - NET_IP_ALIGN)
+#define RX_JUMBO_DMA_MAP_LEN	\
+	(MAX_RX_JUMBO_BUFFER_LENGTH - NET_IP_ALIGN)
+
+/*
+ * Maximum number of ring contexts
+ */
+#define MAX_RING_CTX 1
+
+/* Opcodes to be used with the commands */
+#define	TX_ETHER_PKT 0x01
+/* The following opcodes are for IP checksum	*/
+#define	TX_TCP_PKT 	0x02
+#define	TX_UDP_PKT	0x03
+#define	TX_IP_PKT	0x04
+#define	TX_TCP_LSO	0x05
+#define	TX_IPSEC	0x06
+#define	TX_IPSEC_CMD	0x07
+
+/* The following opcodes are for internal consumption. */
+#define NETXEN_CONTROL_OP	0x10
+#define PEGNET_REQUEST		0x11
+
+#define	MAX_NUM_CARDS		4
+
+#define MAX_BUFFERS_PER_CMD	32
+
+/*
+ * Following are the states of the Phantom. Phantom will set them and
+ * Host will read to check if the fields are correct.
+ */
+#define PHAN_INITIALIZE_START		0xff00
+#define PHAN_INITIALIZE_FAILED		0xffff
+#define PHAN_INITIALIZE_COMPLETE	0xff01
+
+/* Host writes the following to notify that it has done the init-handshake */
+#define PHAN_INITIALIZE_ACK	0xf00f
+
+#define NUM_RCV_DESC_RINGS	2	/* No of Rcv Descriptor contexts */
+
+/* descriptor types */
+#define RCV_DESC_NORMAL		0x01
+#define RCV_DESC_JUMBO		0x02
+#define RCV_DESC_NORMAL_CTXID	0
+#define RCV_DESC_JUMBO_CTXID	1
+
+#define RCV_DESC_TYPE(ID) \
+	((ID == RCV_DESC_JUMBO_CTXID) ? RCV_DESC_JUMBO : RCV_DESC_NORMAL)
+
+#define MAX_CMD_DESCRIPTORS		1024
+#define MAX_RCV_DESCRIPTORS		32768
+#define MAX_JUMBO_RCV_DESCRIPTORS	1024
+#define MAX_RCVSTATUS_DESCRIPTORS	MAX_RCV_DESCRIPTORS
+#define MAX_JUMBO_RCV_DESC	MAX_JUMBO_RCV_DESCRIPTORS
+#define MAX_RCV_DESC		MAX_RCV_DESCRIPTORS
+#define MAX_RCVSTATUS_DESC	MAX_RCV_DESCRIPTORS
+#define NUM_RCV_DESC		(MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS)
+#define MAX_EPG_DESCRIPTORS	MAX_CMD_DESCRIPTORS * 8
+
+#define MIN_TX_COUNT	4096
+#define MIN_RX_COUNT	4096
+
+#define MAX_FRAME_SIZE	0x10000	/* 64K MAX size for LSO */
+
+#define PHAN_PEG_RCV_INITIALIZED	0xff01
+#define PHAN_PEG_RCV_START_INITIALIZE	0xff00
+
+#define get_next_index(index, length)	\
+	((((index) + 1) == length) ? \
+		0 : \
+		(index) +1)
+
+#define get_index_range(index,length,count)	\
+	((((index) + (count)) >= length) ?	\
+		(((index) + (count))-(length)) :	\
+		((index) + (count)))
+
+/**
+ * Following data structures describe the descriptors that will be used.
+ * Added fileds of tcpHdrSize and ipHdrSize, The driver needs to do it only when
+ * we are doing LSO (above the 1500 size packet) only.
+ **/
+
+/**
+ * The size of reference handle been changed to 16 bits to pass the MSS fields
+ * for the LSO packet
+ **/
+
+#define FLAGS_CHECKSUM_ENABLED	0x01
+#define FLAGS_LSO_ENABLED	0x02
+#define FLAGS_IPSEC_SA_ADD	0x04
+#define FLAGS_IPSEC_SA_DELETE	0x08
+#define FLAGS_VLAN_TAGGED	0x10
+
+struct cmd_desc_type0_t {
+	u64 netxen_next;	/* for fragments handled by Phantom */
+	union {
+		struct {
+			u32 addr_low_part2;
+			u32 addr_high_part2;
+		};
+		u64 addr_buffer2;
+	};
+
+	u64 total_length:24,	/* Total size of the packet */
+	 tcp_hdr_offset:8,	/* For LSO only */
+	 ip_hdr_offset:8,	/* For LSO only */
+	 num_of_buffers:8,	/* total number of segments */
+	 flags:8,		/* as defined above */
+	 opcode:8;
+
+	u64 reference_handle:16,	/* changed to u16 to add mss */
+	 mss:16,		/* passed by NDIS_PACKET for LSO */
+	 port:4,
+	 ctx_id:4,
+	 total_hdr_length:8,	/* LSO only : MAC+IP+TCP Hdr size */
+	 conn_id:16;		/* IPSec offoad only */
+
+	union {
+		struct {
+			u32 addr_low_part3;
+			u32 addr_high_part3;
+		};
+		u64 addr_buffer3;
+	};
+
+	union {
+		struct {
+			u32 addr_low_part1;
+			u32 addr_high_part1;
+		};
+		u64 addr_buffer1;
+	};
+
+	u64 buffer1_length:16,
+	    buffer2_length:16, buffer3_length:16, buffer4_length:16;
+
+	union {
+		struct {
+			u32 addr_low_part4;
+			u32 addr_high_part4;
+		};
+		u64 addr_buffer4;
+	};
+
+} __attribute__ ((aligned(64)));
+
+/* Note: sizeof(rcv_desc) should always be a mutliple of 2 */
+struct rcv_desc_t {
+	u64 reference_handle:16,
+	 reserved:16,
+	 buffer_length:32;	/* allocated buffer length (usually 2K) */
+	u64 addr_buffer;
+};
+
+/* opcode field in status_desc_t */
+#define RCV_NIC_PKT	(0xA)
+#define STATUS_NIC_PKT	((RCV_NIC_PKT) << 12)
+
+/* for status field in status_desc_t */
+#define STATUS_NEED_CKSUM	(1)
+#define STATUS_CKSUM_OK		(2)
+
+/* owner bits of status_desc_t */
+#define STATUS_OWNER_HOST	(1ULL)
+#define STATUS_OWNER_PHANTOM	(2ULL)
+#define HOST_STATUS_DESC	((STATUS_OWNER_HOST) << 48)
+#define PHANTOM_STATUS_DESC	((STATUS_OWNER_PHANTOM) << 48)
+
+#define NETXEN_PROT_IP		(1)
+#define NETXEN_PROT_UNKNOWN	(0)
+
+/* Note: sizeof(status_desc) should always be a mutliple of 2 */
+struct status_desc_t {
+	u64 port:4,		/* initially to be used but noe now */
+	 status:4,		/* completion status may not have use */
+	 type:4,		/* type/index of descriptor ring */
+	 opcode:4,		/* Completion of receive or transmit */
+	 total_length:16,	/* NIC mode */
+	 reference_handle:16,	/* handle for the associated packet */
+	 owner:2,		/* Owner of the descriptor */
+	 prot:4;		/* protocol type for skb (Linux) */
+} __attribute__ ((aligned(8)));
+
+enum {
+	NETXEN_RCV_PEG_0 = 0,
+	NETXEN_RCV_PEG_1
+};
+
+/* The version of the main data structure */
+#define	NETXEN_BDINFO_VERSION 1
+
+/* Magic number to let user know flash is programmed */
+#define	NETXEN_BDINFO_MAGIC 0x12345678
+
+/* Max number of Gig ports on a Phantom board */
+#define NETXEN_MAX_PORTS 4
+
+typedef enum {
+	NETXEN_BRDTYPE_P1_BD = 0x0000,
+	NETXEN_BRDTYPE_P1_SB = 0x0001,
+	NETXEN_BRDTYPE_P1_SMAX = 0x0002,
+	NETXEN_BRDTYPE_P1_SOCK = 0x0003,
+
+	NETXEN_BRDTYPE_P2_SOCK_31 = 0x0008,
+	NETXEN_BRDTYPE_P2_SOCK_35 = 0x0009,
+	NETXEN_BRDTYPE_P2_SB35_4G = 0x000a,
+	NETXEN_BRDTYPE_P2_SB31_10G = 0x000b,
+	NETXEN_BRDTYPE_P2_SB31_2G = 0x000c,
+
+	NETXEN_BRDTYPE_P2_SB31_10G_IMEZ = 0x000d,
+	NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e,
+	NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f
+} netxen_brdtype_t;
+
+typedef enum {
+	NETXEN_BRDMFG_INVENTEC = 1
+} netxen_brdmfg;
+
+typedef enum {
+	MEM_ORG_128Mbx4 = 0x0,	/* DDR1 only */
+	MEM_ORG_128Mbx8 = 0x1,	/* DDR1 only */
+	MEM_ORG_128Mbx16 = 0x2,	/* DDR1 only */
+	MEM_ORG_256Mbx4 = 0x3,
+	MEM_ORG_256Mbx8 = 0x4,
+	MEM_ORG_256Mbx16 = 0x5,
+	MEM_ORG_512Mbx4 = 0x6,
+	MEM_ORG_512Mbx8 = 0x7,
+	MEM_ORG_512Mbx16 = 0x8,
+	MEM_ORG_1Gbx4 = 0x9,
+	MEM_ORG_1Gbx8 = 0xa,
+	MEM_ORG_1Gbx16 = 0xb,
+	MEM_ORG_2Gbx4 = 0xc,
+	MEM_ORG_2Gbx8 = 0xd,
+	MEM_ORG_2Gbx16 = 0xe,
+	MEM_ORG_128Mbx32 = 0x10002,	/* GDDR only */
+	MEM_ORG_256Mbx32 = 0x10005	/* GDDR only */
+} netxen_mn_mem_org_t;
+
+typedef enum {
+	MEM_ORG_512Kx36 = 0x0,
+	MEM_ORG_1Mx36 = 0x1,
+	MEM_ORG_2Mx36 = 0x2
+} netxen_sn_mem_org_t;
+
+typedef enum {
+	MEM_DEPTH_4MB = 0x1,
+	MEM_DEPTH_8MB = 0x2,
+	MEM_DEPTH_16MB = 0x3,
+	MEM_DEPTH_32MB = 0x4,
+	MEM_DEPTH_64MB = 0x5,
+	MEM_DEPTH_128MB = 0x6,
+	MEM_DEPTH_256MB = 0x7,
+	MEM_DEPTH_512MB = 0x8,
+	MEM_DEPTH_1GB = 0x9,
+	MEM_DEPTH_2GB = 0xa,
+	MEM_DEPTH_4GB = 0xb,
+	MEM_DEPTH_8GB = 0xc,
+	MEM_DEPTH_16GB = 0xd,
+	MEM_DEPTH_32GB = 0xe
+} netxen_mem_depth_t;
+
+struct netxen_board_info {
+	u32 header_version;
+
+	u32 board_mfg;
+	u32 board_type;
+	u32 board_num;
+	u32 chip_id;
+	u32 chip_minor;
+	u32 chip_major;
+	u32 chip_pkg;
+	u32 chip_lot;
+
+	u32 port_mask;		/* available niu ports */
+	u32 peg_mask;		/* available pegs */
+	u32 icache_ok;		/* can we run with icache? */
+	u32 dcache_ok;		/* can we run with dcache? */
+	u32 casper_ok;
+
+	u32 mac_addr_lo_0;
+	u32 mac_addr_lo_1;
+	u32 mac_addr_lo_2;
+	u32 mac_addr_lo_3;
+
+	/* MN-related config */
+	u32 mn_sync_mode;	/* enable/ sync shift cclk/ sync shift mclk */
+	u32 mn_sync_shift_cclk;
+	u32 mn_sync_shift_mclk;
+	u32 mn_wb_en;
+	u32 mn_crystal_freq;	/* in MHz */
+	u32 mn_speed;		/* in MHz */
+	u32 mn_org;
+	u32 mn_depth;
+	u32 mn_ranks_0;		/* ranks per slot */
+	u32 mn_ranks_1;		/* ranks per slot */
+	u32 mn_rd_latency_0;
+	u32 mn_rd_latency_1;
+	u32 mn_rd_latency_2;
+	u32 mn_rd_latency_3;
+	u32 mn_rd_latency_4;
+	u32 mn_rd_latency_5;
+	u32 mn_rd_latency_6;
+	u32 mn_rd_latency_7;
+	u32 mn_rd_latency_8;
+	u32 mn_dll_val[18];
+	u32 mn_mode_reg;	/* MIU DDR Mode Register */
+	u32 mn_ext_mode_reg;	/* MIU DDR Extended Mode Register */
+	u32 mn_timing_0;	/* MIU Memory Control Timing Rgister */
+	u32 mn_timing_1;	/* MIU Extended Memory Ctrl Timing Register */
+	u32 mn_timing_2;	/* MIU Extended Memory Ctrl Timing2 Register */
+
+	/* SN-related config */
+	u32 sn_sync_mode;	/* enable/ sync shift cclk / sync shift mclk */
+	u32 sn_pt_mode;		/* pass through mode */
+	u32 sn_ecc_en;
+	u32 sn_wb_en;
+	u32 sn_crystal_freq;
+	u32 sn_speed;
+	u32 sn_org;
+	u32 sn_depth;
+	u32 sn_dll_tap;
+	u32 sn_rd_latency;
+
+	u32 mac_addr_hi_0;
+	u32 mac_addr_hi_1;
+	u32 mac_addr_hi_2;
+	u32 mac_addr_hi_3;
+
+	u32 magic;		/* indicates flash has been initialized */
+
+	u32 mn_rdimm;
+	u32 mn_dll_override;
+
+};
+
+#define FLASH_NUM_PORTS		(4)
+
+struct netxen_flash_mac_addr {
+	u32 flash_addr[32];
+};
+
+#define FLASH_NUM_MAC_PER_PORT	32
+struct netxen_user_info {
+	u8 flash_md5[16 * 64];
+	/* bootloader */
+	u32 bootld_version;
+	u32 bootld_size;
+	/* image */
+	u32 image_version;
+	u32 image_size;
+	/* primary image status */
+	u32 primary_status;
+	u32 secondary_present;
+
+	/* MAC address , 4 ports, 32 address per port */
+	u64 mac_addr[FLASH_NUM_PORTS * FLASH_NUM_MAC_PER_PORT];
+	u32 sub_sys_id;
+	u8 serial_num[32];
+
+	/* Any user defined data */
+};
+
+/*
+ * Flash Layout - new format.
+ */
+#define FLASH_NUM_MAC_PER_PORT	32
+struct netxen_new_user_info {
+	u8 flash_md5[16 * 64];
+	/* bootloader */
+	u32 bootld_version;
+	u32 bootld_size;
+	/* image */
+	u32 image_version;
+	u32 image_size;
+	/* primary image status */
+	u32 primary_status;
+	u32 secondary_present;
+
+	/* MAC address , 4 ports, 32 address per port */
+	u64 mac_addr[FLASH_NUM_PORTS * FLASH_NUM_MAC_PER_PORT];
+	u32 sub_sys_id;
+	u8 serial_num[32];
+
+	/* Any user defined data */
+};
+
+#define SECONDARY_IMAGE_PRESENT 0xb3b4b5b6
+#define SECONDARY_IMAGE_ABSENT	0xffffffff
+#define PRIMARY_IMAGE_GOOD	0x5a5a5a5a
+#define PRIMARY_IMAGE_BAD	0xffffffff
+
+/* Flash memory map */
+typedef enum {
+	CRBINIT_START = 0,	/* Crbinit section */
+	BRDCFG_START = 0x4000,	/* board config */
+	INITCODE_START = 0x6000,	/* pegtune code */
+	BOOTLD_START = 0x10000,	/* bootld */
+	IMAGE_START = 0x43000,	/* compressed image */
+	SECONDARY_START = 0x200000,	/* backup images */
+	PXE_START = 0x3E0000,	/* user defined region */
+	USER_START = 0x3E8000,	/* User defined region for new boards */
+	FIXED_START = 0x3F0000	/* backup of crbinit */
+} netxen_flash_map_t;
+
+#define USER_START_OLD PXE_START	/* for backward compatibility */
+
+#define FLASH_START		(CRBINIT_START)
+#define INIT_SECTOR		(0)
+#define PRIMARY_START 		(BOOTLD_START)
+#define FLASH_CRBINIT_SIZE 	(0x4000)
+#define FLASH_BRDCFG_SIZE 	(sizeof(struct netxen_board_info))
+#define FLASH_USER_SIZE		(sizeof(netxen_user_info)/sizeof(u32))
+#define FLASH_SECONDARY_SIZE 	(USER_START-SECONDARY_START)
+#define NUM_PRIMARY_SECTORS	(0x20)
+#define NUM_CONFIG_SECTORS 	(1)
+int is_flash_supported(struct netxen_adapter *adapter);
+int get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]);
+extern char netxen_nic_driver_string[];
+extern void netxen_change_ringparam(struct netxen_adapter *adapter);
+extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
+				int *valp);
+
+extern struct ethtool_ops netxen_nic_ethtool_ops;
+
+/*
+ * The PCI VendorID and DeviceID for our board.
+ */
+#define PCI_VENDOR_ID_NX       0x4040
+#define PCI_DEVICE_ID_NX_XG    0x0001
+#define PCI_DEVICE_ID_NX_CX4   0x0002
+#define PCI_DEVICE_ID_NX_QG    0x0003
+#define PCI_DEVICE_ID_NX_IMEZ  0x0004
+#define PCI_DEVICE_ID_NX_HMEZ  0x0005
+
+#define NETXEN_PCI_ID(X) { PCI_DEVICE(PCI_VENDOR_ID_NX, (X)) }
+
+#define PFX "netxen: "
+
+/* Note: Make sure to not call this before adapter->port is valid */
+#if !defined(NETXEN_DEBUG)
+#define DPRINTK(klevel, fmt, args...)	do { \
+	} while (0)
+#else
+#define DPRINTK(klevel, fmt, args...)	do { \
+	printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\
+		(adapter != NULL && adapter->port != NULL && \
+		adapter->port[0] != NULL && \
+		adapter->port[0]->netdev != NULL) ? \
+		adapter->port[0]->netdev->name : NULL, \
+		## args); } while(0)
+#endif
+
+/* Number of status descriptors to handle per interrupt */
+#define MAX_STATUS_HANDLE	(128)
+
+/*
+ * netxen_skb_frag{} is to contain mapping info for each SG list. This
+ * has to be freed when DMA is complete. This is part of netxen_tx_buffer{}.
+ */
+struct netxen_skb_frag {
+	u64 dma;
+	u32 length;
+};
+
+/*    Following defines are for the state of the buffers    */
+#define	NETXEN_BUFFER_FREE	0
+#define	NETXEN_BUFFER_BUSY	1
+
+/*
+ * There will be one netxen_buffer per skb packet.    These will be
+ * used to save the dma info for pci_unmap_page()
+ */
+struct netxen_cmd_buffer {
+	struct sk_buff *skb;
+	struct netxen_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1];
+	u32 total_length;
+	u32 mss;
+	u32 port:16, cmd:8, frag_count:8;
+	unsigned long time_stamp;
+	u32 state;
+	u32 no_of_descriptors;
+};
+
+/* In rx_buffer, we do not need multiple fragments as is a single buffer */
+struct netxen_rx_buffer {
+	struct sk_buff *skb;
+	u64 dma;
+	u32 ref_handle:16, state:16;
+};
+
+/* Board types */
+#define	NETXEN_NIC_GBE	0x01
+#define	NETXEN_NIC_XGBE	0x02
+
+/*
+ * One hardware_context{} per adapter
+ * contains interrupt info as well shared hardware info.
+ */
+struct netxen_hardware_context {
+	struct pci_dev *pdev;
+	unsigned long pci_base;	/* base of mapped phantom memory */
+	unsigned long pci_len;	/* length of mapped phantom memory */
+	u16 vendor_id;
+	u16 device_id;
+	u8 revision_id;
+	u16 pci_cmd_word;
+	u16 board_type;
+	u16 max_ports;
+	struct netxen_board_info boardcfg;
+	u32 xg_linkup;
+	struct netxen_adapter *adapter;
+	u32 crb_base;
+	unsigned long db_base;	/* base of mapped db memory */
+	unsigned long db_len;	/* length of mapped db memory */
+};
+
+#define MINIMUM_ETHERNET_FRAME_SIZE	64	/* With FCS */
+#define ETHERNET_FCS_SIZE		4
+
+struct netxen_adapter_stats {
+	u64 ints;
+	u64 hostints;
+	u64 otherints;
+	u64 process_rcv;
+	u64 process_xmit;
+	u64 noxmitdone;
+	u64 xmitcsummed;
+	u64 post_called;
+	u64 posted;
+	u64 lastposted;
+	u64 goodskbposts;
+};
+
+/*
+ * Ring which will hold the skbs which can be fed to receive ring
+ */
+#define NETXEN_SKB_ARRAY_SIZE	1024
+
+struct netxen_recv_skb_ring {
+	struct sk_buff **skb_array;
+	u32 interrupt_index;
+	u32 tasklet_index;
+	u32 data_size;
+};
+
+/*
+ * Rcv Descriptor Context. One such per Rcv Descriptor. There may
+ * be one Rcv Descriptor for normal packets, one for jumbo and may be others.
+ */
+struct netxen_rcv_desc_ctx {
+	u32 flags;
+	u32 producer;
+	u32 rcv_pending;	/* Num of bufs posted in phantom */
+	u32 rcv_free;		/* Num of bufs in free list */
+	u32 phys_addr;
+	struct rcv_desc_t *desc_head;	/* address of rx ring in Phantom */
+	u32 max_rx_desc_count;
+	u32 dma_size;
+	u32 skb_size;
+	struct netxen_rx_buffer *rx_buf_arr;	/* rx buffers for receive   */
+	dma_addr_t rx_buf_phys;	/* physical address of above */
+	int begin_alloc;
+};
+
+/*
+ * Receive context. There is one such structure per instance of the
+ * receive processing. Any state information that is relevant to
+ * the receive, and is must be in this structure. The global data may be
+ * present elsewhere.
+ */
+struct netxen_recv_context {
+	struct netxen_rcv_desc_ctx rcv_desc[NUM_RCV_DESC_RINGS];
+	u32 status_rx_producer;
+	u32 status_rx_consumer;
+	u32 rcv_status_desc_phys_addr;
+	struct status_desc_t *rcv_status_desc_head;
+};
+
+#define NETXEN_NIC_MSI_ENABLED 0x02
+
+struct netxen_hardware_ring_context {
+	/* Address of cmd ring in Phantom */
+	struct cmd_desc_type0_t *cmd_desc_head;
+	u32 cmd_producer;
+	u32 cmd_consumer;
+	u32 status_rx_producer;
+	u32 status_rx_consumer;
+	u32 cmd_desc_phys_addr;
+};
+
+struct netxen_ring_context {
+	struct netxen_hardware_ring_context hw_ring_ctx;
+	u32 cmd_producer;
+	u32 *cmd_consumer;
+
+	u32 last_cmd_consumer;
+	/* Num of bufs posted in phantom */
+	u32 pending_cmd_count;
+	u32 free_cmd_count;	/* Num of bufs in free list */
+	u32 max_tx_desc_count;
+	u32 max_rx_desc_count;
+	u32 max_jumbo_rx_desc_count;
+	/* Num of instances active on cmd buffer ring */
+	u32 proc_cmd_buf_counter;
+	volatile u32 cmd_peg_consumer;
+
+	struct netxen_cmd_buffer *cmd_buf_arr;	/* Command buffers for xmit */
+	struct netxen_rx_buffer *rx_buf_arr;	/* rx buffers for receive   */
+
+	/*
+	 * Receive instance.
+	 */
+	struct netxen_recv_context recv_ctx;
+
+	/* context interface shared between card and host */
+	struct ring_context *ctx_desc;
+	u32 ctx_desc_phys_addr;
+
+};
+
+/* this structure by all ports on the adapter */
+struct netxen_adapter {
+	struct netxen_hardware_context ahw;
+	int port_count;		/* Number of configured ports  */
+	int active_ports;	/* Number of open ports */
+	struct netxen_port **port;	/* ptr to each port  */
+	spinlock_t tx_lock;
+	rwlock_t adapter_lock;
+	spinlock_t lock;
+	struct work_struct watchdog_task;
+	struct work_struct tx_timeout_task[4];
+	struct timer_list watchdog_timer;
+
+	u32 curr_window;
+
+	u32 num_threads, total_threads;	/*Use to keep track of xmit threads */
+
+	u32 flags;
+	u32 irq;
+	int driver_mismatch;
+
+	struct netxen_adapter_stats stats;
+
+	struct netxen_ring_context ring_ctx[MAX_RING_CTX];
+	int number;
+	int is_up;
+	int work_done;
+};				/* netxen_adapter structure */
+
+/* Max number of xmit producer threads that can run simultaneously */
+#define	MAX_XMIT_PRODUCERS		16
+
+struct netxen_port_stats {
+	u64 rcvdbadskb;
+	u64 xmitcalled;
+	u64 xmitedframes;
+	u64 xmitfinished;
+	u64 badskblen;
+	u64 nocmddescriptor;
+	u64 polled;
+	u64 uphappy;
+	u64 updropped;
+	u64 uplcong;
+	u64 uphcong;
+	u64 upmcong;
+	u64 updunno;
+	u64 skbfreed;
+	u64 txdropped;
+	u64 txnullskb;
+	u64 csummed;
+	u64 no_rcv;
+	u64 rxbytes;
+	u64 txbytes;
+};
+
+struct netxen_port {
+	struct netxen_adapter *adapter;
+
+	u16 portnum;		/* GBE port number */
+	u16 link_speed;
+	u16 link_duplex;
+	u16 link_autoneg;
+
+	int flags;
+	spinlock_t stats_lock;
+
+	struct net_device *netdev;
+	struct pci_dev *pdev;
+	struct net_device_stats net_stats;
+	struct netxen_port_stats stats;
+};
+
+extern char netxen_nic_driver_name[];
+
+#define NETXEN_CTX_SIGNATURE	0xdee0
+#define MAX_PEG_RING_CTX	4
+
+#define RX_PRODUCER 0
+#define RX_PRODUCER_JUMBO 1
+#define TX_PRODUCER 2
+#define STS_PRODUCER 3
+
+#define NUM_DB_CODE 16
+
+#define NETXEN_RCV_PRODUCER(ringid)	(ringid)
+
+#define NETXEN_CMD_PRODUCER 2
+#define NETXEN_RCV_STATUS_CONSUMER 3
+
+struct ctx_msg {
+	u32 PegId:2, Count:16, CtxId:10, Opcode:4;
+};
+
+struct rcv_context {
+	u64 RcvRingAddrLo:32, RcvRingAddrHi:32;
+	u32 RcvRingSize;
+	u32 Rsrv;
+};
+
+struct ring_context {
+
+	u64 CMD_CONSUMER_OFFSET;
+	u64 CmdRingAddrLo:32, CmdRingAddrHi:32;
+	u32 CmdRingSize;
+	u32 Rsrv;
+	struct rcv_context RcvContext[2];
+	u64 StsRingAddrLo:32, StsRingAddrHi:32;
+	u32 StsRingSize;
+	u32 CtxId;
+} __attribute__ ((aligned(64)));
+
+#define NETXEN_RCV_PEG_DB_ID  1
+#define NETXEN_XMIT_PEG_DB_ID 2
+
+long netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter,
+					  long port);
+long netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter,
+					   long port);
+long netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter,
+					 long port);
+void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, long port,
+				 long enable);
+void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, long port,
+				  long enable);
+long netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, long reg,
+			     netxen_crbword_t * readval);
+long netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long phy,
+			      long reg, netxen_crbword_t val);
+
+/* Functions available from netxen_nic_hw.c */
+void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw);
+void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val);
+int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off);
+void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value);
+void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value);
+
+int netxen_nic_get_board_info(struct netxen_adapter *adapter);
+void netxen_nic_hw_block_write(struct netxen_adapter *adapter,
+			       u64 off, void *data, int num_words);
+int netxen_nic_pci_mem_write(struct netxen_adapter *adapter,
+			     u64 off, void *data, int size);
+int netxen_nic_pci_mem_read(struct netxen_adapter *adapter,
+			    u64 off, void *data, int size);
+void netxen_nic_mem_block_read(struct netxen_adapter *adapter, u64 off,
+			       void *data, int num_words);
+void netxen_nic_mem_block_write(struct netxen_adapter *adapter, u64 off,
+				void *data, int num_words);
+int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data,
+			  int len);
+int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
+			   int len);
+int netxen_nic_macaddr_set(struct netxen_port *port, u8 * addr);
+int netxen_nic_macaddr_get(struct netxen_port *port, u8 ** addr);
+int netxen_nic_macaddr_set(struct netxen_port *port, u8 * addr);
+int netxen_nic_macaddr_get(struct netxen_port *port, u8 ** addr);
+int netxen_nic_set_mtu(struct netxen_port *port, int new_mtu);
+long netxen_nic_phy_read(struct netxen_adapter *adapter, long phy, long, u32 *);
+long netxen_nic_phy_write(struct netxen_adapter *adapter, long phy, long reg,
+			  u32);
+long netxen_nic_init_port(struct netxen_port *port);
+void netxen_nic_init_niu(struct netxen_adapter *adapter);
+void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
+				 unsigned long off, int data);
+
+/* Functions from netxen_nic_init.c */
+void phantom_init(struct netxen_adapter *adapter);
+void load_firmware(struct netxen_adapter *adapter);
+int pinit_from_rom(struct netxen_adapter *adapter, int verbose);
+int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp);
+
+/* Functions from netxen_nic_isr.c */
+void netxen_nic_isr_other(struct netxen_adapter *adapter);
+void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter);
+long netxen_nic_phy_read(struct netxen_adapter *adapter, long phy, long reg,
+			 u32 * readval);
+long netxen_nic_phy_write(struct netxen_adapter *adapter, long phy, long reg,
+			  u32 val);
+long netxen_nic_enable_phy_interrupts(struct netxen_adapter *adapter,
+				      long port);
+long netxen_nic_disable_phy_interrupts(struct netxen_adapter *adapter,
+				       long port);
+long netxen_nic_clear_phy_interrupts(struct netxen_adapter *adapter, long port);
+void netxen_nic_set_mii_mode(struct netxen_adapter *adapter, long port,
+			     long enable);
+void netxen_nic_set_gmii_mode(struct netxen_adapter *adapter, long port,
+			      long enable);
+void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 port,
+				 u32 link);
+void netxen_handle_port_int(struct netxen_adapter *adapter, u32 port,
+			    u32 enable);
+int netxen_nic_set_promisc_mode(struct netxen_port *port);
+int netxen_nic_unset_promisc_mode(struct netxen_port *port);
+void netxen_nic_stop_all_ports(struct netxen_adapter *adapter);
+void netxen_nic_stop_port(struct netxen_port *port);
+int netxen_nic_get_board_num(struct netxen_adapter *adapter);
+void initialize_adapter_sw(struct netxen_adapter *adapter);
+int initialize_adapter_hw(struct netxen_adapter *adapter);
+int init_firmware(struct netxen_adapter *adapter);
+void netxen_free_hw_resources(struct netxen_adapter *adapter);
+void netxen_tso_check(struct netxen_adapter *adapter,
+		      struct cmd_desc_type0_t *desc, struct sk_buff *skb);
+int netxen_nic_hw_resources(struct netxen_adapter *adapter);
+void netxen_nic_clear_stats(struct netxen_adapter *adapter);
+int
+netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data,
+		    struct netxen_port *port);
+int netxen_nic_rx_has_work(struct netxen_adapter *adapter);
+int netxen_nic_tx_has_work(struct netxen_adapter *adapter);
+void netxen_watchdog_task(unsigned long v);
+void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
+			    u32 ringid);
+void netxen_process_cmd_ring(unsigned long data, int ctxid);
+u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
+void netxen_nic_set_multi(struct net_device *netdev);
+int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
+int netxen_nic_set_mac(struct net_device *netdev, void *p);
+struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
+int netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state);
+int netxen_nic_resume(struct pci_dev *pdev);
+void netxen_nic_down(struct netxen_port *port);
+void __devinit netxen_check_options(struct netxen_adapter *adapter);
+void netxen_check_cmdline_params(void);
+
+static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
+{
+	u32 mask;
+
+	mask = 0x7ff;
+
+	/*
+	 * ISR_INT_MASK: Can be read from window 0 or 1.
+	 */
+	writel(mask, (void *)(adapter->ahw.pci_base + ISR_INT_MASK));
+}
+
+static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
+{
+	u32 mask;
+
+	switch (adapter->ahw.board_type) {
+	case NETXEN_NIC_GBE:
+		mask = 0x77b;
+		break;
+	case NETXEN_NIC_XGBE:
+		mask = 0x77f;
+		break;
+	default:
+		mask = 0x7ff;
+		break;
+	}
+
+	writel(mask, (void *)(adapter->ahw.pci_base + ISR_INT_MASK));
+
+	if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+		mask = 0xbff;
+		writel(mask,
+		       (void *)(adapter->ahw.pci_base + ISR_INT_TARGET_MASK));
+	}
+}
+
+#endif				/* __NETXEN_NIC_H_ */

^ permalink raw reply

* [PATCH 1/9] NetXen 1G/10G ethernet driver patch with corrections
From: Linsys Contractor Amit S. Kale @ 2006-06-07  9:39 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, unmproj

2006-06-07 Amit S. Kale <amitkale@unminc.com>
 	* Add Kconfig, Makefile entries and Makefiles for netxen driver
 	* Add ethtool interface for netxen driver

diff -Naru linux-2.6.16.20.orig/drivers/net/Kconfig linux-2.6.16.20/drivers/net/Kconfig
--- linux-2.6.16.20.orig/drivers/net/Kconfig	2006-06-06 04:48:38.000000000 -0700
+++ linux-2.6.16.20/drivers/net/Kconfig	2006-06-06 05:02:26.000000000 -0700
@@ -2313,6 +2313,11 @@

  	  If in doubt, say N.

+config NETXEN_NIC
+	tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC"
+	help
+	  This enables the support for NetXen's Gigabit Ethernet card.
+
  endmenu

  if !UML
diff -Naru linux-2.6.16.20.orig/drivers/net/Makefile linux-2.6.16.20/drivers/net/Makefile
--- linux-2.6.16.20.orig/drivers/net/Makefile	2006-06-06 04:48:38.000000000 -0700
+++ linux-2.6.16.20/drivers/net/Makefile	2006-06-06 04:49:32.000000000 -0700
@@ -213,3 +213,4 @@

  obj-$(CONFIG_FS_ENET) += fs_enet/

+obj-$(CONFIG_NETXEN_NIC) += netxen/
diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/Makefile linux-2.6.16.20/drivers/net/netxen/Makefile
--- linux-2.6.16.20.orig/drivers/net/netxen/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/Makefile	2006-06-06 06:58:11.000000000 -0700
@@ -0,0 +1,35 @@
+# 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:
+#    info@netxen.com
+# NetXen,
+# 3965 Freedom Circle, Fourth floor,
+# Santa Clara, CA 95054
+#
+# Makefile for the NetXen NIC Driver
+#
+
+
+obj-$(CONFIG_NETXEN_NIC) := netxen_nic.o
+
+netxen_nic-y := netxen_nic_hw.o netxen_nic_main.o netxen_nic_init.o \
+	netxen_nic_isr.o netxen_nic_ethtool.o netxen_nic_niu.o
diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_ethtool.c linux-2.6.16.20/drivers/net/netxen/netxen_nic_ethtool.c
--- linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_ethtool.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/netxen_nic_ethtool.c	2006-06-06 06:58:11.000000000 -0700
@@ -0,0 +1,775 @@
+/*
+ * 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:
+ *    info@netxen.com
+ * NetXen,
+ * 3965 Freedom Circle, Fourth floor,
+ * Santa Clara, CA 95054
+ *
+ *
+ * ethtool support for netxen nic
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/version.h>
+
+#include "netxen_nic_hw.h"
+#include "netxen_nic.h"
+#include "netxen_nic_phan_reg.h"
+#include "netxen_nic_ioctl.h"
+
+struct netxen_nic_stats {
+	char stat_string[ETH_GSTRING_LEN];
+	int sizeof_stat;
+	int stat_offset;
+};
+
+#define NETXEN_NIC_STAT(m) sizeof(((struct netxen_port *)0)->m), \
+                    offsetof(struct netxen_port, m)
+
+static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
+	{"rcvd_bad_skb", NETXEN_NIC_STAT(stats.rcvdbadskb)},
+	{"xmit_called", NETXEN_NIC_STAT(stats.xmitcalled)},
+	{"xmited_frames", NETXEN_NIC_STAT(stats.xmitedframes)},
+	{"xmit_finished", NETXEN_NIC_STAT(stats.xmitfinished)},
+	{"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)},
+	{"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)},
+	{"polled", NETXEN_NIC_STAT(stats.polled)},
+	{"uphappy", NETXEN_NIC_STAT(stats.uphappy)},
+	{"updropped", NETXEN_NIC_STAT(stats.updropped)},
+	{"uplcong", NETXEN_NIC_STAT(stats.uplcong)},
+	{"uphcong", NETXEN_NIC_STAT(stats.uphcong)},
+	{"upmcong", NETXEN_NIC_STAT(stats.upmcong)},
+	{"updunno", NETXEN_NIC_STAT(stats.updunno)},
+	{"skb_freed", NETXEN_NIC_STAT(stats.skbfreed)},
+	{"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
+	{"tx_null_skb", NETXEN_NIC_STAT(stats.txnullskb)},
+	{"csummed", NETXEN_NIC_STAT(stats.csummed)},
+	{"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)},
+	{"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)},
+	{"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)},
+};
+
+#define NETXEN_NIC_STATS_LEN        \
+        sizeof(netxen_nic_gstrings_stats) / sizeof(struct netxen_nic_stats)
+
+static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = {
+	"Register_Test  (offline)", "EEPROM_Test    (offline)",
+	"Interrupt_Test (offline)", "Loopback_Test  (offline)",
+	"Link_Test   (on/offline)"
+};
+
+#define NETXEN_NIC_TEST_LEN sizeof(netxen_nic_gstrings_test) / ETH_GSTRING_LEN
+
+#define NETXEN_NIC_REGS_COUNT 42
+#define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(netxen_crbword_t))
+
+static int netxen_nic_get_eeprom_len(struct net_device *dev)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	struct netxen_adapter *adapter = port->adapter;
+	int n;
+
+	if ((netxen_rom_fast_read(adapter, 0, &n) == 0) && (n & 0x80000000)) {
+		n &= ~0x80000000;
+		if (n < 1024)
+			return n;
+	}
+	return 0;
+}
+
+static void
+netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
+{
+	struct netxen_port *port = netdev_priv(dev);
+
+	strncpy(drvinfo->driver, "NetXen NIC Driver", 32);
+	strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
+	strncpy(drvinfo->fw_version, NETXEN_NIC_FW_VERSIONID, 32);
+	strncpy(drvinfo->bus_info, pci_name(port->pdev), 32);
+	drvinfo->n_stats = NETXEN_NIC_STATS_LEN;
+	drvinfo->testinfo_len = NETXEN_NIC_TEST_LEN;
+	drvinfo->regdump_len = NETXEN_NIC_REGS_LEN;
+	drvinfo->eedump_len = netxen_nic_get_eeprom_len(dev);
+}
+
+static int
+netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	struct netxen_adapter *adapter = port->adapter;
+
+	/* read which mode */
+	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+		ecmd->supported = (SUPPORTED_10baseT_Half |
+				   SUPPORTED_10baseT_Full |
+				   SUPPORTED_100baseT_Half |
+				   SUPPORTED_100baseT_Full |
+				   SUPPORTED_1000baseT_Half |
+				   SUPPORTED_1000baseT_Full |
+				   SUPPORTED_TP |
+				   SUPPORTED_MII | SUPPORTED_Autoneg);
+
+		ecmd->advertising = (ADVERTISED_100baseT_Half |
+				     ADVERTISED_100baseT_Full |
+				     ADVERTISED_1000baseT_Half |
+				     ADVERTISED_1000baseT_Full |
+				     ADVERTISED_TP |
+				     ADVERTISED_MII | ADVERTISED_Autoneg);
+
+		ecmd->port = PORT_TP;
+
+		if (netif_running(dev)) {
+			ecmd->speed = port->link_speed;
+			ecmd->duplex = port->link_duplex;
+		} else
+			return -EIO;	/* link absent */
+
+		ecmd->phy_address = port->portnum;
+		ecmd->transceiver = XCVR_EXTERNAL;
+
+		/* get autoneg settings */
+		ecmd->autoneg = port->link_autoneg;
+		return 0;
+	}
+
+	if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+		ecmd->supported = (SUPPORTED_TP |
+				   SUPPORTED_1000baseT_Full |
+				   SUPPORTED_10000baseT_Full);
+		ecmd->advertising = (ADVERTISED_TP |
+				     ADVERTISED_1000baseT_Full |
+				     ADVERTISED_10000baseT_Full);
+		ecmd->port = PORT_TP;
+
+		ecmd->speed = SPEED_10000;
+		ecmd->duplex = DUPLEX_FULL;
+		ecmd->phy_address = port->portnum;
+		ecmd->transceiver = XCVR_EXTERNAL;
+		ecmd->autoneg = AUTONEG_DISABLE;
+		return 0;
+	}
+
+	return -EIO;
+}
+
+static int
+netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	struct netxen_adapter *adapter = port->adapter;
+	struct netxen_niu_phy_status status;
+
+	/* read which mode */
+	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+		/* autonegotiation */
+		if (netxen_nic_phy_write(port->adapter, port->portnum,
+					 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
+					 (netxen_crbword_t) ecmd->autoneg) != 0)
+			return -EIO;
+		else
+			port->link_autoneg = ecmd->autoneg;
+
+		if (netxen_nic_phy_read(port->adapter, port->portnum,
+					NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+					(netxen_crbword_t *) & status) != 0)
+			return -EIO;
+
+		/* speed */
+		switch (ecmd->speed) {
+		case SPEED_10:
+			status.speed = 0;
+			break;
+		case SPEED_100:
+			status.speed = 1;
+			break;
+		case SPEED_1000:
+			status.speed = 2;
+			break;
+		}
+		/* set duplex mode */
+		if (ecmd->duplex == DUPLEX_HALF)
+			status.duplex = 0;
+		if (ecmd->duplex == DUPLEX_FULL)
+			status.duplex = 1;
+
+		if (netxen_nic_phy_write(port->adapter, port->portnum,
+					 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+					 *((int *)&status)) != 0)
+			return -EIO;
+		else {
+			port->link_speed = ecmd->speed;
+			port->link_duplex = ecmd->duplex;
+		}
+	}
+	if (netif_running(dev)) {
+		dev->stop(dev);
+		dev->open(dev);
+	}
+	return 0;
+}
+
+static int netxen_nic_get_regs_len(struct net_device *dev)
+{
+	return NETXEN_NIC_REGS_LEN;
+}
+
+static void
+netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	struct netxen_adapter *adapter = port->adapter;
+	netxen_crbword_t mode, *regs_buff = p;
+	unsigned long flags;
+	void *addr;
+
+	memset(p, 0, NETXEN_NIC_REGS_LEN);
+	regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
+	    adapter->ahw.device_id;
+	write_lock_irqsave(&adapter->adapter_lock, flags);
+	/* which mode */
+	NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_MODE, &regs_buff[0]);
+	mode = regs_buff[0];
+
+	/* Common registers to all the modes */
+	NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER,
+				   &regs_buff[2]);
+	switch (mode) {
+	case 4:{		/* XGB Mode */
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_SINGLE_TERM,
+						   &regs_buff[3]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_DRIVE_HI,
+						   &regs_buff[4]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_DRIVE_LO,
+						   &regs_buff[5]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_DTX,
+						   &regs_buff[6]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_DEQ,
+						   &regs_buff[7]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_WORD_ALIGN,
+						   &regs_buff[8]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_RESET,
+						   &regs_buff[9]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_POWER_DOWN,
+						   &regs_buff[10]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_RESET_PLL,
+						   &regs_buff[11]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XG_SERDES_LOOPBACK, &regs_buff[12]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_DO_BYTE_ALIGN,
+						   &regs_buff[13]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_TX_ENABLE,
+						   &regs_buff[14]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_RX_ENABLE,
+						   &regs_buff[15]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XG_STATUS,
+						   &regs_buff[16]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XG_PAUSE_THRESHOLD, &regs_buff[17]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_CONFIG_0,
+						   &regs_buff[18]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_CONFIG_1,
+						   &regs_buff[19]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_IPG,
+						   &regs_buff[20]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_STATION_ADDR_0_HI, &regs_buff[21]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_STATION_ADDR_0_1, &regs_buff[22]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_STATION_ADDR_1_LO, &regs_buff[23]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_STATUS,
+						   &regs_buff[24]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_MAX_FRAME_SIZE, &regs_buff[25]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_PAUSE_FRAME_VALUE, &regs_buff[26]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_BYTE_CNT,
+						   &regs_buff[27]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_FRAME_CNT,
+						   &regs_buff[28]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_BYTE_CNT,
+						   &regs_buff[29]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_FRAME_CNT,
+						   &regs_buff[30]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_AGGR_ERROR_CNT, &regs_buff[31]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_MULTICAST_FRAME_CNT,
+			     &regs_buff[32]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_UNICAST_FRAME_CNT, &regs_buff[33]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_CRC_ERROR_CNT,
+						   &regs_buff[34]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR, &regs_buff[35]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR,
+			     &regs_buff[36]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_LOCAL_ERROR_CNT, &regs_buff[37]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_REMOTE_ERROR_CNT, &regs_buff[38]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_CONTROL_CHAR_CNT, &regs_buff[39]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_XGE_PAUSE_FRAME_CNT, &regs_buff[40]);
+			break;
+		}
+
+	case 2:{		/* GB Mode */
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_SERDES_RESET,
+						   &regs_buff[3]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB0_MII_MODE,
+						   &regs_buff[4]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB1_MII_MODE,
+						   &regs_buff[5]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB2_MII_MODE,
+						   &regs_buff[6]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB3_MII_MODE,
+						   &regs_buff[7]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB0_GMII_MODE,
+						   &regs_buff[8]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB1_GMII_MODE,
+						   &regs_buff[9]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB2_GMII_MODE,
+						   &regs_buff[10]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB3_GMII_MODE,
+						   &regs_buff[11]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_REMOTE_LOOPBACK,
+						   &regs_buff[12]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB0_HALF_DUPLEX,
+						   &regs_buff[13]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB1_HALF_DUPLEX,
+						   &regs_buff[14]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_RESET_SYS_FIFOS,
+						   &regs_buff[15]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_CRC_DROP,
+						   &regs_buff[16]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_DROP_WRONGADDR,
+						   &regs_buff[17]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_TEST_MUX_CTL,
+						   &regs_buff[18]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_MAC_CONFIG_0
+						   (port->portnum),
+						   &regs_buff[19]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_MAC_CONFIG_1
+						   (port->portnum),
+						   &regs_buff[20]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_GB_HALF_DUPLEX_CTRL(port->portnum),
+			     &regs_buff[21]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_MAX_FRAME_SIZE
+						   (port->portnum),
+						   &regs_buff[22]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_TEST_REG
+						   (port->portnum),
+						   &regs_buff[23]);
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_MII_MGMT_CONFIG
+						   (port->portnum),
+						   &regs_buff[24]);
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_GB_MII_MGMT_COMMAND(port->portnum),
+			     &regs_buff[25]);
+
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_MII_MGMT_ADDR
+						   (port->portnum),
+						   &regs_buff[26]);
+
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_MII_MGMT_CTRL
+						   (port->portnum),
+						   &regs_buff[27]);
+
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_MII_MGMT_STATUS
+						   (port->portnum),
+						   &regs_buff[28]);
+
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_GB_MII_MGMT_INDICATE(port->portnum),
+			     &regs_buff[29]);
+
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_INTERFACE_CTRL
+						   (port->portnum),
+						   &regs_buff[30]);
+
+			NETXEN_NIC_LOCKED_READ_REG
+			    (NETXEN_NIU_GB_INTERFACE_STATUS(port->portnum),
+			     &regs_buff[31]);
+
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_STATION_ADDR_0
+						   (port->portnum),
+						   &regs_buff[32]);
+
+			NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_GB_STATION_ADDR_1
+						   (port->portnum),
+						   &regs_buff[33]);
+			break;
+		}
+	}
+	write_unlock_irqrestore(&adapter->adapter_lock, flags);
+}
+
+static void
+netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
+	wol->wolopts = 0;	/* options can be added depending upon the mode */
+}
+
+/* Restart Link Process */
+static int netxen_nic_nway_reset(struct net_device *dev)
+{
+	if (netif_running(dev)) {
+		dev->stop(dev);	/* verify */
+		dev->open(dev);
+	}
+	return 0;
+}
+
+static u32 netxen_nic_get_link(struct net_device *dev)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	struct netxen_adapter *adapter = port->adapter;
+	struct netxen_niu_phy_status status;
+
+	/* read which mode */
+	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+		if (netxen_nic_phy_read(port->adapter, port->portnum,
+					NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+					(netxen_crbword_t *) & status) != 0)
+			return -EIO;
+		else
+			return status.link;
+	}
+	return -EIO;
+}
+
+static int
+netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+		      u8 * bytes)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	struct netxen_adapter *adapter = port->adapter;
+	int offset;
+
+	if (eeprom->len == 0)
+		return -EINVAL;
+
+	eeprom->magic = adapter->ahw.vendor_id | (adapter->ahw.device_id << 16);
+	for (offset = 0; offset < eeprom->len; offset++)
+		if (netxen_rom_fast_read
+		    (adapter, (8 * offset) + 8, (int *)eeprom->data) == -1)
+			return -1;
+	return 0;
+}
+
+static void
+netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	struct netxen_adapter *adapter = port->adapter;
+	int i, j;
+	struct netxen_ring_context *ctx;
+
+	ring->rx_pending = 0;
+	ring->rx_max_pending = 0;
+	ring->tx_max_pending = 0;
+	for (i = 0; i < MAX_RING_CTX; ++i) {
+		ctx = &adapter->ring_ctx[i];
+		for (j = 0; j < NUM_RCV_DESC_RINGS; j++)
+			ring->rx_pending +=
+			    ctx->recv_ctx.rcv_desc[j].rcv_pending;
+		ring->tx_pending += ctx->pending_cmd_count;
+		ring->rx_max_pending += ctx->max_rx_desc_count;
+		ring->tx_max_pending += ctx->max_tx_desc_count;
+	}
+
+	ring->rx_mini_max_pending = 0;
+	ring->rx_mini_pending = 0;
+	ring->rx_jumbo_max_pending = 0;
+	ring->rx_jumbo_pending = 0;
+}
+
+static void
+netxen_nic_get_pauseparam(struct net_device *dev,
+			  struct ethtool_pauseparam *pause)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	struct netxen_adapter *adapter = port->adapter;
+	struct netxen_niu_gb_mac_config_0_t val;
+
+	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+		/* get flow control settings */
+		netxen_nic_read_w0(adapter,
+				   NETXEN_NIU_GB_MAC_CONFIG_0(port->portnum),
+				   (u32 *) & val);
+		pause->rx_pause = val.rx_flowctl;
+		pause->tx_pause = val.tx_flowctl;
+		/* get autoneg settings */
+		pause->autoneg = port->link_autoneg;
+	}
+}
+
+static int
+netxen_nic_set_pauseparam(struct net_device *dev,
+			  struct ethtool_pauseparam *pause)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	struct netxen_adapter *adapter = port->adapter;
+	struct netxen_niu_gb_mac_config_0_t val;
+	unsigned int autoneg;
+
+	/* read mode */
+	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+		/* set flow control */
+		netxen_nic_read_w0(adapter,
+				   NETXEN_NIU_GB_MAC_CONFIG_0(port->portnum),
+				   (u32 *) & val);
+		val.rx_flowctl = pause->rx_pause;
+		val.tx_flowctl = pause->tx_pause;
+		netxen_nic_write_w0(adapter,
+				    NETXEN_NIU_GB_MAC_CONFIG_0(port->portnum),
+				    *(u32 *) (&val));
+		/* set autoneg */
+		autoneg = pause->autoneg;
+		if (netxen_nic_phy_write(port->adapter, port->portnum,
+					 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
+					 (netxen_crbword_t) autoneg) != 0)
+			return -EIO;
+		else {
+			port->link_autoneg = pause->autoneg;
+			return 0;
+		}
+	} else
+		return -EIO;
+}
+
+static int netxen_nic_reg_test(struct net_device *dev)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	struct netxen_adapter *adapter = port->adapter;
+	int data_read, data_written, save;
+	struct netxen_niu_control mode;
+
+	/* 
+	 * first test the "Read Only" registers by writing which mode
+	 */
+	netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, (u32 *) & mode);
+	if (mode.enable_ge) {	/* GB Mode */
+		netxen_nic_read_w0(adapter,
+				   NETXEN_NIU_GB_MII_MGMT_STATUS(port->portnum),
+				   &data_read);
+
+		save = data_read;
+		if (data_read)
+			data_written = data_read & 0xDEADBEEF;
+		else
+			data_written = 0xDEADBEEF;
+		netxen_nic_write_w0(adapter,
+				    NETXEN_NIU_GB_MII_MGMT_STATUS(port->
+								  portnum),
+				    data_written);
+		netxen_nic_read_w0(adapter,
+				   NETXEN_NIU_GB_MII_MGMT_STATUS(port->portnum),
+				   &data_read);
+
+		if (data_written == data_read) {
+			netxen_nic_write_w0(adapter,
+					    NETXEN_NIU_GB_MII_MGMT_STATUS(port->
+									  portnum),
+					    save);
+
+			return 0;
+		}
+
+		/* netxen_niu_gb_mii_mgmt_indicators_t is read only */
+		netxen_nic_read_w0(adapter,
+				   NETXEN_NIU_GB_MII_MGMT_INDICATE(port->
+								   portnum),
+				   &data_read);
+
+		save = data_read;
+		if (data_read)
+			data_written = data_read & 0xDEADBEEF;
+		else
+			data_written = 0xDEADBEEF;
+		netxen_nic_write_w0(adapter,
+				    NETXEN_NIU_GB_MII_MGMT_INDICATE(port->
+								    portnum),
+				    data_written);
+
+		netxen_nic_read_w0(adapter,
+				   NETXEN_NIU_GB_MII_MGMT_INDICATE(port->
+								   portnum),
+				   &data_read);
+
+		if (data_written == data_read) {
+			netxen_nic_write_w0(adapter,
+					    NETXEN_NIU_GB_MII_MGMT_INDICATE
+					    (port->portnum), save);
+			return 0;
+		}
+
+		/* netxen_niu_gb_interface_status_t is read only */
+		netxen_nic_read_w0(adapter,
+				   NETXEN_NIU_GB_INTERFACE_STATUS(port->
+								  portnum),
+				   &data_read);
+
+		save = data_read;
+		if (data_read)
+			data_written = data_read & 0xDEADBEEF;
+		else
+			data_written = 0xDEADBEEF;
+		netxen_nic_write_w0(adapter,
+				    NETXEN_NIU_GB_INTERFACE_STATUS(port->
+								   portnum),
+				    data_written);
+
+		netxen_nic_read_w0(adapter,
+				   NETXEN_NIU_GB_INTERFACE_STATUS(port->
+								  portnum),
+				   &data_read);
+
+		if (data_written == data_read) {
+			netxen_nic_write_w0(adapter,
+					    NETXEN_NIU_GB_INTERFACE_STATUS
+					    (port->portnum), save);
+
+			return 0;
+		}
+	}			/* GB Mode */
+	return 1;
+}
+
+static int netxen_nic_diag_test_count(struct net_device *dev)
+{
+	return NETXEN_NIC_TEST_LEN;
+}
+
+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[4] = (u64) netxen_nic_get_link(dev)))
+			eth_test->flags |= ETH_TEST_FL_FAILED;
+
+		if (netif_running(dev))
+			dev->stop(dev);
+
+		/* register tests */
+		if (!(data[0] = netxen_nic_reg_test(dev)))
+			eth_test->flags |= ETH_TEST_FL_FAILED;
+		/* other tests pass as of now */
+		data[1] = data[2] = data[3] = 1;
+		if (netif_running(dev))
+			dev->open(dev);
+	} else {		/* online tests */
+		/* link test */
+		if (!(data[4] = (u64) netxen_nic_get_link(dev)))
+			eth_test->flags |= ETH_TEST_FL_FAILED;
+
+		/* other tests pass by default */
+		data[0] = data[1] = data[2] = data[3] = 1;
+	}
+}
+
+static void
+netxen_nic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
+{
+	int index;
+
+	switch (stringset) {
+	case ETH_SS_TEST:
+		memcpy(data, *netxen_nic_gstrings_test,
+		       NETXEN_NIC_TEST_LEN * ETH_GSTRING_LEN);
+		break;
+	case ETH_SS_STATS:
+		for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
+			memcpy(data + index * ETH_GSTRING_LEN,
+			       netxen_nic_gstrings_stats[index].stat_string,
+			       ETH_GSTRING_LEN);
+		}
+		break;
+	}
+}
+
+static int netxen_nic_get_stats_count(struct net_device *dev)
+{
+	return NETXEN_NIC_STATS_LEN;
+}
+
+static void
+netxen_nic_get_ethtool_stats(struct net_device *dev,
+			     struct ethtool_stats *stats, u64 * data)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	int index;
+
+	for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
+		char *p =
+		    (char *)port + netxen_nic_gstrings_stats[index].stat_offset;
+		data[index] =
+		    (netxen_nic_gstrings_stats[index].sizeof_stat ==
+		     sizeof(u64)) ? *(u64 *) p : *(u32 *) p;
+	}
+
+}
+
+struct ethtool_ops netxen_nic_ethtool_ops = {
+	.get_settings = netxen_nic_get_settings,
+	.set_settings = netxen_nic_set_settings,
+	.get_drvinfo = netxen_nic_get_drvinfo,
+	.get_regs_len = netxen_nic_get_regs_len,
+	.get_regs = netxen_nic_get_regs,
+	.get_wol = netxen_nic_get_wol,
+	.nway_reset = netxen_nic_nway_reset,
+	.get_link = netxen_nic_get_link,
+	.get_eeprom_len = netxen_nic_get_eeprom_len,
+	.get_eeprom = netxen_nic_get_eeprom,
+	.get_ringparam = netxen_nic_get_ringparam,
+	.get_pauseparam = netxen_nic_get_pauseparam,
+	.set_pauseparam = netxen_nic_set_pauseparam,
+	.get_tx_csum = ethtool_op_get_tx_csum,
+	.set_tx_csum = ethtool_op_set_tx_csum,
+	.get_sg = ethtool_op_get_sg,
+	.set_sg = ethtool_op_set_sg,
+#ifdef NETIF_F_TSO
+	.get_tso = ethtool_op_get_tso,
+	.set_tso = ethtool_op_set_tso,
+#endif
+	.self_test_count = netxen_nic_diag_test_count,
+	.self_test = netxen_nic_diag_test,
+	.get_strings = netxen_nic_get_strings,
+	.get_stats_count = netxen_nic_get_stats_count,
+	.get_ethtool_stats = netxen_nic_get_ethtool_stats,
+	.get_perm_addr = ethtool_op_get_perm_addr,
+};

^ permalink raw reply

* [PATCH 0/9] NetXen 1G/10G ethernet driver patch with corrections
From: Linsys Contractor Amit S. Kale @ 2006-06-07  9:30 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, unmproj

Hi,

I'll be sending a NetXen 1G/10G ethernet driver patch in
subsequent emails. We have made changes as per the feedback received.
We would like this driver to be inluded in mainline kernel.

Kindly review it and feel free to send feedback.

Thanks.
-Amit


Signed-off-by: Amit S. Kale <amitkale@unminc.com>

  Kconfig                      |    5
  Makefile                     |    1
  netxen/Makefile              |   35 +
  netxen/netxen_nic.h          |  998 ++++++++++++++++++++++++++++++++
  netxen/netxen_nic_ethtool.c  |  775 +++++++++++++++++++++++++
  netxen/netxen_nic_hdr.h      |  684 ++++++++++++++++++++++
  netxen/netxen_nic_hw.c       | 1308 
+++++++++++++++++++++++++++++++++++++++++++
  netxen/netxen_nic_hw.h       |  346 +++++++++++
  netxen/netxen_nic_init.c     | 1263 
+++++++++++++++++++++++++++++++++++++++++
  netxen/netxen_nic_ioctl.h    |   75 ++
  netxen/netxen_nic_isr.c      |  430 ++++++++++++++
  netxen/netxen_nic_main.c     | 1228 
++++++++++++++++++++++++++++++++++++++++
  netxen/netxen_nic_niu.c      |  761 +++++++++++++++++++++++++
  netxen/netxen_nic_phan_reg.h |  293 +++++++++
  14 files changed, 8202 insertions(+)
~


^ permalink raw reply

* Re: [PATCH 3/4] Make Intel e1000 driver legacy I/O port free
From: Kenji Kaneshige @ 2006-06-07  7:39 UTC (permalink / raw)
  To: Auke Kok
  Cc: Greg KH, akpm, Rajesh Shah, Grant Grundler, bibo,mao,
	linux-kernel, linux-pci, netdev, Jesse Brandeburg, Ronciak, John
In-Reply-To: <44865FD8.4060801@foo-projects.org>

Auke Kok wrote:
> Kenji Kaneshige wrote:
> 
>> This patch makes Intel e1000 driver legacy I/O port free.
>>
>> Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
> 
> 
> (adding netdev and the other e1000 maintainers to cc:)
> 
> without sending this to any of the listed e1000 maintainers???? *and* 
> not even including netdev???
> 

I'm sorry about that.
 
> I'm going to take a look at it first, and have some other colleagues 
> look at this and the impact, which is unclear to me at the moment. 

Thank you for reviewing.
What this patch try to do is not to request/enable I/O port regions
if the device can be handled without using I/O port so that the device
can work even if I/O port resource is not assigned to it on the large
servers. Please see the "[PATCH 2/4] Update Document/pci.txt" about
details.

Thanks,
Kenji Kaneshige



> Please don't commit  this like this.
> 
> Auke
> 
> 
>>
>> ---
>>  drivers/net/e1000/e1000.h      |    6 +
>>  drivers/net/e1000/e1000_main.c |  130 
>> ++++++++++++++++++++++-------------------
>>  2 files changed, 75 insertions(+), 61 deletions(-)
>>
>> Index: linux-2.6.17-rc6/drivers/net/e1000/e1000.h
>> ===================================================================
>> --- linux-2.6.17-rc6.orig/drivers/net/e1000/e1000.h    2006-06-06 
>> 21:39:11.000000000 +0900
>> +++ linux-2.6.17-rc6/drivers/net/e1000/e1000.h    2006-06-06 
>> 21:56:41.000000000 +0900
>> @@ -77,8 +77,9 @@
>>  #define BAR_1        1
>>  #define BAR_5        5
>>  
>> -#define INTEL_E1000_ETHERNET_DEVICE(device_id) {\
>> -    PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
>> +#define E1000_NO_IOPORT    (1 << 0)
>> +#define INTEL_E1000_ETHERNET_DEVICE(device_id, flags) {\
>> +    PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id), .driver_data = flags}
>>  
>>  struct e1000_adapter;
>>  
>> @@ -338,6 +339,7 @@
>>  #ifdef NETIF_F_TSO
>>      boolean_t tso_force;
>>  #endif
>> +    int bars;    /* BARs to be enabled */
>>  };
>>  
>>  
>> Index: linux-2.6.17-rc6/drivers/net/e1000/e1000_main.c
>> ===================================================================
>> --- linux-2.6.17-rc6.orig/drivers/net/e1000/e1000_main.c    2006-06-06 
>> 21:39:11.000000000 +0900
>> +++ linux-2.6.17-rc6/drivers/net/e1000/e1000_main.c    2006-06-06 
>> 21:56:41.000000000 +0900
>> @@ -86,54 +86,54 @@
>>   *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
>>   */
>>  static struct pci_device_id e1000_pci_tbl[] = {
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1000),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1001),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1004),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1008),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1009),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x100C),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x100D),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x100E),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x100F),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1010),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1011),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1012),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1013),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1014),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1015),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1016),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1017),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1018),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1019),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x101A),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x101D),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x101E),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1026),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1027),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1028),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x105E),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x105F),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1060),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1075),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1076),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1077),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1078),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1079),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x107A),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x107B),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x107C),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x107D),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x107E),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x107F),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x108A),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x108B),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x108C),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1096),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1098),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x1099),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x109A),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x10B5),
>> -    INTEL_E1000_ETHERNET_DEVICE(0x10B9),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1000, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1001, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1004, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1008, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1009, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x100C, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x100D, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x100E, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x100F, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1010, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1011, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1012, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1013, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1014, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1015, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1016, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1017, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1018, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1019, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x101A, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x101D, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x101E, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1026, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1027, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1028, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x105E, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x105F, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1060, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1075, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1076, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1077, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1078, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1079, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x107A, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x107B, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x107C, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x107D, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x107E, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x107F, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x108A, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x108B, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x108C, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1096, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1098, 0),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x1099, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x109A, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x10B5, E1000_NO_IOPORT),
>> +    INTEL_E1000_ETHERNET_DEVICE(0x10B9, 0),
>>      /* required last entry */
>>      {0,}
>>  };
>> @@ -621,7 +621,14 @@
>>      int i, err, pci_using_dac;
>>      uint16_t eeprom_data;
>>      uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
>> -    if ((err = pci_enable_device(pdev)))
>> +    int bars;
>> +
>> +    if (ent->driver_data & E1000_NO_IOPORT)
>> +        bars = pci_select_bars(pdev, IORESOURCE_MEM);
>> +    else
>> +        bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
>> +
>> +    if ((err = pci_enable_device_bars(pdev, bars)))
>>          return err;
>>  
>>      if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
>> @@ -634,7 +641,8 @@
>>          pci_using_dac = 0;
>>      }
>>  
>> -    if ((err = pci_request_regions(pdev, e1000_driver_name)))
>> +    err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
>> +    if (err)
>>          return err;
>>  
>>      pci_set_master(pdev);
>> @@ -654,6 +662,7 @@
>>      adapter->pdev = pdev;
>>      adapter->hw.back = adapter;
>>      adapter->msg_enable = (1 << debug) - 1;
>> +    adapter->bars = bars;
>>  
>>      mmio_start = pci_resource_start(pdev, BAR_0);
>>      mmio_len = pci_resource_len(pdev, BAR_0);
>> @@ -664,12 +673,15 @@
>>          goto err_ioremap;
>>      }
>>  
>> -    for (i = BAR_1; i <= BAR_5; i++) {
>> -        if (pci_resource_len(pdev, i) == 0)
>> -            continue;
>> -        if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
>> -            adapter->hw.io_base = pci_resource_start(pdev, i);
>> -            break;
>> +    if (!(ent->driver_data & E1000_NO_IOPORT)) {
>> +        for (i = BAR_1; i <= BAR_5; i++) {
>> +            if (pci_resource_len(pdev, i) == 0)
>> +                continue;
>> +            if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
>> +                adapter->hw.io_base =
>> +                    pci_resource_start(pdev, i);
>> +                break;
>> +            }
>>          }
>>      }
>>  
>> @@ -880,7 +892,7 @@
>>  err_ioremap:
>>      free_netdev(netdev);
>>  err_alloc_etherdev:
>> -    pci_release_regions(pdev);
>> +    pci_release_selected_regions(pdev, bars);
>>      return err;
>>  }
>>  
>> @@ -935,7 +947,7 @@
>>  #endif
>>  
>>      iounmap(adapter->hw.hw_addr);
>> -    pci_release_regions(pdev);
>> +    pci_release_selected_regions(pdev, adapter->bars);
>>  
>>      free_netdev(netdev);
>>  
>> @@ -4577,7 +4589,7 @@
>>      if (retval)
>>          DPRINTK(PROBE, ERR, "Error in setting power state\n");
>>      e1000_pci_restore_state(adapter);
>> -    ret_val = pci_enable_device(pdev);
>> +    ret_val = pci_enable_device_bars(pdev, adapter->bars);
>>      pci_set_master(pdev);
>>  
>>      retval = pci_enable_wake(pdev, PCI_D3hot, 0);
>>
>> -
>> To unsubscribe from this list: send the line "unsubscribe 
>> linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
> 
> 
> 


^ permalink raw reply

* Re: 2.6.17-rc5-mm3-lockdep -
From: Herbert Xu @ 2006-06-07  7:12 UTC (permalink / raw)
  To: Stefan Richter
  Cc: Andrew Morton, Valdis.Kletnieks, Jiri Slaby, netdev, linux-kernel,
	mingo, linux1394-devel, David S. Miller, arjan
In-Reply-To: <4485AFB9.3040005@s5r6.in-berlin.de>

On Tue, Jun 06, 2006 at 04:39:21PM +0000, Stefan Richter wrote:
> 
> BTW, the locking in -mm's net/unix/af_unix.c::unix_stream_connect() 
> differs a bit from stock unix_stream_connect(). I see spin_lock_bh() in 
> 2.6.17-rc5-mm3 where 2.6.17-rc5 has spin_lock().

Hi Ingo:

Looks like this change was introduced by the validator patch.  Any idea
why this was done? AF_UNIX is a user-space-driven socket so there shouldn't
be any need for BH to be disabled there.

Even if it does this patch should go through the normal channels rather
than the lock validator.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH 3/4] Make Intel e1000 driver legacy I/O port free
From: Auke Kok @ 2006-06-07  5:10 UTC (permalink / raw)
  To: Kenji Kaneshige
  Cc: Greg KH, akpm, Rajesh Shah, Grant Grundler, bibo,mao,
	linux-kernel, linux-pci, netdev, Jesse Brandeburg, Ronciak, John
In-Reply-To: <448644A2.7000208@jp.fujitsu.com>

Kenji Kaneshige wrote:
> This patch makes Intel e1000 driver legacy I/O port free.
> 
> Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>

(adding netdev and the other e1000 maintainers to cc:)

without sending this to any of the listed e1000 maintainers???? *and* not even 
including netdev???


I'm going to take a look at it first, and have some other colleagues look at 
this and the impact, which is unclear to me at the moment. Please don't commit 
  this like this.

Auke


> 
> ---
>  drivers/net/e1000/e1000.h      |    6 +
>  drivers/net/e1000/e1000_main.c |  130 ++++++++++++++++++++++-------------------
>  2 files changed, 75 insertions(+), 61 deletions(-)
> 
> Index: linux-2.6.17-rc6/drivers/net/e1000/e1000.h
> ===================================================================
> --- linux-2.6.17-rc6.orig/drivers/net/e1000/e1000.h	2006-06-06 21:39:11.000000000 +0900
> +++ linux-2.6.17-rc6/drivers/net/e1000/e1000.h	2006-06-06 21:56:41.000000000 +0900
> @@ -77,8 +77,9 @@
>  #define BAR_1		1
>  #define BAR_5		5
>  
> -#define INTEL_E1000_ETHERNET_DEVICE(device_id) {\
> -	PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
> +#define E1000_NO_IOPORT	(1 << 0)
> +#define INTEL_E1000_ETHERNET_DEVICE(device_id, flags) {\
> +	PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id), .driver_data = flags}
>  
>  struct e1000_adapter;
>  
> @@ -338,6 +339,7 @@
>  #ifdef NETIF_F_TSO
>  	boolean_t tso_force;
>  #endif
> +	int bars;	/* BARs to be enabled */
>  };
>  
>  
> Index: linux-2.6.17-rc6/drivers/net/e1000/e1000_main.c
> ===================================================================
> --- linux-2.6.17-rc6.orig/drivers/net/e1000/e1000_main.c	2006-06-06 21:39:11.000000000 +0900
> +++ linux-2.6.17-rc6/drivers/net/e1000/e1000_main.c	2006-06-06 21:56:41.000000000 +0900
> @@ -86,54 +86,54 @@
>   *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
>   */
>  static struct pci_device_id e1000_pci_tbl[] = {
> -	INTEL_E1000_ETHERNET_DEVICE(0x1000),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1001),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1004),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1008),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1009),
> -	INTEL_E1000_ETHERNET_DEVICE(0x100C),
> -	INTEL_E1000_ETHERNET_DEVICE(0x100D),
> -	INTEL_E1000_ETHERNET_DEVICE(0x100E),
> -	INTEL_E1000_ETHERNET_DEVICE(0x100F),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1010),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1011),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1012),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1013),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1014),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1015),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1016),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1017),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1018),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1019),
> -	INTEL_E1000_ETHERNET_DEVICE(0x101A),
> -	INTEL_E1000_ETHERNET_DEVICE(0x101D),
> -	INTEL_E1000_ETHERNET_DEVICE(0x101E),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1026),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1027),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1028),
> -	INTEL_E1000_ETHERNET_DEVICE(0x105E),
> -	INTEL_E1000_ETHERNET_DEVICE(0x105F),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1060),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1075),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1076),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1077),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1078),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1079),
> -	INTEL_E1000_ETHERNET_DEVICE(0x107A),
> -	INTEL_E1000_ETHERNET_DEVICE(0x107B),
> -	INTEL_E1000_ETHERNET_DEVICE(0x107C),
> -	INTEL_E1000_ETHERNET_DEVICE(0x107D),
> -	INTEL_E1000_ETHERNET_DEVICE(0x107E),
> -	INTEL_E1000_ETHERNET_DEVICE(0x107F),
> -	INTEL_E1000_ETHERNET_DEVICE(0x108A),
> -	INTEL_E1000_ETHERNET_DEVICE(0x108B),
> -	INTEL_E1000_ETHERNET_DEVICE(0x108C),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1096),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1098),
> -	INTEL_E1000_ETHERNET_DEVICE(0x1099),
> -	INTEL_E1000_ETHERNET_DEVICE(0x109A),
> -	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
> -	INTEL_E1000_ETHERNET_DEVICE(0x10B9),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1000, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1001, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1004, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1008, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1009, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x100C, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x100D, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x100E, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x100F, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1010, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1011, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1012, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1013, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1014, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1015, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1016, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1017, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1018, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1019, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x101A, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x101D, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x101E, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1026, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1027, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1028, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x105E, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x105F, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1060, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1075, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1076, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1077, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1078, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1079, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x107A, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x107B, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x107C, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x107D, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x107E, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x107F, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x108A, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x108B, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x108C, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1096, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1098, 0),
> +	INTEL_E1000_ETHERNET_DEVICE(0x1099, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x109A, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x10B5, E1000_NO_IOPORT),
> +	INTEL_E1000_ETHERNET_DEVICE(0x10B9, 0),
>  	/* required last entry */
>  	{0,}
>  };
> @@ -621,7 +621,14 @@
>  	int i, err, pci_using_dac;
>  	uint16_t eeprom_data;
>  	uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
> -	if ((err = pci_enable_device(pdev)))
> +	int bars;
> +
> +	if (ent->driver_data & E1000_NO_IOPORT)
> +		bars = pci_select_bars(pdev, IORESOURCE_MEM);
> +	else
> +		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
> +
> +	if ((err = pci_enable_device_bars(pdev, bars)))
>  		return err;
>  
>  	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
> @@ -634,7 +641,8 @@
>  		pci_using_dac = 0;
>  	}
>  
> -	if ((err = pci_request_regions(pdev, e1000_driver_name)))
> +	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
> +	if (err)
>  		return err;
>  
>  	pci_set_master(pdev);
> @@ -654,6 +662,7 @@
>  	adapter->pdev = pdev;
>  	adapter->hw.back = adapter;
>  	adapter->msg_enable = (1 << debug) - 1;
> +	adapter->bars = bars;
>  
>  	mmio_start = pci_resource_start(pdev, BAR_0);
>  	mmio_len = pci_resource_len(pdev, BAR_0);
> @@ -664,12 +673,15 @@
>  		goto err_ioremap;
>  	}
>  
> -	for (i = BAR_1; i <= BAR_5; i++) {
> -		if (pci_resource_len(pdev, i) == 0)
> -			continue;
> -		if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
> -			adapter->hw.io_base = pci_resource_start(pdev, i);
> -			break;
> +	if (!(ent->driver_data & E1000_NO_IOPORT)) {
> +		for (i = BAR_1; i <= BAR_5; i++) {
> +			if (pci_resource_len(pdev, i) == 0)
> +				continue;
> +			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
> +				adapter->hw.io_base =
> +					pci_resource_start(pdev, i);
> +				break;
> +			}
>  		}
>  	}
>  
> @@ -880,7 +892,7 @@
>  err_ioremap:
>  	free_netdev(netdev);
>  err_alloc_etherdev:
> -	pci_release_regions(pdev);
> +	pci_release_selected_regions(pdev, bars);
>  	return err;
>  }
>  
> @@ -935,7 +947,7 @@
>  #endif
>  
>  	iounmap(adapter->hw.hw_addr);
> -	pci_release_regions(pdev);
> +	pci_release_selected_regions(pdev, adapter->bars);
>  
>  	free_netdev(netdev);
>  
> @@ -4577,7 +4589,7 @@
>  	if (retval)
>  		DPRINTK(PROBE, ERR, "Error in setting power state\n");
>  	e1000_pci_restore_state(adapter);
> -	ret_val = pci_enable_device(pdev);
> +	ret_val = pci_enable_device_bars(pdev, adapter->bars);
>  	pci_set_master(pdev);
>  
>  	retval = pci_enable_wake(pdev, PCI_D3hot, 0);
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


^ permalink raw reply

* Re: [PATCH 1/2] e1000: fix netpoll with NAPI
From: Matt Mackall @ 2006-06-06 23:17 UTC (permalink / raw)
  To: Jeff Moyer
  Cc: Auke Kok, Garzik, Jeff, Neil Horman, Mitch Williams, netdev,
	Brandeburg, Jesse, Kok, Auke
In-Reply-To: <x49zmgquqn0.fsf@segfault.boston.redhat.com>

On Tue, Jun 06, 2006 at 01:42:59PM -0400, Jeff Moyer wrote:
> ==> Regarding Re: [PATCH 1/2] e1000: fix netpoll with NAPI; Auke Kok <auke-jan.h.kok@intel.com> adds:
> 
> auke-jan.h.kok> Jeff Moyer wrote:
> >> ==> Regarding Re: [PATCH 1/2] e1000: fix netpoll with NAPI; Auke Kok <auke-jan.h.kok@intel.com> adds:
> auke-jan.h.kok> Neil Horman wrote:
> >>>> On Tue, Jun 06, 2006 at 09:39:25AM -0700, Mitch Williams wrote:
> >>>>> On Tue, 2006-06-06 at 09:52 -0400, Neil Horman wrote:
> auke-jan.h.kok> [snip]
> >> 
> >>>>> However, just for the sake of correctness (and paranoia), I'll whip up
> >>>>> another patch that does this check.
> >>>>> 
> >>>> Thanks for the quick feedback!
> >>>> Regards
> >>>> Neil
> >>>> 
> >>>>> Jeff, please do not commit this patch.
> auke-jan.h.kok> Jeff,
> auke-jan.h.kok> I've popped the patch off from our gitserver, so you can
> >> pull the two
> auke-jan.h.kok> outstanding patches while we revamp this one.
> >> Would you please send patches to this list?  I'd certainly like to review
> >> them.  I don't think the problem needs solving in the e1000 driver.  I
> >> think it is an issue that should be handled properly by netpoll.
> 
> auke-jan.h.kok> ???
> 
> auke-jan.h.kok> that message was directed to Jeff Garzik, perhaps that was too confusing.
> 
> I figured it was directed at Jeff G.
> 
> auke-jan.h.kok> They were sent here in the first place:
> 
> auke-jan.h.kok> http://marc.theaimsgroup.com/?l=linux-netdev&m=114954878711789&w=2
> 
> Thanks for the pointer.
> 
> As you noted, e1000 now uses a separate device for polling.  Netpoll should
> be able to deal with this, though.  I'd like to solicit mpm's input on
> this, as I'm having difficulties coming up with a clean solution.

It's a bit ad-hoc at the moment, but it might be a step towards a
cleaner model. 

> For some background, the netpoll_poll_lock calls were introduced to prevent
> recursion in a device driver's ->poll routine.  By essentially calling the
> poll routine from the poll_controller routine, you are no longer prevented
> from such recursion.
> 
> It would be best if the poll_controller routine was kept simple.  It should
> do the equivalent of the interrupt processing portion of the work, and
> leave the delivery to the network stack for a call to the ->poll routine.
> 
> Solving this at the netpoll layer will be a bit difficult, since we have no
> insight into the driver design (as your driver illustrates).  Up until now,
> our model worked well.

That's probably an overstatement.
 
> We could, potentially, walk the list of devices scheduled for a poll much
> the same as net_rx_action does.  However, we don't want to process work
> pending on other network adapters, only the one associated with the netpoll
> net device.  I can think of at least one way to make this distinction, but
> it feels too much like a hack.

Processing work on other devices may not be completely wrong. 
 
> Matt, any ideas on this?

Not at the moment.

-- 
Mathematics is the supreme nostalgia of our time.

^ permalink raw reply

* Re: [PATCH] TCP changes for 2.6.18
From: Stephen Hemminger @ 2006-06-06 20:13 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20060606.122924.99202474.davem@davemloft.net>

On Tue, 06 Jun 2006 12:29:24 -0700 (PDT)
David Miller <davem@davemloft.net> wrote:

> From: Stephen Hemminger <shemminger@osdl.org>
> Date: Tue, 6 Jun 2006 09:46:55 -0700
> 
> > On Mon, 05 Jun 2006 16:58:59 -0700 (PDT)
> > David Miller <davem@davemloft.net> wrote:
> > 
> > > BTW, it seems we now have at least 3 instances "VEGAS + stuff"
> > > and thus the core vegas logic is duplicated that many times.
> > > Would be nice to have some core vegas infrastructure in the
> > > generic congestion avoidance layer at some point.
> > 
> > Agreed, and the vegas stuff needs some work as well. It should
> > have more smoothing like Westwood+
> 
> And that Westwood+ "smoothing" is the same sample smoothing algorithm
> used in other parts of the generic TCP input processing, for example
> in functions such as tcp_rtt_estimator() :-)

We could even support different (or smarter) smoothing functions???
The vegas stuff needs to be smarter that's for sure. Time to go catch up
on my reading.

^ permalink raw reply

* Re: [PATCH] TCP changes for 2.6.18
From: David Miller @ 2006-06-06 19:29 UTC (permalink / raw)
  To: shemminger; +Cc: netdev
In-Reply-To: <20060606094655.6fd3711f@localhost.localdomain>

From: Stephen Hemminger <shemminger@osdl.org>
Date: Tue, 6 Jun 2006 09:46:55 -0700

> On Mon, 05 Jun 2006 16:58:59 -0700 (PDT)
> David Miller <davem@davemloft.net> wrote:
> 
> > BTW, it seems we now have at least 3 instances "VEGAS + stuff"
> > and thus the core vegas logic is duplicated that many times.
> > Would be nice to have some core vegas infrastructure in the
> > generic congestion avoidance layer at some point.
> 
> Agreed, and the vegas stuff needs some work as well. It should
> have more smoothing like Westwood+

And that Westwood+ "smoothing" is the same sample smoothing algorithm
used in other parts of the generic TCP input processing, for example
in functions such as tcp_rtt_estimator() :-)

^ permalink raw reply

* Problem authenticating using WPA with bcm43xx-softmac
From: Larry Finger @ 2006-06-06 19:24 UTC (permalink / raw)
  To: netdev

Since my Linksys WRT54G V1 died and was replaced with a V5 (Yes, I know it was a mistake.), I have 
been unable to authenticate using WPA-PSK TKIP with bcm43xx-softmac. I'm sure that my wpa_supplicant 
setup is OK as it has not been changed since the AP was changed, and the system works if I use 
ndiswrapper with the Windows driver.

The logged messages are:

Jun  6 13:34:08 larrylap kernel: bcm43xx: set security called
Jun  6 13:34:08 larrylap kernel: bcm43xx:    .level = 0
Jun  6 13:34:08 larrylap kernel: bcm43xx:    .enabled = 0
Jun  6 13:34:08 larrylap kernel: bcm43xx:    .encrypt = 0
Jun  6 13:34:09 larrylap kernel: SoftMAC: Start scanning with channel: 1
Jun  6 13:34:09 larrylap kernel: SoftMAC: Scanning 11 channels
Jun  6 13:34:09 larrylap kernel: SoftMAC: Scanning finished
Jun  6 13:34:09 larrylap kernel: SoftMAC: Associate: Scanning for networks first.
Jun  6 13:34:09 larrylap kernel: SoftMAC: Start scanning with channel: 1
Jun  6 13:34:09 larrylap kernel: SoftMAC: Scanning 11 channels
Jun  6 13:34:09 larrylap kernel: SoftMAC: Scanning finished
Jun  6 13:34:09 larrylap kernel: SoftMAC: Associate: Scanning for networks first.
Jun  6 13:34:09 larrylap kernel: SoftMAC: Start scanning with channel: 1
Jun  6 13:34:09 larrylap kernel: SoftMAC: Scanning 11 channels
Jun  6 13:34:09 larrylap kernel: SoftMAC: Associate: Scanning for networks first.
Jun  6 13:34:09 larrylap kernel: SoftMAC: Start scanning with channel: 1
Jun  6 13:34:09 larrylap kernel: SoftMAC: Scanning 11 channels
Jun  6 13:34:09 larrylap kernel: SoftMAC: Queueing Authentication Request to 00:14:bf:85:49:fa
Jun  6 13:34:09 larrylap kernel: SoftMAC: cannot associate without being authenticated, requested 
authentication
Jun  6 13:34:09 larrylap kernel: SoftMAC: Sent Authentication Request to 00:14:bf:85:49:fa.
Jun  6 13:34:10 larrylap kernel: SoftMAC: Open Authentication completed with 00:14:bf:85:49:fa
Jun  6 13:34:10 larrylap kernel: SoftMAC: sent association request!
Jun  6 13:34:10 larrylap kernel: SoftMAC: Scanning finished
Jun  6 13:34:10 larrylap kernel: SoftMAC: sent association request!
Jun  6 13:34:10 larrylap kernel: SoftMAC: generic IE set to 
ffffffdd160050fffffff20101000050fffffff20201000050fffffff20201000050fffffff202
Jun  6 13:34:10 larrylap kernel: SoftMAC: associating failed due to invalid pairwise cipher
Jun  6 13:34:10 larrylap kernel: SoftMAC: sent association request!
Jun  6 13:34:10 larrylap kernel: SoftMAC: associating failed due to invalid pairwise cipher

The debug output from wpa_supplicant is as follows:

larrylap:~ # wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -Dwext -ddd
Initializing interface 'wlan0' conf '/etc/wpa_supplicant.conf' driver 'wext' ctrl_interface 'N/A'
Configuration file '/etc/wpa_supplicant.conf' -> '/etc/wpa_supplicant.conf'
Reading configuration file '/etc/wpa_supplicant.conf'
ctrl_interface='/var/run/wpa_supplicant'
Line: 3 - start of a new network block
ssid - hexdump_ascii(len=6):
      6c 77 66 64 6a 66                                 lwfdjf
scan_ssid=1 (0x1)
key_mgmt: 0x2
proto: 0x1
pairwise: 0x18
group: 0x18
PSK (ASCII passphrase) - hexdump_ascii(len=27): [REMOVED]
priority=3 (0x3)
PSK (from passphrase) - hexdump(len=32): [REMOVED]
Priority group 3
    id=0 ssid='lwfdjf'
Initializing interface (2) 'wlan0'
EAPOL: SUPP_PAE entering state DISCONNECTED
EAPOL: KEY_RX entering state NO_KEY_RECEIVE
EAPOL: SUPP_BE entering state INITIALIZE
EAP: EAP entering state DISABLED
EAPOL: External notification - portEnabled=0
EAPOL: External notification - portValid=0
SIOCGIWRANGE: WE(compiled)=20 WE(source)=18 enc_capa=0xf
   capabilities: key_mgmt 0xf enc 0xf
Own MAC address: 00:06:25:40:6f:03
wpa_driver_wext_set_wpa
WEXT auth param 7 value 0x1 -
wpa_driver_wext_set_key: alg=0 key_idx=0 set_tx=0 seq_len=0 key_len=0
wpa_driver_wext_set_key: alg=0 key_idx=1 set_tx=0 seq_len=0 key_len=0
wpa_driver_wext_set_key: alg=0 key_idx=2 set_tx=0 seq_len=0 key_len=0
wpa_driver_wext_set_key: alg=0 key_idx=3 set_tx=0 seq_len=0 key_len=0
wpa_driver_wext_set_countermeasures
WEXT auth param 4 value 0x0 -
wpa_driver_wext_set_drop_unencrypted
WEXT auth param 5 value 0x1 -
Setting scan request: 0 sec 100000 usec
Added interface wlan0
Wireless event: cmd=0x8b06 len=8
State: DISCONNECTED -> SCANNING
Starting AP scan (specific SSID)
Scan SSID - hexdump_ascii(len=6):
      6c 77 66 64 6a 66                                 lwfdjf
Wireless event: cmd=0x8b19 len=8
Received 395 bytes of scan results (2 BSSes)
Scan results: 2
Selecting BSS from priority group 3
0: 00:14:bf:85:49:fa ssid='lwfdjf' wpa_ie_len=26 rsn_ie_len=0 caps=0x11
    selected based on WPA IE
Trying to associate with 00:14:bf:85:49:fa (SSID='lwfdjf' freq=0 MHz)
Cancelling scan request
WPA: clearing own WPA/RSN IE
Automatic auth_alg selection: 0x1
WEXT auth param 6 value 0x1 -
WPA: using IEEE 802.11i/D3.0
WPA: Selected cipher suites: group 8 pairwise 8 key_mgmt 2
WPA: set AP WPA IE - hexdump(len=26): dd 18 00 50 f2 01 01 00 00 50 f2 02 01 00 00 50 f2 02 01 00 00 
50 f2 02 00 00
WPA: clearing AP RSN IE
WPA: using GTK TKIP
WPA: using PTK TKIP
WPA: using KEY_MGMT WPA-PSK
WPA: Set own WPA IE default - hexdump(len=24): dd 16 00 50 f2 01 01 00 00 50 f2 02 01 00 00 50 f2 02 
01 00 00 50 f2 02
No keys have been configured - skip key clearing
wpa_driver_wext_set_drop_unencrypted
WEXT auth param 5 value 0x1 -
State: SCANNING -> ASSOCIATING
wpa_driver_wext_associate
wpa_driver_wext_set_gen_ie
WEXT auth param 0 value 0x2 -
WEXT auth param 1 value 0x4 -
WEXT auth param 2 value 0x4 -
WEXT auth param 3 value 0x2 -
WEXT auth param 10 value 0x1 -
WEXT auth param 8 value 0x0 -
Setting authentication timeout: 10 sec 0 usec
EAPOL: External notification - EAP success=0
EAPOL: External notification - EAP fail=0
EAPOL: External notification - portControl=Auto
Wireless event: cmd=0x8b06 len=8
Wireless event: cmd=0x8b1a len=15
Authentication with 00:00:00:00:00:00 timed out.
Added BSSID 00:00:00:00:00:00 into blacklist
State: ASSOCIATING -> DISCONNECTED
No keys have been configured - skip key clearing
EAPOL: External notification - portEnabled=0
EAPOL: External notification - portValid=0
Setting scan request: 0 sec 0 usec
State: DISCONNECTED -> SCANNING
Starting AP scan (broadcast SSID)
Wireless event: cmd=0x8b19 len=8
Received 395 bytes of scan results (2 BSSes)
Scan results: 2
Selecting BSS from priority group 3
0: 00:14:bf:85:49:fa ssid='lwfdjf' wpa_ie_len=26 rsn_ie_len=0 caps=0x11
    selected based on WPA IE
Trying to associate with 00:14:bf:85:49:fa (SSID='lwfdjf' freq=0 MHz)
Cancelling scan request
WPA: clearing own WPA/RSN IE
Automatic auth_alg selection: 0x1
WEXT auth param 6 value 0x1 -
WPA: using IEEE 802.11i/D3.0
WPA: Selected cipher suites: group 8 pairwise 8 key_mgmt 2
WPA: set AP WPA IE - hexdump(len=26): dd 18 00 50 f2 01 01 00 00 50 f2 02 01 00 00 50 f2 02 01 00 00 
50 f2 02 00 00
WPA: clearing AP RSN IE
WPA: using GTK TKIP
WPA: using PTK TKIP
WPA: using KEY_MGMT WPA-PSK
WPA: Set own WPA IE default - hexdump(len=24): dd 16 00 50 f2 01 01 00 00 50 f2 02 01 00 00 50 f2 02 
01 00 00 50 f2 02
No keys have been configured - skip key clearing
wpa_driver_wext_set_drop_unencrypted
WEXT auth param 5 value 0x1 -
State: SCANNING -> ASSOCIATING
wpa_driver_wext_associate
wpa_driver_wext_set_gen_ie
WEXT auth param 0 value 0x2 -
WEXT auth param 1 value 0x4 -
WEXT auth param 2 value 0x4 -
WEXT auth param 3 value 0x2 -
WEXT auth param 10 value 0x1 -
WEXT auth param 8 value 0x0 -
Setting authentication timeout: 10 sec 0 usec
EAPOL: External notification - EAP success=0
EAPOL: External notification - EAP fail=0
EAPOL: External notification - portControl=Auto
Wireless event: cmd=0x8b06 len=8
Wireless event: cmd=0x8b1a len=15
Authentication with 00:00:00:00:00:00 timed out.
BSSID 00:00:00:00:00:00 blacklist count incremented to 2
State: ASSOCIATING -> DISCONNECTED
No keys have been configured - skip key clearing
EAPOL: External notification - portEnabled=0
EAPOL: External notification - portValid=0
Setting scan request: 0 sec 0 usec
State: DISCONNECTED -> SCANNING

---repeats forever----

Why does SoftMAC set a generic IE rather than get one from wpa_supplicant? I would appreciate help 
with this problem.

Larry

^ permalink raw reply

* Re: NETDEV WATCHDOG: eth2: transmit timed out with 3c905C-TX
From: Steffen Klassert @ 2006-06-06 19:13 UTC (permalink / raw)
  To: Marco Berizzi; +Cc: netdev
In-Reply-To: <BAY103-F31CD06F5FF6568FC37AFEAB2950@phx.gbl>

On Tue, Jun 06, 2006 at 11:12:45AM +0200, Marco Berizzi wrote:
> 
> I have moved this damn pc from the remote to my site and I have
> placed it in production environment with 2.6.17-rc5
> No problem after 24 hours (on the remote side the problem was
> arising after a couple of hours). I have modprobed 3c59x with
> debug=4. I see only these kind of messages (are they fine?):
> 
> Jun  5 14:31:25 Pleiadi kernel: eth2: vortex_error(), status=0x8081
> Jun  5 14:31:40 Pleiadi last message repeated 3 times
> Jun  5 14:31:47 Pleiadi kernel: eth2: vortex_error(), status=0x8281
> Jun  5 14:31:47 Pleiadi kernel: eth2: Media selection timer tick happened, 
> Autonegotiate.
> Jun  5 14:31:47 Pleiadi kernel: dev->watchdog_timeo=1250
> Jun  5 14:31:47 Pleiadi kernel: eth2: MII transceiver has status 782d.
> Jun  5 14:31:47 Pleiadi kernel: eth2: Media selection timer finished, 
> Autonegotiate.
> Jun  5 14:31:51 Pleiadi kernel: eth2: vortex_error(), status=0x8081
> Jun  5 14:32:03 Pleiadi last message repeated 2 times
> Jun  5 14:32:10 Pleiadi kernel: eth2: vortex_error(), status=0x8481
> Jun  5 14:32:15 Pleiadi kernel: eth2: vortex_error(), status=0x8081
> Jun  5 14:32:46 Pleiadi last message repeated 7 times

This is ok, just normal operation of the NIC.

> 
> The only relevant change, between the remote and my site, is a
> different ethernet switch where the 3c905C is connected to.
> Could it be an issue?

Well, I think it can. Problems with a switch are mostly related
to the autonegotiation of the media type and full/half-duplex. 
But in your case the autonegotiation seems to be ok 
(mii-tool/ethtool output). More specific information you can
get with the mii-diag and vortex-diag tools. You can find    
these tools at http://www.scyld.com/ethercard_diag.html

There are problems with a cisco switch documented in
Documentation/networking/vortex.txt for example.

Steffen

^ permalink raw reply

* TCP Westwood+ patches
From: Stephen Hemminger @ 2006-06-06 18:53 UTC (permalink / raw)
  To: Luca De Cicco, David S. Miller; +Cc: netdev, Saverio Mascolo
In-Reply-To: <20060606184152.6d97a193@localhost>

I cleaned these up and put them in a git tree. Luco if you want to be the
maintainer of this, then the correct way is to send a patch to the MAINTAINER
file.
-------

The following changes since commit bd6673d239e7041bc3f81f8d6d0242b7bf6dd62f:
  Andreas Schwab:
        [CONNECTOR]: Fix warning in cn_queue.c

are found in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/tcp-2.6.18.git#tcp

Luca De Cicco:
      TCP Westwood: comment fixes
      TCP Westwood: bandwidth filter startup
      TCP Westwood: reset RTT min after FRTO

Stephen Hemminger:
      TCP Westwood: fix first sample

 net/ipv4/tcp_westwood.c |   62 ++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/net/ipv4/tcp_westwood.c b/net/ipv4/tcp_westwood.c
index 62a96b7..4247da1 100644
--- a/net/ipv4/tcp_westwood.c
+++ b/net/ipv4/tcp_westwood.c
@@ -1,7 +1,24 @@
 /*
- * TCP Westwood+
+ * TCP Westwood+: end-to-end bandwidth estimation for TCP
  *
- *	Angelo Dell'Aera:	TCP Westwood+ support
+ *      Angelo Dell'Aera: author of the first version of TCP Westwood+ in Linux 2.4
+ *
+ * Support at http://c3lab.poliba.it/index.php/Westwood
+ * Main references in literature:
+ *
+ * - Mascolo S, Casetti, M. Gerla et al.
+ *   "TCP Westwood: bandwidth estimation for TCP" Proc. ACM Mobicom 2001
+ *
+ * - A. Grieco, s. Mascolo
+ *   "Performance evaluation of New Reno, Vegas, Westwood+ TCP" ACM Computer
+ *     Comm. Review, 2004
+ *
+ * - A. Dell'Aera, L. Grieco, S. Mascolo.
+ *   "Linux 2.4 Implementation of Westwood+ TCP with Rate-Halving :
+ *    A Performance Evaluation Over the Internet" (ICC 2004), Paris, June 2004
+ *
+ * Westwood+ employs end-to-end bandwidth measurement to set cwnd and
+ * ssthresh after packet loss. The probing phase is as the original Reno.
  */
 
 #include <linux/config.h>
@@ -23,6 +40,7 @@ struct westwood {
 	u32    rtt;
 	u32    rtt_min;          /* minimum observed RTT */
 	u8     first_ack;        /* flag which infers that this is the first ack */
+	u8     reset_rtt_min;    /* Reset RTT min to next RTT sample*/
 };
 
 
@@ -50,6 +68,7 @@ static void tcp_westwood_init(struct soc
         w->bw_est = 0;
         w->accounted = 0;
         w->cumul_ack = 0;
+	w->reset_rtt_min = 1;
 	w->rtt_min = w->rtt = TCP_WESTWOOD_INIT_RTT;
 	w->rtt_win_sx = tcp_time_stamp;
 	w->snd_una = tcp_sk(sk)->snd_una;
@@ -65,10 +84,16 @@ static inline u32 westwood_do_filter(u32
 	return (((7 * a) + b) >> 3);
 }
 
-static inline void westwood_filter(struct westwood *w, u32 delta)
+static void westwood_filter(struct westwood *w, u32 delta)
 {
-	w->bw_ns_est = westwood_do_filter(w->bw_ns_est, w->bk / delta);
-	w->bw_est = westwood_do_filter(w->bw_est, w->bw_ns_est);
+	/* If the filter is empty fill it with the first sample of bandwidth  */
+	if (w->bw_ns_est == 0 && w->bw_est == 0) {
+		w->bw_ns_est = w->bk / delta;
+		w->bw_est = w->bw_ns_est;
+	} else {
+		w->bw_ns_est = westwood_do_filter(w->bw_ns_est, w->bk / delta);
+		w->bw_est = westwood_do_filter(w->bw_est, w->bw_ns_est);
+	}
 }
 
 /*
@@ -93,7 +118,7 @@ static void westwood_update_window(struc
 	struct westwood *w = inet_csk_ca(sk);
 	s32 delta = tcp_time_stamp - w->rtt_win_sx;
 
-	/* Initialise w->snd_una with the first acked sequence number in order
+	/* Initialize w->snd_una with the first acked sequence number in order
 	 * to fix mismatch between tp->snd_una and w->snd_una for the first
 	 * bandwidth sample
 	 */
@@ -119,6 +144,16 @@ static void westwood_update_window(struc
 	}
 }
 
+static inline void update_rtt_min(struct westwood *w)
+{
+	if (w->reset_rtt_min) {
+		w->rtt_min = w->rtt;
+		w->reset_rtt_min = 0;	
+	} else
+		w->rtt_min = min(w->rtt, w->rtt_min);
+}
+
+
 /*
  * @westwood_fast_bw
  * It is called when we are in fast path. In particular it is called when
@@ -134,7 +169,7 @@ static inline void westwood_fast_bw(stru
 
 	w->bk += tp->snd_una - w->snd_una;
 	w->snd_una = tp->snd_una;
-	w->rtt_min = min(w->rtt, w->rtt_min);
+	update_rtt_min(w);
 }
 
 /*
@@ -191,7 +226,7 @@ static void tcp_westwood_event(struct so
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct westwood *w = inet_csk_ca(sk);
-	
+
 	switch(event) {
 	case CA_EVENT_FAST_ACK:
 		westwood_fast_bw(sk);
@@ -203,12 +238,14 @@ static void tcp_westwood_event(struct so
 
 	case CA_EVENT_FRTO:
 		tp->snd_ssthresh = tcp_westwood_bw_rttmin(sk);
+ 		/* Update RTT_min when next ack arrives */
+		w->reset_rtt_min = 1;
 		break;
 
 	case CA_EVENT_SLOW_ACK:
 		westwood_update_window(sk);
 		w->bk += westwood_acked_count(sk);
-		w->rtt_min = min(w->rtt, w->rtt_min);
+		update_rtt_min(w);
 		break;
 
 	default:

^ permalink raw reply related

* [ PATCH 2.6.17-rc6 1/1]  udp.c:  counting InDatagrams which are never delivered
From: Gerrit Renker @ 2006-06-06 18:25 UTC (permalink / raw)
  To: netdev; +Cc: kaber, jmorris

This problem involves MIB counter inaccuracies triggered by 
failed UDP checksums.

Problem: ip_local_deliver_finish calls udp_rcv, which calls
         udp_queue_rcv_skb. 
         Unless the sk_filter is set, the checksum of the incoming
         UDP datagram is not verified. If there are no other problems
         InDatagrams (UDP_MIB_INDATAGRAMS) is then incremented.
         Now, if udp_recvmsg is called as a handler for incoming
         UDP datagrams, the checksum is verified for the first time
         (unless sk_filter was set) and if the checksum fails, the
         `goto csum_copy_err' leads to forcibly removing the datagram
         _and_ incrementing InErrors (UDP_MIB_INERRORS). 

Issue:   When problem occurs in the manner described, the datagram
         is counted twice: once as InDatagram and once as InErrors.
         RFC 2013 defines InDatagrams as counter for delivered datagrams;
         these datagrams are counted but never delivered.

How to reproduce: Send UDP datagrams with checksums enabled, use middlebox
         which corrupts part of the traffic (e.g. bit errors / NetEm) and
         use /proc/net/snmp to watch the counters. The sum of InErrors,
         NoPorts and InDatagrams exceeds the real number of sent datagrams 
         by the number of datagrams which were counted twice and forcibly
         removed by udp_recvmsg.
Non-occurrence: The problem does not occur if the sender disabled 
         UDP checksums (zero field; allowed for IPv4, but not for IPv6), 
         since then the checksum code returns success.

Fix:   Move the `UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS)' statement from 
       udp_queue_rcv_skb to udp_recvmsg. Now InDatagrams only counts those
       datagrams which were really delivered (as per RFC 2013). 

Please CC: any correspondence to gerrit@erg.abdn.ac.uk  

Signed-off-by: <gerrit@erg.abdn.ac.uk>

---

diff -Nurp  a/net/ipv4/udp.c b/net/ipv4/udp.c
--- a/net/ipv4/udp.c	2006-06-06 17:01:26.000000000 +0100
+++ b/net/ipv4/udp.c	2006-06-06 23:39:45.000000000 +0100
@@ -823,6 +823,7 @@ try_again:
 		goto out_free;
 
 	sock_recv_timestamp(msg, sk, skb);
+	UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS);
 
 	/* Copy the address. */
 	if (sin)
@@ -1032,7 +1033,6 @@ static int udp_queue_rcv_skb(struct sock
 		kfree_skb(skb);
 		return -1;
 	}
-	UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS);
 	return 0;
 }
 



^ permalink raw reply

* Re: [PATCH 1/2] e1000: fix netpoll with NAPI
From: Jeff Moyer @ 2006-06-06 17:42 UTC (permalink / raw)
  To: Auke Kok
  Cc: Garzik, Jeff, Neil Horman, Mitch Williams, netdev,
	Brandeburg, Jesse, Kok, Auke, mpm
In-Reply-To: <4485BCA2.5070904@intel.com>

==> Regarding Re: [PATCH 1/2] e1000: fix netpoll with NAPI; Auke Kok <auke-jan.h.kok@intel.com> adds:

auke-jan.h.kok> Jeff Moyer wrote:
>> ==> Regarding Re: [PATCH 1/2] e1000: fix netpoll with NAPI; Auke Kok <auke-jan.h.kok@intel.com> adds:
auke-jan.h.kok> Neil Horman wrote:
>>>> On Tue, Jun 06, 2006 at 09:39:25AM -0700, Mitch Williams wrote:
>>>>> On Tue, 2006-06-06 at 09:52 -0400, Neil Horman wrote:
auke-jan.h.kok> [snip]
>> 
>>>>> However, just for the sake of correctness (and paranoia), I'll whip up
>>>>> another patch that does this check.
>>>>> 
>>>> Thanks for the quick feedback!
>>>> Regards
>>>> Neil
>>>> 
>>>>> Jeff, please do not commit this patch.
auke-jan.h.kok> Jeff,
auke-jan.h.kok> I've popped the patch off from our gitserver, so you can
>> pull the two
auke-jan.h.kok> outstanding patches while we revamp this one.
>> Would you please send patches to this list?  I'd certainly like to review
>> them.  I don't think the problem needs solving in the e1000 driver.  I
>> think it is an issue that should be handled properly by netpoll.

auke-jan.h.kok> ???

auke-jan.h.kok> that message was directed to Jeff Garzik, perhaps that was too confusing.

I figured it was directed at Jeff G.

auke-jan.h.kok> They were sent here in the first place:

auke-jan.h.kok> http://marc.theaimsgroup.com/?l=linux-netdev&m=114954878711789&w=2

Thanks for the pointer.

As you noted, e1000 now uses a separate device for polling.  Netpoll should
be able to deal with this, though.  I'd like to solicit mpm's input on
this, as I'm having difficulties coming up with a clean solution.

For some background, the netpoll_poll_lock calls were introduced to prevent
recursion in a device driver's ->poll routine.  By essentially calling the
poll routine from the poll_controller routine, you are no longer prevented
from such recursion.

It would be best if the poll_controller routine was kept simple.  It should
do the equivalent of the interrupt processing portion of the work, and
leave the delivery to the network stack for a call to the ->poll routine.

Solving this at the netpoll layer will be a bit difficult, since we have no
insight into the driver design (as your driver illustrates).  Up until now,
our model worked well.

We could, potentially, walk the list of devices scheduled for a poll much
the same as net_rx_action does.  However, we don't want to process work
pending on other network adapters, only the one associated with the netpoll
net device.  I can think of at least one way to make this distinction, but
it feels too much like a hack.

Matt, any ideas on this?

-Jeff

^ permalink raw reply

* Re: [PATCH 1/2] e1000: fix netpoll with NAPI
From: Auke Kok @ 2006-06-06 17:34 UTC (permalink / raw)
  To: Jeff Moyer
  Cc: Garzik, Jeff, Neil Horman, Mitch Williams, netdev,
	Brandeburg, Jesse, Kok, Auke, mpm
In-Reply-To: <x494pyyw5sr.fsf@segfault.boston.redhat.com>

Jeff Moyer wrote:
> ==> Regarding Re: [PATCH 1/2] e1000: fix netpoll with NAPI; Auke Kok <auke-jan.h.kok@intel.com> adds:
> 
> auke-jan.h.kok> Neil Horman wrote:
>>> On Tue, Jun 06, 2006 at 09:39:25AM -0700, Mitch Williams wrote:
>>>> On Tue, 2006-06-06 at 09:52 -0400, Neil Horman wrote:
> 
> 
> auke-jan.h.kok> [snip]
> 
> 
>>>> However, just for the sake of correctness (and paranoia), I'll whip up
>>>> another patch that does this check.
>>>>
>>> Thanks for the quick feedback!
>>> Regards
>>> Neil
>>>
>>>> Jeff, please do not commit this patch.
> 
> auke-jan.h.kok> Jeff,
> 
> auke-jan.h.kok> I've popped the patch off from our gitserver, so you can pull the two
> auke-jan.h.kok> outstanding patches while we revamp this one.
> 
> Would you please send patches to this list?  I'd certainly like to review
> them.  I don't think the problem needs solving in the e1000 driver.  I
> think it is an issue that should be handled properly by netpoll.

???

that message was directed to Jeff Garzik, perhaps that was too confusing.


They were sent here in the first place:

http://marc.theaimsgroup.com/?l=linux-netdev&m=114954878711789&w=2


Cheers,

Auke


^ permalink raw reply

* Re: [PATCH 1/2] e1000: fix netpoll with NAPI
From: Jeff Moyer @ 2006-06-06 17:30 UTC (permalink / raw)
  To: Auke Kok
  Cc: Garzik, Jeff, Neil Horman, Mitch Williams, netdev,
	Brandeburg, Jesse, Kok, Auke, mpm
In-Reply-To: <4485B8EC.4090603@intel.com>

==> Regarding Re: [PATCH 1/2] e1000: fix netpoll with NAPI; Auke Kok <auke-jan.h.kok@intel.com> adds:

auke-jan.h.kok> Neil Horman wrote:
>> On Tue, Jun 06, 2006 at 09:39:25AM -0700, Mitch Williams wrote:
>>> On Tue, 2006-06-06 at 09:52 -0400, Neil Horman wrote:


auke-jan.h.kok> [snip]


>>> However, just for the sake of correctness (and paranoia), I'll whip up
>>> another patch that does this check.
>>> 
>> Thanks for the quick feedback!
>> Regards
>> Neil
>> 
>>> Jeff, please do not commit this patch.

auke-jan.h.kok> Jeff,

auke-jan.h.kok> I've popped the patch off from our gitserver, so you can pull the two
auke-jan.h.kok> outstanding patches while we revamp this one.

Would you please send patches to this list?  I'd certainly like to review
them.  I don't think the problem needs solving in the e1000 driver.  I
think it is an issue that should be handled properly by netpoll.

-Jeff

^ permalink raw reply

* Re: [PATCH 1/2] e1000: fix netpoll with NAPI
From: Jeff Moyer @ 2006-06-06 17:29 UTC (permalink / raw)
  To: Mitch Williams
  Cc: Neil Horman, Kok, Auke, Garzik, Jeff, netdev, Brandeburg, Jesse,
	Kok, Auke, mpm
In-Reply-To: <1149611965.13635.19.camel@strongmad>

==> Regarding Re: [PATCH 1/2] e1000: fix netpoll with NAPI; Mitch Williams <mitch.a.williams@intel.com> adds:

mitch> On Tue, 2006-06-06 at 09:52 -0400, Neil Horman wrote:
>> I've been speaking about this fix with a Jeff Moyer, and we've come up with some
>> concerns regarding its implementation.  Specifically the call to
adapter-> clean_rx in the case of the e1000 driver is rather a layering
>> violation in the netpoll code, in the sense that the function pointed to by clean_rx
>> is functionality that is nominally used by the dev->poll method.  In fact in
>> this case, it would appear possible since dev->poll is called under the
>> poll_lock, but dev->poll_controller is not, that is is possible to have cpus in
>> a system executing in e1000_clean_rx_irq_[ps] at the same time leading to data
>> corruption:
>> 
>> CPU0:
>> netpoll_poll_dev
dev-> poll_controller (e1000_netpoll)
adapter-> clean_rx (e1000_clean_rx_irq)
>> 
>> CPU1:
>> napi_poll
dev-> poll (e1000_clean)
>> e1000_clean_rx_irq

mitch> Hmmm. You may have a point.  I don't think a spinlock is required, but
mitch> we do need to check if the poll is already scheduled on another CPU,
mitch> like netpoll does in poll_napi().

mitch> In practice, of course, we never see this.  The only netpoll client in
mitch> the kernel is netconsole, which doesn't do receives.  A few Major
mitch> Distros use netdump, which does do receives, but only after the system
mitch> has crashed.  In that case, all other CPUs are stopped anyway.

Don't forget about driver/net/kgdb_eth.c, which is in-tree, and does sends
and receives.

-Jeff

^ permalink raw reply

* Re: [PATCH 1/2] e1000: fix netpoll with NAPI
From: Auke Kok @ 2006-06-06 17:18 UTC (permalink / raw)
  To: Garzik, Jeff
  Cc: Neil Horman, Mitch Williams, netdev, Brandeburg, Jesse, Kok, Auke,
	jmoyer, mpm
In-Reply-To: <20060606170513.GB21969@hmsreliant.homelinux.net>

Neil Horman wrote:
> On Tue, Jun 06, 2006 at 09:39:25AM -0700, Mitch Williams wrote:
>> On Tue, 2006-06-06 at 09:52 -0400, Neil Horman wrote:


[snip]


>> However, just for the sake of correctness (and paranoia), I'll whip up
>> another patch that does this check.
>>
> Thanks for the quick feedback!
> 
> Regards
> Neil
> 
>> Jeff, please do not commit this patch.

Jeff,

I've popped the patch off from our gitserver, so you can pull the two 
outstanding patches while we revamp this one.

Auke


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox