/*
 * 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 <linux/vmalloc.h>
#include <linux/highmem.h>
#include "netxen_nic_hw.h"

#include "netxen_nic.h"
#include "netxen_nic_phan_reg.h"

#include <linux/dma-mapping.h>
#include <net/ip.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_nic";
static char netxen_nic_driver_string[] = "NetXen Network Driver version "
    NETXEN_NIC_LINUX_VERSIONID;

#define NETXEN_NETDEV_WEIGHT 120
#define NETXEN_ADAPTER_UP_MAGIC 777
#define NETXEN_NIC_PEG_TUNE 0

/* Local functions to NetXen NIC driver */
static int __devinit netxen_nic_probe(struct pci_dev *pdev,
				      const struct pci_device_id *ent);
static void __devexit netxen_nic_remove(struct pci_dev *pdev);
static int netxen_nic_open(struct net_device *netdev);
static int netxen_nic_close(struct net_device *netdev);
static int netxen_nic_xmit_frame(struct sk_buff *, struct net_device *);
static void netxen_tx_timeout(struct net_device *netdev);
static void netxen_tx_timeout_task(struct work_struct *work);
static void netxen_watchdog(unsigned long);
static int netxen_nic_poll(struct napi_struct *napi, 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);
static irqreturn_t netxen_msi_intr(int irq, void *data);

int physical_port[] = {0, 1, 2, 3};

/*  PCI Device ID Table  */
static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
	{PCI_DEVICE(0x4040, 0x0001)},
	{PCI_DEVICE(0x4040, 0x0002)},
	{PCI_DEVICE(0x4040, 0x0003)},
	{PCI_DEVICE(0x4040, 0x0004)},
	{PCI_DEVICE(0x4040, 0x0005)},
	{PCI_DEVICE(0x4040, 0x0024)},
	{PCI_DEVICE(0x4040, 0x0025)},
	{0,}
};

MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);

struct workqueue_struct *netxen_workq;
static void netxen_watchdog(unsigned long);

static void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
					   uint32_t crb_producer)
{
	switch (adapter->portnum) {
		case 0:
			writel(crb_producer, NETXEN_CRB_NORMALIZE
					(adapter, CRB_CMD_PRODUCER_OFFSET));
			return;
		case 1:
			writel(crb_producer, NETXEN_CRB_NORMALIZE
					(adapter, CRB_CMD_PRODUCER_OFFSET_1));
			return;
		case 2:
			writel(crb_producer, NETXEN_CRB_NORMALIZE
					(adapter, CRB_CMD_PRODUCER_OFFSET_2));
			return;
		case 3:
			writel(crb_producer, NETXEN_CRB_NORMALIZE
					(adapter, CRB_CMD_PRODUCER_OFFSET_3));
			return;
		default:
			printk(KERN_WARNING "We tried to update "
					"CRB_CMD_PRODUCER_OFFSET for invalid "
					"PCI function id %d\n",
					adapter->portnum);
			return;
	}
}

static void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
					   u32 crb_consumer)
{
	switch (adapter->portnum) {
		case 0:
			writel(crb_consumer, NETXEN_CRB_NORMALIZE
				(adapter, CRB_CMD_CONSUMER_OFFSET));
			return;
		case 1:
			writel(crb_consumer, NETXEN_CRB_NORMALIZE
				(adapter, CRB_CMD_CONSUMER_OFFSET_1));
			return;
		case 2:
			writel(crb_consumer, NETXEN_CRB_NORMALIZE
				(adapter, CRB_CMD_CONSUMER_OFFSET_2));
			return;
		case 3:
			writel(crb_consumer, NETXEN_CRB_NORMALIZE
				(adapter, CRB_CMD_CONSUMER_OFFSET_3));
			return;
		default:
			printk(KERN_WARNING "We tried to update "
					"CRB_CMD_PRODUCER_OFFSET for invalid "
					"PCI function id %d\n",
					adapter->portnum);
			return;
	}
}

#define	ADAPTER_LIST_SIZE 12

static uint32_t msi_tgt_status[4] = {
	ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1,
	ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3
};

static uint32_t sw_int_mask[4] = {
	CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
	CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
};

static void netxen_nic_disable_int(struct netxen_adapter *adapter)
{
	u32 mask = 0x7ff;
	int retries = 32;
	int port = adapter->portnum;
	int pci_fn = adapter->ahw.pci_func;

	if (adapter->msi_mode != MSI_MODE_MULTIFUNC)
		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port]));

	if (adapter->intr_scheme != -1 &&
	    adapter->intr_scheme != INTR_SCHEME_PERPORT)
		writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));

	if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
		do {
			writel(0xffffffff,
			       PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS));
			mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR));
			if (!(mask & 0x80))
				break;
			udelay(10);
		} while (--retries);

		if (!retries) {
			printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
					netxen_nic_driver_name);
		}
	} else {
		if (adapter->msi_mode == MSI_MODE_MULTIFUNC) {
			writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter,
						msi_tgt_status[pci_fn]));
		}
	}
}

static void netxen_nic_enable_int(struct netxen_adapter *adapter)
{
	u32 mask;
	int port = adapter->portnum;

	DPRINTK(1, INFO, "Entered ISR Enable \n");

	if (adapter->intr_scheme != -1 &&
		adapter->intr_scheme != INTR_SCHEME_PERPORT) {
		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, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
	}

	writel(0x1, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port]));

	if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
		mask = 0xbff;
		if (adapter->intr_scheme != -1 &&
			adapter->intr_scheme != INTR_SCHEME_PERPORT) {
			writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
		}
		writel(mask,
		       PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK));
	}

	DPRINTK(1, INFO, "Done with enable Int\n");
}

/*
 * 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;
	void __iomem *mem_ptr0 = NULL;
	void __iomem *mem_ptr1 = NULL;
	void __iomem *mem_ptr2 = NULL;
	unsigned long first_page_group_end;
	unsigned long first_page_group_start;


	u8 __iomem *db_ptr = NULL;
	unsigned long mem_base, mem_len, db_base, db_len;
	int pci_using_dac, i = 0, 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;
	__le64 mac_addr[FLASH_NUM_PORTS + 1];
	int valid_mac = 0;
	u32 val;
	int pci_func_id = PCI_FUNC(pdev->devfn);
	DECLARE_MAC_BUF(mac);

	printk(KERN_INFO "%s \n", netxen_nic_driver_string);

	if (pdev->class != 0x020000) {
		printk(KERN_ERR"NetXen function %d, class %x will not "
				"be enabled.\n",pci_func_id, pdev->class);
		return -ENODEV;
	}
	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 (pdev->revision == NX_P2_C1 &&
	    (pci_set_dma_mask(pdev, DMA_35BIT_MASK) == 0) &&
	    (pci_set_consistent_dma_mask(pdev, DMA_35BIT_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;
	}


	netdev = alloc_etherdev(sizeof(struct netxen_adapter));
	if(!netdev) {
		printk(KERN_ERR"%s: Failed to allocate memory for the "
				"device block.Check system memory resource"
				" usage.\n", netxen_nic_driver_name);
		goto err_out_free_res;
	}

	SET_NETDEV_DEV(netdev, &pdev->dev);

	adapter = netdev->priv;

	adapter->ahw.pdev = pdev;
	adapter->ahw.pci_func  = pci_func_id;

	/* 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 */
	if (mem_len == NETXEN_PCI_128MB_SIZE) {
		mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
		mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START,
				SECOND_PAGE_GROUP_SIZE);
		mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
				THIRD_PAGE_GROUP_SIZE);
		first_page_group_start = FIRST_PAGE_GROUP_START;
		first_page_group_end   = FIRST_PAGE_GROUP_END;
	} else if (mem_len == NETXEN_PCI_32MB_SIZE) {
		mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
		mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
			SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
		first_page_group_start = 0;
		first_page_group_end   = 0;
	} else {
		err = -EIO;
		goto err_out_free_netdev;
	}

	if ((!mem_ptr0 && mem_len == NETXEN_PCI_128MB_SIZE) ||
			!mem_ptr1 || !mem_ptr2) {
		DPRINTK(ERR,
			"Cannot remap adapter memory aborting.:"
			"0 -> %p, 1 -> %p, 2 -> %p\n",
			mem_ptr0, mem_ptr1, mem_ptr2);

		err = -EIO;
		goto err_out_iounmap;
	}
	db_base = pci_resource_start(pdev, 4);	/* doorbell is on bar 4 */
	db_len = pci_resource_len(pdev, 4);

	if (db_len == 0) {
		printk(KERN_ERR "%s: doorbell is disabled\n",
		       netxen_nic_driver_name);
		err = -EIO;
		goto err_out_iounmap;
	}
	DPRINTK(INFO, "doorbell ioremap from %lx a size of %lx\n", db_base,
		db_len);

	db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES);
	if (!db_ptr) {
		printk(KERN_ERR "%s: Failed to allocate doorbell map.",
		       netxen_nic_driver_name);
		err = -EIO;
		goto err_out_iounmap;
	}
	DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr);

	adapter->ahw.pci_base0 = mem_ptr0;
	adapter->ahw.first_page_group_start = first_page_group_start;
	adapter->ahw.first_page_group_end   = first_page_group_end;
	adapter->ahw.pci_base1 = mem_ptr1;
	adapter->ahw.pci_base2 = mem_ptr2;
	adapter->ahw.db_base = db_ptr;
	adapter->ahw.db_len = db_len;

	adapter->netdev  = netdev;
	adapter->pdev    = pdev;

	netif_napi_add(netdev, &adapter->napi,
		       netxen_nic_poll, NETXEN_NETDEV_WEIGHT);

	/* this will be read from FW later */
	adapter->intr_scheme = -1;
	adapter->msi_mode = -1;

	/* This will be reset for mezz cards  */
	adapter->portnum = pci_func_id;
	adapter->status   &= ~NETXEN_NETDEV_STATUS;
	adapter->rx_csum = 1;

	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->tx_timeout	   = netxen_tx_timeout;
	netdev->watchdog_timeo     = 2*HZ;

	netxen_nic_change_mtu(netdev, netdev->mtu);

	SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
#ifdef CONFIG_NET_POLL_CONTROLLER
	netdev->poll_controller = netxen_nic_poll_controller;
#endif
	/* ScatterGather support */
	netdev->features = NETIF_F_SG;
	netdev->features |= NETIF_F_IP_CSUM;
	netdev->features |= NETIF_F_TSO;

	if (pci_using_dac)
		netdev->features |= NETIF_F_HIGHDMA;

	if (pci_enable_msi(pdev))
		adapter->flags &= ~NETXEN_NIC_MSI_ENABLED;
	else
		adapter->flags |= NETXEN_NIC_MSI_ENABLED;

	netdev->irq = pdev->irq;
	INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);

	/*
	 * Set the CRB window to invalid. If any register in window 0 is
	 * accessed it should set the window to 0 and then reset it to 1.
	 */
	adapter->curr_window = 255;

	/* initialize the adapter */
	netxen_initialize_adapter_hw(adapter);

	/*
	 *  Adapter in our case is quad port so initialize it before
	 *  initializing the ports
	 */

	netxen_initialize_adapter_ops(adapter);

	adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST;
	if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) ||
			(adapter->ahw.boardcfg.board_type ==
			 NETXEN_BRDTYPE_P2_SB31_2G))
		adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
	else
		adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS;
	adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
	adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS;

	cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
	if (cmd_buf_arr == NULL) {
		printk(KERN_ERR
		       "%s: Could not allocate cmd_buf_arr memory:%d\n",
		       netxen_nic_driver_name, (int)TX_RINGSIZE);
		err = -ENOMEM;
		goto err_out_free_adapter;
	}
	memset(cmd_buf_arr, 0, TX_RINGSIZE);
	adapter->cmd_buf_arr = cmd_buf_arr;

	for (i = 0; i < MAX_RCV_CTX; ++i) {
		recv_ctx = &adapter->recv_ctx[i];
		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;

			case RCV_RING_LRO:
				rcv_desc->max_rx_desc_count =
				    adapter->max_lro_rx_desc_count;
				rcv_desc->flags = RCV_DESC_LRO;
				rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN;
				rcv_desc->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
				break;

			}
			rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *)
			    vmalloc(RCV_BUFFSIZE);

			if (rcv_desc->rx_buf_arr == NULL) {
				printk(KERN_ERR "%s: Could not allocate "
				       "rcv_desc->rx_buf_arr memory:%d\n",
				       netxen_nic_driver_name,
				       (int)RCV_BUFFSIZE);
				err = -ENOMEM;
				goto err_out_free_rx_buffer;
			}
			memset(rcv_desc->rx_buf_arr, 0, RCV_BUFFSIZE);
		}

	}

	netxen_initialize_adapter_sw(adapter);	/* initialize the buffers in adapter */

	/* Mezz cards have PCI function 0,2,3 enabled */
	if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ)
		&& (pci_func_id >= 2))
			adapter->portnum = pci_func_id - 2;

#ifdef CONFIG_IA64
	if(adapter->portnum == 0) {
		netxen_pinit_from_rom(adapter, 0);
		udelay(500);
		netxen_load_firmware(adapter);
	}
#endif

	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, netxen_watchdog_task);
	adapter->ahw.pdev = pdev;
	adapter->ahw.revision_id = pdev->revision;

	/* make sure Window == 1 */
	netxen_nic_pci_change_crbwindow(adapter, 1);

	netxen_nic_update_cmd_producer(adapter, 0);
	netxen_nic_update_cmd_consumer(adapter, 0);
	writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));

	if (netxen_is_flash_supported(adapter) == 0 &&
	    netxen_get_flash_mac_addr(adapter, mac_addr) == 0)
		valid_mac = 1;
	else
		valid_mac = 0;

	if (valid_mac) {
		unsigned char *p = (unsigned char *)&mac_addr[adapter->portnum];
		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 %s.\n",
			       netxen_nic_driver_name,
			       print_mac(mac, netdev->dev_addr));
		} else {
			if (adapter->macaddr_set)
				adapter->macaddr_set(adapter,
							netdev->dev_addr);
		}
	}

	if (adapter->portnum == 0) {
		err = netxen_initialize_adapter_offload(adapter);
		if (err)
			goto err_out_free_rx_buffer;
		val = readl(NETXEN_CRB_NORMALIZE(adapter,
					NETXEN_CAM_RAM(0x1fc)));
		if (val == 0x55555555) {
		    /* This is the first boot after power up */
		    netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val);
			if (!(val & 0x4)) {
				val |= 0x4;
				netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val);
				netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val);
				if (!(val & 0x4))
					printk(KERN_ERR "%s: failed to set MSI bit in PCI-e reg\n",
							netxen_nic_driver_name);
			}
		    val = readl(NETXEN_CRB_NORMALIZE(adapter,
					NETXEN_ROMUSB_GLB_SW_RESET));
		    printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val);
		    if (val != 0x80000f) {
			/* clear the register for future unloads/loads */
				writel(0, NETXEN_CRB_NORMALIZE(adapter,
							NETXEN_CAM_RAM(0x1fc)));
				printk(KERN_ERR "ERROR in NetXen HW init sequence.\n");
				err = -ENODEV;
				goto err_out_free_dev;
		    }
		}

		/* clear the register for future unloads/loads */
		writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
		printk(KERN_INFO "State: 0x%0x\n",
			readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));

		/*
		 * Tell the hardware our version number.
		 */
		i = (_NETXEN_NIC_LINUX_MAJOR << 16)
			| ((_NETXEN_NIC_LINUX_MINOR << 8))
			| (_NETXEN_NIC_LINUX_SUBVERSION);
		writel(i, NETXEN_CRB_NORMALIZE(adapter, CRB_DRIVER_VERSION));

		/* Unlock the HW, prompting the boot sequence */
		writel(1,
			NETXEN_CRB_NORMALIZE(adapter,
				NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
		/* Handshake with the card before we register the devices. */
		netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
	}

	/*
	 * See if the firmware gave us a virtual-physical port mapping.
	 */
	i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum)));
	if (i != 0x55555555)
		physical_port[adapter->portnum] = i;

	netif_carrier_off(netdev);
	netif_stop_queue(netdev);

	if ((err = register_netdev(netdev))) {
		printk(KERN_ERR "%s: register_netdev failed port #%d"
			       " aborting\n", netxen_nic_driver_name,
			       adapter->portnum);
		err = -EIO;
		goto err_out_free_dev;
	}

	pci_set_drvdata(pdev, adapter);

	switch (adapter->ahw.board_type) {
		case NETXEN_NIC_GBE:
			printk(KERN_INFO "%s: QUAD GbE board initialized\n",
			       netxen_nic_driver_name);
			break;

		case NETXEN_NIC_XGBE:
			printk(KERN_INFO "%s: XGbE board initialized\n",
					netxen_nic_driver_name);
			break;
	}

	adapter->driver_mismatch = 0;

	return 0;

err_out_free_dev:
	if (adapter->portnum == 0)
		netxen_free_adapter_offload(adapter);

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);

err_out_free_adapter:
	if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
		pci_disable_msi(pdev);

	pci_set_drvdata(pdev, NULL);

	if (db_ptr)
		iounmap(db_ptr);

err_out_iounmap:
	if (mem_ptr0)
		iounmap(mem_ptr0);
	if (mem_ptr1)
		iounmap(mem_ptr1);
	if (mem_ptr2)
		iounmap(mem_ptr2);

err_out_free_netdev:
	free_netdev(netdev);

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 net_device *netdev;
	struct netxen_rx_buffer *buffer;
	struct netxen_recv_context *recv_ctx;
	struct netxen_rcv_desc_ctx *rcv_desc;
	int i, ctxid, ring;
	static int init_firmware_done = 0;

	adapter = pci_get_drvdata(pdev);
	if (adapter == NULL)
		return;

	netdev = adapter->netdev;

	unregister_netdev(netdev);

	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
		init_firmware_done++;
		netxen_free_hw_resources(adapter);
	}

	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);

	if (adapter->portnum == 0) {
		if (init_firmware_done) {
			i = 100;
			do {
				if (dma_watchdog_shutdown_request(adapter) == 1)
					break;
				msleep(100);
				if (dma_watchdog_shutdown_poll_result(adapter) == 1)
					break;
			} while (--i);

			if (i == 0)
				printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
						netdev->name);

			/* clear the register for future unloads/loads */
			writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
			printk(KERN_INFO "State: 0x%0x\n",
				readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));

			/* leave the hw in the same state as reboot */
			writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
			netxen_pinit_from_rom(adapter, 0);
			msleep(1);
			netxen_load_firmware(adapter);
			netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
		}

		/* clear the register for future unloads/loads */
		writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
		printk(KERN_INFO "State: 0x%0x\n",
			readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));

		i = 100;
		do {
			if (dma_watchdog_shutdown_request(adapter) == 1)
				break;
			msleep(100);
			if (dma_watchdog_shutdown_poll_result(adapter) == 1)
				break;
		} while (--i);

		if (i) {
			netxen_free_adapter_offload(adapter);
		} else {
			printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
					netdev->name);
		}
	}

	if (adapter->irq)
		free_irq(adapter->irq, adapter);

	if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
		pci_disable_msi(pdev);

	iounmap(adapter->ahw.db_base);
	iounmap(adapter->ahw.pci_base0);
	iounmap(adapter->ahw.pci_base1);
	iounmap(adapter->ahw.pci_base2);

	pci_release_regions(pdev);
	pci_disable_device(pdev);
	pci_set_drvdata(pdev, NULL);

	free_netdev(netdev);
}

/*
 * 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_adapter *adapter = (struct netxen_adapter *)netdev->priv;
	int err = 0;
	int ctx, ring;
	irq_handler_t handler;
	unsigned long flags = IRQF_SAMPLE_RANDOM;

	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;
		}
		for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
			for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++)
				netxen_post_rx_buffers(adapter, ctx, ring);
		}
		adapter->irq = adapter->ahw.pdev->irq;
		if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
			handler = netxen_msi_intr;
		else {
			flags |= IRQF_SHARED;
			handler = netxen_intr;
		}
		err = request_irq(adapter->irq, handler,
				  flags, netdev->name, adapter);
		if (err) {
			printk(KERN_ERR "request_irq failed with: %d\n", err);
			netxen_free_hw_resources(adapter);
			return err;
		}

		adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
	}
	/* Done here again so that even if phantom sw overwrote it,
	 * we set it */
	if (adapter->init_port
	    && adapter->init_port(adapter, adapter->portnum) != 0) {
		printk(KERN_ERR "%s: Failed to initialize port %d\n",
				netxen_nic_driver_name, adapter->portnum);
		return -EIO;
	}
	if (adapter->macaddr_set)
		adapter->macaddr_set(adapter, netdev->dev_addr);

	netxen_nic_set_link_parameters(adapter);

	netxen_nic_set_multi(netdev);
	if (adapter->set_mtu)
		adapter->set_mtu(adapter, netdev->mtu);

	if (!adapter->driver_mismatch)
		mod_timer(&adapter->watchdog_timer, jiffies);

	napi_enable(&adapter->napi);
	netxen_nic_enable_int(adapter);

	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_adapter *adapter = netdev_priv(netdev);
	int i, j;
	struct netxen_cmd_buffer *cmd_buff;
	struct netxen_skb_frag *buffrag;

	netif_carrier_off(netdev);
	netif_stop_queue(netdev);
	napi_disable(&adapter->napi);

	if (adapter->stop_port)
		adapter->stop_port(adapter);

	netxen_nic_disable_int(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(adapter->pdev, buffrag->dma,
					 buffrag->length, PCI_DMA_TODEVICE);
			buffrag->dma = 0ULL;
		}
		for (j = 0; j < cmd_buff->frag_count; j++) {
			buffrag++;
			if (buffrag->dma) {
				pci_unmap_page(adapter->pdev, buffrag->dma,
					       buffrag->length,
					       PCI_DMA_TODEVICE);
				buffrag->dma = 0ULL;
			}
		}
		/* 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++;
	}
	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
		FLUSH_SCHEDULED_WORK();
		del_timer_sync(&adapter->watchdog_timer);
	}

	return 0;
}

static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
	struct netxen_adapter *adapter = netdev_priv(netdev);
	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, consumer;
	u32 saved_producer = 0;
	struct cmd_desc_type0 *hwdesc;
	int k;
	struct netxen_cmd_buffer *pbuf = NULL;
	int frag_count;
	int no_of_desc;
	u32 num_txd = adapter->max_tx_desc_count;

	frag_count = skb_shinfo(skb)->nr_frags + 1;

	/* There 4 fragments per descriptor */
	no_of_desc = (frag_count + 3) >> 2;
	if (netdev->features & NETIF_F_TSO) {
		if (skb_shinfo(skb)->gso_size > 0) {

			no_of_desc++;
			if ((ip_hdrlen(skb) + tcp_hdrlen(skb) +
			     sizeof(struct ethhdr)) >
			    (sizeof(struct cmd_desc_type0) - 2)) {
				no_of_desc++;
			}
		}
	}

	producer = adapter->cmd_producer;
	smp_mb();
	consumer = adapter->last_cmd_consumer;
	if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) {
		netif_stop_queue(netdev);
		smp_mb();
		return NETDEV_TX_BUSY;
	}

	/* Copy the descriptors into the hardware    */
	saved_producer = producer;
	hwdesc = &hw->cmd_desc_head[producer];
	memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
	/* Take skb->data itself */
	pbuf = &adapter->cmd_buf_arr[producer];
	if ((netdev->features & NETIF_F_TSO) && skb_shinfo(skb)->gso_size > 0) {
		pbuf->mss = skb_shinfo(skb)->gso_size;
		hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
	} else {
		pbuf->mss = 0;
		hwdesc->mss = 0;
	}
	pbuf->total_length = skb->len;
	pbuf->skb = skb;
	pbuf->cmd = TX_ETHER_PKT;
	pbuf->frag_count = frag_count;
	pbuf->port = adapter->portnum;
	buffrag = &pbuf->frag_array[0];
	buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len,
				      PCI_DMA_TODEVICE);
	buffrag->length = first_seg_len;
	netxen_set_cmd_desc_totallength(hwdesc, skb->len);
	netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count);
	netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT);

	netxen_set_cmd_desc_port(hwdesc, adapter->portnum);
	netxen_set_cmd_desc_ctxid(hwdesc, adapter->portnum);
	hwdesc->buffer1_length = cpu_to_le16(first_seg_len);
	hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);

	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, num_txd);
			hwdesc = &hw->cmd_desc_head[producer];
			memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
			pbuf = &adapter->cmd_buf_arr[producer];
			pbuf->skb = NULL;
		}
		frag = &skb_shinfo(skb)->frags[i - 1];
		len = frag->size;
		offset = frag->page_offset;

		temp_len = len;
		temp_dma = pci_map_page(adapter->pdev, frag->page, offset,
					len, PCI_DMA_TODEVICE);

		buffrag++;
		buffrag->dma = temp_dma;
		buffrag->length = temp_len;

		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 = cpu_to_le16(temp_len);
			hwdesc->addr_buffer4 = cpu_to_le64(temp_dma);
			break;
		}
		frag++;
	}
	producer = get_next_index(producer, num_txd);

	/* might change opcode to TX_TCP_LSO */
	netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb);

	/* For LSO, we need to copy the MAC/IP/TCP headers into
	 * the descriptor ring
	 */
	if (netxen_get_cmd_desc_opcode(&hw->cmd_desc_head[saved_producer])
	    == 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) - 2)) {
			first_hdr_len = sizeof(struct cmd_desc_type0) - 2;
			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];
		pbuf = &adapter->cmd_buf_arr[producer];
		pbuf->skb = NULL;

		/* copy the first 64 bytes */
		memcpy(((void *)hwdesc) + 2,
		       (void *)(skb->data), first_hdr_len);
		producer = get_next_index(producer, num_txd);

		if (more_hdr) {
			hwdesc = &hw->cmd_desc_head[producer];
			pbuf = &adapter->cmd_buf_arr[producer];
			pbuf->skb = NULL;
			/* copy the next 64 bytes - should be enough except
			 * for pathological case
			 */
			skb_copy_from_linear_data_offset(skb, first_hdr_len,
							 hwdesc,
							 (hdr_len -
							  first_hdr_len));
			producer = get_next_index(producer, num_txd);
		}
	}

	adapter->cmd_producer = producer;
	adapter->stats.txbytes += skb->len;

	netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);

	adapter->stats.xmitcalled++;
	netdev->trans_start = jiffies;

	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_adapter *adapter = (struct netxen_adapter *)
						netdev_priv(netdev);
	SCHEDULE_WORK(&adapter->tx_timeout_task);
}

static void netxen_tx_timeout_task(struct work_struct *work)
{
	struct netxen_adapter *adapter =
		container_of(work, struct netxen_adapter, tx_timeout_task);

	printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
	       netxen_nic_driver_name, adapter->netdev->name);

	netxen_nic_disable_int(adapter);
	napi_disable(&adapter->napi);

	adapter->netdev->trans_start = jiffies;

	napi_enable(&adapter->napi);
	netxen_nic_enable_int(adapter);
	netif_wake_queue(adapter->netdev);
}

static inline void
netxen_handle_int(struct netxen_adapter *adapter)
{
	netxen_nic_disable_int(adapter);
	napi_schedule(&adapter->napi);
}

irqreturn_t netxen_intr(int irq, void *data)
{
	struct netxen_adapter *adapter = data;
	u32 our_int = 0;

	our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
	/* not our interrupt */
	if ((our_int & (0x80 << adapter->portnum)) == 0)
		return IRQ_NONE;

	if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
		/* claim interrupt */
		writel(our_int & ~((u32)(0x80 << adapter->portnum)),
			NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
	}

	netxen_handle_int(adapter);

	return IRQ_HANDLED;
}

irqreturn_t netxen_msi_intr(int irq, void *data)
{
	struct netxen_adapter *adapter = data;

	netxen_handle_int(adapter);
	return IRQ_HANDLED;
}

static int netxen_nic_poll(struct napi_struct *napi, int budget)
{
	struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi);
	int tx_complete;
	int ctx;
	int work_done;

	tx_complete = netxen_process_cmd_ring(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.
		 */
		work_done += netxen_process_rcv_ring(adapter, ctx,
						     budget / MAX_RCV_CTX);
	}

	if ((work_done < budget) && tx_complete) {
		netif_rx_complete(adapter->netdev, &adapter->napi);
		netxen_nic_enable_int(adapter);
	}

	return work_done;
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void netxen_nic_poll_controller(struct net_device *netdev)
{
	struct netxen_adapter *adapter = netdev_priv(netdev);
	disable_irq(adapter->irq);
	netxen_intr(adapter->irq, adapter);
	enable_irq(adapter->irq);
}
#endif

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)
{
	if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL)
		return -ENOMEM;

	return pci_register_driver(&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.
	 */
	msleep(100);
	pci_unregister_driver(&netxen_driver);
	destroy_workqueue(netxen_workq);
}

module_exit(netxen_exit_module);
