/*
 * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
#include <linux/crc32.h>
#include <linux/in.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/if_arp.h>
#include <linux/highmem.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/byteorder.h>
#include <rdma/ib_smi.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_pack.h>
#include <rdma/iw_cm.h>

#include "nes.h"

#include <net/netevent.h>
#include <net/neighbour.h>
#include <linux/route.h>
#include <net/ip_fib.h>

MODULE_AUTHOR("NetEffect");
MODULE_DESCRIPTION("NetEffect RNIC Low-level iWARP Driver");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRV_VERSION);

int max_mtu = 9000;
int interrupt_mod_interval = 0;


/* Interoperability */
int mpa_version = 1;
module_param(mpa_version, int, 0);
MODULE_PARM_DESC(mpa_version, "MPA version to be used int MPA Req/Resp (0 or 1)");

/* Interoperability */
int disable_mpa_crc = 0;
module_param(disable_mpa_crc, int, 0);
MODULE_PARM_DESC(disable_mpa_crc, "Disable checking of MPA CRC");

unsigned int send_first = 0;
module_param(send_first, int, 0);
MODULE_PARM_DESC(send_first, "Send RDMA Message First on Active Connection");


unsigned int nes_drv_opt = 0;
module_param(nes_drv_opt, int, 0);
MODULE_PARM_DESC(nes_drv_opt, "Driver option parameters");

unsigned int nes_debug_level = 0;
module_param_named(debug_level, nes_debug_level, uint, 0644);
MODULE_PARM_DESC(debug_level, "Enable debug output level");

LIST_HEAD(nes_adapter_list);
static LIST_HEAD(nes_dev_list);

atomic_t qps_destroyed;

static unsigned int ee_flsh_adapter;
static unsigned int sysfs_nonidx_addr;
static unsigned int sysfs_idx_addr;

static struct pci_device_id nes_pci_table[] = {
	{PCI_VENDOR_ID_NETEFFECT, PCI_DEVICE_ID_NETEFFECT_NE020, PCI_ANY_ID, PCI_ANY_ID},
	{0}
};

MODULE_DEVICE_TABLE(pci, nes_pci_table);

static int nes_inetaddr_event(struct notifier_block *, unsigned long, void *);
static int nes_net_event(struct notifier_block *, unsigned long, void *);
static int nes_notifiers_registered;


static struct notifier_block nes_inetaddr_notifier = {
	.notifier_call = nes_inetaddr_event
};

static struct notifier_block nes_net_notifier = {
	.notifier_call = nes_net_event
};




/**
 * nes_inetaddr_event
 */
static int nes_inetaddr_event(struct notifier_block *notifier,
		unsigned long event, void *ptr)
{
	struct in_ifaddr *ifa = ptr;
	struct net_device *event_netdev = ifa->ifa_dev->dev;
	struct nes_device *nesdev;
	struct net_device *netdev;
	struct nes_vnic *nesvnic;
	unsigned int addr;
	unsigned int mask;

	addr = ntohl(ifa->ifa_address);
	mask = ntohl(ifa->ifa_mask);
	nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address " NIPQUAD_FMT
		  ", netmask " NIPQUAD_FMT ".\n",
		  HIPQUAD(addr), HIPQUAD(mask));
	list_for_each_entry(nesdev, &nes_dev_list, list) {
		nes_debug(NES_DBG_NETDEV, "Nesdev list entry = 0x%p. (%s)\n",
				nesdev, nesdev->netdev[0]->name);
		netdev = nesdev->netdev[0];
		nesvnic = netdev_priv(netdev);
		if (netdev == event_netdev) {
			if (nesvnic->rdma_enabled == 0) {
				nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since"
						" RDMA is not enabled.\n",
						netdev->name);
				return NOTIFY_OK;
			}
			/* we have ifa->ifa_address/mask here if we need it */
			switch (event) {
				case NETDEV_DOWN:
					nes_debug(NES_DBG_NETDEV, "event:DOWN\n");
					nes_write_indexed(nesdev,
							NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)), 0);

					nes_manage_arp_cache(netdev, netdev->dev_addr,
							ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE);
					nesvnic->local_ipaddr = 0;
					return NOTIFY_OK;
					break;
				case NETDEV_UP:
					nes_debug(NES_DBG_NETDEV, "event:UP\n");

					if (nesvnic->local_ipaddr != 0) {
						nes_debug(NES_DBG_NETDEV, "Interface already has local_ipaddr\n");
						return NOTIFY_OK;
					}
					/* Add the address to the IP table */
					nesvnic->local_ipaddr = ifa->ifa_address;

					nes_write_indexed(nesdev,
							NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)),
							ntohl(ifa->ifa_address));
					nes_manage_arp_cache(netdev, netdev->dev_addr,
							ntohl(nesvnic->local_ipaddr), NES_ARP_ADD);
					return NOTIFY_OK;
					break;
				default:
					break;
			}
		}
	}

	return NOTIFY_DONE;
}


/**
 * nes_net_event
 */
static int nes_net_event(struct notifier_block *notifier,
		unsigned long event, void *ptr)
{
	struct neighbour *neigh = ptr;
	struct nes_device *nesdev;
	struct net_device *netdev;
	struct nes_vnic *nesvnic;

	switch (event) {
		case NETEVENT_NEIGH_UPDATE:
			list_for_each_entry(nesdev, &nes_dev_list, list) {
				/* nes_debug(NES_DBG_NETDEV, "Nesdev list entry = 0x%p.\n", nesdev); */
				netdev = nesdev->netdev[0];
				nesvnic = netdev_priv(netdev);
				if (netdev == neigh->dev) {
					if (nesvnic->rdma_enabled == 0) {
						nes_debug(NES_DBG_NETDEV, "Skipping device %s since no RDMA\n",
								netdev->name);
					} else {
						if (neigh->nud_state & NUD_VALID) {
							nes_manage_arp_cache(neigh->dev, neigh->ha,
									ntohl(*(__be32 *)neigh->primary_key), NES_ARP_ADD);
						} else {
							nes_manage_arp_cache(neigh->dev, neigh->ha,
									ntohl(*(__be32 *)neigh->primary_key), NES_ARP_DELETE);
						}
					}
					return NOTIFY_OK;
				}
			}
			break;
		default:
			nes_debug(NES_DBG_NETDEV, "NETEVENT_ %lu undefined\n", event);
			break;
	}

	return NOTIFY_DONE;
}


/**
 * nes_add_ref
 */
void nes_add_ref(struct ib_qp *ibqp)
{
	struct nes_qp *nesqp;

	nesqp = to_nesqp(ibqp);
	nes_debug(NES_DBG_QP, "Bumping refcount for QP%u.  Pre-inc value = %u\n",
			ibqp->qp_num, atomic_read(&nesqp->refcount));
	atomic_inc(&nesqp->refcount);
}

static void nes_cqp_rem_ref_callback(struct nes_device *nesdev, struct nes_cqp_request *cqp_request)
{
	unsigned long flags;
	struct nes_qp *nesqp = cqp_request->cqp_callback_pointer;
	struct nes_adapter *nesadapter = nesdev->nesadapter;
	u32 qp_id;

	atomic_inc(&qps_destroyed);

	/* Free the control structures */

	qp_id = nesqp->hwqp.qp_id;
	if (nesqp->pbl_vbase) {
		pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size,
				nesqp->hwqp.q2_vbase, nesqp->hwqp.q2_pbase);
		spin_lock_irqsave(&nesadapter->pbl_lock, flags);
		nesadapter->free_256pbl++;
		spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
		pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase);
		nesqp->pbl_vbase = NULL;

	} else {
		pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size,
				nesqp->hwqp.sq_vbase, nesqp->hwqp.sq_pbase);
	}
	nes_free_resource(nesadapter, nesadapter->allocated_qps, nesqp->hwqp.qp_id);

	nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = NULL;
	kfree(nesqp->allocated_buffer);

}

/**
 * nes_rem_ref
 */
void nes_rem_ref(struct ib_qp *ibqp)
{
	u64 u64temp;
	struct nes_qp *nesqp;
	struct nes_vnic *nesvnic = to_nesvnic(ibqp->device);
	struct nes_device *nesdev = nesvnic->nesdev;
	struct nes_hw_cqp_wqe *cqp_wqe;
	struct nes_cqp_request *cqp_request;
	u32 opcode;

	nesqp = to_nesqp(ibqp);

	if (atomic_read(&nesqp->refcount) == 0) {
		printk(KERN_INFO PFX "%s: Reference count already 0 for QP%d, last aeq = 0x%04X.\n",
				__func__, ibqp->qp_num, nesqp->last_aeq);
		BUG();
	}

	if (atomic_dec_and_test(&nesqp->refcount)) {
		/* Destroy the QP */
		cqp_request = nes_get_cqp_request(nesdev);
		if (cqp_request == NULL) {
			nes_debug(NES_DBG_QP, "Failed to get a cqp_request.\n");
			return;
		}
		cqp_request->waiting = 0;
		cqp_request->callback = 1;
		cqp_request->cqp_callback = nes_cqp_rem_ref_callback;
		cqp_request->cqp_callback_pointer = nesqp;
		cqp_wqe = &cqp_request->cqp_wqe;

		nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
		opcode = NES_CQP_DESTROY_QP | NES_CQP_QP_TYPE_IWARP;

		if (nesqp->hte_added) {
			opcode  |= NES_CQP_QP_DEL_HTE;
			nesqp->hte_added = 0;
		}
		set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode);
		set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, nesqp->hwqp.qp_id);
		u64temp = (u64)nesqp->nesqp_context_pbase;
		set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, u64temp);
		nes_post_cqp_request(nesdev, cqp_request);
	}
}


/**
 * nes_get_qp
 */
struct ib_qp *nes_get_qp(struct ib_device *device, int qpn)
{
	struct nes_vnic *nesvnic = to_nesvnic(device);
	struct nes_device *nesdev = nesvnic->nesdev;
	struct nes_adapter *nesadapter = nesdev->nesadapter;

	if ((qpn < NES_FIRST_QPN) || (qpn >= (NES_FIRST_QPN + nesadapter->max_qp)))
		return NULL;

	return &nesadapter->qp_table[qpn - NES_FIRST_QPN]->ibqp;
}


/**
 * nes_print_macaddr
 */
static void nes_print_macaddr(struct net_device *netdev)
{
	DECLARE_MAC_BUF(mac);

	nes_debug(NES_DBG_INIT, "%s: %s, IRQ %u\n",
		  netdev->name, print_mac(mac, netdev->dev_addr), netdev->irq);
}

/**
 * nes_interrupt - handle interrupts
 */
static irqreturn_t nes_interrupt(int irq, void *dev_id)
{
	struct nes_device *nesdev = (struct nes_device *)dev_id;
	int handled = 0;
	u32 int_mask;
	u32 int_req;
	u32 int_stat;
	u32 intf_int_stat;
	u32 timer_stat;

	if (nesdev->msi_enabled) {
		/* No need to read the interrupt pending register if msi is enabled */
		handled = 1;
	} else {
		if (unlikely(nesdev->nesadapter->hw_rev == NE020_REV)) {
			/* Master interrupt enable provides synchronization for kicking off bottom half
			  when interrupt sharing is going on */
			int_mask = nes_read32(nesdev->regs + NES_INT_MASK);
			if (int_mask & 0x80000000) {
				/* Check interrupt status to see if this might be ours */
				int_stat = nes_read32(nesdev->regs + NES_INT_STAT);
				int_req = nesdev->int_req;
				if (int_stat&int_req) {
					/* if interesting CEQ or AEQ is pending, claim the interrupt */
					if ((int_stat&int_req) & (~(NES_INT_TIMER|NES_INT_INTF))) {
						handled = 1;
					} else {
						if (((int_stat & int_req) & NES_INT_TIMER) == NES_INT_TIMER) {
							/* Timer might be running but might be for another function */
							timer_stat = nes_read32(nesdev->regs + NES_TIMER_STAT);
							if ((timer_stat & nesdev->timer_int_req) != 0) {
								handled = 1;
							}
						}
						if ((((int_stat & int_req) & NES_INT_INTF) == NES_INT_INTF) &&
								(handled == 0)) {
							intf_int_stat = nes_read32(nesdev->regs+NES_INTF_INT_STAT);
							if ((intf_int_stat & nesdev->intf_int_req) != 0) {
								handled = 1;
							}
						}
					}
					if (handled) {
						nes_write32(nesdev->regs+NES_INT_MASK, int_mask & (~0x80000000));
						int_mask = nes_read32(nesdev->regs+NES_INT_MASK);
						/* Save off the status to save an additional read */
						nesdev->int_stat = int_stat;
						nesdev->napi_isr_ran = 1;
					}
				}
			}
		} else {
			handled = nes_read32(nesdev->regs+NES_INT_PENDING);
		}
	}

	if (handled) {

		if (nes_napi_isr(nesdev) == 0) {
			tasklet_schedule(&nesdev->dpc_tasklet);

		}
		return IRQ_HANDLED;
	} else {
		return IRQ_NONE;
	}
}


/**
 * nes_probe - Device initialization
 */
static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
{
	struct net_device *netdev = NULL;
	struct nes_device *nesdev = NULL;
	int ret = 0;
	struct nes_vnic *nesvnic = NULL;
	void __iomem *mmio_regs = NULL;
	u8 hw_rev;

	assert(pcidev != NULL);
	assert(ent != NULL);

	printk(KERN_INFO PFX "NetEffect RNIC driver v%s loading. (%s)\n",
			DRV_VERSION, pci_name(pcidev));

	ret = pci_enable_device(pcidev);
	if (ret) {
		printk(KERN_ERR PFX "Unable to enable PCI device. (%s)\n", pci_name(pcidev));
		goto bail0;
	}

	nes_debug(NES_DBG_INIT, "BAR0 (@0x%08lX) size = 0x%lX bytes\n",
			(long unsigned int)pci_resource_start(pcidev, BAR_0),
			(long unsigned int)pci_resource_len(pcidev, BAR_0));
	nes_debug(NES_DBG_INIT, "BAR1 (@0x%08lX) size = 0x%lX bytes\n",
			(long unsigned int)pci_resource_start(pcidev, BAR_1),
			(long unsigned int)pci_resource_len(pcidev, BAR_1));

	/* Make sure PCI base addr are MMIO */
	if (!(pci_resource_flags(pcidev, BAR_0) & IORESOURCE_MEM) ||
			!(pci_resource_flags(pcidev, BAR_1) & IORESOURCE_MEM)) {
		printk(KERN_ERR PFX "PCI regions not an MMIO resource\n");
		ret = -ENODEV;
		goto bail1;
	}

	/* Reserve PCI I/O and memory resources */
	ret = pci_request_regions(pcidev, DRV_NAME);
	if (ret) {
		printk(KERN_ERR PFX "Unable to request regions. (%s)\n", pci_name(pcidev));
		goto bail1;
	}

	if ((sizeof(dma_addr_t) > 4)) {
		ret = pci_set_dma_mask(pcidev, DMA_64BIT_MASK);
		if (ret < 0) {
			printk(KERN_ERR PFX "64b DMA mask configuration failed\n");
			goto bail2;
		}
		ret = pci_set_consistent_dma_mask(pcidev, DMA_64BIT_MASK);
		if (ret) {
			printk(KERN_ERR PFX "64b DMA consistent mask configuration failed\n");
			goto bail2;
		}
	} else {
		ret = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
		if (ret < 0) {
			printk(KERN_ERR PFX "32b DMA mask configuration failed\n");
			goto bail2;
		}
		ret = pci_set_consistent_dma_mask(pcidev, DMA_32BIT_MASK);
		if (ret) {
			printk(KERN_ERR PFX "32b DMA consistent mask configuration failed\n");
			goto bail2;
		}
	}

	pci_set_master(pcidev);

	/* Allocate hardware structure */
	nesdev = kzalloc(sizeof(struct nes_device), GFP_KERNEL);
	if (!nesdev) {
		printk(KERN_ERR PFX "%s: Unable to alloc hardware struct\n", pci_name(pcidev));
		ret = -ENOMEM;
		goto bail2;
	}

	nes_debug(NES_DBG_INIT, "Allocated nes device at %p\n", nesdev);
	nesdev->pcidev = pcidev;
	pci_set_drvdata(pcidev, nesdev);

	pci_read_config_byte(pcidev, 0x0008, &hw_rev);
	nes_debug(NES_DBG_INIT, "hw_rev=%u\n", hw_rev);

	spin_lock_init(&nesdev->indexed_regs_lock);

	/* Remap the PCI registers in adapter BAR0 to kernel VA space */
	mmio_regs = ioremap_nocache(pci_resource_start(pcidev, BAR_0), sizeof(mmio_regs));
	if (mmio_regs == NULL) {
		printk(KERN_ERR PFX "Unable to remap BAR0\n");
		ret = -EIO;
		goto bail3;
	}
	nesdev->regs = mmio_regs;
	nesdev->index_reg = 0x50 + (PCI_FUNC(pcidev->devfn)*8) + mmio_regs;

	/* Ensure interrupts are disabled */
	nes_write32(nesdev->regs+NES_INT_MASK, 0x7fffffff);

	if (nes_drv_opt & NES_DRV_OPT_ENABLE_MSI) {
		if (!pci_enable_msi(nesdev->pcidev)) {
			nesdev->msi_enabled = 1;
			nes_debug(NES_DBG_INIT, "MSI is enabled for device %s\n",
					pci_name(pcidev));
		} else {
			nes_debug(NES_DBG_INIT, "MSI is disabled by linux for device %s\n",
					pci_name(pcidev));
		}
	} else {
		nes_debug(NES_DBG_INIT, "MSI not requested due to driver options for device %s\n",
				pci_name(pcidev));
	}

	nesdev->csr_start = pci_resource_start(nesdev->pcidev, BAR_0);
	nesdev->doorbell_region = pci_resource_start(nesdev->pcidev, BAR_1);

	/* Init the adapter */
	nesdev->nesadapter = nes_init_adapter(nesdev, hw_rev);
	if (!nesdev->nesadapter) {
		printk(KERN_ERR PFX "Unable to initialize adapter.\n");
		ret = -ENOMEM;
		goto bail5;
	}
	nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval;

	/* nesdev->base_doorbell_index =
			nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */
	nesdev->base_doorbell_index = 1;
	nesdev->doorbell_start = nesdev->nesadapter->doorbell_start;
	nesdev->mac_index = PCI_FUNC(nesdev->pcidev->devfn) % nesdev->nesadapter->port_count;

	tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev);

	/* bring up the Control QP */
	if (nes_init_cqp(nesdev)) {
		ret = -ENODEV;
		goto bail6;
	}

	/* Arm the CCQ */
	nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
			PCI_FUNC(nesdev->pcidev->devfn));
	nes_read32(nesdev->regs+NES_CQE_ALLOC);

	/* Enable the interrupts */
	nesdev->int_req = (0x101 << PCI_FUNC(nesdev->pcidev->devfn)) |
			(1 << (PCI_FUNC(nesdev->pcidev->devfn)+16));
	if (PCI_FUNC(nesdev->pcidev->devfn) < 4) {
		nesdev->int_req |= (1 << (PCI_FUNC(nesdev->pcidev->devfn)+24));
	}

	/* TODO: This really should be the first driver to load, not function 0 */
	if (PCI_FUNC(nesdev->pcidev->devfn) == 0) {
		/* pick up PCI and critical errors if the first driver to load */
		nesdev->intf_int_req = NES_INTF_INT_PCIERR | NES_INTF_INT_CRITERR;
		nesdev->int_req |= NES_INT_INTF;
	} else {
		nesdev->intf_int_req = 0;
	}
	nesdev->intf_int_req |= (1 << (PCI_FUNC(nesdev->pcidev->devfn)+16));
	nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS0, 0);
	nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS1, 0);
	nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS2, 0x00001265);
	nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS4, 0x18021804);

	nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS3, 0x17801790);

	/* deal with both periodic and one_shot */
	nesdev->timer_int_req = 0x101 << PCI_FUNC(nesdev->pcidev->devfn);
	nesdev->nesadapter->timer_int_req |= nesdev->timer_int_req;
	nes_debug(NES_DBG_INIT, "setting int_req for function %u, nesdev = 0x%04X, adapter = 0x%04X\n",
			PCI_FUNC(nesdev->pcidev->devfn),
			nesdev->timer_int_req, nesdev->nesadapter->timer_int_req);

	nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req));

	list_add_tail(&nesdev->list, &nes_dev_list);

	/* Request an interrupt line for the driver */
	ret = request_irq(pcidev->irq, nes_interrupt, IRQF_SHARED, DRV_NAME, nesdev);
	if (ret) {
		printk(KERN_ERR PFX "%s: requested IRQ %u is busy\n",
				pci_name(pcidev), pcidev->irq);
		goto bail65;
	}

	nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req);

	if (nes_notifiers_registered == 0) {
		register_inetaddr_notifier(&nes_inetaddr_notifier);
		register_netevent_notifier(&nes_net_notifier);
	}
	nes_notifiers_registered++;

	/* Initialize network devices */
		if ((netdev = nes_netdev_init(nesdev, mmio_regs)) == NULL) {
			goto bail7;
		}

		/* Register network device */
		ret = register_netdev(netdev);
		if (ret) {
			printk(KERN_ERR PFX "Unable to register netdev, ret = %d\n", ret);
			nes_netdev_destroy(netdev);
			goto bail7;
		}

		nes_print_macaddr(netdev);
		/* create a CM core for this netdev */
		nesvnic = netdev_priv(netdev);

		nesdev->netdev_count++;
		nesdev->nesadapter->netdev_count++;


	printk(KERN_ERR PFX "%s: NetEffect RNIC driver successfully loaded.\n",
			pci_name(pcidev));
	return 0;

	bail7:
	printk(KERN_ERR PFX "bail7\n");
	while (nesdev->netdev_count > 0) {
		nesdev->netdev_count--;
		nesdev->nesadapter->netdev_count--;

		unregister_netdev(nesdev->netdev[nesdev->netdev_count]);
		nes_netdev_destroy(nesdev->netdev[nesdev->netdev_count]);
	}

	nes_debug(NES_DBG_INIT, "netdev_count=%d, nesadapter->netdev_count=%d\n",
			nesdev->netdev_count, nesdev->nesadapter->netdev_count);

	nes_notifiers_registered--;
	if (nes_notifiers_registered == 0) {
		unregister_netevent_notifier(&nes_net_notifier);
		unregister_inetaddr_notifier(&nes_inetaddr_notifier);
	}

	list_del(&nesdev->list);
	nes_destroy_cqp(nesdev);

	bail65:
	printk(KERN_ERR PFX "bail65\n");
	free_irq(pcidev->irq, nesdev);
	if (nesdev->msi_enabled) {
		pci_disable_msi(pcidev);
	}
	bail6:
	printk(KERN_ERR PFX "bail6\n");
	tasklet_kill(&nesdev->dpc_tasklet);
	/* Deallocate the Adapter Structure */
	nes_destroy_adapter(nesdev->nesadapter);

	bail5:
	printk(KERN_ERR PFX "bail5\n");
	iounmap(nesdev->regs);

	bail3:
	printk(KERN_ERR PFX "bail3\n");
	kfree(nesdev);

	bail2:
	pci_release_regions(pcidev);

	bail1:
	pci_disable_device(pcidev);

	bail0:
	return ret;
}


/**
 * nes_remove - unload from kernel
 */
static void __devexit nes_remove(struct pci_dev *pcidev)
{
	struct nes_device *nesdev = pci_get_drvdata(pcidev);
	struct net_device *netdev;
	int netdev_index = 0;

		if (nesdev->netdev_count) {
			netdev = nesdev->netdev[netdev_index];
			if (netdev) {
				netif_stop_queue(netdev);
				unregister_netdev(netdev);
				nes_netdev_destroy(netdev);

				nesdev->netdev[netdev_index] = NULL;
				nesdev->netdev_count--;
				nesdev->nesadapter->netdev_count--;
			}
		}

	nes_notifiers_registered--;
	if (nes_notifiers_registered == 0) {
		unregister_netevent_notifier(&nes_net_notifier);
		unregister_inetaddr_notifier(&nes_inetaddr_notifier);
	}

	list_del(&nesdev->list);
	nes_destroy_cqp(nesdev);

	free_irq(pcidev->irq, nesdev);
	tasklet_kill(&nesdev->dpc_tasklet);

	/* Deallocate the Adapter Structure */
	nes_destroy_adapter(nesdev->nesadapter);

	if (nesdev->msi_enabled) {
		pci_disable_msi(pcidev);
	}

	iounmap(nesdev->regs);
	kfree(nesdev);

	/* nes_debug(NES_DBG_SHUTDOWN, "calling pci_release_regions.\n"); */
	pci_release_regions(pcidev);
	pci_disable_device(pcidev);
	pci_set_drvdata(pcidev, NULL);
}


static struct pci_driver nes_pci_driver = {
	.name = DRV_NAME,
	.id_table = nes_pci_table,
	.probe = nes_probe,
	.remove = __devexit_p(nes_remove),
};

static ssize_t nes_show_adapter(struct device_driver *ddp, char *buf)
{
	unsigned int  devfn = 0xffffffff;
	unsigned char bus_number = 0xff;
	unsigned int  i = 0;
	struct nes_device *nesdev;

	list_for_each_entry(nesdev, &nes_dev_list, list) {
		if (i == ee_flsh_adapter) {
			devfn      = nesdev->nesadapter->devfn;
			bus_number = nesdev->nesadapter->bus_number;
			break;
		}
		i++;
	}

	return snprintf(buf, PAGE_SIZE, "%x:%x", bus_number, devfn);
}

static ssize_t nes_store_adapter(struct device_driver *ddp,
	const char *buf, size_t count)
{
	char *p = (char *)buf;

	ee_flsh_adapter = simple_strtoul(p, &p, 10);
	return strnlen(buf, count);
}

static ssize_t nes_show_ee_cmd(struct device_driver *ddp, char *buf)
{
	u32 eeprom_cmd = 0xdead;
	u32 i = 0;
	struct nes_device *nesdev;

	list_for_each_entry(nesdev, &nes_dev_list, list) {
		if (i == ee_flsh_adapter) {
			eeprom_cmd = nes_read32(nesdev->regs + NES_EEPROM_COMMAND);
			break;
		}
		i++;
	}
	return snprintf(buf, PAGE_SIZE, "0x%x\n", eeprom_cmd);
}

static ssize_t nes_store_ee_cmd(struct device_driver *ddp,
	const char *buf, size_t count)
{
	char *p = (char *)buf;
	u32 val;
	u32 i = 0;
	struct nes_device *nesdev;

	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
		val = simple_strtoul(p, &p, 16);
		list_for_each_entry(nesdev, &nes_dev_list, list) {
			if (i == ee_flsh_adapter) {
				nes_write32(nesdev->regs + NES_EEPROM_COMMAND, val);
				break;
			}
			i++;
		}
	}
	return strnlen(buf, count);
}

static ssize_t nes_show_ee_data(struct device_driver *ddp, char *buf)
{
	u32 eeprom_data = 0xdead;
	u32 i = 0;
	struct nes_device *nesdev;

	list_for_each_entry(nesdev, &nes_dev_list, list) {
		if (i == ee_flsh_adapter) {
			eeprom_data = nes_read32(nesdev->regs + NES_EEPROM_DATA);
			break;
		}
		i++;
	}

	return  snprintf(buf, PAGE_SIZE, "0x%x\n", eeprom_data);
}

static ssize_t nes_store_ee_data(struct device_driver *ddp,
	const char *buf, size_t count)
{
	char *p = (char *)buf;
	u32 val;
	u32 i = 0;
	struct nes_device *nesdev;

	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
		val = simple_strtoul(p, &p, 16);
		list_for_each_entry(nesdev, &nes_dev_list, list) {
			if (i == ee_flsh_adapter) {
				nes_write32(nesdev->regs + NES_EEPROM_DATA, val);
				break;
			}
			i++;
		}
	}
	return strnlen(buf, count);
}

static ssize_t nes_show_flash_cmd(struct device_driver *ddp, char *buf)
{
	u32 flash_cmd = 0xdead;
	u32 i = 0;
	struct nes_device *nesdev;

	list_for_each_entry(nesdev, &nes_dev_list, list) {
		if (i == ee_flsh_adapter) {
			flash_cmd = nes_read32(nesdev->regs + NES_FLASH_COMMAND);
			break;
		}
		i++;
	}

	return  snprintf(buf, PAGE_SIZE, "0x%x\n", flash_cmd);
}

static ssize_t nes_store_flash_cmd(struct device_driver *ddp,
	const char *buf, size_t count)
{
	char *p = (char *)buf;
	u32 val;
	u32 i = 0;
	struct nes_device *nesdev;

	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
		val = simple_strtoul(p, &p, 16);
		list_for_each_entry(nesdev, &nes_dev_list, list) {
			if (i == ee_flsh_adapter) {
				nes_write32(nesdev->regs + NES_FLASH_COMMAND, val);
				break;
			}
			i++;
		}
	}
	return strnlen(buf, count);
}

static ssize_t nes_show_flash_data(struct device_driver *ddp, char *buf)
{
	u32 flash_data = 0xdead;
	u32 i = 0;
	struct nes_device *nesdev;

	list_for_each_entry(nesdev, &nes_dev_list, list) {
		if (i == ee_flsh_adapter) {
			flash_data = nes_read32(nesdev->regs + NES_FLASH_DATA);
			break;
		}
		i++;
	}

	return  snprintf(buf, PAGE_SIZE, "0x%x\n", flash_data);
}

static ssize_t nes_store_flash_data(struct device_driver *ddp,
	const char *buf, size_t count)
{
	char *p = (char *)buf;
	u32 val;
	u32 i = 0;
	struct nes_device *nesdev;

	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
		val = simple_strtoul(p, &p, 16);
		list_for_each_entry(nesdev, &nes_dev_list, list) {
			if (i == ee_flsh_adapter) {
				nes_write32(nesdev->regs + NES_FLASH_DATA, val);
				break;
			}
			i++;
		}
	}
	return strnlen(buf, count);
}

static ssize_t nes_show_nonidx_addr(struct device_driver *ddp, char *buf)
{
	return  snprintf(buf, PAGE_SIZE, "0x%x\n", sysfs_nonidx_addr);
}

static ssize_t nes_store_nonidx_addr(struct device_driver *ddp,
	const char *buf, size_t count)
{
	char *p = (char *)buf;

	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X')
		sysfs_nonidx_addr = simple_strtoul(p, &p, 16);

	return strnlen(buf, count);
}

static ssize_t nes_show_nonidx_data(struct device_driver *ddp, char *buf)
{
	u32 nonidx_data = 0xdead;
	u32 i = 0;
	struct nes_device *nesdev;

	list_for_each_entry(nesdev, &nes_dev_list, list) {
		if (i == ee_flsh_adapter) {
			nonidx_data = nes_read32(nesdev->regs + sysfs_nonidx_addr);
			break;
		}
		i++;
	}

	return  snprintf(buf, PAGE_SIZE, "0x%x\n", nonidx_data);
}

static ssize_t nes_store_nonidx_data(struct device_driver *ddp,
	const char *buf, size_t count)
{
	char *p = (char *)buf;
	u32 val;
	u32 i = 0;
	struct nes_device *nesdev;

	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
		val = simple_strtoul(p, &p, 16);
		list_for_each_entry(nesdev, &nes_dev_list, list) {
			if (i == ee_flsh_adapter) {
				nes_write32(nesdev->regs + sysfs_nonidx_addr, val);
				break;
			}
			i++;
		}
	}
	return strnlen(buf, count);
}

static ssize_t nes_show_idx_addr(struct device_driver *ddp, char *buf)
{
	return  snprintf(buf, PAGE_SIZE, "0x%x\n", sysfs_idx_addr);
}

static ssize_t nes_store_idx_addr(struct device_driver *ddp,
	const char *buf, size_t count)
{
	char *p = (char *)buf;

	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X')
		sysfs_idx_addr = simple_strtoul(p, &p, 16);

	return strnlen(buf, count);
}

static ssize_t nes_show_idx_data(struct device_driver *ddp, char *buf)
{
	u32 idx_data = 0xdead;
	u32 i = 0;
	struct nes_device *nesdev;

	list_for_each_entry(nesdev, &nes_dev_list, list) {
		if (i == ee_flsh_adapter) {
			idx_data = nes_read_indexed(nesdev, sysfs_idx_addr);
			break;
		}
		i++;
	}

	return  snprintf(buf, PAGE_SIZE, "0x%x\n", idx_data);
}

static ssize_t nes_store_idx_data(struct device_driver *ddp,
	const char *buf, size_t count)
{
	char *p = (char *)buf;
	u32 val;
	u32 i = 0;
	struct nes_device *nesdev;

	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
		val = simple_strtoul(p, &p, 16);
		list_for_each_entry(nesdev, &nes_dev_list, list) {
			if (i == ee_flsh_adapter) {
				nes_write_indexed(nesdev, sysfs_idx_addr, val);
				break;
			}
			i++;
		}
	}
	return strnlen(buf, count);
}

static DRIVER_ATTR(adapter, S_IRUSR | S_IWUSR,
		   nes_show_adapter, nes_store_adapter);
static DRIVER_ATTR(eeprom_cmd, S_IRUSR | S_IWUSR,
		   nes_show_ee_cmd, nes_store_ee_cmd);
static DRIVER_ATTR(eeprom_data, S_IRUSR | S_IWUSR,
		   nes_show_ee_data, nes_store_ee_data);
static DRIVER_ATTR(flash_cmd, S_IRUSR | S_IWUSR,
		   nes_show_flash_cmd, nes_store_flash_cmd);
static DRIVER_ATTR(flash_data, S_IRUSR | S_IWUSR,
		   nes_show_flash_data, nes_store_flash_data);
static DRIVER_ATTR(nonidx_addr, S_IRUSR | S_IWUSR,
		   nes_show_nonidx_addr, nes_store_nonidx_addr);
static DRIVER_ATTR(nonidx_data, S_IRUSR | S_IWUSR,
		   nes_show_nonidx_data, nes_store_nonidx_data);
static DRIVER_ATTR(idx_addr, S_IRUSR | S_IWUSR,
		   nes_show_idx_addr, nes_store_idx_addr);
static DRIVER_ATTR(idx_data, S_IRUSR | S_IWUSR,
		   nes_show_idx_data, nes_store_idx_data);

static int nes_create_driver_sysfs(struct pci_driver *drv)
{
	int error;
	error  = driver_create_file(&drv->driver, &driver_attr_adapter);
	error |= driver_create_file(&drv->driver, &driver_attr_eeprom_cmd);
	error |= driver_create_file(&drv->driver, &driver_attr_eeprom_data);
	error |= driver_create_file(&drv->driver, &driver_attr_flash_cmd);
	error |= driver_create_file(&drv->driver, &driver_attr_flash_data);
	error |= driver_create_file(&drv->driver, &driver_attr_nonidx_addr);
	error |= driver_create_file(&drv->driver, &driver_attr_nonidx_data);
	error |= driver_create_file(&drv->driver, &driver_attr_idx_addr);
	error |= driver_create_file(&drv->driver, &driver_attr_idx_data);
	return error;
}

static void nes_remove_driver_sysfs(struct pci_driver *drv)
{
	driver_remove_file(&drv->driver, &driver_attr_adapter);
	driver_remove_file(&drv->driver, &driver_attr_eeprom_cmd);
	driver_remove_file(&drv->driver, &driver_attr_eeprom_data);
	driver_remove_file(&drv->driver, &driver_attr_flash_cmd);
	driver_remove_file(&drv->driver, &driver_attr_flash_data);
	driver_remove_file(&drv->driver, &driver_attr_nonidx_addr);
	driver_remove_file(&drv->driver, &driver_attr_nonidx_data);
	driver_remove_file(&drv->driver, &driver_attr_idx_addr);
	driver_remove_file(&drv->driver, &driver_attr_idx_data);
}

/**
 * nes_init_module - module initialization entry point
 */
static int __init nes_init_module(void)
{
	int retval;
	int retval1;

	retval = nes_cm_start();
	if (retval) {
		printk(KERN_ERR PFX "Unable to start NetEffect iWARP CM.\n");
		return retval;
	}
	retval = pci_register_driver(&nes_pci_driver);
	if (retval >= 0) {
		retval1 = nes_create_driver_sysfs(&nes_pci_driver);
		if (retval1 < 0)
			printk(KERN_ERR PFX "Unable to create NetEffect sys files.\n");
	}
	return retval;
}


/**
 * nes_exit_module - module unload entry point
 */
static void __exit nes_exit_module(void)
{
	nes_cm_stop();
	nes_remove_driver_sysfs(&nes_pci_driver);

	pci_unregister_driver(&nes_pci_driver);
}


module_init(nes_init_module);
module_exit(nes_exit_module);
