All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver
@ 2006-08-31 14:02 Amit S. Kale
  2006-08-31 14:05 ` [PATCH 2.6.17 1/9] NetXen: Makefile and driver main file Amit S. Kale
                   ` (10 more replies)
  0 siblings, 11 replies; 18+ messages in thread
From: Amit S. Kale @ 2006-08-31 14:02 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, rob, unmproj, shemminger, brazilnut, wendyx, jeff

Hi All,

Thank you Stephen, Don and Wendy.
We have incorporated feedbacks which have received since after last post. 
I'll be resending updated patchset in subsequent emails.

We are working on finding out good way of using tables to manage 
compatibility between firmware version number and driver version number.

Kindly review it and feel free to send feedback.

Thanks,
-Amit

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

  MAINTAINERS                              |    7
  drivers/net/Kconfig                      |    5
  drivers/net/Makefile                     |    1
  drivers/net/netxen/Makefile              |   35
  drivers/net/netxen/netxen_nic.h          |  901 +++++++++++++++++++++++++
  drivers/net/netxen/netxen_nic_ethtool.c  |  696 +++++++++++++++++++
  drivers/net/netxen/netxen_nic_hdr.h      |  611 +++++++++++++++++
  drivers/net/netxen/netxen_nic_hw.c       | 1102 ++++++++++++++++++++++++++++++
  drivers/net/netxen/netxen_nic_hw.h       |  499 +++++++++++++
  drivers/net/netxen/netxen_nic_init.c     | 1089 ++++++++++++++++++++++++++++++
  drivers/net/netxen/netxen_nic_ioctl.h    |   75 ++
  drivers/net/netxen/netxen_nic_isr.c      |  301 ++++++++
  drivers/net/netxen/netxen_nic_main.c     | 1107 +++++++++++++++++++++++++++++++
  drivers/net/netxen/netxen_nic_niu.c      |  779 +++++++++++++++++++++
  drivers/net/netxen/netxen_nic_phan_reg.h |  195 +++++
  15 files changed, 7403 insertions(+)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2.6.17 1/9] NetXen: Makefile and driver main file
  2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
@ 2006-08-31 14:05 ` Amit S. Kale
  2006-08-31 14:13 ` [PATCH 2.6.17 2/9] NetXen: Hardware access routines Amit S. Kale
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Amit S. Kale @ 2006-08-31 14:05 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, rob, unmproj, shemminger, brazilnut, wendyx, jeff

diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/MAINTAINERS linux-2.6.17/MAINTAINERS
--- linux-2.6.17.orig/MAINTAINERS	2006-08-30 06:51:57.000000000 -0700
+++ linux-2.6.17/MAINTAINERS	2006-08-30 06:56:27.000000000 -0700
@@ -1987,6 +1987,13 @@ L:	netdev@vger.kernel.org
  T:	git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git
  S:	Maintained

+NETXEN (1/10) GbE SUPPORT
+P:	Amit S. Kale
+M:	amitkale@netxen.com
+L:	netdev@vger.kernel.org
+W:	http://www.netxen.com
+S:	Supported
+
  IPVS
  P:	Wensong Zhang
  M:	wensong@linux-vs.org
diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/Kconfig linux-2.6.17/drivers/net/Kconfig
--- linux-2.6.17.orig/drivers/net/Kconfig	2006-08-30 06:51:55.000000000 -0700
+++ linux-2.6.17/drivers/net/Kconfig	2006-08-30 06:54:30.000000000 -0700
@@ -2311,6 +2311,11 @@ config S2IO_NAPI

  	  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

  source "drivers/net/tokenring/Kconfig"
diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/Makefile linux-2.6.17/drivers/net/Makefile
--- linux-2.6.17.orig/drivers/net/Makefile	2006-08-30 06:51:55.000000000 -0700
+++ linux-2.6.17/drivers/net/Makefile	2006-08-30 06:52:15.000000000 -0700
@@ -213,3 +213,4 @@ obj-$(CONFIG_NETCONSOLE) += netconsole.o

  obj-$(CONFIG_FS_ENET) += fs_enet/

+obj-$(CONFIG_NETXEN_NIC) += netxen/
diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/Makefile linux-2.6.17/drivers/net/netxen/Makefile
--- linux-2.6.17.orig/drivers/net/netxen/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/Makefile	2006-08-31 06:17:22.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 -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/netxen_nic_main.c linux-2.6.17/drivers/net/netxen/netxen_nic_main.c
--- linux-2.6.17.orig/drivers/net/netxen/netxen_nic_main.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/netxen_nic_main.c	2006-08-31 06:17:22.000000000 -0700
@@ -0,0 +1,1107 @@
+/*
+ * 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_hw.h"
+
+#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";
+static char netxen_nic_driver_string[] = "NetXen Network Driver version "
+    NETXEN_NIC_LINUX_VERSIONID "-" NETXEN_NIC_BUILD_NO;
+
+#define NETXEN_NETDEV_WEIGHT 120
+#define NETXEN_ADAPTER_UP_MAGIC 777
+
+/* 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 = {
+	{PCI_DEVICE(0x4040, 0x0001)},
+	{PCI_DEVICE(0x4040, 0x0002)},
+	{PCI_DEVICE(0x4040, 0x0003)},
+	{PCI_DEVICE(0x4040, 0x0004)},
+	{PCI_DEVICE(0x4040, 0x0005)},
+	{0,}
+};
+
+MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
+
+/*
+ * netxen_nic_probe()
+ *
+ * The Linux system will invoke this after identifying the vendor ID and
+ * device Id in the pci_tbl supported by this module.
+ *
+ * A quad port card has one operational PCI config space, (function 0),
+ * which is used to access all four ports.
+ *
+ * This routine 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 __iomem *mem_ptr = NULL;
+	unsigned long mem_base, mem_len;
+	int pci_using_dac, i, err;
+	int ring;
+	struct netxen_recv_context *recv_ctx = NULL;
+	struct netxen_rcv_desc_ctx *rcv_desc = NULL;
+	struct netxen_cmd_buffer *cmd_buf_arr = NULL;
+	u64 mac_addr[FLASH_NUM_PORTS + 1];
+	int valid_mac;
+
+	if ((err = pci_enable_device(pdev)))
+		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;
+	}
+
+/*
+ *      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;
+	}
+
+	adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS;
+	adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS;
+	adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
+
+	pci_set_drvdata(pdev, adapter);
+
+	cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
+	if (cmd_buf_arr == NULL) {
+		err = -ENOMEM;
+		goto err_out_free_adapter;
+	}
+	memset(cmd_buf_arr, 0, TX_RINGSIZE);
+
+	for (i = 0; i < MAX_RCV_CTX; ++i) {
+		recv_ctx = &adapter->recv_ctx[i];
+		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+			switch (RCV_DESC_TYPE(ring)) {
+			case RCV_DESC_NORMAL:
+				rcv_desc->max_rx_desc_count =
+				    adapter->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 =
+				    adapter->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;
+
+			}
+			rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *)
+			    vmalloc(RCV_BUFFSIZE);
+
+			if (rcv_desc->rx_buf_arr == NULL) {
+				err = -ENOMEM;
+				goto err_out_free_rx_buffer;
+			}
+			memset(rcv_desc->rx_buf_arr, 0, RCV_BUFFSIZE);
+		}
+
+	}
+
+	adapter->cmd_buf_arr = cmd_buf_arr;
+	adapter->ahw.pci_base = mem_ptr;
+	spin_lock_init(&adapter->tx_lock);
+	spin_lock_init(&adapter->lock);
+	/* initialize the buffers in adapter */
+	netxen_initialize_adapter_sw(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 before
+	 *  initializing the ports
+	 */
+	netxen_initialize_adapter_hw(adapter);	/* initialize the adapter */
+
+	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.pdev = pdev;
+	adapter->proc_cmd_buf_counter = 0;
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->ahw.revision_id);
+
+#if defined(CONFIG_PCI_MSI)
+	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;
+#endif
+
+	if (netxen_is_flash_supported(adapter) == 0 &&
+	    netxen_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 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;
+		netdev->watchdog_timeo = HZ;
+
+		SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
+		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;
+#ifdef NETIF_F_TSO
+		netdev->features |= NETIF_F_TSO;
+#endif
+
+		if (pci_using_dac)
+			netdev->features |= NETIF_F_HIGHDMA;
+
+		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,
+			  (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);
+			err = -EIO;
+			free_netdev(netdev);
+			goto err_out_free_dev;
+		}
+		adapter->port_count++;
+		adapter->active_ports = 0;
+		adapter->port[i] = port;
+	}
+
+	/*
+	 * Initialize all the CRB registers here.
+	 */
+	/* Window = 1 */
+	writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET));
+	writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET));
+	writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
+
+	netxen_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_NIC_GBE:
+		printk("%s: QUAD GbE board initialized\n",
+		       netxen_nic_driver_name);
+		break;
+
+	case NETXEN_NIC_XGBE:
+		printk("%s: XGbE board initialized\n", netxen_nic_driver_name);
+		break;
+	}
+
+	adapter->driver_mismatch = 0;
+
+	return 0;
+
+      err_out_free_dev:
+	if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
+		pci_disable_msi(pdev);
+	for (i = 0; i < adapter->port_count; i++) {
+		port = adapter->port[i];
+		if ((port) && (port->netdev)) {
+			unregister_netdev(port->netdev);
+			free_netdev(port->netdev);
+		}
+	}
+
+      err_out_free_rx_buffer:
+	for (i = 0; i < MAX_RCV_CTX; ++i) {
+		recv_ctx = &adapter->recv_ctx[i];
+		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+			if (rcv_desc->rx_buf_arr != NULL) {
+				vfree(rcv_desc->rx_buf_arr);
+				rcv_desc->rx_buf_arr = NULL;
+			}
+		}
+	}
+
+	vfree(cmd_buf_arr);
+
+	kfree(adapter->port);
+
+      err_out_free_adapter:
+	pci_set_drvdata(pdev, NULL);
+	kfree(adapter);
+
+      err_out_iounmap:
+	iounmap(mem_ptr);
+      err_out_free_res:
+	pci_release_regions(pdev);
+      err_out_disable_pdev:
+	pci_disable_device(pdev);
+	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;
+	int i;
+	int ctxid, ring;
+
+	adapter = pci_get_drvdata(pdev);
+	if (adapter == NULL)
+		return;
+
+	netxen_nic_stop_all_ports(adapter);
+	/* leave the hw in the same state as reboot */
+	netxen_pinit_from_rom(adapter, 0);
+	udelay(500);
+	netxen_load_firmware(adapter);
+
+	if ((adapter->flags & NETXEN_NIC_MSI_ENABLED))
+		netxen_nic_disable_int(adapter);
+
+	udelay(500);		/* Delay for a while to drain the DMA engines */
+	for (i = 0; i < adapter->port_count; i++) {
+		port = adapter->port[i];
+		if ((port) && (port->netdev)) {
+			unregister_netdev(port->netdev);
+			free_netdev(port->netdev);
+		}
+	}
+
+	if ((adapter->flags & NETXEN_NIC_MSI_ENABLED))
+		pci_disable_msi(pdev);
+	pci_set_drvdata(pdev, NULL);
+	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
+		netxen_free_hw_resources(adapter);
+
+	iounmap((u8 *) adapter->ahw.pci_base);
+
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+
+	for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
+		recv_ctx = &adapter->recv_ctx[ctxid];
+		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);
+			}
+			vfree(rcv_desc->rx_buf_arr);
+		}
+	}
+
+	vfree(adapter->cmd_buf_arr);
+
+	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;
+	struct netxen_rcv_desc_ctx *rcv_desc;
+	int err = 0;
+	int ctx, ring;
+
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
+		err = netxen_init_firmware(adapter);
+		if (err != 0) {
+			printk(KERN_ERR "Failed to init firmware\n");
+			return -EIO;
+		}
+		netxen_nic_flash_print(adapter);
+
+		/* 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);
+			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);
+			netxen_free_hw_resources(adapter);
+			return -EIO;
+		}
+		netxen_nic_init_niu(adapter);
+		for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+			for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+				rcv_desc =
+				    &adapter->recv_ctx[ctx].rcv_desc[ring];
+				netxen_post_rx_buffers(adapter, ctx, ring);
+			}
+		}
+		adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
+	}
+	adapter->active_ports++;
+	if (adapter->active_ports == 1) {
+		err = request_irq(adapter->ahw.pdev->irq, &netxen_intr,
+				  SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name,
+				  adapter);
+		if (err) {
+			printk(KERN_ERR "request_irq failed with: %d\n", err);
+			adapter->active_ports--;
+			return err;
+		}
+		adapter->irq = adapter->ahw.pdev->irq;
+		if (!adapter->driver_mismatch)
+			mod_timer(&adapter->watchdog_timer, jiffies);
+
+		netxen_nic_enable_int(adapter);
+	}
+
+	/* 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);
+	struct netxen_adapter *adapter = port->adapter;
+	int i, j;
+	struct netxen_cmd_buffer *cmd_buff;
+	struct netxen_skb_frag *buffrag;
+
+	netif_carrier_off(netdev);
+	netif_stop_queue(netdev);
+
+	/* disable phy_ints */
+	netxen_nic_disable_phy_interrupts(adapter, (long)port->portnum);
+
+	adapter->active_ports--;
+
+	if (!adapter->active_ports) {
+		netxen_nic_disable_int(adapter);
+		if (adapter->irq)
+			free_irq(adapter->irq, adapter);
+		cmd_buff = adapter->cmd_buf_arr;
+		for (i = 0; i < adapter->max_tx_desc_count; i++) {
+			buffrag = cmd_buff->frag_array;
+			if (buffrag->dma) {
+				pci_unmap_single(port->pdev, buffrag->dma,
+						 buffrag->length,
+						 PCI_DMA_TODEVICE);
+				buffrag->dma = (u64) NULL;
+			}
+			for (j = 0; 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);
+	}
+
+	return 0;
+}
+
+static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct netxen_port *port = netdev_priv(netdev);
+	struct netxen_adapter *adapter = port->adapter;
+	struct netxen_hardware_context *hw = &adapter->ahw;
+	unsigned int first_seg_len = skb->len - skb->data_len;
+	struct netxen_skb_frag *buffrag;
+	unsigned int i;
+
+	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;
+	int frag_count;
+	u32 local_producer = 0;
+	u32 max_tx_desc_count = 0;
+	u32 last_cmd_consumer = 0;
+	int no_of_desc;
+
+	port->stats.xmitcalled++;
+	frag_count = skb_shinfo(skb)->nr_frags + 1;
+
+	if (unlikely(skb->len <= 0)) {
+		dev_kfree_skb_any(skb);
+		port->stats.badskblen++;
+		return NETDEV_TX_OK;
+	}
+
+	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);
+		port->stats.txdropped++;
+		if ((++dropped_packet & 0xff) == 0xff)
+			printk("%s: %s droppped packets = %d\n",
+			       netxen_nic_driver_name, netdev->name,
+			       dropped_packet);
+
+		return NETDEV_TX_OK;
+	}
+
+	/*
+	 * 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 = adapter->cmd_producer;
+	/* There 4 fragments per descriptor */
+	no_of_desc = (frag_count + 3) >> 2;
+#ifdef NETIF_F_TSO
+	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++;
+		}
+	}
+#endif
+	k = adapter->cmd_producer;
+	max_tx_desc_count = adapter->max_tx_desc_count;
+	last_cmd_consumer = adapter->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();
+			netxen_process_cmd_ring((unsigned long)adapter);
+			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,
+				adapter->last_cmd_consumer,
+				port->stats.nocmddescriptor);
+
+			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;
+		}
+	}
+	k = get_index_range(k, max_tx_desc_count, no_of_desc);
+	adapter->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 = &hw->cmd_desc_head[producer];
+	memset(hwdesc, 0, sizeof(struct cmd_desc_type0_t));
+	/* Take skb->data itself */
+	pbuf = &adapter->cmd_buf_arr[producer];
+#ifdef NETIF_F_TSO
+	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;
+	}
+#endif
+	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;
+	CMD_DESC_TOTAL_LENGTH_WRT(hwdesc, skb->len);
+	hwdesc->num_of_buffers = frag_count;
+	hwdesc->opcode = TX_ETHER_PKT;
+
+	CMD_DESC_PORT_WRT(hwdesc, port->portnum);
+	hwdesc->buffer1_length = cpu_to_le16(first_seg_len);
+	hwdesc->addr_buffer1 = cpu_to_le64(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,
+						  adapter->max_tx_desc_count);
+			hwdesc = &hw->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 = cpu_to_le16(temp_len);
+			hwdesc->addr_buffer1 = cpu_to_le64(temp_dma);
+			break;
+		case 1:
+			hwdesc->buffer2_length = cpu_to_le16(temp_len);
+			hwdesc->addr_buffer2 = cpu_to_le64(temp_dma);
+			break;
+		case 2:
+			hwdesc->buffer3_length = cpu_to_le16(temp_len);
+			hwdesc->addr_buffer3 = cpu_to_le64(temp_dma);
+			break;
+		case 3:
+			hwdesc->buffer4_length = temp_len;
+			hwdesc->addr_buffer4 = cpu_to_le64(temp_dma);
+			break;
+		}
+		frag++;
+	}
+	producer = get_next_index(producer, adapter->max_tx_desc_count);
+
+	/* might change opcode to TX_TCP_LSO */
+#ifdef NETIF_F_TSO
+	netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb);
+#endif
+
+	/* For LSO, we need to copy the MAC/IP/TCP headers into
+	 * the descriptor ring
+	 */
+	if (hw->cmd_desc_head[saved_producer].opcode == TX_TCP_LSO) {
+		int hdr_len, first_hdr_len, more_hdr;
+		hdr_len = hw->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->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->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 +=
+	    CMD_DESC_TOTAL_LENGTH(&hw->cmd_desc_head[saved_producer]);
+	/* 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 = adapter->cmd_producer;
+		writel(crb_producer,
+		       NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET));
+		wmb();
+		adapter->total_threads = 0;
+	} else {
+		u32 crb_producer = 0;
+		crb_producer =
+		    readl(NETXEN_CRB_NORMALIZE
+			  (adapter, CRB_CMD_PRODUCER_OFFSET));
+		if (crb_producer == local_producer) {
+			crb_producer = get_index_range(crb_producer,
+						       max_tx_desc_count,
+						       no_of_desc);
+			writel(crb_producer,
+			       NETXEN_CRB_NORMALIZE(adapter,
+						    CRB_CMD_PRODUCER_OFFSET));
+			wmb();
+		}
+	}
+
+	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");
+	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);
+}
+
+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;
+		netxen_nic_disable_int(adapter);
+		/* Window = 0 or 1 */
+		do {
+			writel(0xffffffff, (void __iomem *)
+			       (adapter->ahw.pci_base + ISR_INT_TARGET_STATUS));
+			mask = readl((void __iomem *)
+				     (adapter->ahw.pci_base + ISR_INT_VECTOR));
+		} while (((mask & 0x80) != 0) && (++count < 32));
+		if ((mask & 0x80) != 0)
+			printk("Could not disable interrupt completely\n");
+
+	}
+	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) {
+		netxen_nic_enable_int(adapter);
+	}
+
+	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;
+	int i;
+
+	if (unlikely(!irq)) {
+		return IRQ_NONE;	/* Not our interrupt */
+	}
+
+	adapter = (struct netxen_adapter *)data;
+	for (i = 0; i < adapter->ahw.max_ports; i++) {
+		port = adapter->port[i];
+		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 ctx;
+	int this_work_done;
+
+	DPRINTK(INFO, "polling for %d descriptors\n", *budget);
+	port->stats.polled++;
+
+	adapter->work_done = 0;
+	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+		/*
+		 * 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, ctx,
+							 work_to_do /
+							 MAX_RCV_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;
+
+	netxen_process_cmd_ring((unsigned long)adapter);
+
+	DPRINTK(INFO, "new work_done: %d work_to_do: %d\n",
+		adapter->work_done, work_to_do);
+	if (done) {
+		netif_rx_complete(netdev);
+		netxen_nic_enable_int(adapter);
+	}
+
+	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(adapter->irq);
+	netxen_intr(adapter->irq, adapter, NULL);
+	enable_irq(adapter->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)
+};
+
+/* Driver Registration on NetXen card    */
+
+static int __init netxen_init_module(void)
+{
+	printk(KERN_INFO "%s \n", netxen_nic_driver_string);
+
+	return pci_module_init(&netxen_driver);
+}
+
+module_init(netxen_init_module);
+
+static void __exit netxen_exit_module(void)
+{
+	/*
+	 * 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	[flat|nested] 18+ messages in thread

* [PATCH 2.6.17 2/9] NetXen: Hardware access routines
  2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
  2006-08-31 14:05 ` [PATCH 2.6.17 1/9] NetXen: Makefile and driver main file Amit S. Kale
@ 2006-08-31 14:13 ` Amit S. Kale
  2006-08-31 14:16 ` [PATCH 2.6.17 3/9] NetXen: hw initialization routines Amit S. Kale
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Amit S. Kale @ 2006-08-31 14:13 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, rob, unmproj, shemminger, brazilnut, wendyx, jeff

diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/netxen_nic_hw.c linux-2.6.17/drivers/net/netxen/netxen_nic_hw.c
--- linux-2.6.17.orig/drivers/net/netxen/netxen_nic_hw.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/netxen_nic_hw.c	2006-08-31 06:17:22.000000000 -0700
@@ -0,0 +1,1102 @@
+/*
+ * 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 "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)))
+
+#define NETXEN_FLASH_BASE	(BOOTLD_START)
+#define NETXEN_PHANTOM_MEM_BASE	(NETXEN_FLASH_BASE)
+#define NETXEN_MAX_MTU		8000
+#define NETXEN_MTU_MASK		0xFFFF0000
+#define NETXEN_WINDOW_ONE 0x2000000	/* CRB Window: bit 25 of CRB address */
+
+unsigned long netxen_nic_pci_set_window(void __iomem * 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;
+
+	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 & NETXEN_MTU_MASK)
+		return -EINVAL;
+
+	if (new_mtu > NETXEN_MAX_MTU) {
+		printk(KERN_ERR
+		       "%s: %s MTU > NETXEN_MAX_MTU 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)
+{
+	struct netxen_hardware_context *hw = &adapter->ahw;
+	int i;
+	u32 state = 0;
+	void *addr;
+	int loops = 0, err = 0;
+	int ctx, ring;
+	u32 card_cmdring = 0;
+	struct netxen_rcv_desc_crb *rcv_desc_crb = NULL;
+	struct netxen_recv_context *recv_ctx;
+	struct netxen_rcv_desc_ctx *rcv_desc;
+	struct cmd_desc_type0_t *pcmd;
+
+	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 */
+	card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING));
+
+	DPRINTK(INFO, "Command Peg sends 0x%x for cmdring base\n",
+		card_cmdring);
+
+	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+		DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n");
+		loops = 0;
+		state = 0;
+		/* Window 1 call */
+		state = readl(NETXEN_CRB_NORMALIZE(adapter,
+						   recv_crb_registers[ctx].
+						   crb_rcvpeg_state));
+		while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) {
+			udelay(100);
+			/* Window 1 call */
+			state = readl(NETXEN_CRB_NORMALIZE(adapter,
+							   recv_crb_registers
+							   [ctx].
+							   crb_rcvpeg_state));
+			loops++;
+		}
+		if (loops >= 20) {
+			printk(KERN_ERR "Rcv Peg initialization not complete:"
+			       "%x.\n", state);
+			err = -EIO;
+			return err;
+		}
+	}
+	DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n");
+
+	addr = pci_alloc_consistent(adapter->ahw.pdev,
+				    sizeof(struct cmd_desc_type0_t) *
+				    adapter->max_tx_desc_count,
+				    &hw->cmd_desc_phys_addr);
+	if (addr == NULL) {
+		DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
+		err = -ENOMEM;
+		return err;
+	}
+
+	/* we need to prelink all of the cmd descriptors */
+	pcmd = (struct cmd_desc_type0_t *)addr;
+	for (i = 1; i < adapter->max_tx_desc_count; i++) {
+		pcmd->netxen_next =
+		    (card_cmdring + i * sizeof(struct cmd_desc_type0_t));
+		pcmd++;
+	}
+	/* fill in last link (point to first) */
+	pcmd->netxen_next = card_cmdring;
+
+	hw->cmd_desc_head = (struct cmd_desc_type0_t *)addr;
+
+	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+		recv_ctx = &adapter->recv_ctx[ctx];
+
+		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+			addr = pci_alloc_consistent(adapter->ahw.pdev,
+						    RCV_DESC_RINGSIZE,
+						    &rcv_desc->phys_addr);
+			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;
+		}
+
+		addr = pci_alloc_consistent(adapter->ahw.pdev,
+					    STATUS_DESC_RINGSIZE,
+					    &recv_ctx->
+					    rcv_status_desc_phys_addr);
+		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;
+		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+			rcv_desc_crb =
+			    &recv_crb_registers[ctx].rcv_desc_crb[ring];
+			DPRINTK(INFO, "ring #%d crb global ring reg 0x%x\n",
+				ring, rcv_desc_crb->crb_globalrcv_ring);
+			/* Window = 1 */
+			writel(rcv_desc->phys_addr,
+			       NETXEN_CRB_NORMALIZE(adapter,
+						    rcv_desc_crb->
+						    crb_globalrcv_ring));
+			DPRINTK(INFO, "GLOBAL_RCV_RING ctx %d, addr 0x%x"
+				" val 0x%x,"
+				" virt %p\n", ctx,
+				rcv_desc_crb->crb_globalrcv_ring,
+				rcv_desc->phys_addr, rcv_desc->desc_head);
+		}
+
+		/* Window = 1 */
+		writel(recv_ctx->rcv_status_desc_phys_addr,
+		       NETXEN_CRB_NORMALIZE(adapter,
+					    recv_crb_registers[ctx].
+					    crb_rcvstatus_ring));
+		DPRINTK(INFO, "RCVSTATUS_RING, ctx %d, addr 0x%x,"
+			" val 0x%x,virt%p\n",
+			ctx,
+			recv_crb_registers[ctx].crb_rcvstatus_ring,
+			recv_ctx->rcv_status_desc_phys_addr,
+			recv_ctx->rcv_status_desc_head);
+	}
+	/* Window = 1 */
+	writel(hw->cmd_desc_phys_addr,
+	       NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
+
+	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 ctx, ring;
+
+	if (adapter->ahw.cmd_desc_head != NULL) {
+		pci_free_consistent(adapter->ahw.pdev,
+				    sizeof(struct cmd_desc_type0_t) *
+				    adapter->max_tx_desc_count,
+				    adapter->ahw.cmd_desc_head,
+				    adapter->ahw.cmd_desc_phys_addr);
+		adapter->ahw.cmd_desc_head = NULL;
+	}
+
+	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+		recv_ctx = &adapter->recv_ctx[ctx];
+		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+			rcv_desc = &recv_ctx->rcv_desc[ring];
+
+			if (rcv_desc->desc_head != NULL) {
+				pci_free_consistent(adapter->ahw.pdev,
+						    RCV_DESC_RINGSIZE,
+						    rcv_desc->desc_head,
+						    rcv_desc->phys_addr);
+				rcv_desc->desc_head = NULL;
+			}
+		}
+
+		if (recv_ctx->rcv_status_desc_head != NULL) {
+			pci_free_consistent(adapter->ahw.pdev,
+					    STATUS_DESC_RINGSIZE,
+					    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;
+		}
+	}
+	CMD_DESC_TCP_HDR_OFFSET_WRT(desc, skb->h.raw - skb->data);
+	desc->length_tcp_hdr = cpu_to_le32(desc->length_tcp_hdr);
+	desc->ip_hdr_offset = skb->nh.raw - skb->data;
+	adapter->stats.xmitcsummed++;
+}
+
+int netxen_is_flash_supported(struct netxen_adapter *adapter)
+{
+	const 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 netxen_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_old_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)
+{
+	void __iomem *offset;
+	u32 tmp;
+	int count = 0;
+
+	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);
+
+	if (wndw & 0x1)
+		wndw = NETXEN_WINDOW_ONE;
+
+	writel(wndw, offset);
+
+	/* MUST make sure window is set before we forge on... */
+	while ((tmp = readl(offset)) != wndw) {
+		printk(KERN_WARNING "%s: %s WARNING: CRB window value not "
+		       "registered properly: 0x%08x.\n",
+		       netxen_nic_driver_name, __FUNCTION__, tmp);
+		udelay(1000);
+		if (count >= 10)
+			break;
+		count++;
+	}
+
+	adapter->curr_window = wndw;
+}
+
+void netxen_load_firmware(struct netxen_adapter *adapter)
+{
+	int i;
+	long data, size = 0;
+	long flashaddr = NETXEN_FLASH_BASE, memaddr = NETXEN_PHANTOM_MEM_BASE;
+	u64 off;
+	ptrdiff_t addr;
+
+	size = (16 * 1024) / 4;
+	writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));
+
+	for (i = 0; i < size; i++) {
+		if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) {
+			DPRINTK(ERR,
+				"Error in netxen_rom_fast_read(). Will skip"
+				"loading flash image\n");
+			return;
+		}
+		off = netxen_nic_pci_set_window(adapter->ahw.pci_base, memaddr);
+		addr = (ptrdiff_t) (adapter->ahw.pci_base + off);
+		writel(data, (void __iomem *)addr);
+		flashaddr += 4;
+		memaddr += 4;
+	}
+	udelay(100);
+	/* 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));
+
+	udelay(10000);
+}
+
+int
+netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
+		       int len)
+{
+	void __iomem *addr;
+
+	if (ADDR_IN_WINDOW1(off)) {
+		addr = NETXEN_CRB_NORMALIZE(adapter, off);
+	} else {		/* Window 0 */
+		addr = (void *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+		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))
+		netxen_nic_pci_change_crbwindow(adapter, 1);
+
+	return 0;
+}
+
+int
+netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data,
+		      int len)
+{
+	void __iomem *addr;
+
+	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
+		addr = NETXEN_CRB_NORMALIZE(adapter, off);
+	} else {		/* Window 0 */
+		addr = (void *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+		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))
+		netxen_nic_pci_change_crbwindow(adapter, 1);
+
+	return 0;
+}
+
+void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
+{				/* Only for window 1 */
+	void __iomem *addr;
+
+	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);
+
+}
+
+int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
+{				/* Only for window 1 */
+	void __iomem *addr;
+	int val;
+
+	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);
+
+	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)
+{
+	void __iomem *addr;
+
+	netxen_nic_pci_change_crbwindow(adapter, 0);
+	addr = (void *)(adapter->ahw.pci_base + index);
+	writel(value, addr);
+	netxen_nic_pci_change_crbwindow(adapter, 1);
+}
+
+/* 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)
+{
+	void __iomem *addr;
+
+	addr = (void *)(adapter->ahw.pci_base + index);
+
+	netxen_nic_pci_change_crbwindow(adapter, 0);
+	*value = readl(addr);
+	netxen_nic_pci_change_crbwindow(adapter, 1);
+}
+
+int netxen_pci_set_window_warning_count = 0;
+
+unsigned long
+netxen_nic_pci_set_window(void __iomem * 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 __iomem *)(ptrdiff_t) (pci_base +
+								    NETXEN_PCIX_PH_REG
+								    (PCIX_MN_WINDOW)));
+			/* MUST make sure window is set before we forge on... */
+			readl((void __iomem *)(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 __iomem *)(ptrdiff_t) (pci_base +
+							    NETXEN_PCIX_PH_REG
+							    (PCIX_SN_WINDOW)));
+			/* MUST make sure window is set before we forge on... */
+			readl((void __iomem *)(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;
+}
+
+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) {
+			return -EIO;
+		}
+		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;
+}
+
+/* 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;
+}
+
+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__);
+		ret = -1;
+		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__);
+		ret = -1;
+		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(2000);
+		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)
+{
+	void __iomem *addr;
+
+	if (ADDR_IN_WINDOW1(off)) {
+		writel(data, NETXEN_CRB_NORMALIZE(adapter, off));
+	} else {
+		netxen_nic_pci_change_crbwindow(adapter, 0);
+		addr = (void *)(adapter->ahw.pci_base + off);
+		writel(data, addr);
+		netxen_nic_pci_change_crbwindow(adapter, 1);
+	}
+}
+
+void netxen_nic_set_link_parameters(struct netxen_port *port)
+{
+	struct netxen_adapter *adapter = port->adapter;
+	netxen_niu_phy_status status;
+	u16 autoneg;
+	netxen_niu_control mode;
+
+	netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode);
+	if (netxen_get_niu_enable_ge(mode)) {	/* Gb 10/100/1000 Mbps mode */
+		if (netxen_nic_phy_read(port->adapter, port->portnum,
+					NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+					&status) == 0) {
+			if (netxen_get_phy_link(status)) {
+				switch (netxen_get_phy_speed(status)) {
+				case 0:
+					port->link_speed = SPEED_10;
+					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 (netxen_get_phy_duplex(status)) {
+				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);
+		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));
+
+		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);
+}
+
+long netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off)
+{
+	int data;
+	netxen_nic_hw_read_wx(adapter, off, &data, 4);
+	return data;
+}


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2.6.17 3/9] NetXen: hw initialization routines
  2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
  2006-08-31 14:05 ` [PATCH 2.6.17 1/9] NetXen: Makefile and driver main file Amit S. Kale
  2006-08-31 14:13 ` [PATCH 2.6.17 2/9] NetXen: Hardware access routines Amit S. Kale
@ 2006-08-31 14:16 ` Amit S. Kale
  2006-08-31 14:20 ` [PATCH 2.6.17 4/9] NetXen: intr routines and niu handling Amit S. Kale
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Amit S. Kale @ 2006-08-31 14:16 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, rob, unmproj, shemminger, brazilnut, wendyx, jeff

diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/netxen_nic_init.c linux-2.6.17/drivers/net/netxen/netxen_nic_init.c
--- linux-2.6.17.orig/drivers/net/netxen/netxen_nic_init.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/netxen_nic_init.c	2006-08-31 06:17:22.000000000 -0700
@@ -0,0 +1,1089 @@
+/*
+ * 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
+
+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);
+}
+
+int netxen_init_firmware(struct netxen_adapter *adapter)
+{
+	u32 state = 0, loops = 0, err = 0;
+
+	/* Window 1 call */
+	state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+
+	if (state == PHAN_INITIALIZE_ACK)
+		return 0;
+
+	while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) {
+		udelay(100);
+		/* Window 1 call */
+		state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+
+		loops++;
+	}
+	if (loops >= 2000) {
+		printk(KERN_ERR "Cmd Peg initialization not complete:%x.\n",
+		       state);
+		err = -EIO;
+		return err;
+	}
+	/* Window 1 call */
+	writel(PHAN_INITIALIZE_ACK,
+	       NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+
+	return err;
+}
+
+void netxen_initialize_adapter_sw(struct netxen_adapter *adapter)
+{
+	int ctxid, ring;
+	u32 i;
+	u32 num_rx_bufs = 0;
+	struct netxen_rcv_desc_ctx *rcv_desc;
+
+	DPRINTK(INFO, "initializing some queues: %p\n", adapter);
+	for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
+		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
+			struct netxen_rx_buffer *rx_buf;
+			rcv_desc = &adapter->recv_ctx[ctxid].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");
+}
+
+void netxen_initialize_adapter_hw(struct netxen_adapter *adapter)
+{
+	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);
+	}
+}
+
+/*
+ * 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 = 1000000;
+
+static inline int rom_lock(struct netxen_adapter *adapter)
+{
+	int iter;
+	u32 done = 0;
+	int 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 -EIO;
+
+		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;
+}
+
+static inline void rom_unlock(struct netxen_adapter *adapter)
+{
+	u32 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 -EIO;
+		}
+	}
+	return 0;
+}
+
+static inline 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 -EIO;
+	}
+	/* 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 -EIO;
+
+	ret = do_rom_fast_read(adapter, addr, valp);
+	rom_unlock(adapter);
+	return ret;
+}
+
+#define NETXEN_BOARDTYPE		0x4008
+#define NETXEN_BOARDNUM 		0x400c
+#define NETXEN_CHIPNUM			0x4010
+#define NETXEN_ROMBUS_RESET		0xFFFFFFFF
+#define NETXEN_ROM_FIRST_BARRIER	0x800000000ULL
+#define NETXEN_ROM_ROUNDUP		0x80000000ULL
+#define NETXEN_ROM_FOUND_INIT		0x400
+
+int netxen_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;
+
+	/* 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,
+				    NETXEN_ROMBUS_RESET);
+
+	if (verbose) {
+		int val;
+		if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &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, NETXEN_BOARDNUM, &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, NETXEN_CHIPNUM, &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 & NETXEN_ROM_FIRST_BARRIER)) {
+		n &= ~NETXEN_ROM_ROUNDUP;
+		if (n < NETXEN_ROM_FOUND_INIT) {
+			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 -EIO;
+		}
+		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 -ENOMEM;
+		}
+		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)
+				return -EIO;
+
+			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)) {
+				writel(buf[i].data,
+				       NETXEN_CRB_NORMALIZE(adapter, off));
+			} else {
+				netxen_nic_pci_change_crbwindow(adapter, 0);
+				writel(buf[i].data,
+				       adapter->ahw.pci_base + off);
+
+				netxen_nic_pci_change_crbwindow(adapter, 1);
+			}
+			if (init_delay == 1) {
+				ssleep(1);
+				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;
+}
+
+void netxen_phantom_init(struct netxen_adapter *adapter)
+{
+	u32 val = 0;
+	int loops = 0;
+
+	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 < 200000) {
+			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");
+	}
+}
+
+int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
+{
+	int ctx;
+
+	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+		struct netxen_recv_context *recv_ctx =
+		    &(adapter->recv_ctx[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 (((le16_to_cpu(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;
+
+	for (port_num = 0; port_num < adapter->ahw.max_ports; port_num++) {
+		port = adapter->port[port_num];
+		netdev = port->netdev;
+
+		if ((netif_running(netdev)) && !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);
+	}
+
+	netxen_nic_pci_change_crbwindow(adapter, 1);
+
+	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...
+ */
+void
+netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
+		   struct status_desc_t *desc)
+{
+	struct netxen_port *port = adapter->port[STATUS_DESC_PORT(desc)];
+	struct pci_dev *pdev = port->pdev;
+	struct net_device *netdev = port->netdev;
+	int index = le16_to_cpu(desc->reference_handle);
+	struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
+	struct netxen_rx_buffer *buffer;
+	struct sk_buff *skb;
+	u32 length = le16_to_cpu(desc->total_length);
+	u32 desc_ctx;
+	struct netxen_rcv_desc_ctx *rcv_desc;
+	int ret;
+
+	desc_ctx = STATUS_DESC_TYPE(desc);
+	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 (likely(STATUS_DESC_STATUS(desc) == 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_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
+	struct status_desc_t *desc_head = recv_ctx->rcv_status_desc_head;
+	struct status_desc_t *desc;	/* used to read status desc here */
+	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 (!((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST)) {
+			DPRINTK(ERR, "desc %p ownedby %x\n", desc, desc->owner);
+			break;
+		}
+		netxen_process_rcv(adapter, ctxid, desc);
+		desc->owner = STATUS_OWNER_PHANTOM;
+		consumer = (consumer + 1) & (adapter->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) {
+		adapter->stats.process_rcv++;
+		recv_ctx->status_rx_consumer = consumer;
+
+		/* Window = 1 */
+		writel(consumer,
+		       NETXEN_CRB_NORMALIZE(adapter,
+					    recv_crb_registers[ctxid].
+					    crb_rcv_status_consumer));
+	}
+
+	return count;
+}
+
+/* Process Command status ring */
+void netxen_process_cmd_ring(unsigned long data)
+{
+	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;
+
+	spin_lock(&adapter->tx_lock);
+	last_consumer = adapter->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 =
+	    readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET));
+
+	if (last_consumer == consumer) {	/* Ring is empty    */
+		DPRINTK(INFO, "last_consumer %d == consumer %d\n",
+			last_consumer, consumer);
+		spin_unlock(&adapter->tx_lock);
+		return;
+	}
+
+	adapter->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 = &adapter->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 (adapter->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);
+		}
+
+		last_consumer = get_next_index(last_consumer,
+					       adapter->max_tx_desc_count);
+		count++;
+	}
+	adapter->stats.noxmitdone += count;
+
+	count = 0;
+	spin_lock(&adapter->tx_lock);
+	if ((--adapter->proc_cmd_buf_counter) == 0) {
+		adapter->last_cmd_consumer = last_consumer;
+		while ((adapter->last_cmd_consumer != consumer)
+		       && (count < MAX_STATUS_HANDLE)) {
+			buffer =
+			    &adapter->cmd_buf_arr[adapter->last_cmd_consumer];
+			count++;
+			if (buffer->skb)
+				break;
+			else
+				adapter->last_cmd_consumer =
+				    get_next_index(adapter->last_cmd_consumer,
+						   adapter->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 ctx, u32 ringid)
+{
+	struct pci_dev *pdev = adapter->ahw.pdev;
+	struct sk_buff *skb;
+	struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
+	struct netxen_rcv_desc_ctx *rcv_desc = NULL;
+	struct netxen_recv_crb *crbarea = &recv_crb_registers[ctx];
+	struct netxen_rcv_desc_crb *rcv_desc_crb = NULL;
+	u32 producer;
+	struct rcv_desc_t *pdesc;
+	struct netxen_rx_buffer *buffer;
+	int count = 0;
+	int index = 0;
+
+	adapter->stats.post_called++;
+	rcv_desc = &recv_ctx->rcv_desc[ringid];
+	rcv_desc_crb = &crbarea->rcv_desc_crb[ringid];
+
+	producer = rcv_desc->producer;
+	index = rcv_desc->begin_alloc;
+	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, "unm_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 = le16_to_cpu(buffer->ref_handle);
+		pdesc->buffer_length = le16_to_cpu(rcv_desc->dma_size);
+		pdesc->addr_buffer = cpu_to_le64(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];
+	}
+
+	/* 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;
+			/* Window = 1 */
+			writel((producer - 1) &
+			       (rcv_desc->max_rx_desc_count - 1),
+			       NETXEN_CRB_NORMALIZE(adapter,
+						    rcv_desc_crb->
+						    crb_rcv_producer_offset));
+			wmb();
+		}
+	}
+}
+
+int netxen_nic_tx_has_work(struct netxen_adapter *adapter)
+{
+	if (find_diff_among(adapter->last_cmd_consumer,
+			    adapter->cmd_producer,
+			    adapter->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)
+{
+	void __iomem *addr;
+
+	if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+		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);
+	} 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)
+{
+	void __iomem *addr;
+	int data = 0;
+
+	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);
+	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_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	[flat|nested] 18+ messages in thread

* [PATCH 2.6.17 4/9] NetXen: intr routines and niu handling
  2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
                   ` (2 preceding siblings ...)
  2006-08-31 14:16 ` [PATCH 2.6.17 3/9] NetXen: hw initialization routines Amit S. Kale
@ 2006-08-31 14:20 ` Amit S. Kale
  2006-08-31 14:25 ` [PATCH 2.6.17 5/9] NetXen: ethtool interface Amit S. Kale
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Amit S. Kale @ 2006-08-31 14:20 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, rob, unmproj, shemminger, brazilnut, wendyx, jeff

diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/netxen_nic_isr.c linux-2.6.17/drivers/net/netxen/netxen_nic_isr.c
--- linux-2.6.17.orig/drivers/net/netxen/netxen_nic_isr.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/netxen_nic_isr.c	2006-08-31 06:17:22.000000000 -0700
@@ -0,0 +1,301 @@
+/*
+ * 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"
+
+/*
+ * 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_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)
+{
+	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, &int_src);
+	if (int_src == 0) {
+		DPRINTK(INFO, "No phy interrupts for port #%d\n", portno);
+		return;
+	}
+	netxen_nic_disable_phy_interrupts(adapter, portno);
+
+	port = adapter->port[portno];
+
+	if (netxen_get_phy_int_jabber(int_src))
+		DPRINTK(INFO, "NetXen: %s Jabber interrupt \n",
+			port->netdev->name);
+
+	if (netxen_get_phy_int_polarity_changed(int_src))
+		DPRINTK(INFO, "NetXen: %s POLARITY CHANGED int \n",
+			port->netdev->name);
+
+	if (netxen_get_phy_int_energy_detect(int_src))
+		DPRINTK(INFO, "NetXen: %s ENERGY DETECT INT \n",
+			port->netdev->name);
+
+	if (netxen_get_phy_int_downshift(int_src))
+		DPRINTK(INFO, "NetXen: %s DOWNSHIFT INT \n",
+			port->netdev->name);
+	/* write it down later.. */
+	if ((netxen_get_phy_int_speed_changed(int_src))
+	    || (netxen_get_phy_int_link_status_changed(int_src))) {
+		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,
+					&status) == 0) {
+			if (netxen_get_phy_int_link_status_changed(int_src)) {
+				if (netxen_get_phy_link(status)) {
+					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,
+							    netxen_get_phy_link
+							    (status));
+			}
+		}
+	}
+	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 */
+	i2qhi = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_I2Q_CLR_PCI_HI));
+
+	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 */
+		writel((u32) i2qhi,
+		       NETXEN_CRB_NORMALIZE(adapter, NETXEN_I2Q_CLR_PCI_HI));
+
+	}
+}
+
+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 */
+			val1 =
+			    readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
+
+			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);
+	}
+}
diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/netxen_nic_niu.c linux-2.6.17/drivers/net/netxen/netxen_nic_niu.c
--- linux-2.6.17.orig/drivers/net/netxen/netxen_nic_niu.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/netxen_nic_niu.c	2006-08-31 06:17:22.000000000 -0700
@@ -0,0 +1,779 @@
+/*
+ * 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
+ *
+ *
+ * Provides access to the Network Interface Unit h/w block.
+ *
+ */
+
+#include "netxen_nic.h"
+#include <linux/delay.h>
+
+/** 
+ * netxen_niu_gbe_phy_read - read a register from the GbE PHY via
+ * mii management interface.
+ *
+ * Note: The MII management interface goes through port 0.
+ *       Individual phys are addressed as follows:
+ * @param phy  [15:8]  phy id
+ * @param reg  [7:0]   register number
+ *
+ * @returns  0 on success
+ *          -1 on error
+ *
+ **/
+long netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy,
+			     long reg, netxen_crbword_t * readval)
+{
+	long timeout = 0;
+	long result = 0;
+	long restore = 0;
+	netxen_niu_gb_mii_mgmt_address address;
+	netxen_niu_gb_mii_mgmt_command command;
+	netxen_niu_gb_mii_mgmt_indicators status;
+	netxen_niu_gb_mii_mgmt_config mii_cfg;
+	netxen_niu_gb_mac_config_0_t mac_cfg0;
+
+	/* MII mgmt all goes through port 0 MAC interface, so it cannot be in reset */
+	if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
+				  &mac_cfg0, 4))
+		return -EIO;
+	if (netxen_gb_get_soft_reset(mac_cfg0)) {
+		netxen_niu_gb_mac_config_0_t temp;
+		temp = 0;
+		netxen_gb_tx_reset_pb(temp);
+		netxen_gb_rx_reset_pb(temp);
+		netxen_gb_tx_reset_mac(temp);
+		netxen_gb_rx_reset_mac(temp);
+		if (netxen_nic_hw_write_wx(adapter,
+					   NETXEN_NIU_GB_MAC_CONFIG_0(0),
+					   &temp, 4))
+			return -EIO;
+		restore = 1;
+	}
+
+	/* reset MII management interface */
+	mii_cfg = 0;
+	netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7);
+	netxen_gb_mii_mgmt_reset(mii_cfg);
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(0),
+				   &mii_cfg, 4))
+		return -EIO;
+	netxen_gb_mii_mgmt_unset(mii_cfg);
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(0),
+				   &mii_cfg, 4))
+		return -EIO;
+
+	address = 0;
+	netxen_gb_mii_mgmt_reg_addr(address, reg);
+	netxen_gb_mii_mgmt_phy_addr(address, phy);
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
+				   &address, 4))
+		return -EIO;
+	command = 0;		/* turn off any prior activity */
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
+				   &command, 4))
+		return -EIO;
+	/* send read command */
+	netxen_gb_mii_mgmt_set_read_cycle(command);
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
+				   &command, 4))
+		return -EIO;
+
+	status = 0;
+	do {
+		if (netxen_nic_hw_read_wx(adapter,
+					  NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
+					  &status, 4))
+			return -EIO;
+		timeout++;
+	} while ((netxen_get_gb_mii_mgmt_busy(status)
+		  || netxen_get_gb_mii_mgmt_notvalid(status))
+		 && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
+
+	if (timeout < NETXEN_NIU_PHY_WAITMAX) {
+		if (netxen_nic_hw_read_wx(adapter,
+					  NETXEN_NIU_GB_MII_MGMT_STATUS(0),
+					  readval, 4))
+			return -EIO;
+		result = 0;
+	} else
+		result = -1;
+
+	if (restore)
+		if (netxen_nic_hw_write_wx(adapter,
+					   NETXEN_NIU_GB_MAC_CONFIG_0(0),
+					   &mac_cfg0, 4))
+			return -EIO;
+
+	return result;
+}
+
+/** 
+ * netxen_niu_gbe_phy_write - write a register to the GbE PHY via
+ * mii management interface.
+ *
+ * Note: The MII management interface goes through port 0.
+ *       Individual phys are addressed as follows:
+ * @param phy      [15:8]  phy id
+ * @param reg      [7:0]   register number
+ *
+ * @returns  0 on success
+ *          -1 on error
+ *
+ **/
+long netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
+			      long phy, long reg, netxen_crbword_t val)
+{
+	long timeout = 0;
+	long result = 0;
+	long restore = 0;
+	netxen_niu_gb_mii_mgmt_address address;
+	netxen_niu_gb_mii_mgmt_command command;
+	netxen_niu_gb_mii_mgmt_indicators status;
+	netxen_niu_gb_mac_config_0_t mac_cfg0;
+
+	/* MII mgmt all goes through port 0 MAC interface, so it cannot be in reset */
+	if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
+				  &mac_cfg0, 4))
+		return -EIO;
+	if (netxen_gb_get_soft_reset(mac_cfg0)) {
+		netxen_niu_gb_mac_config_0_t temp;
+		temp = 0;
+		netxen_gb_tx_reset_pb(temp);
+		netxen_gb_rx_reset_pb(temp);
+		netxen_gb_tx_reset_mac(temp);
+		netxen_gb_rx_reset_mac(temp);
+
+		if (netxen_nic_hw_write_wx(adapter,
+					   NETXEN_NIU_GB_MAC_CONFIG_0(0),
+					   &temp, 4))
+			return -EIO;
+		restore = 1;
+	}
+
+	command = 0;		/* turn off any prior activity */
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
+				   &command, 4))
+		return -EIO;
+
+	address = 0;
+	netxen_gb_mii_mgmt_reg_addr(address, reg);
+	netxen_gb_mii_mgmt_phy_addr(address, phy);
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
+				   &address, 4))
+		return -EIO;
+
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0),
+				   &val, 4))
+		return -EIO;
+
+	status = 0;
+	do {
+		if (netxen_nic_hw_read_wx(adapter,
+					  NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
+					  &status, 4))
+			return -EIO;
+		timeout++;
+	} while ((netxen_get_gb_mii_mgmt_busy(status))
+		 && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
+
+	if (timeout < NETXEN_NIU_PHY_WAITMAX)
+		result = 0;
+	else
+		result = -EIO;
+
+	/* restore the state of port 0 MAC in case we tampered with it */
+	if (restore)
+		if (netxen_nic_hw_write_wx(adapter,
+					   NETXEN_NIU_GB_MAC_CONFIG_0(0),
+					   &mac_cfg0, 4))
+			return -EIO;
+
+	return result;
+}
+
+long netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter,
+					  long port)
+{
+	long result = 0;
+	netxen_niu_phy_interrupt enable = 0;
+	netxen_set_phy_int_link_status_changed(enable);
+	netxen_set_phy_int_autoneg_completed(enable);
+	netxen_set_phy_int_speed_changed(enable);
+
+	if (0 !=
+	    netxen_niu_gbe_phy_write(adapter, port,
+				     NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE,
+				     enable))
+		result = -EIO;
+
+	return result;
+}
+
+long netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter,
+					   long port)
+{
+	long result = 0;
+	if (0 !=
+	    netxen_niu_gbe_phy_write(adapter, port,
+				     NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 0))
+		result = -EIO;
+
+	return result;
+}
+
+long netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter,
+					 long port)
+{
+	long result = 0;
+	if (0 !=
+	    netxen_niu_gbe_phy_write(adapter, port,
+				     NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
+				     -EIO))
+		result = -EIO;
+
+	return result;
+}
+
+/** 
+ * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC
+ *
+ **/
+void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
+				 long port, long enable)
+{
+	netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
+	netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+				    0x80000000);
+	netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+				    0x0000f0025);
+	netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
+				    0xf1ff);
+	netxen_crb_writelit_adapter(adapter,
+				    NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
+	netxen_crb_writelit_adapter(adapter,
+				    NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
+	netxen_crb_writelit_adapter(adapter,
+				    (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
+	netxen_crb_writelit_adapter(adapter,
+				    NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
+
+	if (enable) {
+		/* 
+		 * Do NOT enable flow control until a suitable solution for 
+		 *  shutting down pause frames is found. 
+		 */
+		netxen_crb_writelit_adapter(adapter,
+					    NETXEN_NIU_GB_MAC_CONFIG_0(port),
+					    0x5);
+	}
+
+	if (netxen_niu_gbe_enable_phy_interrupts(adapter, port))
+		printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
+	if (netxen_niu_gbe_clear_phy_interrupts(adapter, port))
+		printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
+}
+
+/** 
+ * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC
+ **/
+void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
+				  long port, long enable)
+{
+	netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
+	netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+				    0x80000000);
+	netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+				    0x0000f0025);
+	netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
+				    0xf2ff);
+	netxen_crb_writelit_adapter(adapter,
+				    NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
+	netxen_crb_writelit_adapter(adapter,
+				    NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
+	netxen_crb_writelit_adapter(adapter,
+				    (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
+	netxen_crb_writelit_adapter(adapter,
+				    NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
+
+	if (enable) {
+		/* 
+		 * Do NOT enable flow control until a suitable solution for 
+		 *  shutting down pause frames is found. 
+		 */
+		netxen_crb_writelit_adapter(adapter,
+					    NETXEN_NIU_GB_MAC_CONFIG_0(port),
+					    0x5);
+	}
+
+	if (netxen_niu_gbe_enable_phy_interrupts(adapter, port))
+		printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
+	if (netxen_niu_gbe_clear_phy_interrupts(adapter, port))
+		printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
+}
+
+long netxen_niu_gbe_init_port(struct netxen_adapter *adapter, long port)
+{
+	long result = 0;
+	netxen_niu_phy_status status;
+
+	if (0 ==
+	    netxen_niu_gbe_phy_read(adapter, port,
+				    NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+				    (netxen_crbword_t *) & status)) {
+		if (netxen_get_phy_link(status)) {
+			if (netxen_get_phy_speed(status) == 2) {
+				netxen_niu_gbe_set_gmii_mode(adapter, port, 1);
+			} else if ((netxen_get_phy_speed(status) == 1)
+				   || (netxen_get_phy_speed(status) == 0)) {
+				netxen_niu_gbe_set_mii_mode(adapter, port, 1);
+			} else {
+				result = -1;
+			}
+
+		} else {
+			/* We don't have link. Cable  must be unconnected. */
+			/* Enable phy interrupts so we take action when plugged in */
+			netxen_crb_writelit_adapter(adapter,
+						    NETXEN_NIU_GB_MAC_CONFIG_0
+						    (port), 0x80000000);
+			netxen_crb_writelit_adapter(adapter,
+						    NETXEN_NIU_GB_MAC_CONFIG_0
+						    (port), 0x0000f0025);
+			if (netxen_niu_gbe_clear_phy_interrupts(adapter, port))
+				printk(KERN_ERR PFX
+				       "ERROR clearing PHY interrupts\n");
+			if (netxen_niu_gbe_enable_phy_interrupts(adapter, port))
+				printk(KERN_ERR PFX
+				       "ERROR enabling PHY interrupts\n");
+			if (netxen_niu_gbe_clear_phy_interrupts(adapter, port))
+				printk(KERN_ERR PFX
+				       "ERROR clearing PHY interrupts\n");
+			result = -1;
+		}
+	} else {
+		result = -EIO;
+	}
+	return result;
+}
+
+/** 
+ * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts
+ * @param enable 0 means don't enable the port
+ *               1 means enable (or re-enable) the port
+ **/
+long netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
+					 long port, long enable)
+{
+	long result = 0;
+	netxen_niu_phy_interrupt int_src;
+
+	printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d"
+	       " (device enable = %d)\n", (int)port, (int)enable);
+
+	/* The read of the PHY INT status will clear the pending interrupt status */
+	if (netxen_niu_gbe_phy_read(adapter, port,
+				    NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
+				    &int_src) != 0)
+		result = -EINVAL;
+	else {
+		printk(KERN_INFO PFX "PHY Interrupt source = 0x%x \n", int_src);
+		if (netxen_get_phy_int_jabber(int_src))
+			printk(KERN_INFO PFX "jabber Interrupt ");
+		if (netxen_get_phy_int_polarity_changed(int_src))
+			printk(KERN_INFO PFX "polarity changed ");
+		if (netxen_get_phy_int_energy_detect(int_src))
+			printk(KERN_INFO PFX "energy detect \n");
+		if (netxen_get_phy_int_downshift(int_src))
+			printk(KERN_INFO PFX "downshift \n");
+		if (netxen_get_phy_int_mdi_xover_changed(int_src))
+			printk(KERN_INFO PFX "mdi_xover_changed ");
+		if (netxen_get_phy_int_fifo_over_underflow(int_src))
+			printk(KERN_INFO PFX "fifo_over_underflow ");
+		if (netxen_get_phy_int_false_carrier(int_src))
+			printk(KERN_INFO PFX "false_carrier ");
+		if (netxen_get_phy_int_symbol_error(int_src))
+			printk(KERN_INFO PFX "symbol_error ");
+		if (netxen_get_phy_int_autoneg_completed(int_src))
+			printk(KERN_INFO PFX "autoneg_completed ");
+		if (netxen_get_phy_int_page_received(int_src))
+			printk(KERN_INFO PFX "page_received ");
+		if (netxen_get_phy_int_duplex_changed(int_src))
+			printk(KERN_INFO PFX "duplex_changed ");
+		if (netxen_get_phy_int_autoneg_error(int_src))
+			printk(KERN_INFO PFX "autoneg_error ");
+		if ((netxen_get_phy_int_speed_changed(int_src))
+		    || (netxen_get_phy_int_link_status_changed(int_src))) {
+			netxen_niu_phy_status status;
+
+			printk(KERN_INFO PFX
+			       "speed_changed or link status changed");
+			if (netxen_niu_gbe_phy_read
+			    (adapter, port,
+			     NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+			     &status) == 0) {
+				if (netxen_get_phy_speed(status) == 2) {
+					printk
+					    (KERN_INFO PFX "Link speed changed"
+					     " to 1000 Mbps\n");
+					netxen_niu_gbe_set_gmii_mode(adapter,
+								     port,
+								     enable);
+				} else if (netxen_get_phy_speed(status) == 1) {
+					printk
+					    (KERN_INFO PFX "Link speed changed"
+					     " to 100 Mbps\n");
+					netxen_niu_gbe_set_mii_mode(adapter,
+								    port,
+								    enable);
+				} else if (netxen_get_phy_speed(status) == 0) {
+					printk
+					    (KERN_INFO PFX "Link speed changed"
+					     " to 10 Mbps\n");
+					netxen_niu_gbe_set_mii_mode(adapter,
+								    port,
+								    enable);
+				} else {
+					printk(KERN_ERR PFX "ERROR reading"
+					       "PHY status. Illegal speed.\n");
+					result = -1;
+				}
+			} else {
+				printk(KERN_ERR PFX
+				       "ERROR reading PHY status.\n");
+				result = -1;
+			}
+
+		}
+		printk(KERN_INFO "\n");
+	}
+	return result;
+}
+
+/**
+ * Return the current station MAC address.
+ * Note that the passed-in value must already be in network byte order.
+ **/
+int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
+			   int phy, netxen_ethernet_macaddr_t * addr)
+{
+	u64 result = 0;
+	netxen_niu_gb_station_address_high stationhigh;
+	netxen_niu_gb_station_address_low stationlow;
+
+	if (addr == NULL)
+		return -EINVAL;
+	if ((phy < 0) || (phy > 3))
+		return -EINVAL;
+
+	if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
+				  &stationhigh, 4))
+		return -EIO;
+	if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
+				  &stationlow, 4))
+		return -EIO;
+
+	result = (u64) netxen_gb_get_stationaddress_low(stationlow);
+	result |= (u64) stationhigh << 16;
+	memcpy(*addr, &result, sizeof(netxen_ethernet_macaddr_t));
+
+	return 0;
+}
+
+/**
+ * Set the station MAC address.
+ * Note that the passed-in value must already be in network byte order.
+ **/
+int netxen_niu_macaddr_set(struct netxen_adapter *adapter, int phy,
+			   netxen_ethernet_macaddr_t addr)
+{
+	netxen_crbword_t temp = 0;
+
+	if ((phy < 0) || (phy > 3))
+		return -EINVAL;
+
+	memcpy(&temp, addr, 2);
+	temp <<= 16;
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
+				   &temp, 4))
+		return -EIO;
+
+	temp = 0;
+
+	memcpy(&temp, ((u8 *) addr) + 2, sizeof(netxen_crbword_t));
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
+				   &temp, 4))
+		return -2;
+
+	return 0;
+}
+
+/* Enable a GbE interface */
+long netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
+				long port, netxen_niu_gbe_ifmode_t mode)
+{
+	netxen_niu_gb_mac_config_0_t mac_cfg0;
+	netxen_niu_gb_mac_config_1_t mac_cfg1;
+	netxen_niu_gb_mii_mgmt_config mii_cfg;
+
+	if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+		return -EINVAL;
+
+	mac_cfg0 = 0;
+	netxen_gb_soft_reset(mac_cfg0);
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+				   &mac_cfg0, 4))
+		return -EIO;
+	mac_cfg0 = 0;
+	netxen_gb_enable_tx(mac_cfg0);
+	netxen_gb_enable_rx(mac_cfg0);
+	netxen_gb_unset_rx_flowctl(mac_cfg0);
+	netxen_gb_tx_reset_pb(mac_cfg0);
+	netxen_gb_rx_reset_pb(mac_cfg0);
+	netxen_gb_tx_reset_mac(mac_cfg0);
+	netxen_gb_rx_reset_mac(mac_cfg0);
+
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+				   &mac_cfg0, 4))
+		return -EIO;
+	mac_cfg1 = 0;
+	netxen_gb_set_preamblelen(mac_cfg1, 0xf);
+	netxen_gb_set_duplex(mac_cfg1);
+	netxen_gb_set_crc_enable(mac_cfg1);
+	netxen_gb_set_padshort(mac_cfg1);
+	netxen_gb_set_checklength(mac_cfg1);
+	netxen_gb_set_hugeframes(mac_cfg1);
+
+	if (mode == NETXEN_NIU_10_100_MB) {
+		netxen_gb_set_intfmode(mac_cfg1, 1);
+		if (netxen_nic_hw_write_wx(adapter,
+					   NETXEN_NIU_GB_MAC_CONFIG_1(port),
+					   &mac_cfg1, 4))
+			return -EIO;
+
+		/* set mii mode */
+		netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
+					    (port << 3), 0);
+		netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
+					    (port << 3), 1);
+
+	} else if (mode == NETXEN_NIU_1000_MB) {
+		netxen_gb_set_intfmode(mac_cfg1, 2);
+		if (netxen_nic_hw_write_wx(adapter,
+					   NETXEN_NIU_GB_MAC_CONFIG_1(port),
+					   &mac_cfg1, 4))
+			return -EIO;
+		/* set gmii mode */
+		netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
+					    (port << 3), 0);
+		netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
+					    (port << 3), 1);
+	}
+	mii_cfg = 0;
+	netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7);
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port),
+				   &mii_cfg, 4))
+		return -EIO;
+	mac_cfg0 = 0;
+	netxen_gb_enable_tx(mac_cfg0);
+	netxen_gb_enable_rx(mac_cfg0);
+	netxen_gb_unset_rx_flowctl(mac_cfg0);
+	netxen_gb_unset_tx_flowctl(mac_cfg0);
+
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+				   &mac_cfg0, 4))
+		return -EIO;
+	return 0;
+}
+
+/* Disable a GbE interface */
+long netxen_niu_disable_gbe_port(struct netxen_adapter *adapter, long port)
+{
+	netxen_niu_gb_mac_config_0_t mac_cfg0;
+
+	if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+		return -EINVAL;
+
+	mac_cfg0 = 0;
+	netxen_gb_soft_reset(mac_cfg0);
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+				   &mac_cfg0, 4))
+		return -EIO;
+	return 0;
+}
+
+/* Disable an XG interface */
+long netxen_niu_disable_xg_port(struct netxen_adapter *adapter, long port)
+{
+	netxen_niu_xg_mac_config_0_t mac_cfg;
+
+	if (port != 0)
+		return -EINVAL;
+
+	mac_cfg = 0;
+	netxen_xg_soft_reset(mac_cfg);
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_CONFIG_0,
+				   &mac_cfg, 4))
+		return -EIO;
+	return 0;
+}
+
+/* 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)
+{
+	netxen_niu_gb_drop_crc reg;
+
+	if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+		return -EINVAL;
+
+	/* save previous contents */
+	if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
+				  &reg, 4))
+		return -EIO;
+	if (mode == NETXEN_NIU_PROMISCOUS_MODE) {
+		switch (port) {
+		case 0:
+			netxen_clear_gb_drop_gb0(reg);
+			break;
+		case 1:
+			netxen_clear_gb_drop_gb1(reg);
+			break;
+		case 2:
+			netxen_clear_gb_drop_gb2(reg);
+			break;
+		case 3:
+			netxen_clear_gb_drop_gb3(reg);
+			break;
+		default:
+			return -EIO;
+		}
+	} else {
+		switch (port) {
+		case 0:
+			netxen_set_gb_drop_gb0(reg);
+			break;
+		case 1:
+			netxen_set_gb_drop_gb1(reg);
+			break;
+		case 2:
+			netxen_set_gb_drop_gb2(reg);
+			break;
+		case 3:
+			netxen_set_gb_drop_gb3(reg);
+			break;
+		default:
+			return -EIO;
+		}
+	}
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
+				   &reg, 4))
+		return -EIO;
+	return 0;
+}
+
+/**
+ * Set the MAC address for an XG port
+ * Note that the passed-in value must already be in network byte order.
+ **/
+int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, int phy,
+			      netxen_ethernet_macaddr_t addr)
+{
+	netxen_crbword_t temp = 0;
+
+	if ((phy < 0) || (phy > 3))
+		return -EINVAL;
+
+	memcpy(&temp, addr, 2);
+	temp = cpu_to_le32(temp);
+	temp <<= 16;
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
+				   &temp, 4))
+		return -EIO;
+
+	temp = 0;
+
+	memcpy(&temp, ((u8 *) addr) + 2, sizeof(netxen_crbword_t));
+	temp = cpu_to_le32(temp);
+	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
+				   &temp, 4))
+		return -EIO;
+
+	return 0;
+}
+
+/**
+ * Return the current station MAC address.
+ * Note that the passed-in value must already be in network byte order.
+ **/
+int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int phy,
+			      netxen_ethernet_macaddr_t * addr)
+{
+	netxen_crbword_t stationhigh;
+	netxen_crbword_t stationlow;
+	u64 result;
+
+	if (addr == NULL)
+		return -EINVAL;
+	if (phy != 0)
+		return -EINVAL;
+
+	if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
+				  &stationhigh, 4))
+		return -EIO;
+	if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
+				  &stationlow, 4))
+		return -EIO;
+
+	result = ((u64) stationlow) >> 16;
+	result |= (u64) stationhigh << 16;
+	memcpy(*addr, &result, sizeof(netxen_ethernet_macaddr_t));
+
+	return 0;
+}
+
+long netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
+					long port, netxen_niu_prom_mode_t mode)
+{
+	netxen_crbword_t reg;
+
+	if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+		return -EINVAL;
+
+	if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_CONFIG_1, &reg, 4))
+		return -EIO;
+	if (mode == NETXEN_NIU_PROMISCOUS_MODE)
+		reg = (reg | 0x2000UL);
+	else
+		reg = (reg & ~0x2000UL);
+
+	netxen_crb_writelit_adapter(adapter, NETXEN_NIU_XGE_CONFIG_1, reg);
+
+	return 0;
+}


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2.6.17 5/9] NetXen: ethtool interface
  2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
                   ` (3 preceding siblings ...)
  2006-08-31 14:20 ` [PATCH 2.6.17 4/9] NetXen: intr routines and niu handling Amit S. Kale
@ 2006-08-31 14:25 ` Amit S. Kale
  2006-08-31 14:27 ` [PATCH 2.6.17 6/9] NetXen: Main header file Amit S. Kale
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Amit S. Kale @ 2006-08-31 14:25 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, rob, unmproj, shemminger, brazilnut, wendyx, jeff

diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/netxen_nic_ethtool.c linux-2.6.17/drivers/net/netxen/netxen_nic_ethtool.c
--- linux-2.6.17.orig/drivers/net/netxen/netxen_nic_ethtool.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/netxen_nic_ethtool.c	2006-08-31 06:17:22.000000000 -0700
@@ -0,0 +1,696 @@
+/*
+ * 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;
+	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,
+					&status) != 0)
+			return -EIO;
+
+		/* speed */
+		switch (ecmd->speed) {
+		case SPEED_10:
+			netxen_set_phy_speed(status, 0);
+			break;
+		case SPEED_100:
+			netxen_set_phy_speed(status, 1);
+			break;
+		case SPEED_1000:
+			netxen_set_phy_speed(status, 2);
+			break;
+		}
+		/* set duplex mode */
+		if (ecmd->duplex == DUPLEX_HALF)
+			netxen_clear_phy_duplex(status);
+		if (ecmd->duplex == DUPLEX_FULL)
+			netxen_set_phy_duplex(status);
+		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;
+}
+
+struct netxen_niu_regs {
+	netxen_crbword_t reg[NETXEN_NIC_REGS_COUNT];
+};
+
+static struct netxen_niu_regs niu_registers[] = {
+	{
+	 /* GB Mode */
+	 {
+	  NETXEN_NIU_GB_SERDES_RESET,
+	  NETXEN_NIU_GB0_MII_MODE,
+	  NETXEN_NIU_GB1_MII_MODE,
+	  NETXEN_NIU_GB2_MII_MODE,
+	  NETXEN_NIU_GB3_MII_MODE,
+	  NETXEN_NIU_GB0_GMII_MODE,
+	  NETXEN_NIU_GB1_GMII_MODE,
+	  NETXEN_NIU_GB2_GMII_MODE,
+	  NETXEN_NIU_GB3_GMII_MODE,
+	  NETXEN_NIU_REMOTE_LOOPBACK,
+	  NETXEN_NIU_GB0_HALF_DUPLEX,
+	  NETXEN_NIU_GB1_HALF_DUPLEX,
+	  NETXEN_NIU_RESET_SYS_FIFOS,
+	  NETXEN_NIU_GB_CRC_DROP,
+	  NETXEN_NIU_GB_DROP_WRONGADDR,
+	  NETXEN_NIU_TEST_MUX_CTL,
+
+	  NETXEN_NIU_GB_MAC_CONFIG_0(0),
+	  NETXEN_NIU_GB_MAC_CONFIG_1(0),
+	  NETXEN_NIU_GB_HALF_DUPLEX_CTRL(0),
+	  NETXEN_NIU_GB_MAX_FRAME_SIZE(0),
+	  NETXEN_NIU_GB_TEST_REG(0),
+	  NETXEN_NIU_GB_MII_MGMT_CONFIG(0),
+	  NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
+	  NETXEN_NIU_GB_MII_MGMT_ADDR(0),
+	  NETXEN_NIU_GB_MII_MGMT_CTRL(0),
+	  NETXEN_NIU_GB_MII_MGMT_STATUS(0),
+	  NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
+	  NETXEN_NIU_GB_INTERFACE_CTRL(0),
+	  NETXEN_NIU_GB_INTERFACE_STATUS(0),
+	  NETXEN_NIU_GB_STATION_ADDR_0(0),
+	  NETXEN_NIU_GB_STATION_ADDR_1(0),
+	  -1,
+	  }
+	 },
+	{
+	 /* XG Mode */
+	 {
+	  NETXEN_NIU_XG_SINGLE_TERM,
+	  NETXEN_NIU_XG_DRIVE_HI,
+	  NETXEN_NIU_XG_DRIVE_LO,
+	  NETXEN_NIU_XG_DTX,
+	  NETXEN_NIU_XG_DEQ,
+	  NETXEN_NIU_XG_WORD_ALIGN,
+	  NETXEN_NIU_XG_RESET,
+	  NETXEN_NIU_XG_POWER_DOWN,
+	  NETXEN_NIU_XG_RESET_PLL,
+	  NETXEN_NIU_XG_SERDES_LOOPBACK,
+	  NETXEN_NIU_XG_DO_BYTE_ALIGN,
+	  NETXEN_NIU_XG_TX_ENABLE,
+	  NETXEN_NIU_XG_RX_ENABLE,
+	  NETXEN_NIU_XG_STATUS,
+	  NETXEN_NIU_XG_PAUSE_THRESHOLD,
+	  NETXEN_NIU_XGE_CONFIG_0,
+	  NETXEN_NIU_XGE_CONFIG_1,
+	  NETXEN_NIU_XGE_IPG,
+	  NETXEN_NIU_XGE_STATION_ADDR_0_HI,
+	  NETXEN_NIU_XGE_STATION_ADDR_0_1,
+	  NETXEN_NIU_XGE_STATION_ADDR_1_LO,
+	  NETXEN_NIU_XGE_STATUS,
+	  NETXEN_NIU_XGE_MAX_FRAME_SIZE,
+	  NETXEN_NIU_XGE_PAUSE_FRAME_VALUE,
+	  NETXEN_NIU_XGE_TX_BYTE_CNT,
+	  NETXEN_NIU_XGE_TX_FRAME_CNT,
+	  NETXEN_NIU_XGE_RX_BYTE_CNT,
+	  NETXEN_NIU_XGE_RX_FRAME_CNT,
+	  NETXEN_NIU_XGE_AGGR_ERROR_CNT,
+	  NETXEN_NIU_XGE_MULTICAST_FRAME_CNT,
+	  NETXEN_NIU_XGE_UNICAST_FRAME_CNT,
+	  NETXEN_NIU_XGE_CRC_ERROR_CNT,
+	  NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR,
+	  NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR,
+	  NETXEN_NIU_XGE_LOCAL_ERROR_CNT,
+	  NETXEN_NIU_XGE_REMOTE_ERROR_CNT,
+	  NETXEN_NIU_XGE_CONTROL_CHAR_CNT,
+	  NETXEN_NIU_XGE_PAUSE_FRAME_CNT,
+	  -1,
+	  }
+	 }
+};
+
+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;
+	void *addr;
+	int i, window;
+
+	memset(p, 0, NETXEN_NIC_REGS_LEN);
+	regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
+	    (port->pdev)->device;
+	/* 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]);
+	/* GB/XGB Mode */
+	mode = (mode / 2) - 1;
+	window = 0;
+	if (mode <= 1) {
+		for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) {
+			/* GB: port specific registers */
+			if (mode == 0 && i >= 19)
+				window = port->portnum * 0x10000;
+
+			NETXEN_NIC_LOCKED_READ_REG
+			    (niu_registers[mode].reg[i - 3] + window,
+			     &regs_buff[i]);
+		}
+
+	}
+}
+
+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 */
+}
+
+static u32 netxen_nic_get_link(struct net_device *dev)
+{
+	struct netxen_port *port = netdev_priv(dev);
+	struct netxen_adapter *adapter = port->adapter;
+	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,
+					&status) != 0)
+			return -EIO;
+		else
+			return (netxen_get_phy_link(status));
+	} else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+		int val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
+		return val == XG_LINK_UP;
+	}
+	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 = (port->pdev)->vendor | ((port->pdev)->device << 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;
+
+	ring->rx_pending = 0;
+	for (i = 0; i < MAX_RCV_CTX; ++i) {
+		for (j = 0; j < NUM_RCV_DESC_RINGS; j++)
+			ring->rx_pending +=
+			    adapter->recv_ctx[i].rcv_desc[j].rcv_pending;
+	}
+
+	ring->rx_max_pending = adapter->max_rx_desc_count;
+	ring->tx_max_pending = adapter->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;
+	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 = netxen_gb_get_rx_flowctl(val);
+		pause->tx_pause = netxen_gb_get_tx_flowctl(val);
+		/* 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;
+	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);
+		if (pause->tx_pause)
+			netxen_gb_tx_flowctl(val);
+		else
+			netxen_gb_unset_tx_flowctl(val);
+		if (pause->rx_pause)
+			netxen_gb_rx_flowctl(val);
+		else
+			netxen_gb_unset_rx_flowctl(val);
+
+		netxen_nic_write_w0(adapter,
+				    NETXEN_NIU_GB_MAC_CONFIG_0(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;
+	u32 data_read, data_written, save;
+	netxen_niu_control mode;
+
+	/* 
+	 * first test the "Read Only" registers by writing which mode
+	 */
+	netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode);
+	if (netxen_get_niu_enable_ge(mode)) {	/* 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,
+	.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,
+	.get_tso = ethtool_op_get_tso,
+	.set_tso = ethtool_op_set_tso,
+	.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	[flat|nested] 18+ messages in thread

* [PATCH 2.6.17 6/9] NetXen: Main header file
  2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
                   ` (4 preceding siblings ...)
  2006-08-31 14:25 ` [PATCH 2.6.17 5/9] NetXen: ethtool interface Amit S. Kale
@ 2006-08-31 14:27 ` Amit S. Kale
  2006-08-31 14:29 ` [PATCH 2.6.17 7/9] NetXen: hw access routines " Amit S. Kale
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Amit S. Kale @ 2006-08-31 14:27 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, rob, unmproj, shemminger, brazilnut, wendyx, jeff

diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/netxen_nic.h linux-2.6.17/drivers/net/netxen/netxen_nic.h
--- linux-2.6.17.orig/drivers/net/netxen/netxen_nic.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/netxen_nic.h	2006-08-31 06:17:22.000000000 -0700
@@ -0,0 +1,901 @@
+/*
+ * 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"
+
+#define NETXEN_NIC_BUILD_NO     "232"
+#define _NETXEN_NIC_LINUX_MAJOR 2
+#define _NETXEN_NIC_LINUX_MINOR 3
+#define _NETXEN_NIC_LINUX_SUBVERSION 57
+#define NETXEN_NIC_LINUX_VERSIONID  "2.3.57"
+#define NETXEN_NIC_FW_VERSIONID "2.3.57"
+
+#define RCV_DESC_RINGSIZE	\
+	(sizeof(struct rcv_desc_t) * adapter->max_rx_desc_count)
+#define STATUS_DESC_RINGSIZE	\
+	(sizeof(struct status_desc_t)* adapter->max_rx_desc_count)
+#define TX_RINGSIZE	\
+	(sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count)
+#define RCV_BUFFSIZE	\
+	(sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count)
+#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 __iomem *)(ptrdiff_t)((adapter)->ahw.pci_base + (reg)	\
+	- NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST)
+
+#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 */
+enum {
+	TX_ETHER_PKT = 0x01,
+/* The following opcodes are for IP checksum	*/
+	TX_TCP_PKT,
+	TX_UDP_PKT,
+	TX_IP_PKT,
+	TX_TCP_LSO,
+	TX_IPSEC,
+	TX_IPSEC_CMD
+};
+
+/* 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) - 1))
+
+#define get_index_range(index,length,count)	\
+	(((index) + (count)) & ((length) - 1))
+
+/**
+ * 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
+
+#define CMD_DESC_TOTAL_LENGTH(cmd_desc)	\
+		((cmd_desc)->length_tcp_hdr & 0x00FFFFFF)
+#define CMD_DESC_TCP_HDR_OFFSET(cmd_desc)	\
+		(((cmd_desc)->length_tcp_hdr >> 24) & 0x0FF)
+#define CMD_DESC_PORT(cmd_desc)		((cmd_desc)->port_ctxid & 0x0F)
+#define CMD_DESC_CTX_ID(cmd_desc)	(((cmd_desc)->port_ctxid >> 4) & 0x0F)
+
+#define CMD_DESC_TOTAL_LENGTH_WRT(cmd_desc, var)	\
+		((cmd_desc)->length_tcp_hdr |= ((var) & 0x00FFFFFF))
+#define CMD_DESC_TCP_HDR_OFFSET_WRT(cmd_desc, var)	\
+		((cmd_desc)->length_tcp_hdr |= (((var) << 24) & 0xFF000000))
+#define CMD_DESC_PORT_WRT(cmd_desc, var)	\
+		((cmd_desc)->port_ctxid |= ((var) & 0x0F))
+
+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;
+	};
+
+	/* Bit pattern: 0-23 total length, 24-32 tcp header offset */
+	u32 length_tcp_hdr;
+	u8 ip_hdr_offset;	/* For LSO only */
+	u8 num_of_buffers;	/* total number of segments */
+	u8 flags;		/* as defined above */
+	u8 opcode;
+
+	u16 reference_handle;	/* changed to u16 to add mss */
+	u16 mss;		/* passed by NDIS_PACKET for LSO */
+	/* Bit pattern 0-3 port, 0-3 ctx id */
+	u8 port_ctxid;
+	u8 total_hdr_length;	/* LSO only : MAC+IP+TCP Hdr size */
+	u16 conn_id;		/* 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;
+	};
+
+	u16 buffer1_length;
+	u16 buffer2_length;
+	u16 buffer3_length;
+	u16 buffer4_length;
+
+	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 {
+	u16 reference_handle;
+	u16 reserved;
+	u32 buffer_length;	/* 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	(0x1)
+#define STATUS_OWNER_PHANTOM	(0x2)
+
+#define NETXEN_PROT_IP		(1)
+#define NETXEN_PROT_UNKNOWN	(0)
+
+/* Note: sizeof(status_desc) should always be a mutliple of 2 */
+#define STATUS_DESC_PORT(status_desc)	\
+		((status_desc)->port_status_type_op & 0x0F)
+#define STATUS_DESC_STATUS(status_desc)	\
+		(((status_desc)->port_status_type_op >> 4) & 0x0F)
+#define STATUS_DESC_TYPE(status_desc)	\
+		(((status_desc)->port_status_type_op >> 8) & 0x0F)
+#define STATUS_DESC_OPCODE(status_desc)	\
+		(((status_desc)->port_status_type_op >> 12) & 0x0F)
+
+struct status_desc_t {
+	/* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-15 opcode */
+	u16 port_status_type_op;
+	u16 total_length;	/* NIC mode */
+	u16 reference_handle;	/* handle for the associated packet */
+	/* Bit pattern: 0-1 owner, 2-5 protocol */
+	u16 owner;		/* Owner of the descriptor */
+} __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];
+};
+
+struct netxen_user_old_info {
+	u8 flash_md5[16];
+	u8 crbinit_md5[16];
+	u8 brdcfg_md5[16];
+	/* bootloader */
+	u32 bootld_version;
+	u32 bootld_size;
+	u8 bootld_md5[16];
+	/* image */
+	u32 image_version;
+	u32 image_size;
+	u8 image_md5[16];
+	/* primary image status */
+	u32 primary_status;
+	u32 secondary_present;
+
+	/* MAC address , 4 ports */
+	struct netxen_flash_mac_addr mac_addr[FLASH_NUM_PORTS];
+};
+#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.
+ */
+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 netxen_is_flash_supported(struct netxen_adapter *adapter);
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]);
+
+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;
+
+#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;
+	u16 port;
+	u8 cmd;
+	u8 frag_count;
+	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;
+	u16 ref_handle;
+	u16 state;
+};
+
+/* 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;
+	void __iomem *pci_base;	/* base of mapped phantom memory */
+	u8 revision_id;
+	u16 board_type;
+	u16 max_ports;
+	struct netxen_board_info boardcfg;
+	u32 xg_linkup;
+	/* Address of cmd ring in Phantom */
+	struct cmd_desc_type0_t *cmd_desc_head;
+	dma_addr_t cmd_desc_phys_addr;
+	struct netxen_adapter *adapter;
+};
+
+#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;
+};
+
+/*
+ * 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 */
+	dma_addr_t 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   */
+	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;
+	dma_addr_t rcv_status_desc_phys_addr;
+	struct status_desc_t *rcv_status_desc_head;
+};
+
+#define NETXEN_NIC_MSI_ENABLED 0x02
+
+/* 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[NETXEN_MAX_PORTS];	/* ptr to each port  */
+	spinlock_t tx_lock;
+	spinlock_t lock;
+	struct work_struct watchdog_task;
+	struct work_struct tx_timeout_task;
+	struct timer_list watchdog_timer;
+
+	u32 curr_window;
+
+	u32 cmd_producer;
+	u32 cmd_consumer;
+
+	u32 last_cmd_consumer;
+	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;
+
+	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_cmd_buffer *cmd_buf_arr;	/* Command buffers for xmit */
+
+	/*
+	 * Receive instances. These can be either one per port,
+	 * or one per peg, etc.
+	 */
+	struct netxen_recv_context recv_ctx[MAX_RCV_CTX];
+
+	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;
+
+	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[];
+
+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 */
+long netxen_niu_xginit(struct netxen_adapter *);
+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);
+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_set(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 netxen_phantom_init(struct netxen_adapter *adapter);
+void netxen_load_firmware(struct netxen_adapter *adapter);
+int netxen_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_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);
+void netxen_initialize_adapter_sw(struct netxen_adapter *adapter);
+void netxen_initialize_adapter_hw(struct netxen_adapter *adapter);
+int netxen_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);
+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);
+
+static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
+{
+	/*
+	 * ISR_INT_MASK: Can be read from window 0 or 1.
+	 */
+	writel(0x7ff, (void __iomem *)(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 __iomem *)(adapter->ahw.pci_base + ISR_INT_MASK));
+
+	if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+		mask = 0xbff;
+		writel(mask, (void __iomem *)
+		       (adapter->ahw.pci_base + ISR_INT_TARGET_MASK));
+	}
+}
+
+#endif				/* __NETXEN_NIC_H_ */


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2.6.17 7/9] NetXen: hw access routines header file
  2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
                   ` (5 preceding siblings ...)
  2006-08-31 14:27 ` [PATCH 2.6.17 6/9] NetXen: Main header file Amit S. Kale
@ 2006-08-31 14:29 ` Amit S. Kale
  2006-08-31 14:32 ` [PATCH 2.6.17 8/9] NetXen: Header file and ioctl " Amit S. Kale
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Amit S. Kale @ 2006-08-31 14:29 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, rob, unmproj, shemminger, brazilnut, wendyx, jeff

diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/netxen_nic_hw.h linux-2.6.17/drivers/net/netxen/netxen_nic_hw.h
--- linux-2.6.17.orig/drivers/net/netxen/netxen_nic_hw.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/netxen_nic_hw.h	2006-08-31 06:17:22.000000000 -0700
@@ -0,0 +1,499 @@
+/*
+ * 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_NIC_LOCKED_READ_REG(X, Y)   			\
+	addr = (void __iomem *)(adapter->ahw.pci_base + X);     \
+	*(u32 *)Y = readl(addr);
+
+#define NETXEN_NIC_LOCKED_WRITE_REG(X, Y)   			\
+	addr = (void __iomem *)(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;
+
+#define _netxen_crb_set_bit(var, bit)	(var |= (1 << bit))
+#define _netxen_crb_clear_bit(var, bit) (var &= (~(1 << bit)))
+#define _netxen_crb_get_bit(var, bit)	((var >> bit) & 0x1)
+
+/*
+ * NIU GB MAC Config Register 0 (applies to GB0, GB1, GB2, GB3)
+ *
+ *	Bit 0 : enable_tx => 1:enable frame xmit, 0:disable
+ *	Bit 1 : tx_synced => R/O: xmit enable synched to xmit stream
+ *	Bit 2 : enable_rx => 1:enable frame recv, 0:disable
+ *	Bit 3 : rx_synced => R/O: recv enable synched to recv stream
+ *	Bit 4 : tx_flowctl => 1:enable pause frame generation, 0:disable
+ *	Bit 5 : rx_flowctl => 1:act on recv'd pause frames, 0:ignore
+ *	Bit 8 : loopback => 1:loop MAC xmits to MAC recvs, 0:normal
+ *	Bit 16: tx_reset_pb => 1:reset frame xmit protocol blk, 0:no-op
+ *	Bit 17: rx_reset_pb => 1:reset frame recv protocol blk, 0:no-op
+ *	Bit 18: tx_reset_mac => 1:reset data/ctl multiplexer blk, 0:no-op
+ *	Bit 19: rx_reset_mac => 1:reset ctl frames & timers blk, 0:no-op
+ *	Bit 31: soft_reset => 1:reset the MAC and the SERDES, 0:no-op
+ */
+
+typedef netxen_crbword_t netxen_niu_gb_mac_config_0_t;
+
+#define netxen_gb_enable_tx(config_word) _netxen_crb_set_bit((config_word), 0)
+#define netxen_gb_enable_rx(config_word) _netxen_crb_set_bit((config_word), 2)
+#define netxen_gb_tx_flowctl(config_word) _netxen_crb_set_bit((config_word), 4)
+#define netxen_gb_rx_flowctl(config_word) _netxen_crb_set_bit((config_word), 5)
+#define netxen_gb_tx_reset_pb(config_word)	\
+		_netxen_crb_set_bit((config_word), 16)
+#define netxen_gb_rx_reset_pb(config_word)	\
+		_netxen_crb_set_bit((config_word), 17)
+#define netxen_gb_tx_reset_mac(config_word)	\
+		_netxen_crb_set_bit((config_word), 18)
+#define netxen_gb_rx_reset_mac(config_word)	\
+		_netxen_crb_set_bit((config_word), 19)
+#define netxen_gb_soft_reset(config_word)	\
+		_netxen_crb_set_bit((config_word), 31)
+
+#define netxen_gb_unset_tx_flowctl(config_word)	\
+		_netxen_crb_clear_bit((config_word), 4)
+#define netxen_gb_unset_rx_flowctl(config_word)	\
+		_netxen_crb_clear_bit((config_word), 5)
+
+#define netxen_gb_get_tx_synced(config_word)	\
+		_netxen_crb_get_bit((config_word), 1)
+#define netxen_gb_get_rx_synced(config_word)	\
+		_netxen_crb_get_bit((config_word), 3)
+#define netxen_gb_get_tx_flowctl(config_word)	\
+		_netxen_crb_get_bit((config_word), 4)
+#define netxen_gb_get_rx_flowctl(config_word)	\
+		_netxen_crb_get_bit((config_word), 5)
+#define netxen_gb_get_soft_reset(config_word)	\
+		_netxen_crb_get_bit((config_word), 31)
+
+/*
+ * NIU GB MAC Config Register 1 (applies to GB0, GB1, GB2, GB3)
+ *
+ *	Bit 0	    : duplex => 1:full duplex mode, 0:half duplex
+ *	Bit 1	    : crc_enable => 1:append CRC to xmit frames, 0:dont append
+ *	Bit 2	    : padshort => 1:pad short frames and add CRC, 0:dont pad
+ *	Bit 4	    : checklength => 1:check framelen with actual,0:dont check
+ *	Bit 5	    : hugeframes => 1:allow oversize xmit frames, 0:dont allow
+ *	Bits 8-9    : intfmode => 01:nibble (10/100), 10:byte (1000)
+ *	Bits 12-15  : preamblelen => preamble field length in bytes, default 7
+ */
+
+typedef netxen_crbword_t netxen_niu_gb_mac_config_1_t;
+
+#define netxen_gb_set_duplex(config_word)	\
+		_netxen_crb_set_bit(config_word, 0)
+#define netxen_gb_set_crc_enable(config_word)	\
+		_netxen_crb_set_bit(config_word, 1)
+#define netxen_gb_set_padshort(config_word)	\
+		_netxen_crb_set_bit(config_word, 2)
+#define netxen_gb_set_checklength(config_word)	\
+		_netxen_crb_set_bit(config_word, 4)
+#define netxen_gb_set_hugeframes(config_word)	\
+		_netxen_crb_set_bit(config_word, 5)
+#define netxen_gb_set_preamblelen(config_word, val)	\
+		((config_word) |= ((val) << 12) & 0xF000)
+#define netxen_gb_set_intfmode(config_word, val)		\
+		((config_word) |= ((val) << 8) & 0x300)
+
+/*
+ * NIU GB Station Address High Register
+ * NOTE: this value is in network byte order.
+ * station address [47:16]
+ */
+
+typedef netxen_crbword_t netxen_niu_gb_station_address_high;
+
+/*
+ * NIU GB Station Address Low Register
+ * NOTE: this value is in network byte order.
+ * station address [15:0]
+ */
+
+typedef netxen_crbword_t netxen_niu_gb_station_address_low;
+
+#define netxen_gb_get_stationaddress_low(config_word) ((config_word) >> 16)
+
+/*
+ * NIU GB MII Mgmt Config Register (applies to GB0, GB1, GB2, GB3)
+ *
+ * Bits 0-2 : clockselect => 0:clk/4,  1:clk/4,  2:clk/6,  3:clk/8
+ *			     4:clk/10, 5:clk/14, 6:clk/20, 7:clk/28
+ * Bit 4    : nopreamble => 1:suppress preamble generation, 0:normal
+ * Bit 5    : scanauto
+ * Bit 31   : reset => 1:reset MII mgmt, 0:no-op
+ */
+
+typedef netxen_crbword_t netxen_niu_gb_mii_mgmt_config;
+
+#define netxen_gb_set_mii_mgmt_clockselect(config_word, val)	\
+		((config_word) |= ((val) & 0x07))
+#define netxen_gb_mii_mgmt_reset(config_word)	\
+		_netxen_crb_set_bit(config_word, 31)
+#define netxen_gb_mii_mgmt_unset(config_word)	\
+		_netxen_crb_clear_bit(config_word, 31)
+
+/*
+ * NIU GB MII Mgmt Command Register (applies to GB0, GB1, GB2, GB3)
+ * Bit 0 : read_cycle => 1:perform single read cycle, 0:no-op
+ * Bit 1 : scan_cycle => 1:perform continuous read cycles, 0:no-op
+ */
+
+#define netxen_gb_mii_mgmt_set_read_cycle(config_word)	\
+		_netxen_crb_set_bit(config_word, 0)
+typedef netxen_crbword_t netxen_niu_gb_mii_mgmt_command;
+
+/*
+ * NIU GB MII Mgmt Address Register (applies to GB0, GB1, GB2, GB3)
+ * Bits 0-4  : reg_addr => which mgmt register we want to talk to
+ * Bits 8-12 : phy_addr => which PHY to talk to (0 is reserved)
+ */
+
+typedef netxen_crbword_t netxen_niu_gb_mii_mgmt_address;
+
+#define netxen_gb_mii_mgmt_reg_addr(config_word, val)	\
+		((config_word) |= ((val) & 0x1F))
+#define netxen_gb_mii_mgmt_phy_addr(config_word, val)	\
+		((config_word) |= (((val) & 0x1F) << 8))
+
+/*
+ * NIU GB MII Mgmt Indicators Register (applies to GB0, GB1, GB2, GB3)
+ * Read-only register.
+ * Bit 0 : busy => 1:performing an MII mgmt cycle, 0:idle
+ * Bit 1 : scanning => 1:scan operation in progress, 0:idle
+ * Bit 2 : notvalid => :mgmt result data not yet valid, 0:idle
+ */
+typedef netxen_crbword_t netxen_niu_gb_mii_mgmt_indicators;
+
+#define netxen_get_gb_mii_mgmt_busy(config_word)	\
+		_netxen_crb_get_bit(config_word, 0)
+#define netxen_get_gb_mii_mgmt_scanning(config_word)	\
+		_netxen_crb_get_bit(config_word, 1)
+#define netxen_get_gb_mii_mgmt_notvalid(config_word)	\
+		_netxen_crb_get_bit(config_word, 2)
+
+/*
+ * 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).
+ *
+ * Bit 0      : jabber => 1:jabber detected, 0:not
+ * Bit 1      : polarity => 1:polarity reversed, 0:normal
+ * Bit 2      : recvpause => 1:receive pause enabled, 0:disabled
+ * Bit 3      : xmitpause => 1:transmit pause enabled, 0:disabled
+ * Bit 4      : energydetect => 1:sleep, 0:active
+ * Bit 5      : downshift => 1:downshift, 0:no downshift
+ * Bit 6      : crossover => 1:MDIX (crossover), 0:MDI (no crossover)
+ * Bits 7-9   : cablelen => not valid in 10Mb/s mode
+ *			0:<50m, 1:50-80m, 2:80-110m, 3:110-140m, 4:>140m
+ * Bit 10     : link => 1:link up, 0:link down
+ * Bit 11     : resolved => 1:speed and duplex resolved, 0:not yet
+ * Bit 12     : pagercvd => 1:page received, 0:page not received
+ * Bit 13     : duplex => 1:full duplex, 0:half duplex
+ * Bits 14-15 : speed => 0:10Mb/s, 1:100Mb/s, 2:1000Mb/s, 3:rsvd
+ */
+
+typedef netxen_crbword_t netxen_niu_phy_status;
+
+#define netxen_get_phy_cablelen(config_word) (((config_word) >> 7) & 0x07)
+#define netxen_get_phy_speed(config_word) (((config_word) >> 14) & 0x03)
+
+#define netxen_set_phy_speed(config_word, val)	\
+		((config_word) |= ((val & 0x03) << 14))
+#define netxen_set_phy_duplex(config_word)	\
+		_netxen_crb_set_bit(config_word, 13)
+#define netxen_clear_phy_duplex(config_word)	\
+		_netxen_crb_clear_bit(config_word, 13)
+
+#define netxen_get_phy_jabber(config_word)	\
+		_netxen_crb_get_bit(config_word, 0)
+#define netxen_get_phy_polarity(config_word)	\
+		_netxen_crb_get_bit(config_word, 1)
+#define netxen_get_phy_recvpause(config_word)	\
+		_netxen_crb_get_bit(config_word, 2)
+#define netxen_get_phy_xmitpause(config_word)	\
+		_netxen_crb_get_bit(config_word, 3)
+#define netxen_get_phy_energydetect(config_word) \
+		_netxen_crb_get_bit(config_word, 4)
+#define netxen_get_phy_downshift(config_word)	\
+		_netxen_crb_get_bit(config_word, 5)
+#define netxen_get_phy_crossover(config_word)	\
+		_netxen_crb_get_bit(config_word, 6)
+#define netxen_get_phy_link(config_word)	\
+		_netxen_crb_get_bit(config_word, 10)
+#define netxen_get_phy_resolved(config_word)	\
+		_netxen_crb_get_bit(config_word, 11)
+#define netxen_get_phy_pagercvd(config_word)	\
+		_netxen_crb_get_bit(config_word, 12)
+#define netxen_get_phy_duplex(config_word)	\
+		_netxen_crb_get_bit(config_word, 13)
+
+/*
+ * Interrupt Register definition
+ * This definition applies to registers 18 and 19 (int enable and int status).
+ * Bit 0 : jabber
+ * Bit 1 : polarity_changed
+ * Bit 4 : energy_detect
+ * Bit 5 : downshift
+ * Bit 6 : mdi_xover_changed
+ * Bit 7 : fifo_over_underflow
+ * Bit 8 : false_carrier
+ * Bit 9 : symbol_error
+ * Bit 10: link_status_changed
+ * Bit 11: autoneg_completed
+ * Bit 12: page_received
+ * Bit 13: duplex_changed
+ * Bit 14: speed_changed
+ * Bit 15: autoneg_error
+ */
+
+typedef netxen_crbword_t netxen_niu_phy_interrupt;
+
+#define netxen_get_phy_int_jabber(config_word)	\
+		_netxen_crb_get_bit(config_word, 0)
+#define netxen_get_phy_int_polarity_changed(config_word)	\
+		_netxen_crb_get_bit(config_word, 1)
+#define netxen_get_phy_int_energy_detect(config_word)	\
+		_netxen_crb_get_bit(config_word, 4)
+#define netxen_get_phy_int_downshift(config_word)	\
+		_netxen_crb_get_bit(config_word, 5)
+#define netxen_get_phy_int_mdi_xover_changed(config_word)	\
+		_netxen_crb_get_bit(config_word, 6)
+#define netxen_get_phy_int_fifo_over_underflow(config_word)	\
+		_netxen_crb_get_bit(config_word, 7)
+#define netxen_get_phy_int_false_carrier(config_word)	\
+		_netxen_crb_get_bit(config_word, 8)
+#define netxen_get_phy_int_symbol_error(config_word)	\
+		_netxen_crb_get_bit(config_word, 9)
+#define netxen_get_phy_int_link_status_changed(config_word)	\
+		_netxen_crb_get_bit(config_word, 10)
+#define netxen_get_phy_int_autoneg_completed(config_word)	\
+		_netxen_crb_get_bit(config_word, 11)
+#define netxen_get_phy_int_page_received(config_word)	\
+		_netxen_crb_get_bit(config_word, 12)
+#define netxen_get_phy_int_duplex_changed(config_word)	\
+		_netxen_crb_get_bit(config_word, 13)
+#define netxen_get_phy_int_speed_changed(config_word)	\
+		_netxen_crb_get_bit(config_word, 14)
+#define netxen_get_phy_int_autoneg_error(config_word)	\
+		_netxen_crb_get_bit(config_word, 15)
+
+#define netxen_set_phy_int_link_status_changed(config_word)	\
+		_netxen_crb_set_bit(config_word, 10)
+#define netxen_set_phy_int_autoneg_completed(config_word)	\
+		_netxen_crb_set_bit(config_word, 11)
+#define netxen_set_phy_int_speed_changed(config_word)	\
+		_netxen_crb_set_bit(config_word, 14)
+
+/*
+ * NIU Mode Register.
+ * Bit 0 : enable FibreChannel
+ * Bit 1 : enable 10/100/1000 Ethernet
+ * Bit 2 : enable 10Gb Ethernet
+ */
+
+typedef netxen_crbword_t netxen_niu_control;
+
+#define netxen_get_niu_enable_ge(config_word)	\
+		_netxen_crb_get_bit(config_word, 1)
+
+/* 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
+ * 
+ * Bit 0 : drop_gb0 => 1:drop pkts with bad CRCs, 0:pass them on
+ * Bit 1 : drop_gb1 => 1:drop pkts with bad CRCs, 0:pass them on
+ * Bit 2 : drop_gb2 => 1:drop pkts with bad CRCs, 0:pass them on
+ * Bit 3 : drop_gb3 => 1:drop pkts with bad CRCs, 0:pass them on
+ */
+
+typedef netxen_crbword_t netxen_niu_gb_drop_crc;
+
+#define netxen_set_gb_drop_gb0(config_word)	\
+		_netxen_crb_set_bit(config_word, 0)
+#define netxen_set_gb_drop_gb1(config_word)	\
+		_netxen_crb_set_bit(config_word, 1)
+#define netxen_set_gb_drop_gb2(config_word)	\
+		_netxen_crb_set_bit(config_word, 2)
+#define netxen_set_gb_drop_gb3(config_word)	\
+		_netxen_crb_set_bit(config_word, 3)
+
+#define netxen_clear_gb_drop_gb0(config_word)	\
+		_netxen_crb_clear_bit(config_word, 0)
+#define netxen_clear_gb_drop_gb1(config_word)	\
+		_netxen_crb_clear_bit(config_word, 1)
+#define netxen_clear_gb_drop_gb2(config_word)	\
+		_netxen_crb_clear_bit(config_word, 2)
+#define netxen_clear_gb_drop_gb3(config_word)	\
+		_netxen_crb_clear_bit(config_word, 3)
+
+/*
+ * NIU XG MAC Config Register
+ *
+ * Bit 0 : tx_enable => 1:enable frame xmit, 0:disable
+ * Bit 2 : rx_enable => 1:enable frame recv, 0:disable
+ * Bit 4 : soft_reset => 1:reset the MAC , 0:no-op
+ * Bit 27: xaui_framer_reset
+ * Bit 28: xaui_rx_reset
+ * Bit 29: xaui_tx_reset
+ * Bit 30: xg_ingress_afifo_reset
+ * Bit 31: xg_egress_afifo_reset
+ */
+
+typedef netxen_crbword_t netxen_niu_xg_mac_config_0_t;
+
+#define netxen_xg_soft_reset(config_word)	\
+		_netxen_crb_set_bit(config_word, 4)
+
+/* 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	[flat|nested] 18+ messages in thread

* [PATCH 2.6.17 8/9] NetXen: Header file and ioctl header file
  2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
                   ` (6 preceding siblings ...)
  2006-08-31 14:29 ` [PATCH 2.6.17 7/9] NetXen: hw access routines " Amit S. Kale
@ 2006-08-31 14:32 ` Amit S. Kale
  2006-08-31 14:36 ` [PATCH 2.6.17 9/9] NetXen: CRB reg definitions Amit S. Kale
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Amit S. Kale @ 2006-08-31 14:32 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, rob, unmproj, shemminger, brazilnut, wendyx, jeff

diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/netxen_nic_hdr.h linux-2.6.17/drivers/net/netxen/netxen_nic_hdr.h
--- linux-2.6.17.orig/drivers/net/netxen/netxen_nic_hdr.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/netxen_nic_hdr.h	2006-08-31 06:17:22.000000000 -0700
@@ -0,0 +1,611 @@
+/*
+ * 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 */
+
+/*
+ * The basic unit of access when reading/writing control registers.
+ */
+
+typedef __le32 netxen_crbword_t;	/* single word in CRB space */
+
+enum {
+	NETXEN_HW_H0_CH_HUB_ADR = 0x05,
+	NETXEN_HW_H1_CH_HUB_ADR = 0x0E,
+	NETXEN_HW_H2_CH_HUB_ADR = 0x03,
+	NETXEN_HW_H3_CH_HUB_ADR = 0x01,
+	NETXEN_HW_H4_CH_HUB_ADR = 0x06,
+	NETXEN_HW_H5_CH_HUB_ADR = 0x07,
+	NETXEN_HW_H6_CH_HUB_ADR = 0x08
+};
+
+/*  Hub 0 */
+enum {
+	NETXEN_HW_MN_CRB_AGT_ADR = 0x15,
+	NETXEN_HW_MS_CRB_AGT_ADR = 0x25
+};
+
+/*  Hub 1 */
+enum {
+	NETXEN_HW_PS_CRB_AGT_ADR = 0x73,
+	NETXEN_HW_SS_CRB_AGT_ADR = 0x20,
+	NETXEN_HW_RPMX3_CRB_AGT_ADR = 0x0b,
+	NETXEN_HW_QMS_CRB_AGT_ADR = 0x00,
+	NETXEN_HW_SQGS0_CRB_AGT_ADR = 0x01,
+	NETXEN_HW_SQGS1_CRB_AGT_ADR = 0x02,
+	NETXEN_HW_SQGS2_CRB_AGT_ADR = 0x03,
+	NETXEN_HW_SQGS3_CRB_AGT_ADR = 0x04,
+	NETXEN_HW_C2C0_CRB_AGT_ADR = 0x58,
+	NETXEN_HW_C2C1_CRB_AGT_ADR = 0x59,
+	NETXEN_HW_C2C2_CRB_AGT_ADR = 0x5a,
+	NETXEN_HW_RPMX2_CRB_AGT_ADR = 0x0a,
+	NETXEN_HW_RPMX4_CRB_AGT_ADR = 0x0c,
+	NETXEN_HW_RPMX7_CRB_AGT_ADR = 0x0f,
+	NETXEN_HW_RPMX9_CRB_AGT_ADR = 0x12,
+	NETXEN_HW_SMB_CRB_AGT_ADR = 0x18
+};
+
+/*  Hub 2 */
+enum {
+	NETXEN_HW_NIU_CRB_AGT_ADR = 0x31,
+	NETXEN_HW_I2C0_CRB_AGT_ADR = 0x19,
+	NETXEN_HW_I2C1_CRB_AGT_ADR = 0x29,
+
+	NETXEN_HW_SN_CRB_AGT_ADR = 0x10,
+	NETXEN_HW_I2Q_CRB_AGT_ADR = 0x20,
+	NETXEN_HW_LPC_CRB_AGT_ADR = 0x22,
+	NETXEN_HW_ROMUSB_CRB_AGT_ADR = 0x21,
+	NETXEN_HW_QM_CRB_AGT_ADR = 0x66,
+	NETXEN_HW_SQG0_CRB_AGT_ADR = 0x60,
+	NETXEN_HW_SQG1_CRB_AGT_ADR = 0x61,
+	NETXEN_HW_SQG2_CRB_AGT_ADR = 0x62,
+	NETXEN_HW_SQG3_CRB_AGT_ADR = 0x63,
+	NETXEN_HW_RPMX1_CRB_AGT_ADR = 0x09,
+	NETXEN_HW_RPMX5_CRB_AGT_ADR = 0x0d,
+	NETXEN_HW_RPMX6_CRB_AGT_ADR = 0x0e,
+	NETXEN_HW_RPMX8_CRB_AGT_ADR = 0x11
+};
+
+/*  Hub 3 */
+enum {
+	NETXEN_HW_PH_CRB_AGT_ADR = 0x1A,
+	NETXEN_HW_SRE_CRB_AGT_ADR = 0x50,
+	NETXEN_HW_EG_CRB_AGT_ADR = 0x51,
+	NETXEN_HW_RPMX0_CRB_AGT_ADR = 0x08
+};
+
+/*  Hub 4 */
+enum {
+	NETXEN_HW_PEGN0_CRB_AGT_ADR = 0x40,
+	NETXEN_HW_PEGN1_CRB_AGT_ADR,
+	NETXEN_HW_PEGN2_CRB_AGT_ADR,
+	NETXEN_HW_PEGN3_CRB_AGT_ADR,
+	NETXEN_HW_PEGNI_CRB_AGT_ADR,
+	NETXEN_HW_PEGND_CRB_AGT_ADR,
+	NETXEN_HW_PEGNC_CRB_AGT_ADR,
+	NETXEN_HW_PEGR0_CRB_AGT_ADR,
+	NETXEN_HW_PEGR1_CRB_AGT_ADR,
+	NETXEN_HW_PEGR2_CRB_AGT_ADR,
+	NETXEN_HW_PEGR3_CRB_AGT_ADR
+};
+
+/*  Hub 5 */
+enum {
+	NETXEN_HW_PEGS0_CRB_AGT_ADR = 0x40,
+	NETXEN_HW_PEGS1_CRB_AGT_ADR,
+	NETXEN_HW_PEGS2_CRB_AGT_ADR,
+	NETXEN_HW_PEGS3_CRB_AGT_ADR,
+	NETXEN_HW_PEGSI_CRB_AGT_ADR,
+	NETXEN_HW_PEGSD_CRB_AGT_ADR,
+	NETXEN_HW_PEGSC_CRB_AGT_ADR
+};
+
+/*  Hub 6 */
+enum {
+	NETXEN_HW_CAS0_CRB_AGT_ADR = 0x46,
+	NETXEN_HW_CAS1_CRB_AGT_ADR = 0x47,
+	NETXEN_HW_CAS2_CRB_AGT_ADR = 0x48,
+	NETXEN_HW_CAS3_CRB_AGT_ADR = 0x49,
+	NETXEN_HW_NCM_CRB_AGT_ADR = 0x16,
+	NETXEN_HW_TMR_CRB_AGT_ADR = 0x17,
+	NETXEN_HW_XDMA_CRB_AGT_ADR = 0x05,
+	NETXEN_HW_OCM0_CRB_AGT_ADR = 0x06,
+	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 */
+enum {
+	NETXEN_HW_PX_MAP_CRB_PH = 0,
+	NETXEN_HW_PX_MAP_CRB_PS,
+	NETXEN_HW_PX_MAP_CRB_MN,
+	NETXEN_HW_PX_MAP_CRB_MS,
+	NETXEN_HW_PX_MAP_CRB_PGR1,
+	NETXEN_HW_PX_MAP_CRB_SRE,
+	NETXEN_HW_PX_MAP_CRB_NIU,
+	NETXEN_HW_PX_MAP_CRB_QMN,
+	NETXEN_HW_PX_MAP_CRB_SQN0,
+	NETXEN_HW_PX_MAP_CRB_SQN1,
+	NETXEN_HW_PX_MAP_CRB_SQN2,
+	NETXEN_HW_PX_MAP_CRB_SQN3,
+	NETXEN_HW_PX_MAP_CRB_QMS,
+	NETXEN_HW_PX_MAP_CRB_SQS0,
+	NETXEN_HW_PX_MAP_CRB_SQS1,
+	NETXEN_HW_PX_MAP_CRB_SQS2,
+	NETXEN_HW_PX_MAP_CRB_SQS3,
+	NETXEN_HW_PX_MAP_CRB_PGN0,
+	NETXEN_HW_PX_MAP_CRB_PGN1,
+	NETXEN_HW_PX_MAP_CRB_PGN2,
+	NETXEN_HW_PX_MAP_CRB_PGN3,
+	NETXEN_HW_PX_MAP_CRB_PGND,
+	NETXEN_HW_PX_MAP_CRB_PGNI,
+	NETXEN_HW_PX_MAP_CRB_PGS0,
+	NETXEN_HW_PX_MAP_CRB_PGS1,
+	NETXEN_HW_PX_MAP_CRB_PGS2,
+	NETXEN_HW_PX_MAP_CRB_PGS3,
+	NETXEN_HW_PX_MAP_CRB_PGSD,
+	NETXEN_HW_PX_MAP_CRB_PGSI,
+	NETXEN_HW_PX_MAP_CRB_SN,
+	NETXEN_HW_PX_MAP_CRB_PGR2,
+	NETXEN_HW_PX_MAP_CRB_EG,
+	NETXEN_HW_PX_MAP_CRB_PH2,
+	NETXEN_HW_PX_MAP_CRB_PS2,
+	NETXEN_HW_PX_MAP_CRB_CAM,
+	NETXEN_HW_PX_MAP_CRB_CAS0,
+	NETXEN_HW_PX_MAP_CRB_CAS1,
+	NETXEN_HW_PX_MAP_CRB_CAS2,
+	NETXEN_HW_PX_MAP_CRB_C2C0,
+	NETXEN_HW_PX_MAP_CRB_C2C1,
+	NETXEN_HW_PX_MAP_CRB_TIMR,
+	NETXEN_HW_PX_MAP_CRB_PGR3,
+	NETXEN_HW_PX_MAP_CRB_RPMX1,
+	NETXEN_HW_PX_MAP_CRB_RPMX2,
+	NETXEN_HW_PX_MAP_CRB_RPMX3,
+	NETXEN_HW_PX_MAP_CRB_RPMX4,
+	NETXEN_HW_PX_MAP_CRB_RPMX5,
+	NETXEN_HW_PX_MAP_CRB_RPMX6,
+	NETXEN_HW_PX_MAP_CRB_RPMX7,
+	NETXEN_HW_PX_MAP_CRB_XDMA,
+	NETXEN_HW_PX_MAP_CRB_I2Q,
+	NETXEN_HW_PX_MAP_CRB_ROMUSB,
+	NETXEN_HW_PX_MAP_CRB_CAS3,
+	NETXEN_HW_PX_MAP_CRB_RPMX0,
+	NETXEN_HW_PX_MAP_CRB_RPMX8,
+	NETXEN_HW_PX_MAP_CRB_RPMX9,
+	NETXEN_HW_PX_MAP_CRB_OCM0,
+	NETXEN_HW_PX_MAP_CRB_OCM1,
+	NETXEN_HW_PX_MAP_CRB_SMB,
+	NETXEN_HW_PX_MAP_CRB_I2C0,
+	NETXEN_HW_PX_MAP_CRB_I2C1,
+	NETXEN_HW_PX_MAP_CRB_LPC,
+	NETXEN_HW_PX_MAP_CRB_PGNC,
+	NETXEN_HW_PX_MAP_CRB_PGR0
+};
+
+/*  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)
+
+/*
+ * 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	(0x00000000UL)
+#define NETXEN_PCI_QDR_NET	(0x04000000UL)
+#define NETXEN_PCI_DIRECT_CRB	(0x04400000UL)
+#define NETXEN_PCI_CAMQM_MAX	(0x04ffffffUL)
+#define NETXEN_PCI_OCM0		(0x05000000UL)
+#define NETXEN_PCI_OCM0_MAX	(0x050fffffUL)
+#define NETXEN_PCI_OCM1		(0x05100000UL)
+#define NETXEN_PCI_OCM1_MAX	(0x051fffffUL)
+#define NETXEN_PCI_CRBSPACE	(0x06000000UL)
+
+#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))
+
+#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_ */
diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/netxen_nic_ioctl.h linux-2.6.17/drivers/net/netxen/netxen_nic_ioctl.h
--- linux-2.6.17.orig/drivers/net/netxen/netxen_nic_ioctl.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/netxen_nic_ioctl.h	2006-08-31 06:17:22.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_ */


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2.6.17 9/9] NetXen: CRB reg definitions
  2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
                   ` (7 preceding siblings ...)
  2006-08-31 14:32 ` [PATCH 2.6.17 8/9] NetXen: Header file and ioctl " Amit S. Kale
@ 2006-08-31 14:36 ` Amit S. Kale
  2006-09-01 18:44 ` [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Pradeep Dalvi
  2006-09-11 13:12 ` Jeff Garzik
  10 siblings, 0 replies; 18+ messages in thread
From: Amit S. Kale @ 2006-08-31 14:36 UTC (permalink / raw)
  To: netdev; +Cc: sanjeev, rob, unmproj, shemminger, brazilnut, wendyx, jeff

diff -Narup -X linux-2.6.17.orig/Documentation/dontdiff linux-2.6.17.orig/drivers/net/netxen/netxen_nic_phan_reg.h linux-2.6.17/drivers/net/netxen/netxen_nic_phan_reg.h
--- linux-2.6.17.orig/drivers/net/netxen/netxen_nic_phan_reg.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.17/drivers/net/netxen/netxen_nic_phan_reg.h	2006-08-31 06:17:22.000000000 -0700
@@ -0,0 +1,195 @@
+/*
+ * 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 __NIC_PHAN_REG_H_
+#define __NIC_PHAN_REG_H_
+
+/** 
+ * CRB Registers or queue message done only at initialization time....
+ **/
+
+/**
+ * The following 2 are the base adresses for the CRB registers and their
+ * offsets will be added to get addresses for the index addresses.......
+ **/
+#define NIC_CRB_BASE_PORT1	NETXEN_CAM_RAM(0x200)
+#define NIC_CRB_BASE_PORT2	NETXEN_CAM_RAM(0x250)
+
+#define NETXEN_NIC_REG(X)	(NIC_CRB_BASE_PORT1+(X))
+
+/**
+ * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
+ * which can be read by the Phantom host to get producer/consumer indexes from
+ * Phantom/Casper. If it is not HOST_SHARED_MEMORY, then the following
+ * registers will be used for the addresses of the ring's shared memory
+ * on the Phantom.
+ **/
+
+#define CRB_PHAN_CNTRL_LO_OFFSET	NETXEN_NIC_REG(0x00)
+#define CRB_PHAN_CNTRL_HI_OFFSET	NETXEN_NIC_REG(0x04)
+
+/* point to the indexes */
+#define CRB_CMD_PRODUCER_OFFSET		NETXEN_NIC_REG(0x08)
+#define CRB_CMD_CONSUMER_OFFSET		NETXEN_NIC_REG(0x0c)
+
+/* address of command descriptors in the host memory */
+#define CRB_HOST_CMD_ADDR_HI		NETXEN_NIC_REG(0x30)
+#define CRB_HOST_CMD_ADDR_LO		NETXEN_NIC_REG(0x34)
+
+/* The following 4 CRB registers are for doing performance coal */
+#define CRB_CMD_INTR_LOOP		NETXEN_NIC_REG(0x38)
+#define CRB_CMD_DMA_LOOP		NETXEN_NIC_REG(0x3c)
+#define CRB_RCV_INTR_LOOP		NETXEN_NIC_REG(0x40)
+#define CRB_RCV_DMA_LOOP		NETXEN_NIC_REG(0x44)
+
+/* Needed by the host to find out the state of Phantom's initialization */
+#define CRB_ENABLE_TX_INTR		NETXEN_NIC_REG(0x4c)
+#define CRB_CMDPEG_STATE		NETXEN_NIC_REG(0x50)
+#define CRB_CMDPEG_CMDRING		NETXEN_NIC_REG(0x54)
+
+/* Interrupt coalescing parameters */
+#define CRB_GLOBAL_INT_COAL		NETXEN_NIC_REG(0x80)
+#define CRB_INT_COAL_MODE		NETXEN_NIC_REG(0x84)
+#define CRB_MAX_RCV_BUFS		NETXEN_NIC_REG(0x88)
+#define CRB_TX_INT_THRESHOLD		NETXEN_NIC_REG(0x8c)
+#define CRB_RX_PKT_TIMER		NETXEN_NIC_REG(0x90)
+#define CRB_TX_PKT_TIMER		NETXEN_NIC_REG(0x94)
+#define CRB_RX_PKT_CNT			NETXEN_NIC_REG(0x98)
+#define CRB_RX_TMR_CNT			NETXEN_NIC_REG(0x9c)
+
+/* Register for communicating XG link status */
+#define CRB_XG_STATE			NETXEN_NIC_REG(0xa0)
+
+/* Debug registers for controlling NIC pkt gen agent */
+#define CRB_AGENT_GO			NETXEN_NIC_REG(0xb0)
+#define CRB_AGENT_TX_SIZE		NETXEN_NIC_REG(0xb4)
+#define CRB_AGENT_TX_TYPE		NETXEN_NIC_REG(0xb8)
+#define CRB_AGENT_TX_ADDR		NETXEN_NIC_REG(0xbc)
+#define CRB_AGENT_TX_MSS		NETXEN_NIC_REG(0xc0)
+
+/* Debug registers for observing NIC performance */
+#define CRB_TX_STATE			NETXEN_NIC_REG(0xd0)
+#define CRB_TX_COUNT			NETXEN_NIC_REG(0xd4)
+#define CRB_RX_STATE			NETXEN_NIC_REG(0xd8)
+
+/* CRB registers per Rcv Descriptor ring */
+struct netxen_rcv_desc_crb {
+	u32 crb_rcv_producer_offset __attribute__ ((aligned(512)));
+	u32 crb_rcv_consumer_offset;
+	u32 crb_globalrcv_ring;
+};
+
+/*
+ * CRB registers used by the receive peg logic. One instance of these
+ * needs to be instantiated per instance of the receive peg.
+ */
+
+struct netxen_recv_crb {
+	struct netxen_rcv_desc_crb rcv_desc_crb[NUM_RCV_DESC_RINGS];
+	u32 crb_rcvstatus_ring;
+	u32 crb_rcv_status_producer;
+	u32 crb_rcv_status_consumer;
+	u32 crb_rcvpeg_state;
+};
+
+#if defined(DEFINE_GLOBAL_RECV_CRB)
+struct netxen_recv_crb recv_crb_registers[] = {
+	/*
+	 * Instance 0.
+	 */
+	{
+	 /* rcv_desc_crb: */
+	 {
+	  {
+	   /* crb_rcv_producer_offset: */
+	   NETXEN_NIC_REG(0x18),
+	   /* crb_rcv_consumer_offset: */
+	   NETXEN_NIC_REG(0x1c),
+	   /* crb_gloablrcv_ring: */
+	   NETXEN_NIC_REG(0x20),
+	   },
+	  /* Jumbo frames */
+	  {
+	   /* crb_rcv_producer_offset: */
+	   NETXEN_NIC_REG(0x100),
+	   /* crb_rcv_consumer_offset: */
+	   NETXEN_NIC_REG(0x104),
+	   /* crb_gloablrcv_ring: */
+	   NETXEN_NIC_REG(0x108),
+	   }
+	  },
+	 /* crb_rcvstatus_ring: */
+	 NETXEN_NIC_REG(0x24),
+	 /* crb_rcv_status_producer: */
+	 NETXEN_NIC_REG(0x28),
+	 /* crb_rcv_status_consumer: */
+	 NETXEN_NIC_REG(0x2c),
+	 /* crb_rcvpeg_state: */
+	 NETXEN_NIC_REG(0x48),
+
+	 },
+	/*
+	 * Instance 1,
+	 */
+	{
+	 /* rcv_desc_crb: */
+	 {
+	  {
+	   /* crb_rcv_producer_offset: */
+	   NETXEN_NIC_REG(0x80),
+	   /* crb_rcv_consumer_offset: */
+	   NETXEN_NIC_REG(0x84),
+	   /* crb_globalrcv_ring: */
+	   NETXEN_NIC_REG(0x88),
+	   },
+	  /* Jumbo frames */
+	  {
+	   /* crb_rcv_producer_offset: */
+	   NETXEN_NIC_REG(0x10C),
+	   /* crb_rcv_consumer_offset: */
+	   NETXEN_NIC_REG(0x110),
+	   /* crb_globalrcv_ring: */
+	   NETXEN_NIC_REG(0x114),
+	   }
+	  },
+	 /* crb_rcvstatus_ring: */
+	 NETXEN_NIC_REG(0x8c),
+	 /* crb_rcv_status_producer: */
+	 NETXEN_NIC_REG(0x90),
+	 /* crb_rcv_status_consumer: */
+	 NETXEN_NIC_REG(0x94),
+	 /* crb_rcvpeg_state: */
+	 NETXEN_NIC_REG(0x98),
+	 },
+};
+#else
+extern struct netxen_recv_crb recv_crb_registers[];
+#endif				/* DEFINE_GLOBAL_RECEIVE_CRB */
+
+#endif				/* __NIC_PHAN_REG_H_ */


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver
  2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
                   ` (8 preceding siblings ...)
  2006-08-31 14:36 ` [PATCH 2.6.17 9/9] NetXen: CRB reg definitions Amit S. Kale
@ 2006-09-01 18:44 ` Pradeep Dalvi
  2006-09-11 13:12 ` Jeff Garzik
  10 siblings, 0 replies; 18+ messages in thread
From: Pradeep Dalvi @ 2006-09-01 18:44 UTC (permalink / raw)
  To: netdev
  Cc: Sanjeev Jorapur, Wen Xiong, Jeff Garzik, Don Fry, Rob Mapes,
	Amit Kale, Stephen Hemminger, unmproj

Hi,

This entire patch is available at,
http://www.netxen.com/products/downloads/netxen-2.6.17.patch.zip

Thanks,
pradeep

On Thu, 31 Aug 2006, Amit S. Kale wrote:

> Hi All,
>
> Thank you Stephen, Don and Wendy.
> We have incorporated feedbacks which have received since after last post. 
> I'll be resending updated patchset in subsequent emails.
>
> We are working on finding out good way of using tables to manage 
> compatibility between firmware version number and driver version number.
>
> Kindly review it and feel free to send feedback.
>
> Thanks,
> -Amit
>
> Signed-off-by: Amit S. Kale <amitkale@netxen.com>
>
> MAINTAINERS                              |    7
> drivers/net/Kconfig                      |    5
> drivers/net/Makefile                     |    1
> drivers/net/netxen/Makefile              |   35
> drivers/net/netxen/netxen_nic.h          |  901 +++++++++++++++++++++++++
> drivers/net/netxen/netxen_nic_ethtool.c  |  696 +++++++++++++++++++
> drivers/net/netxen/netxen_nic_hdr.h      |  611 +++++++++++++++++
> drivers/net/netxen/netxen_nic_hw.c       | 1102 
> ++++++++++++++++++++++++++++++
> drivers/net/netxen/netxen_nic_hw.h       |  499 +++++++++++++
> drivers/net/netxen/netxen_nic_init.c     | 1089 
> ++++++++++++++++++++++++++++++
> drivers/net/netxen/netxen_nic_ioctl.h    |   75 ++
> drivers/net/netxen/netxen_nic_isr.c      |  301 ++++++++
> drivers/net/netxen/netxen_nic_main.c     | 1107 
> +++++++++++++++++++++++++++++++
> drivers/net/netxen/netxen_nic_niu.c      |  779 +++++++++++++++++++++
> drivers/net/netxen/netxen_nic_phan_reg.h |  195 +++++
> 15 files changed, 7403 insertions(+)
>
>
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver
  2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
                   ` (9 preceding siblings ...)
  2006-09-01 18:44 ` [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Pradeep Dalvi
@ 2006-09-11 13:12 ` Jeff Garzik
       [not found]   ` <200609112004.50351.pradeep@linsyssoft.com>
  10 siblings, 1 reply; 18+ messages in thread
From: Jeff Garzik @ 2006-09-11 13:12 UTC (permalink / raw)
  To: Amit S. Kale; +Cc: netdev, sanjeev, rob, unmproj, shemminger, brazilnut, wendyx

email me an all-in-one-patch, please.

	Jeff




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver
       [not found]   ` <200609112004.50351.pradeep@linsyssoft.com>
@ 2006-09-13  2:47     ` Jeff Garzik
  2006-09-13 17:20       ` Pradeep Dalvi
  0 siblings, 1 reply; 18+ messages in thread
From: Jeff Garzik @ 2006-09-13  2:47 UTC (permalink / raw)
  To: Pradeep Dalvi
  Cc: Amit S. Kale, netdev, sanjeev, rob, unmproj, shemminger,
	brazilnut, wendyx, Andrew Morton

More updates needed:

1) diff against 2.6.18-rcX (currently -rc6)

2) remove ifdefs around NETIF_F_TSO

3) remove ifdefs around CONFIG_PCI_MSI

4) during initial allocation of port struct, the following line is 
completely superfluous:

	port->flags &= ~NETXEN_NETDEV_STATUS

5) netxen_nic_set_multi() does not have any multi-cast filter update code

6) remove impossible checks such as the following in nic_set_promise_mode:

+       if ((phy < 0) || (phy > 3))
+               return -1;

7) the following line in nic_set_mtu requires explanation, or fixing:

+       case NETXEN_NIC_XGBE:
+               new_mtu += 100; /* so that MAC accepts frames > MTU */

8) never call udelay() with a number >= 1000.  use mdelay()

9) [major] a great many functions simply do

netxen_nic_do_blah()
        case NETXEN_NIC_GBE:
		netxen_nic_do_blah_gbe()
		break;

        case NETXEN_NIC_XGBE:
		netxen_nic_do_blah_xgbe()
		break;

This is silly and makes the code needlessly larger and needlessly 
slower.  Modularize the driver to avoid all such functions.

10) don't cast iounmap argument to u8*

11) don't case to/from void*, particularly where you accidentally drop 
the __iomem marker:

+               addr = (void *)(adapter->ahw.pci_base + off);

12) make sure the driver passes sparse checks.  Read 
Documentation/sparse.txt

13) __iomem markers missing in NETXEN_NIC_HW_BLOCK_WRITE_64, 
NETXEN_NIC_HW_BLOCK_READ_64

14) If you need a 'void __iomem *' cast in the following macros, there 
is a type definition bug somewhere:


+#define NETXEN_NIC_LOCKED_READ_REG(X, Y)                       \
+       addr = (void __iomem *)(adapter->ahw.pci_base + X);     \
+       *(u32 *)Y = readl(addr);
+
+#define NETXEN_NIC_LOCKED_WRITE_REG(X, Y)                      \
+       addr = (void __iomem *)(adapter->ahw.pci_base + X);     \
+       writel(*(u32 *)Y, addr);
+

15) implement NETXEN_NIC_LOCKED_READ_REG, NETXEN_NIC_LOCKED_WRITE_REG, 
NETXEN_NIC_HW_BLOCK_WRITE_64, NETXEN_NIC_HW_BLOCK_READ_64 as static 
inline functions rather than macros for greater type safety

16) don't invent your own set_bit, clear_bit, etc:  _netxen_crb_set_bit

17) don't needlessly invent new types such as
+typedef __le32 netxen_crbword_t;       /* single word in CRB space */

18) The strings in netxen_nic_gstrings_test[] should be easily 
computer-parseable.  Eliminate parens, spaces

19) eliminate magic numbers (replace with named constants) in, e.g.

+       if ((netxen_rom_fast_read(adapter, 0, &n) == 0) && (n & 
0x80000000)) {
+               n &= ~0x80000000;
+               if (n < 1024)

20) use the short driver name (commonly DRV_NAME constant in other 
drivers) in ETHTOOL_GDRVINFO:
+       strncpy(drvinfo->driver, "NetXen NIC Driver", 32);

21) export the real firmware version in ETHTOOL_GDRVINFO:
+       strncpy(drvinfo->fw_version, NETXEN_NIC_FW_VERSIONID, 32);

22) netxen_nic_set_settings() simply returns success if the NIC is XGBE, 
which is obviously wrong

23) bogus return value -1 in netxen_nic_get_eeprom()

24) -EOPNOTSUPP would seem to be a much better return value for XGBE in 
netxen_nic_set_pauseparam()

25) netxen_nic_change_mtu() should check minimum MTU too

26) long delays should be sleeping, not spinning the CPU and locking out 
other tasks:

+       udelay(10000);



I stopped reviewing here.  That should keep you busy...

	Jeff



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver
  2006-09-13  2:47     ` Jeff Garzik
@ 2006-09-13 17:20       ` Pradeep Dalvi
  0 siblings, 0 replies; 18+ messages in thread
From: Pradeep Dalvi @ 2006-09-13 17:20 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Amit S. Kale, netdev, Sanjeev Jorapur, Rob Mapes, unmproj,
	Stephen Hemminger, brazilnut, wendyx

Jeff,

Thanks for your comments.  We are incorporating these suggestions and will 
resubmit an updated driver asap.

--
pradeep

On Tue, 12 Sep 2006, Jeff Garzik wrote:

> More updates needed:
>
> 1) diff against 2.6.18-rcX (currently -rc6)
>
> 2) remove ifdefs around NETIF_F_TSO
>
> 3) remove ifdefs around CONFIG_PCI_MSI
>
> 4) during initial allocation of port struct, the following line is completely 
> superfluous:
>
> 	port->flags &= ~NETXEN_NETDEV_STATUS
>
> 5) netxen_nic_set_multi() does not have any multi-cast filter update code
>
> 6) remove impossible checks such as the following in nic_set_promise_mode:
>
> +       if ((phy < 0) || (phy > 3))
> +               return -1;
>
> 7) the following line in nic_set_mtu requires explanation, or fixing:
>
> +       case NETXEN_NIC_XGBE:
> +               new_mtu += 100; /* so that MAC accepts frames > MTU */
>
> 8) never call udelay() with a number >= 1000.  use mdelay()
>
> 9) [major] a great many functions simply do
>
> netxen_nic_do_blah()
>       case NETXEN_NIC_GBE:
> 		netxen_nic_do_blah_gbe()
> 		break;
>
>       case NETXEN_NIC_XGBE:
> 		netxen_nic_do_blah_xgbe()
> 		break;
>
> This is silly and makes the code needlessly larger and needlessly slower. 
> Modularize the driver to avoid all such functions.
>
> 10) don't cast iounmap argument to u8*
>
> 11) don't case to/from void*, particularly where you accidentally drop the 
> __iomem marker:
>
> +               addr = (void *)(adapter->ahw.pci_base + off);
>
> 12) make sure the driver passes sparse checks.  Read Documentation/sparse.txt
>
> 13) __iomem markers missing in NETXEN_NIC_HW_BLOCK_WRITE_64, 
> NETXEN_NIC_HW_BLOCK_READ_64
>
> 14) If you need a 'void __iomem *' cast in the following macros, there is a 
> type definition bug somewhere:
>
>
> +#define NETXEN_NIC_LOCKED_READ_REG(X, Y)                       \
> +       addr = (void __iomem *)(adapter->ahw.pci_base + X);     \
> +       *(u32 *)Y = readl(addr);
> +
> +#define NETXEN_NIC_LOCKED_WRITE_REG(X, Y)                      \
> +       addr = (void __iomem *)(adapter->ahw.pci_base + X);     \
> +       writel(*(u32 *)Y, addr);
> +
>
> 15) implement NETXEN_NIC_LOCKED_READ_REG, NETXEN_NIC_LOCKED_WRITE_REG, 
> NETXEN_NIC_HW_BLOCK_WRITE_64, NETXEN_NIC_HW_BLOCK_READ_64 as static inline 
> functions rather than macros for greater type safety
>
> 16) don't invent your own set_bit, clear_bit, etc:  _netxen_crb_set_bit
>
> 17) don't needlessly invent new types such as
> +typedef __le32 netxen_crbword_t;       /* single word in CRB space */
>
> 18) The strings in netxen_nic_gstrings_test[] should be easily 
> computer-parseable.  Eliminate parens, spaces
>
> 19) eliminate magic numbers (replace with named constants) in, e.g.
>
> +       if ((netxen_rom_fast_read(adapter, 0, &n) == 0) && (n & 0x80000000)) 
> {
> +               n &= ~0x80000000;
> +               if (n < 1024)
>
> 20) use the short driver name (commonly DRV_NAME constant in other drivers) 
> in ETHTOOL_GDRVINFO:
> +       strncpy(drvinfo->driver, "NetXen NIC Driver", 32);
>
> 21) export the real firmware version in ETHTOOL_GDRVINFO:
> +       strncpy(drvinfo->fw_version, NETXEN_NIC_FW_VERSIONID, 32);
>
> 22) netxen_nic_set_settings() simply returns success if the NIC is XGBE, 
> which is obviously wrong
>
> 23) bogus return value -1 in netxen_nic_get_eeprom()
>
> 24) -EOPNOTSUPP would seem to be a much better return value for XGBE in 
> netxen_nic_set_pauseparam()
>
> 25) netxen_nic_change_mtu() should check minimum MTU too
>
> 26) long delays should be sleeping, not spinning the CPU and locking out 
> other tasks:
>
> +       udelay(10000);
>
>
>
> I stopped reviewing here.  That should keep you busy...
>
> 	Jeff
>
>
>
>
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver
  2006-08-24  0:04   ` Don Fry
@ 2006-08-25 13:19     ` Amit S. Kale
  0 siblings, 0 replies; 18+ messages in thread
From: Amit S. Kale @ 2006-08-25 13:19 UTC (permalink / raw)
  To: Don Fry
  Cc: Pradeep Dalvi, netdev, jeff, sanjeev, unmproj, Rob Mapes, amitkale

Hi Don,

Thanks. We'll lindent the sources and post an update asap.
-Amit

On Thursday 24 August 2006 05:34, Don Fry wrote:
> It looks like you have not run the source throught Lindent as previously
> requested.  Before you submit the code again, please use the Lindent
> script.
>
> I can get the code to ping between two cards.  Will be doing more
> testing tomorrow.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver
  2006-08-22  7:43 ` Pradeep Dalvi
@ 2006-08-24  0:04   ` Don Fry
  2006-08-25 13:19     ` Amit S. Kale
  0 siblings, 1 reply; 18+ messages in thread
From: Don Fry @ 2006-08-24  0:04 UTC (permalink / raw)
  To: Pradeep Dalvi; +Cc: netdev, jeff, sanjeev, unmproj, Rob Mapes, amitkale

It looks like you have not run the source throught Lindent as previously
requested.  Before you submit the code again, please use the Lindent
script.

I can get the code to ping between two cards.  Will be doing more
testing tomorrow.

-- 
Don Fry
brazilnut@us.ibm.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver
  2006-08-18 14:38 Amit S. Kale
@ 2006-08-22  7:43 ` Pradeep Dalvi
  2006-08-24  0:04   ` Don Fry
  0 siblings, 1 reply; 18+ messages in thread
From: Pradeep Dalvi @ 2006-08-22  7:43 UTC (permalink / raw)
  To: netdev; +Cc: jeff, sanjeev, unmproj, Rob Mapes, amitkale

Hi,

This updated patch with name prefix changes is available for download at,
http://www.netxen.com/products/downloads/netxen-2.6.17.patch.zip

Thanks and regards,
pradeep

On Fri, 18 Aug 2006, Amit S. Kale wrote:

> Hi,
>
> I'll be sending a NetXen Multi port 1G/10G ethernet driver patch in 
> subsequent emails. This set of patches have changes as per the suggestions, 
> which we received since last post.
>
> Kindly review it and feel free to send feedback.
>
> Thanks,
> -Amit
>
> Signed-off-by: Amit S. Kale <amitkale@netxen.com>
>
> MAINTAINERS                              |    7
> drivers/net/Kconfig                      |    5
> drivers/net/Makefile                     |    1
> drivers/net/netxen/Makefile              |   35
> drivers/net/netxen/netxen_nic.h          |  901 +++++++++++++++++++++++++
> drivers/net/netxen/netxen_nic_ethtool.c  |  696 +++++++++++++++++++
> drivers/net/netxen/netxen_nic_hdr.h      |  611 +++++++++++++++++
> drivers/net/netxen/netxen_nic_hw.c       | 1097 
> ++++++++++++++++++++++++++++++
> drivers/net/netxen/netxen_nic_hw.h       |  500 ++++++++++++++
> drivers/net/netxen/netxen_nic_init.c     | 1090 
> ++++++++++++++++++++++++++++++
> drivers/net/netxen/netxen_nic_ioctl.h    |   75 ++
> drivers/net/netxen/netxen_nic_isr.c      |  300 ++++++++
> drivers/net/netxen/netxen_nic_main.c     | 1107 
> +++++++++++++++++++++++++++++++
> drivers/net/netxen/netxen_nic_niu.c      |  778 +++++++++++++++++++++
> drivers/net/netxen/netxen_nic_phan_reg.h |  195 +++++
> 15 files changed, 7398 insertions(+)
>
>
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver
@ 2006-08-18 14:38 Amit S. Kale
  2006-08-22  7:43 ` Pradeep Dalvi
  0 siblings, 1 reply; 18+ messages in thread
From: Amit S. Kale @ 2006-08-18 14:38 UTC (permalink / raw)
  To: netdev; +Cc: jeff, sanjeev, unmproj

Hi,

I'll be sending a NetXen Multi port 1G/10G ethernet driver patch in 
subsequent emails. This set of patches have changes as per the 
suggestions, which we received since last post.

Kindly review it and feel free to send feedback.

Thanks,
-Amit

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

  MAINTAINERS                              |    7
  drivers/net/Kconfig                      |    5
  drivers/net/Makefile                     |    1
  drivers/net/netxen/Makefile              |   35
  drivers/net/netxen/netxen_nic.h          |  901 +++++++++++++++++++++++++
  drivers/net/netxen/netxen_nic_ethtool.c  |  696 +++++++++++++++++++
  drivers/net/netxen/netxen_nic_hdr.h      |  611 +++++++++++++++++
  drivers/net/netxen/netxen_nic_hw.c       | 1097 ++++++++++++++++++++++++++++++
  drivers/net/netxen/netxen_nic_hw.h       |  500 ++++++++++++++
  drivers/net/netxen/netxen_nic_init.c     | 1090 ++++++++++++++++++++++++++++++
  drivers/net/netxen/netxen_nic_ioctl.h    |   75 ++
  drivers/net/netxen/netxen_nic_isr.c      |  300 ++++++++
  drivers/net/netxen/netxen_nic_main.c     | 1107 +++++++++++++++++++++++++++++++
  drivers/net/netxen/netxen_nic_niu.c      |  778 +++++++++++++++++++++
  drivers/net/netxen/netxen_nic_phan_reg.h |  195 +++++
  15 files changed, 7398 insertions(+)

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2006-09-13 17:20 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-08-31 14:02 [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Amit S. Kale
2006-08-31 14:05 ` [PATCH 2.6.17 1/9] NetXen: Makefile and driver main file Amit S. Kale
2006-08-31 14:13 ` [PATCH 2.6.17 2/9] NetXen: Hardware access routines Amit S. Kale
2006-08-31 14:16 ` [PATCH 2.6.17 3/9] NetXen: hw initialization routines Amit S. Kale
2006-08-31 14:20 ` [PATCH 2.6.17 4/9] NetXen: intr routines and niu handling Amit S. Kale
2006-08-31 14:25 ` [PATCH 2.6.17 5/9] NetXen: ethtool interface Amit S. Kale
2006-08-31 14:27 ` [PATCH 2.6.17 6/9] NetXen: Main header file Amit S. Kale
2006-08-31 14:29 ` [PATCH 2.6.17 7/9] NetXen: hw access routines " Amit S. Kale
2006-08-31 14:32 ` [PATCH 2.6.17 8/9] NetXen: Header file and ioctl " Amit S. Kale
2006-08-31 14:36 ` [PATCH 2.6.17 9/9] NetXen: CRB reg definitions Amit S. Kale
2006-09-01 18:44 ` [PATCH 2.6.17 0/9] NetXen: 1G/10G Ethernet Driver Pradeep Dalvi
2006-09-11 13:12 ` Jeff Garzik
     [not found]   ` <200609112004.50351.pradeep@linsyssoft.com>
2006-09-13  2:47     ` Jeff Garzik
2006-09-13 17:20       ` Pradeep Dalvi
  -- strict thread matches above, loose matches on Subject: below --
2006-08-18 14:38 Amit S. Kale
2006-08-22  7:43 ` Pradeep Dalvi
2006-08-24  0:04   ` Don Fry
2006-08-25 13:19     ` Amit S. Kale

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.