/* bnx2fc_fcoe.c: QLogic Linux FCoE offload driver.
 * This file contains the code that interacts with libfc, libfcoe,
 * cnic modules to create FCoE instances, send/receive non-offloaded
 * FIP/FCoE packets, listen to link events etc.
 *
 * Copyright (c) 2008-2013 Broadcom Corporation
 * Copyright (c) 2014-2016 QLogic Corporation
 * Copyright (c) 2016-2017 Cavium Inc.
 *
 * 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.
 *
 * Written by: Bhanu Prakash Gollapudi (bprakash@broadcom.com)
 */

#include "bnx2fc.h"

#include <linux/ethtool.h>

static struct list_head adapter_list;
static struct list_head if_list;
static u32 adapter_count;
static DEFINE_MUTEX(bnx2fc_dev_lock);
DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu);

#define DRV_MODULE_NAME		"bnx2fc"
#define DRV_MODULE_VERSION	BNX2FC_VERSION
#define DRV_MODULE_RELDATE	"October 15, 2015"


static char version[] =
		"QLogic FCoE Driver " DRV_MODULE_NAME \
		" v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";


MODULE_AUTHOR("Bhanu Prakash Gollapudi <bprakash@broadcom.com>");
MODULE_DESCRIPTION("QLogic FCoE Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);

#define BNX2FC_MAX_QUEUE_DEPTH	256
#define BNX2FC_MIN_QUEUE_DEPTH	32
#define FCOE_WORD_TO_BYTE  4

static struct scsi_transport_template	*bnx2fc_transport_template;
static struct scsi_transport_template	*bnx2fc_vport_xport_template;

struct workqueue_struct *bnx2fc_wq;

/* bnx2fc structure needs only one instance of the fcoe_percpu_s structure.
 * Here the io threads are per cpu but the l2 thread is just one
 */
struct fcoe_percpu_s bnx2fc_global;
static DEFINE_SPINLOCK(bnx2fc_global_lock);

static struct cnic_ulp_ops bnx2fc_cnic_cb;
static struct libfc_function_template bnx2fc_libfc_fcn_templ;
static struct scsi_host_template bnx2fc_shost_template;
static struct fc_function_template bnx2fc_transport_function;
static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ;
static struct fc_function_template bnx2fc_vport_xport_function;
static int bnx2fc_create(struct net_device *netdev, enum fip_mode fip_mode);
static void __bnx2fc_destroy(struct bnx2fc_interface *interface);
static int bnx2fc_destroy(struct net_device *net_device);
static int bnx2fc_enable(struct net_device *netdev);
static int bnx2fc_disable(struct net_device *netdev);

/* fcoe_syfs control interface handlers */
static int bnx2fc_ctlr_alloc(struct net_device *netdev);
static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev);

static void bnx2fc_recv_frame(struct sk_buff *skb);

static void bnx2fc_start_disc(struct bnx2fc_interface *interface);
static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev);
static int bnx2fc_lport_config(struct fc_lport *lport);
static int bnx2fc_em_config(struct fc_lport *lport, struct bnx2fc_hba *hba);
static int bnx2fc_bind_adapter_devices(struct bnx2fc_hba *hba);
static void bnx2fc_unbind_adapter_devices(struct bnx2fc_hba *hba);
static int bnx2fc_bind_pcidev(struct bnx2fc_hba *hba);
static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba);
static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface,
				  struct device *parent, int npiv);
static void bnx2fc_port_destroy(struct fcoe_port *port);

static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device *phys_dev);
static struct bnx2fc_interface *bnx2fc_interface_lookup(struct net_device
							*phys_dev);
static inline void bnx2fc_interface_put(struct bnx2fc_interface *interface);
static struct bnx2fc_hba *bnx2fc_find_hba_for_cnic(struct cnic_dev *cnic);

static int bnx2fc_fw_init(struct bnx2fc_hba *hba);
static void bnx2fc_fw_destroy(struct bnx2fc_hba *hba);

static void bnx2fc_port_shutdown(struct fc_lport *lport);
static void bnx2fc_stop(struct bnx2fc_interface *interface);
static int __init bnx2fc_mod_init(void);
static void __exit bnx2fc_mod_exit(void);

unsigned int bnx2fc_debug_level;
module_param_named(debug_logging, bnx2fc_debug_level, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(debug_logging,
		"Option to enable extended logging,\n"
		"\t\tDefault is 0 - no logging.\n"
		"\t\t0x01 - SCSI cmd error, cleanup.\n"
		"\t\t0x02 - Session setup, cleanup, etc.\n"
		"\t\t0x04 - lport events, link, mtu, etc.\n"
		"\t\t0x08 - ELS logs.\n"
		"\t\t0x10 - fcoe L2 fame related logs.\n"
		"\t\t0xff - LOG all messages.");

static uint bnx2fc_devloss_tmo;
module_param_named(devloss_tmo, bnx2fc_devloss_tmo, uint, S_IRUGO);
MODULE_PARM_DESC(devloss_tmo, " Change devloss_tmo for the remote ports "
	"attached via bnx2fc.");

static uint bnx2fc_max_luns = BNX2FC_MAX_LUN;
module_param_named(max_luns, bnx2fc_max_luns, uint, S_IRUGO);
MODULE_PARM_DESC(max_luns, " Change the default max_lun per SCSI host. Default "
	"0xffff.");

static uint bnx2fc_queue_depth;
module_param_named(queue_depth, bnx2fc_queue_depth, uint, S_IRUGO);
MODULE_PARM_DESC(queue_depth, " Change the default queue depth of SCSI devices "
	"attached via bnx2fc.");

static uint bnx2fc_log_fka;
module_param_named(log_fka, bnx2fc_log_fka, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(log_fka, " Print message to kernel log when fcoe is "
	"initiating a FIP keep alive when debug logging is enabled.");

static inline struct net_device *bnx2fc_netdev(const struct fc_lport *lport)
{
	return ((struct bnx2fc_interface *)
		((struct fcoe_port *)lport_priv(lport))->priv)->netdev;
}

static void bnx2fc_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev)
{
	struct fcoe_ctlr_device *ctlr_dev =
		fcoe_fcf_dev_to_ctlr_dev(fcf_dev);
	struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
	struct bnx2fc_interface *fcoe = fcoe_ctlr_priv(ctlr);

	fcf_dev->vlan_id = fcoe->vlan_id;
}

static void bnx2fc_clean_rx_queue(struct fc_lport *lp)
{
	struct fcoe_percpu_s *bg;
	struct fcoe_rcv_info *fr;
	struct sk_buff_head *list;
	struct sk_buff *skb, *next;

	bg = &bnx2fc_global;
	spin_lock_bh(&bg->fcoe_rx_list.lock);
	list = &bg->fcoe_rx_list;
	skb_queue_walk_safe(list, skb, next) {
		fr = fcoe_dev_from_skb(skb);
		if (fr->fr_dev == lp) {
			__skb_unlink(skb, list);
			kfree_skb(skb);
		}
	}
	spin_unlock_bh(&bg->fcoe_rx_list.lock);
}

int bnx2fc_get_paged_crc_eof(struct sk_buff *skb, int tlen)
{
	int rc;
	spin_lock(&bnx2fc_global_lock);
	rc = fcoe_get_paged_crc_eof(skb, tlen, &bnx2fc_global);
	spin_unlock(&bnx2fc_global_lock);

	return rc;
}

static void bnx2fc_abort_io(struct fc_lport *lport)
{
	/*
	 * This function is no-op for bnx2fc, but we do
	 * not want to leave it as NULL either, as libfc
	 * can call the default function which is
	 * fc_fcp_abort_io.
	 */
}

static void bnx2fc_cleanup(struct fc_lport *lport)
{
	struct fcoe_port *port = lport_priv(lport);
	struct bnx2fc_interface *interface = port->priv;
	struct bnx2fc_hba *hba = interface->hba;
	struct bnx2fc_rport *tgt;
	int i;

	BNX2FC_MISC_DBG("Entered %s\n", __func__);
	mutex_lock(&hba->hba_mutex);
	spin_lock_bh(&hba->hba_lock);
	for (i = 0; i < BNX2FC_NUM_MAX_SESS; i++) {
		tgt = hba->tgt_ofld_list[i];
		if (tgt) {
			/* Cleanup IOs belonging to requested vport */
			if (tgt->port == port) {
				spin_unlock_bh(&hba->hba_lock);
				BNX2FC_TGT_DBG(tgt, "flush/cleanup\n");
				bnx2fc_flush_active_ios(tgt);
				spin_lock_bh(&hba->hba_lock);
			}
		}
	}
	spin_unlock_bh(&hba->hba_lock);
	mutex_unlock(&hba->hba_mutex);
}

static int bnx2fc_xmit_l2_frame(struct bnx2fc_rport *tgt,
			     struct fc_frame *fp)
{
	struct fc_rport_priv *rdata = tgt->rdata;
	struct fc_frame_header *fh;
	int rc = 0;

	fh = fc_frame_header_get(fp);
	BNX2FC_TGT_DBG(tgt, "Xmit L2 frame rport = 0x%x, oxid = 0x%x, "
			"r_ctl = 0x%x\n", rdata->ids.port_id,
			ntohs(fh->fh_ox_id), fh->fh_r_ctl);
	if ((fh->fh_type == FC_TYPE_ELS) &&
	    (fh->fh_r_ctl == FC_RCTL_ELS_REQ)) {

		switch (fc_frame_payload_op(fp)) {
		case ELS_ADISC:
			rc = bnx2fc_send_adisc(tgt, fp);
			break;
		case ELS_LOGO:
			rc = bnx2fc_send_logo(tgt, fp);
			break;
		case ELS_RLS:
			rc = bnx2fc_send_rls(tgt, fp);
			break;
		default:
			break;
		}
	} else if ((fh->fh_type ==  FC_TYPE_BLS) &&
	    (fh->fh_r_ctl == FC_RCTL_BA_ABTS))
		BNX2FC_TGT_DBG(tgt, "ABTS frame\n");
	else {
		BNX2FC_TGT_DBG(tgt, "Send L2 frame type 0x%x "
				"rctl 0x%x thru non-offload path\n",
				fh->fh_type, fh->fh_r_ctl);
		return -ENODEV;
	}
	if (rc)
		return -ENOMEM;
	else
		return 0;
}

/**
 * bnx2fc_xmit - bnx2fc's FCoE frame transmit function
 *
 * @lport:	the associated local port
 * @fp:	the fc_frame to be transmitted
 */
static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp)
{
	struct ethhdr		*eh;
	struct fcoe_crc_eof	*cp;
	struct sk_buff		*skb;
	struct fc_frame_header	*fh;
	struct bnx2fc_interface	*interface;
	struct fcoe_ctlr        *ctlr;
	struct bnx2fc_hba *hba;
	struct fcoe_port	*port;
	struct fcoe_hdr		*hp;
	struct bnx2fc_rport	*tgt;
	u8			sof, eof;
	u32			crc;
	unsigned int		hlen, tlen, elen;
	int			wlen, rc = 0;

	port = (struct fcoe_port *)lport_priv(lport);
	interface = port->priv;
	ctlr = bnx2fc_to_ctlr(interface);
	hba = interface->hba;

	fh = fc_frame_header_get(fp);

	skb = fp_skb(fp);
	if (!lport->link_up) {
		BNX2FC_HBA_DBG(lport, "bnx2fc_xmit link down\n");
		kfree_skb(skb);
		return 0;
	}

	if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ)) {
		if (!ctlr->sel_fcf) {
			BNX2FC_HBA_DBG(lport, "FCF not selected yet!\n");
			kfree_skb(skb);
			return -EINVAL;
		}
		if (fcoe_ctlr_els_send(ctlr, lport, skb))
			return 0;
	}

	sof = fr_sof(fp);
	eof = fr_eof(fp);

	/*
	 * Snoop the frame header to check if the frame is for
	 * an offloaded session
	 */
	/*
	 * tgt_ofld_list access is synchronized using
	 * both hba mutex and hba lock. Atleast hba mutex or
	 * hba lock needs to be held for read access.
	 */

	spin_lock_bh(&hba->hba_lock);
	tgt = bnx2fc_tgt_lookup(port, ntoh24(fh->fh_d_id));
	if (tgt && (test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags))) {
		/* This frame is for offloaded session */
		BNX2FC_HBA_DBG(lport, "xmit: Frame is for offloaded session "
				"port_id = 0x%x\n", ntoh24(fh->fh_d_id));
		spin_unlock_bh(&hba->hba_lock);
		rc = bnx2fc_xmit_l2_frame(tgt, fp);
		if (rc != -ENODEV) {
			kfree_skb(skb);
			return rc;
		}
	} else {
		spin_unlock_bh(&hba->hba_lock);
	}

	elen = sizeof(struct ethhdr);
	hlen = sizeof(struct fcoe_hdr);
	tlen = sizeof(struct fcoe_crc_eof);
	wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;

	skb->ip_summed = CHECKSUM_NONE;
	crc = fcoe_fc_crc(fp);

	/* copy port crc and eof to the skb buff */
	if (skb_is_nonlinear(skb)) {
		skb_frag_t *frag;
		if (bnx2fc_get_paged_crc_eof(skb, tlen)) {
			kfree_skb(skb);
			return -ENOMEM;
		}
		frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
		cp = kmap_atomic(skb_frag_page(frag)) + skb_frag_off(frag);
	} else {
		cp = skb_put(skb, tlen);
	}

	memset(cp, 0, sizeof(*cp));
	cp->fcoe_eof = eof;
	cp->fcoe_crc32 = cpu_to_le32(~crc);
	if (skb_is_nonlinear(skb)) {
		kunmap_atomic(cp);
		cp = NULL;
	}

	/* adjust skb network/transport offsets to match mac/fcoe/port */
	skb_push(skb, elen + hlen);
	skb_reset_mac_header(skb);
	skb_reset_network_header(skb);
	skb->mac_len = elen;
	skb->protocol = htons(ETH_P_FCOE);
	skb->dev = interface->netdev;

	/* fill up mac and fcoe headers */
	eh = eth_hdr(skb);
	eh->h_proto = htons(ETH_P_FCOE);
	if (ctlr->map_dest)
		fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
	else
		/* insert GW address */
		memcpy(eh->h_dest, ctlr->dest_addr, ETH_ALEN);

	if (unlikely(ctlr->flogi_oxid != FC_XID_UNKNOWN))
		memcpy(eh->h_source, ctlr->ctl_src_addr, ETH_ALEN);
	else
		memcpy(eh->h_source, port->data_src_addr, ETH_ALEN);

	hp = (struct fcoe_hdr *)(eh + 1);
	memset(hp, 0, sizeof(*hp));
	if (FC_FCOE_VER)
		FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
	hp->fcoe_sof = sof;

	/* fcoe lso, mss is in max_payload which is non-zero for FCP data */
	if (lport->seq_offload && fr_max_payload(fp)) {
		skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
		skb_shinfo(skb)->gso_size = fr_max_payload(fp);
	} else {
		skb_shinfo(skb)->gso_type = 0;
		skb_shinfo(skb)->gso_size = 0;
	}

	/*update tx stats */
	this_cpu_inc(lport->stats->TxFrames);
	this_cpu_add(lport->stats->TxWords, wlen);

	/* send down to lld */
	fr_dev(fp) = lport;
	if (port->fcoe_pending_queue.qlen)
		fcoe_check_wait_queue(lport, skb);
	else if (fcoe_start_io(skb))
		fcoe_check_wait_queue(lport, skb);

	return 0;
}

/**
 * bnx2fc_rcv - This is bnx2fc's receive function called by NET_RX_SOFTIRQ
 *
 * @skb:	the receive socket buffer
 * @dev:	associated net device
 * @ptype:	context
 * @olddev:	last device
 *
 * This function receives the packet and builds FC frame and passes it up
 */
static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev,
		struct packet_type *ptype, struct net_device *olddev)
{
	struct fc_lport *lport;
	struct bnx2fc_interface *interface;
	struct fcoe_ctlr *ctlr;
	struct fcoe_rcv_info *fr;
	struct fcoe_percpu_s *bg;
	struct sk_buff *tmp_skb;

	interface = container_of(ptype, struct bnx2fc_interface,
				 fcoe_packet_type);
	ctlr = bnx2fc_to_ctlr(interface);
	lport = ctlr->lp;

	if (unlikely(lport == NULL)) {
		printk(KERN_ERR PFX "bnx2fc_rcv: lport is NULL\n");
		goto err;
	}

	tmp_skb = skb_share_check(skb, GFP_ATOMIC);
	if (!tmp_skb)
		goto err;

	skb = tmp_skb;

	if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
		printk(KERN_ERR PFX "bnx2fc_rcv: Wrong FC type frame\n");
		goto err;
	}

	/*
	 * Check for minimum frame length, and make sure required FCoE
	 * and FC headers are pulled into the linear data area.
	 */
	if (unlikely((skb->len < FCOE_MIN_FRAME) ||
	    !pskb_may_pull(skb, FCOE_HEADER_LEN)))
		goto err;

	skb_set_transport_header(skb, sizeof(struct fcoe_hdr));

	fr = fcoe_dev_from_skb(skb);
	fr->fr_dev = lport;

	bg = &bnx2fc_global;
	spin_lock(&bg->fcoe_rx_list.lock);

	__skb_queue_tail(&bg->fcoe_rx_list, skb);
	if (bg->fcoe_rx_list.qlen == 1)
		wake_up_process(bg->kthread);

	spin_unlock(&bg->fcoe_rx_list.lock);

	return 0;
err:
	kfree_skb(skb);
	return -1;
}

static int bnx2fc_l2_rcv_thread(void *arg)
{
	struct fcoe_percpu_s *bg = arg;
	struct sk_buff *skb;

	set_user_nice(current, MIN_NICE);
	set_current_state(TASK_INTERRUPTIBLE);
	while (!kthread_should_stop()) {
		schedule();
		spin_lock_bh(&bg->fcoe_rx_list.lock);
		while ((skb = __skb_dequeue(&bg->fcoe_rx_list)) != NULL) {
			spin_unlock_bh(&bg->fcoe_rx_list.lock);
			bnx2fc_recv_frame(skb);
			spin_lock_bh(&bg->fcoe_rx_list.lock);
		}
		__set_current_state(TASK_INTERRUPTIBLE);
		spin_unlock_bh(&bg->fcoe_rx_list.lock);
	}
	__set_current_state(TASK_RUNNING);
	return 0;
}


static void bnx2fc_recv_frame(struct sk_buff *skb)
{
	u64 crc_err;
	u32 fr_len, fr_crc;
	struct fc_lport *lport;
	struct fcoe_rcv_info *fr;
	struct fc_frame_header *fh;
	struct fcoe_crc_eof crc_eof;
	struct fc_frame *fp;
	struct fc_lport *vn_port;
	struct fcoe_port *port, *phys_port;
	u8 *mac = NULL;
	u8 *dest_mac = NULL;
	struct fcoe_hdr *hp;
	struct bnx2fc_interface *interface;
	struct fcoe_ctlr *ctlr;

	fr = fcoe_dev_from_skb(skb);
	lport = fr->fr_dev;
	if (unlikely(lport == NULL)) {
		printk(KERN_ERR PFX "Invalid lport struct\n");
		kfree_skb(skb);
		return;
	}

	if (skb_is_nonlinear(skb))
		skb_linearize(skb);
	mac = eth_hdr(skb)->h_source;
	dest_mac = eth_hdr(skb)->h_dest;

	/* Pull the header */
	hp = (struct fcoe_hdr *) skb_network_header(skb);
	fh = (struct fc_frame_header *) skb_transport_header(skb);
	skb_pull(skb, sizeof(struct fcoe_hdr));
	fr_len = skb->len - sizeof(struct fcoe_crc_eof);

	this_cpu_inc(lport->stats->RxFrames);
	this_cpu_add(lport->stats->RxWords, fr_len / FCOE_WORD_TO_BYTE);

	fp = (struct fc_frame *)skb;
	fc_frame_init(fp);
	fr_dev(fp) = lport;
	fr_sof(fp) = hp->fcoe_sof;
	if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
		kfree_skb(skb);
		return;
	}
	fr_eof(fp) = crc_eof.fcoe_eof;
	fr_crc(fp) = crc_eof.fcoe_crc32;
	if (pskb_trim(skb, fr_len)) {
		kfree_skb(skb);
		return;
	}

	phys_port = lport_priv(lport);
	interface = phys_port->priv;
	ctlr = bnx2fc_to_ctlr(interface);

	fh = fc_frame_header_get(fp);

	if (ntoh24(&dest_mac[3]) != ntoh24(fh->fh_d_id)) {
		BNX2FC_HBA_DBG(lport, "FC frame d_id mismatch with MAC %pM.\n",
		    dest_mac);
		kfree_skb(skb);
		return;
	}

	vn_port = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
	if (vn_port) {
		port = lport_priv(vn_port);
		if (!ether_addr_equal(port->data_src_addr, dest_mac)) {
			BNX2FC_HBA_DBG(lport, "fpma mismatch\n");
			kfree_skb(skb);
			return;
		}
	}
	if (ctlr->state) {
		if (!ether_addr_equal(mac, ctlr->dest_addr)) {
			BNX2FC_HBA_DBG(lport, "Wrong source address: mac:%pM dest_addr:%pM.\n",
			    mac, ctlr->dest_addr);
			kfree_skb(skb);
			return;
		}
	}
	if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
	    fh->fh_type == FC_TYPE_FCP) {
		/* Drop FCP data. We dont this in L2 path */
		kfree_skb(skb);
		return;
	}
	if (fh->fh_r_ctl == FC_RCTL_ELS_REQ &&
	    fh->fh_type == FC_TYPE_ELS) {
		switch (fc_frame_payload_op(fp)) {
		case ELS_LOGO:
			if (ntoh24(fh->fh_s_id) == FC_FID_FLOGI) {
				/* drop non-FIP LOGO */
				kfree_skb(skb);
				return;
			}
			break;
		}
	}

	if (fh->fh_r_ctl == FC_RCTL_BA_ABTS) {
		/* Drop incoming ABTS */
		kfree_skb(skb);
		return;
	}

	/*
	 * If the destination ID from the frame header does not match what we
	 * have on record for lport and the search for a NPIV port came up
	 * empty then this is not addressed to our port so simply drop it.
	 */
	if (lport->port_id != ntoh24(fh->fh_d_id) && !vn_port) {
		BNX2FC_HBA_DBG(lport, "Dropping frame due to destination mismatch: lport->port_id=%x fh->d_id=%x.\n",
		    lport->port_id, ntoh24(fh->fh_d_id));
		kfree_skb(skb);
		return;
	}

	fr_crc = le32_to_cpu(fr_crc(fp));

	if (unlikely(fr_crc != ~crc32(~0, skb->data, fr_len))) {
		crc_err = this_cpu_inc_return(lport->stats->InvalidCRCCount);
		if (crc_err < 5)
			printk(KERN_WARNING PFX "dropping frame with "
			       "CRC error\n");
		kfree_skb(skb);
		return;
	}
	fc_exch_recv(lport, fp);
}

/**
 * bnx2fc_percpu_io_thread - thread per cpu for ios
 *
 * @arg:	ptr to bnx2fc_percpu_info structure
 */
static int bnx2fc_percpu_io_thread(void *arg)
{
	struct bnx2fc_percpu_s *p = arg;
	struct bnx2fc_work *work, *tmp;
	LIST_HEAD(work_list);

	set_user_nice(current, MIN_NICE);
	set_current_state(TASK_INTERRUPTIBLE);
	while (!kthread_should_stop()) {
		schedule();
		spin_lock_bh(&p->fp_work_lock);
		while (!list_empty(&p->work_list)) {
			list_splice_init(&p->work_list, &work_list);
			spin_unlock_bh(&p->fp_work_lock);

			list_for_each_entry_safe(work, tmp, &work_list, list) {
				list_del_init(&work->list);
				bnx2fc_process_cq_compl(work->tgt, work->wqe,
							work->rq_data,
							work->num_rq,
							work->task);
				kfree(work);
			}

			spin_lock_bh(&p->fp_work_lock);
		}
		__set_current_state(TASK_INTERRUPTIBLE);
		spin_unlock_bh(&p->fp_work_lock);
	}
	__set_current_state(TASK_RUNNING);

	return 0;
}

static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost)
{
	struct fc_host_statistics *bnx2fc_stats;
	struct fc_lport *lport = shost_priv(shost);
	struct fcoe_port *port = lport_priv(lport);
	struct bnx2fc_interface *interface = port->priv;
	struct bnx2fc_hba *hba = interface->hba;
	struct fcoe_statistics_params *fw_stats;
	int rc = 0;

	fw_stats = (struct fcoe_statistics_params *)hba->stats_buffer;
	if (!fw_stats)
		return NULL;

	mutex_lock(&hba->hba_stats_mutex);

	bnx2fc_stats = fc_get_host_stats(shost);

	init_completion(&hba->stat_req_done);
	if (bnx2fc_send_stat_req(hba))
		goto unlock_stats_mutex;
	rc = wait_for_completion_timeout(&hba->stat_req_done, (2 * HZ));
	if (!rc) {
		BNX2FC_HBA_DBG(lport, "FW stat req timed out\n");
		goto unlock_stats_mutex;
	}
	BNX2FC_STATS(hba, rx_stat2, fc_crc_cnt);
	bnx2fc_stats->invalid_crc_count += hba->bfw_stats.fc_crc_cnt;
	BNX2FC_STATS(hba, tx_stat, fcoe_tx_pkt_cnt);
	bnx2fc_stats->tx_frames += hba->bfw_stats.fcoe_tx_pkt_cnt;
	BNX2FC_STATS(hba, tx_stat, fcoe_tx_byte_cnt);
	bnx2fc_stats->tx_words += ((hba->bfw_stats.fcoe_tx_byte_cnt) / 4);
	BNX2FC_STATS(hba, rx_stat0, fcoe_rx_pkt_cnt);
	bnx2fc_stats->rx_frames += hba->bfw_stats.fcoe_rx_pkt_cnt;
	BNX2FC_STATS(hba, rx_stat0, fcoe_rx_byte_cnt);
	bnx2fc_stats->rx_words += ((hba->bfw_stats.fcoe_rx_byte_cnt) / 4);

	bnx2fc_stats->dumped_frames = 0;
	bnx2fc_stats->lip_count = 0;
	bnx2fc_stats->nos_count = 0;
	bnx2fc_stats->loss_of_sync_count = 0;
	bnx2fc_stats->loss_of_signal_count = 0;
	bnx2fc_stats->prim_seq_protocol_err_count = 0;

	memcpy(&hba->prev_stats, hba->stats_buffer,
	       sizeof(struct fcoe_statistics_params));

unlock_stats_mutex:
	mutex_unlock(&hba->hba_stats_mutex);
	return bnx2fc_stats;
}

static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev)
{
	struct fcoe_port *port = lport_priv(lport);
	struct bnx2fc_interface *interface = port->priv;
	struct bnx2fc_hba *hba = interface->hba;
	struct Scsi_Host *shost = lport->host;
	int rc = 0;

	shost->max_cmd_len = BNX2FC_MAX_CMD_LEN;
	shost->max_lun = bnx2fc_max_luns;
	shost->max_id = BNX2FC_MAX_FCP_TGT;
	shost->max_channel = 0;
	if (lport->vport)
		shost->transportt = bnx2fc_vport_xport_template;
	else
		shost->transportt = bnx2fc_transport_template;

	/* Add the new host to SCSI-ml */
	rc = scsi_add_host(lport->host, dev);
	if (rc) {
		printk(KERN_ERR PFX "Error on scsi_add_host\n");
		return rc;
	}
	if (!lport->vport)
		fc_host_max_npiv_vports(lport->host) = USHRT_MAX;
	snprintf(fc_host_symbolic_name(lport->host), 256,
		 "%s (QLogic %s) v%s over %s",
		BNX2FC_NAME, hba->chip_num, BNX2FC_VERSION,
		interface->netdev->name);

	return 0;
}

static int bnx2fc_link_ok(struct fc_lport *lport)
{
	struct fcoe_port *port = lport_priv(lport);
	struct bnx2fc_interface *interface = port->priv;
	struct bnx2fc_hba *hba = interface->hba;
	struct net_device *dev = hba->phys_dev;
	int rc = 0;

	if ((dev->flags & IFF_UP) && netif_carrier_ok(dev))
		clear_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state);
	else {
		set_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state);
		rc = -1;
	}
	return rc;
}

/**
 * bnx2fc_get_link_state - get network link state
 *
 * @hba:	adapter instance pointer
 *
 * updates adapter structure flag based on netdev state
 */
void bnx2fc_get_link_state(struct bnx2fc_hba *hba)
{
	if (test_bit(__LINK_STATE_NOCARRIER, &hba->phys_dev->state))
		set_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state);
	else
		clear_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state);
}

static int bnx2fc_net_config(struct fc_lport *lport, struct net_device *netdev)
{
	struct bnx2fc_hba *hba;
	struct bnx2fc_interface *interface;
	struct fcoe_ctlr *ctlr;
	struct fcoe_port *port;
	u64 wwnn, wwpn;

	port = lport_priv(lport);
	interface = port->priv;
	ctlr = bnx2fc_to_ctlr(interface);
	hba = interface->hba;

	/* require support for get_pauseparam ethtool op. */
	if (!hba->phys_dev->ethtool_ops ||
	    !hba->phys_dev->ethtool_ops->get_pauseparam)
		return -EOPNOTSUPP;

	if (fc_set_mfs(lport, BNX2FC_MFS))
		return -EINVAL;

	skb_queue_head_init(&port->fcoe_pending_queue);
	port->fcoe_pending_queue_active = 0;
	timer_setup(&port->timer, fcoe_queue_timer, 0);

	fcoe_link_speed_update(lport);

	if (!lport->vport) {
		if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN))
			wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr,
						 1, 0);
		BNX2FC_HBA_DBG(lport, "WWNN = 0x%llx\n", wwnn);
		fc_set_wwnn(lport, wwnn);

		if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN))
			wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr,
						 2, 0);

		BNX2FC_HBA_DBG(lport, "WWPN = 0x%llx\n", wwpn);
		fc_set_wwpn(lport, wwpn);
	}

	return 0;
}

static void bnx2fc_destroy_timer(struct timer_list *t)
{
	struct bnx2fc_hba *hba = from_timer(hba, t, destroy_timer);

	printk(KERN_ERR PFX "ERROR:bnx2fc_destroy_timer - "
	       "Destroy compl not received!!\n");
	set_bit(BNX2FC_FLAG_DESTROY_CMPL, &hba->flags);
	wake_up_interruptible(&hba->destroy_wait);
}

/**
 * bnx2fc_indicate_netevent - Generic netdev event handler
 *
 * @context:	adapter structure pointer
 * @event:	event type
 * @vlan_id:	vlan id - associated vlan id with this event
 *
 * Handles NETDEV_UP, NETDEV_DOWN, NETDEV_GOING_DOWN,NETDEV_CHANGE and
 * NETDEV_CHANGE_MTU events. Handle NETDEV_UNREGISTER only for vlans.
 */
static void bnx2fc_indicate_netevent(void *context, unsigned long event,
				     u16 vlan_id)
{
	struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context;
	struct fcoe_ctlr_device *cdev;
	struct fc_lport *lport;
	struct fc_lport *vport;
	struct bnx2fc_interface *interface, *tmp;
	struct fcoe_ctlr *ctlr;
	int wait_for_upload = 0;
	u32 link_possible = 1;

	if (vlan_id != 0 && event != NETDEV_UNREGISTER)
		return;

	switch (event) {
	case NETDEV_UP:
		if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state))
			printk(KERN_ERR "indicate_netevent: "\
					"hba is not UP!!\n");
		break;

	case NETDEV_DOWN:
		clear_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state);
		clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
		link_possible = 0;
		break;

	case NETDEV_GOING_DOWN:
		set_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state);
		link_possible = 0;
		break;

	case NETDEV_CHANGE:
		break;

	case NETDEV_UNREGISTER:
		if (!vlan_id)
			return;
		mutex_lock(&bnx2fc_dev_lock);
		list_for_each_entry_safe(interface, tmp, &if_list, list) {
			if (interface->hba == hba &&
			    interface->vlan_id == (vlan_id & VLAN_VID_MASK))
				__bnx2fc_destroy(interface);
		}
		mutex_unlock(&bnx2fc_dev_lock);
		return;

	default:
		return;
	}

	mutex_lock(&bnx2fc_dev_lock);
	list_for_each_entry(interface, &if_list, list) {

		if (interface->hba != hba)
			continue;

		ctlr = bnx2fc_to_ctlr(interface);
		lport = ctlr->lp;
		BNX2FC_HBA_DBG(lport, "netevent handler - event=%s %ld\n",
				interface->netdev->name, event);

		fcoe_link_speed_update(lport);

		cdev = fcoe_ctlr_to_ctlr_dev(ctlr);

		if (link_possible && !bnx2fc_link_ok(lport)) {
			switch (cdev->enabled) {
			case FCOE_CTLR_DISABLED:
				pr_info("Link up while interface is disabled.\n");
				break;
			case FCOE_CTLR_ENABLED:
			case FCOE_CTLR_UNUSED:
				/* Reset max recv frame size to default */
				fc_set_mfs(lport, BNX2FC_MFS);
				/*
				 * ctlr link up will only be handled during
				 * enable to avoid sending discovery
				 * solicitation on a stale vlan
				 */
				if (interface->enabled)
					fcoe_ctlr_link_up(ctlr);
			}
		} else if (fcoe_ctlr_link_down(ctlr)) {
			switch (cdev->enabled) {
			case FCOE_CTLR_DISABLED:
				pr_info("Link down while interface is disabled.\n");
				break;
			case FCOE_CTLR_ENABLED:
			case FCOE_CTLR_UNUSED:
				mutex_lock(&lport->lp_mutex);
				list_for_each_entry(vport, &lport->vports, list)
					fc_host_port_type(vport->host) =
					FC_PORTTYPE_UNKNOWN;
				mutex_unlock(&lport->lp_mutex);
				fc_host_port_type(lport->host) =
					FC_PORTTYPE_UNKNOWN;
				this_cpu_inc(lport->stats->LinkFailureCount);
				fcoe_clean_pending_queue(lport);
				wait_for_upload = 1;
			}
		}
	}
	mutex_unlock(&bnx2fc_dev_lock);

	if (wait_for_upload) {
		clear_bit(ADAPTER_STATE_READY, &hba->adapter_state);
		init_waitqueue_head(&hba->shutdown_wait);
		BNX2FC_MISC_DBG("indicate_netevent "
				"num_ofld_sess = %d\n",
				hba->num_ofld_sess);
		hba->wait_for_link_down = 1;
		wait_event_interruptible(hba->shutdown_wait,
					 (hba->num_ofld_sess == 0));
		BNX2FC_MISC_DBG("wakeup - num_ofld_sess = %d\n",
				hba->num_ofld_sess);
		hba->wait_for_link_down = 0;

		if (signal_pending(current))
			flush_signals(current);
	}
}

static int bnx2fc_libfc_config(struct fc_lport *lport)
{

	/* Set the function pointers set by bnx2fc driver */
	memcpy(&lport->tt, &bnx2fc_libfc_fcn_templ,
		sizeof(struct libfc_function_template));
	fc_elsct_init(lport);
	fc_exch_init(lport);
	fc_disc_init(lport);
	fc_disc_config(lport, lport);
	return 0;
}

static int bnx2fc_em_config(struct fc_lport *lport, struct bnx2fc_hba *hba)
{
	int fcoe_min_xid, fcoe_max_xid;

	fcoe_min_xid = hba->max_xid + 1;
	if (nr_cpu_ids <= 2)
		fcoe_max_xid = hba->max_xid + FCOE_XIDS_PER_CPU_OFFSET;
	else
		fcoe_max_xid = hba->max_xid + FCOE_MAX_XID_OFFSET;
	if (!fc_exch_mgr_alloc(lport, FC_CLASS_3, fcoe_min_xid,
			       fcoe_max_xid, NULL)) {
		printk(KERN_ERR PFX "em_config:fc_exch_mgr_alloc failed\n");
		return -ENOMEM;
	}

	return 0;
}

static int bnx2fc_lport_config(struct fc_lport *lport)
{
	lport->link_up = 0;
	lport->qfull = 0;
	lport->max_retry_count = BNX2FC_MAX_RETRY_CNT;
	lport->max_rport_retry_count = BNX2FC_MAX_RPORT_RETRY_CNT;
	lport->e_d_tov = 2 * 1000;
	lport->r_a_tov = 10 * 1000;

	lport->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
				FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
	lport->does_npiv = 1;

	memset(&lport->rnid_gen, 0, sizeof(struct fc_els_rnid_gen));
	lport->rnid_gen.rnid_atype = BNX2FC_RNID_HBA;

	/* alloc stats structure */
	if (fc_lport_init_stats(lport))
		return -ENOMEM;

	/* Finish fc_lport configuration */
	fc_lport_config(lport);

	return 0;
}

/**
 * bnx2fc_fip_recv - handle a received FIP frame.
 *
 * @skb: the received skb
 * @dev: associated &net_device
 * @ptype: the &packet_type structure which was used to register this handler.
 * @orig_dev: original receive &net_device, in case @ dev is a bond.
 *
 * Returns: 0 for success
 */
static int bnx2fc_fip_recv(struct sk_buff *skb, struct net_device *dev,
			   struct packet_type *ptype,
			   struct net_device *orig_dev)
{
	struct bnx2fc_interface *interface;
	struct fcoe_ctlr *ctlr;
	interface = container_of(ptype, struct bnx2fc_interface,
				 fip_packet_type);
	ctlr = bnx2fc_to_ctlr(interface);
	fcoe_ctlr_recv(ctlr, skb);
	return 0;
}

/**
 * bnx2fc_update_src_mac - Update Ethernet MAC filters.
 *
 * @lport: The local port
 * @addr: Location of data to copy
 *
 * Remove any previously-set unicast MAC filter.
 * Add secondary FCoE MAC address filter for our OUI.
 */
static void bnx2fc_update_src_mac(struct fc_lport *lport, u8 *addr)
{
	struct fcoe_port *port = lport_priv(lport);

	memcpy(port->data_src_addr, addr, ETH_ALEN);
}

/**
 * bnx2fc_get_src_mac - return the ethernet source address for an lport
 *
 * @lport: libfc port
 */
static u8 *bnx2fc_get_src_mac(struct fc_lport *lport)
{
	struct fcoe_port *port;

	port = (struct fcoe_port *)lport_priv(lport);
	return port->data_src_addr;
}

/**
 * bnx2fc_fip_send - send an Ethernet-encapsulated FIP frame.
 *
 * @fip: FCoE controller.
 * @skb: FIP Packet.
 */
static void bnx2fc_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
	struct fip_header *fiph;
	struct ethhdr *eth_hdr;
	u16 op;
	u8 sub;

	fiph = (struct fip_header *) ((void *)skb->data + 2 * ETH_ALEN + 2);
	eth_hdr = (struct ethhdr *)skb_mac_header(skb);
	op = ntohs(fiph->fip_op);
	sub = fiph->fip_subcode;

	if (op == FIP_OP_CTRL && sub == FIP_SC_SOL && bnx2fc_log_fka)
		BNX2FC_MISC_DBG("Sending FKA from %pM to %pM.\n",
		    eth_hdr->h_source, eth_hdr->h_dest);

	skb->dev = bnx2fc_from_ctlr(fip)->netdev;
	dev_queue_xmit(skb);
}

static int bnx2fc_vport_create(struct fc_vport *vport, bool disabled)
{
	struct Scsi_Host *shost = vport_to_shost(vport);
	struct fc_lport *n_port = shost_priv(shost);
	struct fcoe_port *port = lport_priv(n_port);
	struct bnx2fc_interface *interface = port->priv;
	struct net_device *netdev = interface->netdev;
	struct fc_lport *vn_port;
	int rc;
	char buf[32];

	rc = fcoe_validate_vport_create(vport);
	if (rc) {
		fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf));
		printk(KERN_ERR PFX "Failed to create vport, "
		       "WWPN (0x%s) already exists\n",
		       buf);
		return rc;
	}

	if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags)) {
		printk(KERN_ERR PFX "vn ports cannot be created on"
			"this interface\n");
		return -EIO;
	}
	rtnl_lock();
	mutex_lock(&bnx2fc_dev_lock);
	vn_port = bnx2fc_if_create(interface, &vport->dev, 1);
	mutex_unlock(&bnx2fc_dev_lock);
	rtnl_unlock();

	if (!vn_port) {
		printk(KERN_ERR PFX "bnx2fc_vport_create (%s) failed\n",
			netdev->name);
		return -EIO;
	}

	if (bnx2fc_devloss_tmo)
		fc_host_dev_loss_tmo(vn_port->host) = bnx2fc_devloss_tmo;

	if (disabled) {
		fc_vport_set_state(vport, FC_VPORT_DISABLED);
	} else {
		vn_port->boot_time = jiffies;
		fc_lport_init(vn_port);
		fc_fabric_login(vn_port);
		fc_vport_setlink(vn_port);
	}
	return 0;
}

static void bnx2fc_free_vport(struct bnx2fc_hba *hba, struct fc_lport *lport)
{
	struct bnx2fc_lport *blport, *tmp;

	spin_lock_bh(&hba->hba_lock);
	list_for_each_entry_safe(blport, tmp, &hba->vports, list) {
		if (blport->lport == lport) {
			list_del(&blport->list);
			kfree(blport);
		}
	}
	spin_unlock_bh(&hba->hba_lock);
}

static int bnx2fc_vport_destroy(struct fc_vport *vport)
{
	struct Scsi_Host *shost = vport_to_shost(vport);
	struct fc_lport *n_port = shost_priv(shost);
	struct fc_lport *vn_port = vport->dd_data;
	struct fcoe_port *port = lport_priv(vn_port);
	struct bnx2fc_interface *interface = port->priv;
	struct fc_lport *v_port;
	bool found = false;

	mutex_lock(&n_port->lp_mutex);
	list_for_each_entry(v_port, &n_port->vports, list)
		if (v_port->vport == vport) {
			found = true;
			break;
		}

	if (!found) {
		mutex_unlock(&n_port->lp_mutex);
		return -ENOENT;
	}
	list_del(&vn_port->list);
	mutex_unlock(&n_port->lp_mutex);
	bnx2fc_free_vport(interface->hba, port->lport);
	bnx2fc_port_shutdown(port->lport);
	bnx2fc_port_destroy(port);
	bnx2fc_interface_put(interface);
	return 0;
}

static int bnx2fc_vport_disable(struct fc_vport *vport, bool disable)
{
	struct fc_lport *lport = vport->dd_data;

	if (disable) {
		fc_vport_set_state(vport, FC_VPORT_DISABLED);
		fc_fabric_logoff(lport);
	} else {
		lport->boot_time = jiffies;
		fc_fabric_login(lport);
		fc_vport_setlink(lport);
	}
	return 0;
}


static int bnx2fc_interface_setup(struct bnx2fc_interface *interface)
{
	struct net_device *netdev = interface->netdev;
	struct net_device *physdev = interface->hba->phys_dev;
	struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
	struct netdev_hw_addr *ha;
	int sel_san_mac = 0;

	/* setup Source MAC Address */
	rcu_read_lock();
	for_each_dev_addr(physdev, ha) {
		BNX2FC_MISC_DBG("net_config: ha->type = %d, fip_mac = ",
				ha->type);
		printk(KERN_INFO "%2x:%2x:%2x:%2x:%2x:%2x\n", ha->addr[0],
				ha->addr[1], ha->addr[2], ha->addr[3],
				ha->addr[4], ha->addr[5]);

		if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
		    (is_valid_ether_addr(ha->addr))) {
			memcpy(ctlr->ctl_src_addr, ha->addr,
			       ETH_ALEN);
			sel_san_mac = 1;
			BNX2FC_MISC_DBG("Found SAN MAC\n");
		}
	}
	rcu_read_unlock();

	if (!sel_san_mac)
		return -ENODEV;

	interface->fip_packet_type.func = bnx2fc_fip_recv;
	interface->fip_packet_type.type = htons(ETH_P_FIP);
	interface->fip_packet_type.dev = netdev;
	dev_add_pack(&interface->fip_packet_type);

	interface->fcoe_packet_type.func = bnx2fc_rcv;
	interface->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
	interface->fcoe_packet_type.dev = netdev;
	dev_add_pack(&interface->fcoe_packet_type);

	return 0;
}

static int bnx2fc_attach_transport(void)
{
	bnx2fc_transport_template =
		fc_attach_transport(&bnx2fc_transport_function);

	if (bnx2fc_transport_template == NULL) {
		printk(KERN_ERR PFX "Failed to attach FC transport\n");
		return -ENODEV;
	}

	bnx2fc_vport_xport_template =
		fc_attach_transport(&bnx2fc_vport_xport_function);
	if (bnx2fc_vport_xport_template == NULL) {
		printk(KERN_ERR PFX
		       "Failed to attach FC transport for vport\n");
		fc_release_transport(bnx2fc_transport_template);
		bnx2fc_transport_template = NULL;
		return -ENODEV;
	}
	return 0;
}
static void bnx2fc_release_transport(void)
{
	fc_release_transport(bnx2fc_transport_template);
	fc_release_transport(bnx2fc_vport_xport_template);
	bnx2fc_transport_template = NULL;
	bnx2fc_vport_xport_template = NULL;
}

static void bnx2fc_interface_release(struct kref *kref)
{
	struct fcoe_ctlr_device *ctlr_dev;
	struct bnx2fc_interface *interface;
	struct fcoe_ctlr *ctlr;
	struct net_device *netdev;

	interface = container_of(kref, struct bnx2fc_interface, kref);
	BNX2FC_MISC_DBG("Interface is being released\n");

	ctlr = bnx2fc_to_ctlr(interface);
	ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr);
	netdev = interface->netdev;

	/* tear-down FIP controller */
	if (test_and_clear_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags))
		fcoe_ctlr_destroy(ctlr);

	fcoe_ctlr_device_delete(ctlr_dev);

	dev_put(netdev);
	module_put(THIS_MODULE);
}

static inline void bnx2fc_interface_get(struct bnx2fc_interface *interface)
{
	kref_get(&interface->kref);
}

static inline void bnx2fc_interface_put(struct bnx2fc_interface *interface)
{
	kref_put(&interface->kref, bnx2fc_interface_release);
}
static void bnx2fc_hba_destroy(struct bnx2fc_hba *hba)
{
	/* Free the command manager */
	if (hba->cmd_mgr) {
		bnx2fc_cmd_mgr_free(hba->cmd_mgr);
		hba->cmd_mgr = NULL;
	}
	kfree(hba->tgt_ofld_list);
	bnx2fc_unbind_pcidev(hba);
	kfree(hba);
}

/**
 * bnx2fc_hba_create - create a new bnx2fc hba
 *
 * @cnic:	pointer to cnic device
 *
 * Creates a new FCoE hba on the given device.
 *
 */
static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic)
{
	struct bnx2fc_hba *hba;
	struct fcoe_capabilities *fcoe_cap;
	int rc;

	hba = kzalloc(sizeof(*hba), GFP_KERNEL);
	if (!hba) {
		printk(KERN_ERR PFX "Unable to allocate hba structure\n");
		return NULL;
	}
	spin_lock_init(&hba->hba_lock);
	mutex_init(&hba->hba_mutex);
	mutex_init(&hba->hba_stats_mutex);

	hba->cnic = cnic;

	hba->max_tasks = cnic->max_fcoe_exchanges;
	hba->elstm_xids = (hba->max_tasks / 2);
	hba->max_outstanding_cmds = hba->elstm_xids;
	hba->max_xid = (hba->max_tasks - 1);

	rc = bnx2fc_bind_pcidev(hba);
	if (rc) {
		printk(KERN_ERR PFX "create_adapter:  bind error\n");
		goto bind_err;
	}
	hba->phys_dev = cnic->netdev;
	hba->next_conn_id = 0;

	hba->tgt_ofld_list =
		kcalloc(BNX2FC_NUM_MAX_SESS, sizeof(struct bnx2fc_rport *),
			GFP_KERNEL);
	if (!hba->tgt_ofld_list) {
		printk(KERN_ERR PFX "Unable to allocate tgt offload list\n");
		goto tgtofld_err;
	}

	hba->num_ofld_sess = 0;

	hba->cmd_mgr = bnx2fc_cmd_mgr_alloc(hba);
	if (!hba->cmd_mgr) {
		printk(KERN_ERR PFX "em_config:bnx2fc_cmd_mgr_alloc failed\n");
		goto cmgr_err;
	}
	fcoe_cap = &hba->fcoe_cap;

	fcoe_cap->capability1 = BNX2FC_TM_MAX_SQES <<
					FCOE_IOS_PER_CONNECTION_SHIFT;
	fcoe_cap->capability1 |= BNX2FC_NUM_MAX_SESS <<
					FCOE_LOGINS_PER_PORT_SHIFT;
	fcoe_cap->capability2 = hba->max_outstanding_cmds <<
					FCOE_NUMBER_OF_EXCHANGES_SHIFT;
	fcoe_cap->capability2 |= BNX2FC_MAX_NPIV <<
					FCOE_NPIV_WWN_PER_PORT_SHIFT;
	fcoe_cap->capability3 = BNX2FC_NUM_MAX_SESS <<
					FCOE_TARGETS_SUPPORTED_SHIFT;
	fcoe_cap->capability3 |= hba->max_outstanding_cmds <<
					FCOE_OUTSTANDING_COMMANDS_SHIFT;
	fcoe_cap->capability4 = FCOE_CAPABILITY4_STATEFUL;

	init_waitqueue_head(&hba->shutdown_wait);
	init_waitqueue_head(&hba->destroy_wait);
	INIT_LIST_HEAD(&hba->vports);

	return hba;

cmgr_err:
	kfree(hba->tgt_ofld_list);
tgtofld_err:
	bnx2fc_unbind_pcidev(hba);
bind_err:
	kfree(hba);
	return NULL;
}

static struct bnx2fc_interface *
bnx2fc_interface_create(struct bnx2fc_hba *hba,
			struct net_device *netdev,
			enum fip_mode fip_mode)
{
	struct fcoe_ctlr_device *ctlr_dev;
	struct bnx2fc_interface *interface;
	struct fcoe_ctlr *ctlr;
	int size;
	int rc = 0;

	size = (sizeof(*interface) + sizeof(struct fcoe_ctlr));
	ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &bnx2fc_fcoe_sysfs_templ,
					 size);
	if (!ctlr_dev) {
		printk(KERN_ERR PFX "Unable to allocate interface structure\n");
		return NULL;
	}
	ctlr = fcoe_ctlr_device_priv(ctlr_dev);
	ctlr->cdev = ctlr_dev;
	interface = fcoe_ctlr_priv(ctlr);
	dev_hold(netdev);
	kref_init(&interface->kref);
	interface->hba = hba;
	interface->netdev = netdev;

	/* Initialize FIP */
	fcoe_ctlr_init(ctlr, fip_mode);
	ctlr->send = bnx2fc_fip_send;
	ctlr->update_mac = bnx2fc_update_src_mac;
	ctlr->get_src_addr = bnx2fc_get_src_mac;
	set_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags);

	rc = bnx2fc_interface_setup(interface);
	if (!rc)
		return interface;

	fcoe_ctlr_destroy(ctlr);
	dev_put(netdev);
	fcoe_ctlr_device_delete(ctlr_dev);
	return NULL;
}

/**
 * bnx2fc_if_create - Create FCoE instance on a given interface
 *
 * @interface:	FCoE interface to create a local port on
 * @parent:	Device pointer to be the parent in sysfs for the SCSI host
 * @npiv:	Indicates if the port is vport or not
 *
 * Creates a fc_lport instance and a Scsi_Host instance and configure them.
 *
 * Returns:	Allocated fc_lport or an error pointer
 */
static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface,
				  struct device *parent, int npiv)
{
	struct fcoe_ctlr        *ctlr = bnx2fc_to_ctlr(interface);
	struct fc_lport		*lport, *n_port;
	struct fcoe_port	*port;
	struct Scsi_Host	*shost;
	struct fc_vport		*vport = dev_to_vport(parent);
	struct bnx2fc_lport	*blport;
	struct bnx2fc_hba	*hba = interface->hba;
	int			rc = 0;

	blport = kzalloc(sizeof(struct bnx2fc_lport), GFP_KERNEL);
	if (!blport) {
		BNX2FC_HBA_DBG(ctlr->lp, "Unable to alloc blport\n");
		return NULL;
	}

	/* Allocate Scsi_Host structure */
	bnx2fc_shost_template.can_queue = hba->max_outstanding_cmds;
	if (!npiv)
		lport = libfc_host_alloc(&bnx2fc_shost_template, sizeof(*port));
	else
		lport = libfc_vport_create(vport, sizeof(*port));

	if (!lport) {
		printk(KERN_ERR PFX "could not allocate scsi host structure\n");
		goto free_blport;
	}
	shost = lport->host;
	port = lport_priv(lport);
	port->lport = lport;
	port->priv = interface;
	port->get_netdev = bnx2fc_netdev;

	/* Configure fcoe_port */
	rc = bnx2fc_lport_config(lport);
	if (rc)
		goto lp_config_err;

	if (npiv) {
		printk(KERN_ERR PFX "Setting vport names, 0x%llX 0x%llX\n",
			vport->node_name, vport->port_name);
		fc_set_wwnn(lport, vport->node_name);
		fc_set_wwpn(lport, vport->port_name);
	}
	/* Configure netdev and networking properties of the lport */
	rc = bnx2fc_net_config(lport, interface->netdev);
	if (rc) {
		printk(KERN_ERR PFX "Error on bnx2fc_net_config\n");
		goto lp_config_err;
	}

	rc = bnx2fc_shost_config(lport, parent);
	if (rc) {
		printk(KERN_ERR PFX "Couldn't configure shost for %s\n",
			interface->netdev->name);
		goto lp_config_err;
	}

	/* Initialize the libfc library */
	rc = bnx2fc_libfc_config(lport);
	if (rc) {
		printk(KERN_ERR PFX "Couldn't configure libfc\n");
		goto shost_err;
	}
	fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN;

	if (bnx2fc_devloss_tmo)
		fc_host_dev_loss_tmo(shost) = bnx2fc_devloss_tmo;

	/* Allocate exchange manager */
	if (!npiv)
		rc = bnx2fc_em_config(lport, hba);
	else {
		shost = vport_to_shost(vport);
		n_port = shost_priv(shost);
		rc = fc_exch_mgr_list_clone(n_port, lport);
	}

	if (rc) {
		printk(KERN_ERR PFX "Error on bnx2fc_em_config\n");
		goto shost_err;
	}

	bnx2fc_interface_get(interface);

	spin_lock_bh(&hba->hba_lock);
	blport->lport = lport;
	list_add_tail(&blport->list, &hba->vports);
	spin_unlock_bh(&hba->hba_lock);

	return lport;

shost_err:
	scsi_remove_host(shost);
lp_config_err:
	scsi_host_put(lport->host);
free_blport:
	kfree(blport);
	return NULL;
}

static void bnx2fc_net_cleanup(struct bnx2fc_interface *interface)
{
	/* Dont listen for Ethernet packets anymore */
	__dev_remove_pack(&interface->fcoe_packet_type);
	__dev_remove_pack(&interface->fip_packet_type);
	synchronize_net();
}

static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface)
{
	struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
	struct fc_lport *lport = ctlr->lp;
	struct fcoe_port *port = lport_priv(lport);
	struct bnx2fc_hba *hba = interface->hba;

	/* Stop the transmit retry timer */
	del_timer_sync(&port->timer);

	/* Free existing transmit skbs */
	fcoe_clean_pending_queue(lport);

	bnx2fc_net_cleanup(interface);

	bnx2fc_free_vport(hba, lport);
}

static void bnx2fc_if_destroy(struct fc_lport *lport)
{

	/* Free queued packets for the receive thread */
	bnx2fc_clean_rx_queue(lport);

	/* Detach from scsi-ml */
	fc_remove_host(lport->host);
	scsi_remove_host(lport->host);

	/*
	 * Note that only the physical lport will have the exchange manager.
	 * for vports, this function is NOP
	 */
	fc_exch_mgr_free(lport);

	/* Free memory used by statistical counters */
	fc_lport_free_stats(lport);

	/* Release Scsi_Host */
	scsi_host_put(lport->host);
}

static void __bnx2fc_destroy(struct bnx2fc_interface *interface)
{
	struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
	struct fc_lport *lport = ctlr->lp;
	struct fcoe_port *port = lport_priv(lport);

	bnx2fc_interface_cleanup(interface);
	bnx2fc_stop(interface);
	list_del(&interface->list);
	bnx2fc_port_destroy(port);
	bnx2fc_interface_put(interface);
}

/**
 * bnx2fc_destroy - Destroy a bnx2fc FCoE interface
 *
 * @netdev: The net device that the FCoE interface is on
 *
 * Called from sysfs.
 *
 * Returns: 0 for success
 */
static int bnx2fc_destroy(struct net_device *netdev)
{
	struct bnx2fc_interface *interface = NULL;
	struct workqueue_struct *timer_work_queue;
	struct fcoe_ctlr *ctlr;
	int rc = 0;

	rtnl_lock();
	mutex_lock(&bnx2fc_dev_lock);

	interface = bnx2fc_interface_lookup(netdev);
	ctlr = bnx2fc_to_ctlr(interface);
	if (!interface || !ctlr->lp) {
		rc = -ENODEV;
		printk(KERN_ERR PFX "bnx2fc_destroy: interface or lport not found\n");
		goto netdev_err;
	}

	timer_work_queue = interface->timer_work_queue;
	__bnx2fc_destroy(interface);
	destroy_workqueue(timer_work_queue);

netdev_err:
	mutex_unlock(&bnx2fc_dev_lock);
	rtnl_unlock();
	return rc;
}

static void bnx2fc_port_destroy(struct fcoe_port *port)
{
	struct fc_lport *lport;

	lport = port->lport;
	BNX2FC_HBA_DBG(lport, "Entered %s, destroying lport %p\n", __func__, lport);

	bnx2fc_if_destroy(lport);
}

static void bnx2fc_unbind_adapter_devices(struct bnx2fc_hba *hba)
{
	bnx2fc_free_fw_resc(hba);
	bnx2fc_free_task_ctx(hba);
}

/**
 * bnx2fc_bind_adapter_devices - binds bnx2fc adapter with the associated
 *			pci structure
 *
 * @hba:		Adapter instance
 */
static int bnx2fc_bind_adapter_devices(struct bnx2fc_hba *hba)
{
	if (bnx2fc_setup_task_ctx(hba))
		goto mem_err;

	if (bnx2fc_setup_fw_resc(hba))
		goto mem_err;

	return 0;
mem_err:
	bnx2fc_unbind_adapter_devices(hba);
	return -ENOMEM;
}

static int bnx2fc_bind_pcidev(struct bnx2fc_hba *hba)
{
	struct cnic_dev *cnic;
	struct pci_dev *pdev;

	if (!hba->cnic) {
		printk(KERN_ERR PFX "cnic is NULL\n");
		return -ENODEV;
	}
	cnic = hba->cnic;
	pdev = hba->pcidev = cnic->pcidev;
	if (!hba->pcidev)
		return -ENODEV;

	switch (pdev->device) {
	case PCI_DEVICE_ID_NX2_57710:
		strncpy(hba->chip_num, "BCM57710", BCM_CHIP_LEN);
		break;
	case PCI_DEVICE_ID_NX2_57711:
		strncpy(hba->chip_num, "BCM57711", BCM_CHIP_LEN);
		break;
	case PCI_DEVICE_ID_NX2_57712:
	case PCI_DEVICE_ID_NX2_57712_MF:
	case PCI_DEVICE_ID_NX2_57712_VF:
		strncpy(hba->chip_num, "BCM57712", BCM_CHIP_LEN);
		break;
	case PCI_DEVICE_ID_NX2_57800:
	case PCI_DEVICE_ID_NX2_57800_MF:
	case PCI_DEVICE_ID_NX2_57800_VF:
		strncpy(hba->chip_num, "BCM57800", BCM_CHIP_LEN);
		break;
	case PCI_DEVICE_ID_NX2_57810:
	case PCI_DEVICE_ID_NX2_57810_MF:
	case PCI_DEVICE_ID_NX2_57810_VF:
		strncpy(hba->chip_num, "BCM57810", BCM_CHIP_LEN);
		break;
	case PCI_DEVICE_ID_NX2_57840:
	case PCI_DEVICE_ID_NX2_57840_MF:
	case PCI_DEVICE_ID_NX2_57840_VF:
	case PCI_DEVICE_ID_NX2_57840_2_20:
	case PCI_DEVICE_ID_NX2_57840_4_10:
		strncpy(hba->chip_num, "BCM57840", BCM_CHIP_LEN);
		break;
	default:
		pr_err(PFX "Unknown device id 0x%x\n", pdev->device);
		break;
	}
	pci_dev_get(hba->pcidev);
	return 0;
}

static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba)
{
	if (hba->pcidev) {
		hba->chip_num[0] = '\0';
		pci_dev_put(hba->pcidev);
	}
	hba->pcidev = NULL;
}

/**
 * bnx2fc_ulp_get_stats - cnic callback to populate FCoE stats
 *
 * @handle:    transport handle pointing to adapter structure
 */
static int bnx2fc_ulp_get_stats(void *handle)
{
	struct bnx2fc_hba *hba = handle;
	struct cnic_dev *cnic;
	struct fcoe_stats_info *stats_addr;

	if (!hba)
		return -EINVAL;

	cnic = hba->cnic;
	stats_addr = &cnic->stats_addr->fcoe_stat;
	if (!stats_addr)
		return -EINVAL;

	strncpy(stats_addr->version, BNX2FC_VERSION,
		sizeof(stats_addr->version));
	stats_addr->txq_size = BNX2FC_SQ_WQES_MAX;
	stats_addr->rxq_size = BNX2FC_CQ_WQES_MAX;

	return 0;
}


/**
 * bnx2fc_ulp_start - cnic callback to initialize & start adapter instance
 *
 * @handle:	transport handle pointing to adapter structure
 *
 * This function maps adapter structure to pcidev structure and initiates
 *	firmware handshake to enable/initialize on-chip FCoE components.
 *	This bnx2fc - cnic interface api callback is used after following
 *	conditions are met -
 *	a) underlying network interface is up (marked by event NETDEV_UP
 *		from netdev
 *	b) bnx2fc adatper structure is registered.
 */
static void bnx2fc_ulp_start(void *handle)
{
	struct bnx2fc_hba *hba = handle;
	struct bnx2fc_interface *interface;
	struct fcoe_ctlr *ctlr;
	struct fc_lport *lport;

	mutex_lock(&bnx2fc_dev_lock);

	if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags))
		bnx2fc_fw_init(hba);

	BNX2FC_MISC_DBG("bnx2fc started.\n");

	list_for_each_entry(interface, &if_list, list) {
		if (interface->hba == hba) {
			ctlr = bnx2fc_to_ctlr(interface);
			lport = ctlr->lp;
			/* Kick off Fabric discovery*/
			printk(KERN_ERR PFX "ulp_init: start discovery\n");
			lport->tt.frame_send = bnx2fc_xmit;
			bnx2fc_start_disc(interface);
		}
	}

	mutex_unlock(&bnx2fc_dev_lock);
}

static void bnx2fc_port_shutdown(struct fc_lport *lport)
{
	BNX2FC_MISC_DBG("Entered %s\n", __func__);
	fc_fabric_logoff(lport);
	fc_lport_destroy(lport);
}

static void bnx2fc_stop(struct bnx2fc_interface *interface)
{
	struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
	struct fc_lport *lport;
	struct fc_lport *vport;

	if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags))
		return;

	lport = ctlr->lp;
	bnx2fc_port_shutdown(lport);

	mutex_lock(&lport->lp_mutex);
	list_for_each_entry(vport, &lport->vports, list)
		fc_host_port_type(vport->host) =
					FC_PORTTYPE_UNKNOWN;
	mutex_unlock(&lport->lp_mutex);
	fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN;
	fcoe_ctlr_link_down(ctlr);
	fcoe_clean_pending_queue(lport);
}

static int bnx2fc_fw_init(struct bnx2fc_hba *hba)
{
#define BNX2FC_INIT_POLL_TIME		(1000 / HZ)
	int rc = -1;
	int i = HZ;

	rc = bnx2fc_bind_adapter_devices(hba);
	if (rc) {
		printk(KERN_ALERT PFX
			"bnx2fc_bind_adapter_devices failed - rc = %d\n", rc);
		goto err_out;
	}

	rc = bnx2fc_send_fw_fcoe_init_msg(hba);
	if (rc) {
		printk(KERN_ALERT PFX
			"bnx2fc_send_fw_fcoe_init_msg failed - rc = %d\n", rc);
		goto err_unbind;
	}

	/*
	 * Wait until the adapter init message is complete, and adapter
	 * state is UP.
	 */
	while (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state) && i--)
		msleep(BNX2FC_INIT_POLL_TIME);

	if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state)) {
		printk(KERN_ERR PFX "bnx2fc_start: %s failed to initialize.  "
				"Ignoring...\n",
				hba->cnic->netdev->name);
		rc = -1;
		goto err_unbind;
	}


	set_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags);
	return 0;

err_unbind:
	bnx2fc_unbind_adapter_devices(hba);
err_out:
	return rc;
}

static void bnx2fc_fw_destroy(struct bnx2fc_hba *hba)
{
	if (test_and_clear_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags)) {
		if (bnx2fc_send_fw_fcoe_destroy_msg(hba) == 0) {
			timer_setup(&hba->destroy_timer, bnx2fc_destroy_timer,
				    0);
			hba->destroy_timer.expires = BNX2FC_FW_TIMEOUT +
								jiffies;
			add_timer(&hba->destroy_timer);
			wait_event_interruptible(hba->destroy_wait,
					test_bit(BNX2FC_FLAG_DESTROY_CMPL,
						 &hba->flags));
			clear_bit(BNX2FC_FLAG_DESTROY_CMPL, &hba->flags);
			/* This should never happen */
			if (signal_pending(current))
				flush_signals(current);

			del_timer_sync(&hba->destroy_timer);
		}
		bnx2fc_unbind_adapter_devices(hba);
	}
}

/**
 * bnx2fc_ulp_stop - cnic callback to shutdown adapter instance
 *
 * @handle:	transport handle pointing to adapter structure
 *
 * Driver checks if adapter is already in shutdown mode, if not start
 *	the shutdown process.
 */
static void bnx2fc_ulp_stop(void *handle)
{
	struct bnx2fc_hba *hba = handle;
	struct bnx2fc_interface *interface;

	printk(KERN_ERR "ULP_STOP\n");

	mutex_lock(&bnx2fc_dev_lock);
	if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags))
		goto exit;
	list_for_each_entry(interface, &if_list, list) {
		if (interface->hba == hba)
			bnx2fc_stop(interface);
	}
	BUG_ON(hba->num_ofld_sess != 0);

	mutex_lock(&hba->hba_mutex);
	clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
	clear_bit(ADAPTER_STATE_GOING_DOWN,
		  &hba->adapter_state);

	clear_bit(ADAPTER_STATE_READY, &hba->adapter_state);
	mutex_unlock(&hba->hba_mutex);

	bnx2fc_fw_destroy(hba);
exit:
	mutex_unlock(&bnx2fc_dev_lock);
}

static void bnx2fc_start_disc(struct bnx2fc_interface *interface)
{
	struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
	struct fc_lport *lport;
	int wait_cnt = 0;

	BNX2FC_MISC_DBG("Entered %s\n", __func__);
	/* Kick off FIP/FLOGI */
	if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags)) {
		printk(KERN_ERR PFX "Init not done yet\n");
		return;
	}

	lport = ctlr->lp;
	BNX2FC_HBA_DBG(lport, "calling fc_fabric_login\n");

	if (!bnx2fc_link_ok(lport) && interface->enabled) {
		BNX2FC_HBA_DBG(lport, "ctlr_link_up\n");
		fcoe_ctlr_link_up(ctlr);
		fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
		set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state);
	}

	/* wait for the FCF to be selected before issuing FLOGI */
	while (!ctlr->sel_fcf) {
		msleep(250);
		/* give up after 3 secs */
		if (++wait_cnt > 12)
			break;
	}

	/* Reset max receive frame size to default */
	if (fc_set_mfs(lport, BNX2FC_MFS))
		return;

	fc_lport_init(lport);
	fc_fabric_login(lport);
}


/**
 * bnx2fc_ulp_init - Initialize an adapter instance
 *
 * @dev :	cnic device handle
 * Called from cnic_register_driver() context to initialize all
 *	enumerated cnic devices. This routine allocates adapter structure
 *	and other device specific resources.
 */
static void bnx2fc_ulp_init(struct cnic_dev *dev)
{
	struct bnx2fc_hba *hba;
	int rc = 0;

	BNX2FC_MISC_DBG("Entered %s\n", __func__);
	/* bnx2fc works only when bnx2x is loaded */
	if (!test_bit(CNIC_F_BNX2X_CLASS, &dev->flags) ||
	    (dev->max_fcoe_conn == 0)) {
		printk(KERN_ERR PFX "bnx2fc FCoE not supported on %s,"
				    " flags: %lx fcoe_conn: %d\n",
			dev->netdev->name, dev->flags, dev->max_fcoe_conn);
		return;
	}

	hba = bnx2fc_hba_create(dev);
	if (!hba) {
		printk(KERN_ERR PFX "hba initialization failed\n");
		return;
	}

	pr_info(PFX "FCoE initialized for %s.\n", dev->netdev->name);

	/* Add HBA to the adapter list */
	mutex_lock(&bnx2fc_dev_lock);
	list_add_tail(&hba->list, &adapter_list);
	adapter_count++;
	mutex_unlock(&bnx2fc_dev_lock);

	dev->fcoe_cap = &hba->fcoe_cap;
	clear_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic);
	rc = dev->register_device(dev, CNIC_ULP_FCOE,
						(void *) hba);
	if (rc)
		printk(KERN_ERR PFX "register_device failed, rc = %d\n", rc);
	else
		set_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic);
}

/* Assumes rtnl_lock and the bnx2fc_dev_lock are already taken */
static int __bnx2fc_disable(struct fcoe_ctlr *ctlr)
{
	struct bnx2fc_interface *interface = fcoe_ctlr_priv(ctlr);

	if (interface->enabled) {
		if (!ctlr->lp) {
			pr_err(PFX "__bnx2fc_disable: lport not found\n");
			return -ENODEV;
		} else {
			interface->enabled = false;
			fcoe_ctlr_link_down(ctlr);
			fcoe_clean_pending_queue(ctlr->lp);
		}
	}
	return 0;
}

/*
 * Deperecated: Use bnx2fc_enabled()
 */
static int bnx2fc_disable(struct net_device *netdev)
{
	struct bnx2fc_interface *interface;
	struct fcoe_ctlr *ctlr;
	int rc = 0;

	rtnl_lock();
	mutex_lock(&bnx2fc_dev_lock);

	interface = bnx2fc_interface_lookup(netdev);
	ctlr = bnx2fc_to_ctlr(interface);

	if (!interface) {
		rc = -ENODEV;
		pr_err(PFX "bnx2fc_disable: interface not found\n");
	} else {
		rc = __bnx2fc_disable(ctlr);
	}
	mutex_unlock(&bnx2fc_dev_lock);
	rtnl_unlock();
	return rc;
}

static uint bnx2fc_npiv_create_vports(struct fc_lport *lport,
				      struct cnic_fc_npiv_tbl *npiv_tbl)
{
	struct fc_vport_identifiers vpid;
	uint i, created = 0;
	u64 wwnn = 0;
	char wwpn_str[32];
	char wwnn_str[32];

	if (npiv_tbl->count > MAX_NPIV_ENTRIES) {
		BNX2FC_HBA_DBG(lport, "Exceeded count max of npiv table\n");
		goto done;
	}

	/* Sanity check the first entry to make sure it's not 0 */
	if (wwn_to_u64(npiv_tbl->wwnn[0]) == 0 &&
	    wwn_to_u64(npiv_tbl->wwpn[0]) == 0) {
		BNX2FC_HBA_DBG(lport, "First NPIV table entries invalid.\n");
		goto done;
	}

	vpid.roles = FC_PORT_ROLE_FCP_INITIATOR;
	vpid.vport_type = FC_PORTTYPE_NPIV;
	vpid.disable = false;

	for (i = 0; i < npiv_tbl->count; i++) {
		wwnn = wwn_to_u64(npiv_tbl->wwnn[i]);
		if (wwnn == 0) {
			/*
			 * If we get a 0 element from for the WWNN then assume
			 * the WWNN should be the same as the physical port.
			 */
			wwnn = lport->wwnn;
		}
		vpid.node_name = wwnn;
		vpid.port_name = wwn_to_u64(npiv_tbl->wwpn[i]);
		scnprintf(vpid.symbolic_name, sizeof(vpid.symbolic_name),
		    "NPIV[%u]:%016llx-%016llx",
		    created, vpid.port_name, vpid.node_name);
		fcoe_wwn_to_str(vpid.node_name, wwnn_str, sizeof(wwnn_str));
		fcoe_wwn_to_str(vpid.port_name, wwpn_str, sizeof(wwpn_str));
		BNX2FC_HBA_DBG(lport, "Creating vport %s:%s.\n", wwnn_str,
		    wwpn_str);
		if (fc_vport_create(lport->host, 0, &vpid))
			created++;
		else
			BNX2FC_HBA_DBG(lport, "Failed to create vport\n");
	}
done:
	return created;
}

static int __bnx2fc_enable(struct fcoe_ctlr *ctlr)
{
	struct bnx2fc_interface *interface = fcoe_ctlr_priv(ctlr);
	struct bnx2fc_hba *hba;
	struct cnic_fc_npiv_tbl *npiv_tbl;
	struct fc_lport *lport;

	if (!interface->enabled) {
		if (!ctlr->lp) {
			pr_err(PFX "__bnx2fc_enable: lport not found\n");
			return -ENODEV;
		} else if (!bnx2fc_link_ok(ctlr->lp)) {
			fcoe_ctlr_link_up(ctlr);
			interface->enabled = true;
		}
	}

	/* Create static NPIV ports if any are contained in NVRAM */
	hba = interface->hba;
	lport = ctlr->lp;

	if (!hba)
		goto done;

	if (!hba->cnic)
		goto done;

	if (!lport)
		goto done;

	if (!lport->host)
		goto done;

	if (!hba->cnic->get_fc_npiv_tbl)
		goto done;

	npiv_tbl = kzalloc(sizeof(struct cnic_fc_npiv_tbl), GFP_KERNEL);
	if (!npiv_tbl)
		goto done;

	if (hba->cnic->get_fc_npiv_tbl(hba->cnic, npiv_tbl))
		goto done_free;

	bnx2fc_npiv_create_vports(lport, npiv_tbl);
done_free:
	kfree(npiv_tbl);
done:
	return 0;
}

/*
 * Deprecated: Use bnx2fc_enabled()
 */
static int bnx2fc_enable(struct net_device *netdev)
{
	struct bnx2fc_interface *interface;
	struct fcoe_ctlr *ctlr;
	int rc = 0;

	rtnl_lock();
	mutex_lock(&bnx2fc_dev_lock);

	interface = bnx2fc_interface_lookup(netdev);
	ctlr = bnx2fc_to_ctlr(interface);
	if (!interface) {
		rc = -ENODEV;
		pr_err(PFX "bnx2fc_enable: interface not found\n");
	} else {
		rc = __bnx2fc_enable(ctlr);
	}

	mutex_unlock(&bnx2fc_dev_lock);
	rtnl_unlock();
	return rc;
}

/**
 * bnx2fc_ctlr_enabled() - Enable or disable an FCoE Controller
 * @cdev: The FCoE Controller that is being enabled or disabled
 *
 * fcoe_sysfs will ensure that the state of 'enabled' has
 * changed, so no checking is necessary here. This routine simply
 * calls fcoe_enable or fcoe_disable, both of which are deprecated.
 * When those routines are removed the functionality can be merged
 * here.
 */
static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev)
{
	struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev);

	switch (cdev->enabled) {
	case FCOE_CTLR_ENABLED:
		return __bnx2fc_enable(ctlr);
	case FCOE_CTLR_DISABLED:
		return __bnx2fc_disable(ctlr);
	case FCOE_CTLR_UNUSED:
	default:
		return -ENOTSUPP;
	}
}

enum bnx2fc_create_link_state {
	BNX2FC_CREATE_LINK_DOWN,
	BNX2FC_CREATE_LINK_UP,
};

/**
 * _bnx2fc_create() - Create bnx2fc FCoE interface
 * @netdev  :   The net_device object the Ethernet interface to create on
 * @fip_mode:   The FIP mode for this creation
 * @link_state: The ctlr link state on creation
 *
 * Called from either the libfcoe 'create' module parameter
 * via fcoe_create or from fcoe_syfs's ctlr_create file.
 *
 * libfcoe's 'create' module parameter is deprecated so some
 * consolidation of code can be done when that interface is
 * removed.
 *
 * Returns: 0 for success
 */
static int _bnx2fc_create(struct net_device *netdev,
			  enum fip_mode fip_mode,
			  enum bnx2fc_create_link_state link_state)
{
	struct fcoe_ctlr_device *cdev;
	struct fcoe_ctlr *ctlr;
	struct bnx2fc_interface *interface;
	struct bnx2fc_hba *hba;
	struct net_device *phys_dev = netdev;
	struct fc_lport *lport;
	struct ethtool_drvinfo drvinfo;
	int rc = 0;
	int vlan_id = 0;

	BNX2FC_MISC_DBG("Entered bnx2fc_create\n");
	if (fip_mode != FIP_MODE_FABRIC) {
		printk(KERN_ERR "fip mode not FABRIC\n");
		return -EIO;
	}

	rtnl_lock();

	mutex_lock(&bnx2fc_dev_lock);

	if (!try_module_get(THIS_MODULE)) {
		rc = -EINVAL;
		goto mod_err;
	}

	/* obtain physical netdev */
	if (is_vlan_dev(netdev))
		phys_dev = vlan_dev_real_dev(netdev);

	/* verify if the physical device is a netxtreme2 device */
	if (phys_dev->ethtool_ops && phys_dev->ethtool_ops->get_drvinfo) {
		memset(&drvinfo, 0, sizeof(drvinfo));
		phys_dev->ethtool_ops->get_drvinfo(phys_dev, &drvinfo);
		if (strncmp(drvinfo.driver, "bnx2x", strlen("bnx2x"))) {
			printk(KERN_ERR PFX "Not a netxtreme2 device\n");
			rc = -EINVAL;
			goto netdev_err;
		}
	} else {
		printk(KERN_ERR PFX "unable to obtain drv_info\n");
		rc = -EINVAL;
		goto netdev_err;
	}

	/* obtain interface and initialize rest of the structure */
	hba = bnx2fc_hba_lookup(phys_dev);
	if (!hba) {
		rc = -ENODEV;
		printk(KERN_ERR PFX "bnx2fc_create: hba not found\n");
		goto netdev_err;
	}

	if (bnx2fc_interface_lookup(netdev)) {
		rc = -EEXIST;
		goto netdev_err;
	}

	interface = bnx2fc_interface_create(hba, netdev, fip_mode);
	if (!interface) {
		printk(KERN_ERR PFX "bnx2fc_interface_create failed\n");
		rc = -ENOMEM;
		goto netdev_err;
	}

	if (is_vlan_dev(netdev)) {
		vlan_id = vlan_dev_vlan_id(netdev);
		interface->vlan_enabled = 1;
	}

	ctlr = bnx2fc_to_ctlr(interface);
	cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
	interface->vlan_id = vlan_id;
	interface->tm_timeout = BNX2FC_TM_TIMEOUT;

	interface->timer_work_queue =
			create_singlethread_workqueue("bnx2fc_timer_wq");
	if (!interface->timer_work_queue) {
		printk(KERN_ERR PFX "ulp_init could not create timer_wq\n");
		rc = -EINVAL;
		goto ifput_err;
	}

	lport = bnx2fc_if_create(interface, &cdev->dev, 0);
	if (!lport) {
		printk(KERN_ERR PFX "Failed to create interface (%s)\n",
			netdev->name);
		rc = -EINVAL;
		goto if_create_err;
	}

	/* Add interface to if_list */
	list_add_tail(&interface->list, &if_list);

	lport->boot_time = jiffies;

	/* Make this master N_port */
	ctlr->lp = lport;

	if (link_state == BNX2FC_CREATE_LINK_UP)
		cdev->enabled = FCOE_CTLR_ENABLED;
	else
		cdev->enabled = FCOE_CTLR_DISABLED;

	if (link_state == BNX2FC_CREATE_LINK_UP &&
	    !bnx2fc_link_ok(lport)) {
		fcoe_ctlr_link_up(ctlr);
		fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
		set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state);
	}

	BNX2FC_HBA_DBG(lport, "create: START DISC\n");
	bnx2fc_start_disc(interface);

	if (link_state == BNX2FC_CREATE_LINK_UP)
		interface->enabled = true;

	/*
	 * Release from kref_init in bnx2fc_interface_setup, on success
	 * lport should be holding a reference taken in bnx2fc_if_create
	 */
	bnx2fc_interface_put(interface);
	/* put netdev that was held while calling dev_get_by_name */
	mutex_unlock(&bnx2fc_dev_lock);
	rtnl_unlock();
	return 0;

if_create_err:
	destroy_workqueue(interface->timer_work_queue);
ifput_err:
	bnx2fc_net_cleanup(interface);
	bnx2fc_interface_put(interface);
	goto mod_err;
netdev_err:
	module_put(THIS_MODULE);
mod_err:
	mutex_unlock(&bnx2fc_dev_lock);
	rtnl_unlock();
	return rc;
}

/**
 * bnx2fc_create() - Create a bnx2fc interface
 * @netdev  : The net_device object the Ethernet interface to create on
 * @fip_mode: The FIP mode for this creation
 *
 * Called from fcoe transport
 *
 * Returns: 0 for success
 */
static int bnx2fc_create(struct net_device *netdev, enum fip_mode fip_mode)
{
	return _bnx2fc_create(netdev, fip_mode, BNX2FC_CREATE_LINK_UP);
}

/**
 * bnx2fc_ctlr_alloc() - Allocate a bnx2fc interface from fcoe_sysfs
 * @netdev: The net_device to be used by the allocated FCoE Controller
 *
 * This routine is called from fcoe_sysfs. It will start the fcoe_ctlr
 * in a link_down state. The allows the user an opportunity to configure
 * the FCoE Controller from sysfs before enabling the FCoE Controller.
 *
 * Creating in with this routine starts the FCoE Controller in Fabric
 * mode. The user can change to VN2VN or another mode before enabling.
 */
static int bnx2fc_ctlr_alloc(struct net_device *netdev)
{
	return _bnx2fc_create(netdev, FIP_MODE_FABRIC,
			      BNX2FC_CREATE_LINK_DOWN);
}

/**
 * bnx2fc_find_hba_for_cnic - maps cnic instance to bnx2fc hba instance
 *
 * @cnic:	Pointer to cnic device instance
 *
 **/
static struct bnx2fc_hba *bnx2fc_find_hba_for_cnic(struct cnic_dev *cnic)
{
	struct bnx2fc_hba *hba;

	/* Called with bnx2fc_dev_lock held */
	list_for_each_entry(hba, &adapter_list, list) {
		if (hba->cnic == cnic)
			return hba;
	}
	return NULL;
}

static struct bnx2fc_interface *bnx2fc_interface_lookup(struct net_device
							*netdev)
{
	struct bnx2fc_interface *interface;

	/* Called with bnx2fc_dev_lock held */
	list_for_each_entry(interface, &if_list, list) {
		if (interface->netdev == netdev)
			return interface;
	}
	return NULL;
}

static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device
						      *phys_dev)
{
	struct bnx2fc_hba *hba;

	/* Called with bnx2fc_dev_lock held */
	list_for_each_entry(hba, &adapter_list, list) {
		if (hba->phys_dev == phys_dev)
			return hba;
	}
	printk(KERN_ERR PFX "adapter_lookup: hba NULL\n");
	return NULL;
}

/**
 * bnx2fc_ulp_exit - shuts down adapter instance and frees all resources
 *
 * @dev:	cnic device handle
 */
static void bnx2fc_ulp_exit(struct cnic_dev *dev)
{
	struct bnx2fc_hba *hba;
	struct bnx2fc_interface *interface, *tmp;

	BNX2FC_MISC_DBG("Entered bnx2fc_ulp_exit\n");

	if (!test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
		printk(KERN_ERR PFX "bnx2fc port check: %s, flags: %lx\n",
			dev->netdev->name, dev->flags);
		return;
	}

	mutex_lock(&bnx2fc_dev_lock);
	hba = bnx2fc_find_hba_for_cnic(dev);
	if (!hba) {
		printk(KERN_ERR PFX "bnx2fc_ulp_exit: hba not found, dev 0%p\n",
		       dev);
		mutex_unlock(&bnx2fc_dev_lock);
		return;
	}

	list_del_init(&hba->list);
	adapter_count--;

	list_for_each_entry_safe(interface, tmp, &if_list, list)
		/* destroy not called yet, move to quiesced list */
		if (interface->hba == hba)
			__bnx2fc_destroy(interface);
	mutex_unlock(&bnx2fc_dev_lock);

	bnx2fc_ulp_stop(hba);
	/* unregister cnic device */
	if (test_and_clear_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic))
		hba->cnic->unregister_device(hba->cnic, CNIC_ULP_FCOE);
	bnx2fc_hba_destroy(hba);
}

static void bnx2fc_rport_terminate_io(struct fc_rport *rport)
{
	/* This is a no-op */
}

/**
 * bnx2fc_fcoe_reset - Resets the fcoe
 *
 * @shost: shost the reset is from
 *
 * Returns: always 0
 */
static int bnx2fc_fcoe_reset(struct Scsi_Host *shost)
{
	struct fc_lport *lport = shost_priv(shost);
	fc_lport_reset(lport);
	return 0;
}


static bool bnx2fc_match(struct net_device *netdev)
{
	struct net_device *phys_dev = netdev;

	mutex_lock(&bnx2fc_dev_lock);
	if (is_vlan_dev(netdev))
		phys_dev = vlan_dev_real_dev(netdev);

	if (bnx2fc_hba_lookup(phys_dev)) {
		mutex_unlock(&bnx2fc_dev_lock);
		return true;
	}

	mutex_unlock(&bnx2fc_dev_lock);
	return false;
}


static struct fcoe_transport bnx2fc_transport = {
	.name = {"bnx2fc"},
	.attached = false,
	.list = LIST_HEAD_INIT(bnx2fc_transport.list),
	.alloc = bnx2fc_ctlr_alloc,
	.match = bnx2fc_match,
	.create = bnx2fc_create,
	.destroy = bnx2fc_destroy,
	.enable = bnx2fc_enable,
	.disable = bnx2fc_disable,
};

/**
 * bnx2fc_cpu_online - Create a receive thread for an  online CPU
 *
 * @cpu: cpu index for the online cpu
 */
static int bnx2fc_cpu_online(unsigned int cpu)
{
	struct bnx2fc_percpu_s *p;
	struct task_struct *thread;

	p = &per_cpu(bnx2fc_percpu, cpu);

	thread = kthread_create_on_node(bnx2fc_percpu_io_thread,
					(void *)p, cpu_to_node(cpu),
					"bnx2fc_thread/%d", cpu);
	if (IS_ERR(thread))
		return PTR_ERR(thread);

	/* bind thread to the cpu */
	kthread_bind(thread, cpu);
	p->iothread = thread;
	wake_up_process(thread);
	return 0;
}

static int bnx2fc_cpu_offline(unsigned int cpu)
{
	struct bnx2fc_percpu_s *p;
	struct task_struct *thread;
	struct bnx2fc_work *work, *tmp;

	BNX2FC_MISC_DBG("destroying io thread for CPU %d\n", cpu);

	/* Prevent any new work from being queued for this CPU */
	p = &per_cpu(bnx2fc_percpu, cpu);
	spin_lock_bh(&p->fp_work_lock);
	thread = p->iothread;
	p->iothread = NULL;

	/* Free all work in the list */
	list_for_each_entry_safe(work, tmp, &p->work_list, list) {
		list_del_init(&work->list);
		bnx2fc_process_cq_compl(work->tgt, work->wqe, work->rq_data,
					work->num_rq, work->task);
		kfree(work);
	}

	spin_unlock_bh(&p->fp_work_lock);

	if (thread)
		kthread_stop(thread);
	return 0;
}

static int bnx2fc_slave_configure(struct scsi_device *sdev)
{
	if (!bnx2fc_queue_depth)
		return 0;

	scsi_change_queue_depth(sdev, bnx2fc_queue_depth);
	return 0;
}

static enum cpuhp_state bnx2fc_online_state;

/**
 * bnx2fc_mod_init - module init entry point
 *
 * Initialize driver wide global data structures, and register
 * with cnic module
 **/
static int __init bnx2fc_mod_init(void)
{
	struct fcoe_percpu_s *bg;
	struct task_struct *l2_thread;
	int rc = 0;
	unsigned int cpu = 0;
	struct bnx2fc_percpu_s *p;

	printk(KERN_INFO PFX "%s", version);

	/* register as a fcoe transport */
	rc = fcoe_transport_attach(&bnx2fc_transport);
	if (rc) {
		printk(KERN_ERR "failed to register an fcoe transport, check "
			"if libfcoe is loaded\n");
		goto out;
	}

	INIT_LIST_HEAD(&adapter_list);
	INIT_LIST_HEAD(&if_list);
	mutex_init(&bnx2fc_dev_lock);
	adapter_count = 0;

	/* Attach FC transport template */
	rc = bnx2fc_attach_transport();
	if (rc)
		goto detach_ft;

	bnx2fc_wq = alloc_workqueue("bnx2fc", 0, 0);
	if (!bnx2fc_wq) {
		rc = -ENOMEM;
		goto release_bt;
	}

	bg = &bnx2fc_global;
	skb_queue_head_init(&bg->fcoe_rx_list);
	l2_thread = kthread_run(bnx2fc_l2_rcv_thread,
				(void *)bg,
				"bnx2fc_l2_thread");
	if (IS_ERR(l2_thread)) {
		rc = PTR_ERR(l2_thread);
		goto free_wq;
	}
	spin_lock_bh(&bg->fcoe_rx_list.lock);
	bg->kthread = l2_thread;
	spin_unlock_bh(&bg->fcoe_rx_list.lock);

	for_each_possible_cpu(cpu) {
		p = &per_cpu(bnx2fc_percpu, cpu);
		INIT_LIST_HEAD(&p->work_list);
		spin_lock_init(&p->fp_work_lock);
	}

	rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "scsi/bnx2fc:online",
			       bnx2fc_cpu_online, bnx2fc_cpu_offline);
	if (rc < 0)
		goto stop_thread;
	bnx2fc_online_state = rc;

	cnic_register_driver(CNIC_ULP_FCOE, &bnx2fc_cnic_cb);
	return 0;

stop_thread:
	kthread_stop(l2_thread);
free_wq:
	destroy_workqueue(bnx2fc_wq);
release_bt:
	bnx2fc_release_transport();
detach_ft:
	fcoe_transport_detach(&bnx2fc_transport);
out:
	return rc;
}

static void __exit bnx2fc_mod_exit(void)
{
	LIST_HEAD(to_be_deleted);
	struct bnx2fc_hba *hba, *next;
	struct fcoe_percpu_s *bg;
	struct task_struct *l2_thread;
	struct sk_buff *skb;

	/*
	 * NOTE: Since cnic calls register_driver routine rtnl_lock,
	 * it will have higher precedence than bnx2fc_dev_lock.
	 * unregister_device() cannot be called with bnx2fc_dev_lock
	 * held.
	 */
	mutex_lock(&bnx2fc_dev_lock);
	list_splice_init(&adapter_list, &to_be_deleted);
	adapter_count = 0;
	mutex_unlock(&bnx2fc_dev_lock);

	/* Unregister with cnic */
	list_for_each_entry_safe(hba, next, &to_be_deleted, list) {
		list_del_init(&hba->list);
		printk(KERN_ERR PFX "MOD_EXIT:destroy hba = 0x%p\n",
		       hba);
		bnx2fc_ulp_stop(hba);
		/* unregister cnic device */
		if (test_and_clear_bit(BNX2FC_CNIC_REGISTERED,
				       &hba->reg_with_cnic))
			hba->cnic->unregister_device(hba->cnic,
							 CNIC_ULP_FCOE);
		bnx2fc_hba_destroy(hba);
	}
	cnic_unregister_driver(CNIC_ULP_FCOE);

	/* Destroy global thread */
	bg = &bnx2fc_global;
	spin_lock_bh(&bg->fcoe_rx_list.lock);
	l2_thread = bg->kthread;
	bg->kthread = NULL;
	while ((skb = __skb_dequeue(&bg->fcoe_rx_list)) != NULL)
		kfree_skb(skb);

	spin_unlock_bh(&bg->fcoe_rx_list.lock);

	if (l2_thread)
		kthread_stop(l2_thread);

	cpuhp_remove_state(bnx2fc_online_state);

	destroy_workqueue(bnx2fc_wq);
	/*
	 * detach from scsi transport
	 * must happen after all destroys are done
	 */
	bnx2fc_release_transport();

	/* detach from fcoe transport */
	fcoe_transport_detach(&bnx2fc_transport);
}

module_init(bnx2fc_mod_init);
module_exit(bnx2fc_mod_exit);

static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = {
	.set_fcoe_ctlr_enabled = bnx2fc_ctlr_enabled,
	.get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb,

	.get_fcoe_fcf_selected = fcoe_fcf_get_selected,
	.get_fcoe_fcf_vlan_id = bnx2fc_fcf_get_vlan_id,
};

static struct fc_function_template bnx2fc_transport_function = {
	.show_host_node_name = 1,
	.show_host_port_name = 1,
	.show_host_supported_classes = 1,
	.show_host_supported_fc4s = 1,
	.show_host_active_fc4s = 1,
	.show_host_maxframe_size = 1,

	.show_host_port_id = 1,
	.show_host_supported_speeds = 1,
	.get_host_speed = fc_get_host_speed,
	.show_host_speed = 1,
	.show_host_port_type = 1,
	.get_host_port_state = fc_get_host_port_state,
	.show_host_port_state = 1,
	.show_host_symbolic_name = 1,

	.dd_fcrport_size = (sizeof(struct fc_rport_libfc_priv) +
				sizeof(struct bnx2fc_rport)),
	.show_rport_maxframe_size = 1,
	.show_rport_supported_classes = 1,

	.show_host_fabric_name = 1,
	.show_starget_node_name = 1,
	.show_starget_port_name = 1,
	.show_starget_port_id = 1,
	.set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
	.show_rport_dev_loss_tmo = 1,
	.get_fc_host_stats = bnx2fc_get_host_stats,

	.issue_fc_host_lip = bnx2fc_fcoe_reset,

	.terminate_rport_io = bnx2fc_rport_terminate_io,

	.vport_create = bnx2fc_vport_create,
	.vport_delete = bnx2fc_vport_destroy,
	.vport_disable = bnx2fc_vport_disable,
	.bsg_request = fc_lport_bsg_request,
};

static struct fc_function_template bnx2fc_vport_xport_function = {
	.show_host_node_name = 1,
	.show_host_port_name = 1,
	.show_host_supported_classes = 1,
	.show_host_supported_fc4s = 1,
	.show_host_active_fc4s = 1,
	.show_host_maxframe_size = 1,

	.show_host_port_id = 1,
	.show_host_supported_speeds = 1,
	.get_host_speed = fc_get_host_speed,
	.show_host_speed = 1,
	.show_host_port_type = 1,
	.get_host_port_state = fc_get_host_port_state,
	.show_host_port_state = 1,
	.show_host_symbolic_name = 1,

	.dd_fcrport_size = (sizeof(struct fc_rport_libfc_priv) +
				sizeof(struct bnx2fc_rport)),
	.show_rport_maxframe_size = 1,
	.show_rport_supported_classes = 1,

	.show_host_fabric_name = 1,
	.show_starget_node_name = 1,
	.show_starget_port_name = 1,
	.show_starget_port_id = 1,
	.set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
	.show_rport_dev_loss_tmo = 1,
	.get_fc_host_stats = fc_get_host_stats,
	.issue_fc_host_lip = bnx2fc_fcoe_reset,
	.terminate_rport_io = fc_rport_terminate_io,
	.bsg_request = fc_lport_bsg_request,
};

/*
 * Additional scsi_host attributes.
 */
static ssize_t
bnx2fc_tm_timeout_show(struct device *dev, struct device_attribute *attr,
	char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct fc_lport *lport = shost_priv(shost);
	struct fcoe_port *port = lport_priv(lport);
	struct bnx2fc_interface *interface = port->priv;

	sprintf(buf, "%u\n", interface->tm_timeout);
	return strlen(buf);
}

static ssize_t
bnx2fc_tm_timeout_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct fc_lport *lport = shost_priv(shost);
	struct fcoe_port *port = lport_priv(lport);
	struct bnx2fc_interface *interface = port->priv;
	int rval, val;

	rval = kstrtouint(buf, 10, &val);
	if (rval)
		return rval;
	if (val > 255)
		return -ERANGE;

	interface->tm_timeout = (u8)val;
	return strlen(buf);
}

static DEVICE_ATTR(tm_timeout, S_IRUGO|S_IWUSR, bnx2fc_tm_timeout_show,
	bnx2fc_tm_timeout_store);

static struct attribute *bnx2fc_host_attrs[] = {
	&dev_attr_tm_timeout.attr,
	NULL,
};

ATTRIBUTE_GROUPS(bnx2fc_host);

/*
 * scsi_host_template structure used while registering with SCSI-ml
 */
static struct scsi_host_template bnx2fc_shost_template = {
	.module			= THIS_MODULE,
	.name			= "QLogic Offload FCoE Initiator",
	.queuecommand		= bnx2fc_queuecommand,
	.eh_timed_out		= fc_eh_timed_out,
	.eh_abort_handler	= bnx2fc_eh_abort,	  /* abts */
	.eh_device_reset_handler = bnx2fc_eh_device_reset, /* lun reset */
	.eh_target_reset_handler = bnx2fc_eh_target_reset, /* tgt reset */
	.eh_host_reset_handler	= fc_eh_host_reset,
	.slave_alloc		= fc_slave_alloc,
	.change_queue_depth	= scsi_change_queue_depth,
	.this_id		= -1,
	.cmd_per_lun		= 3,
	.sg_tablesize		= BNX2FC_MAX_BDS_PER_CMD,
	.dma_boundary           = 0x7fff,
	.max_sectors		= 0x3fbf,
	.track_queue_depth	= 1,
	.slave_configure	= bnx2fc_slave_configure,
	.shost_groups		= bnx2fc_host_groups,
	.cmd_size		= sizeof(struct bnx2fc_priv),
};

static struct libfc_function_template bnx2fc_libfc_fcn_templ = {
	.frame_send		= bnx2fc_xmit,
	.elsct_send		= bnx2fc_elsct_send,
	.fcp_abort_io		= bnx2fc_abort_io,
	.fcp_cleanup		= bnx2fc_cleanup,
	.get_lesb		= fcoe_get_lesb,
	.rport_event_callback	= bnx2fc_rport_event_handler,
};

/*
 * bnx2fc_cnic_cb - global template of bnx2fc - cnic driver interface
 *			structure carrying callback function pointers
 */
static struct cnic_ulp_ops bnx2fc_cnic_cb = {
	.owner			= THIS_MODULE,
	.cnic_init		= bnx2fc_ulp_init,
	.cnic_exit		= bnx2fc_ulp_exit,
	.cnic_start		= bnx2fc_ulp_start,
	.cnic_stop		= bnx2fc_ulp_stop,
	.indicate_kcqes		= bnx2fc_indicate_kcqe,
	.indicate_netevent	= bnx2fc_indicate_netevent,
	.cnic_get_stats		= bnx2fc_ulp_get_stats,
};
