diff options
author | Bhanu Prakash Gollapudi <bprakash@broadcom.com> | 2011-07-26 14:51:39 -0700 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-07-27 15:37:31 +0400 |
commit | aea71a024914e8b5b8bed31256dae42195a0a207 (patch) | |
tree | d3d155d7323966a56425ad68837b924816719c89 /drivers/scsi/bnx2fc | |
parent | f6e76055ba778c56716ba79e106db28297775e87 (diff) | |
download | talos-obmc-linux-aea71a024914e8b5b8bed31256dae42195a0a207.tar.gz talos-obmc-linux-aea71a024914e8b5b8bed31256dae42195a0a207.zip |
[SCSI] bnx2fc: Introduce interface structure for each vlan interface
Currently, bnx2fc has a hba structure that can work with only a single vlan
interface. When there is a change in vlan id, it does not have the capability
to switch to different vlan interface. To solve this problem, a new structure
called 'interface' has been introduced, and each hba can now have multiple
interfaces, one per vlan id.
Most of the patch is a moving the interface specific fields from hba to the
interface structure, and appropriately modifying the dereferences. A list of
interfaces (if_list) is maintained along with adapter list. During a create
call, the interface structure is allocated and added to if_list and deleted &
freed on a destroy call. Link events are propagated to all interfaces
belonging to the hba.
Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bnx2fc')
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc.h | 74 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_els.c | 9 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 716 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_hwi.c | 98 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_io.c | 48 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_tgt.c | 17 |
6 files changed, 467 insertions, 495 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h index d924236e1b91..6012317c1f2f 100644 --- a/drivers/scsi/bnx2fc/bnx2fc.h +++ b/drivers/scsi/bnx2fc/bnx2fc.h @@ -153,18 +153,13 @@ struct bnx2fc_percpu_s { }; struct bnx2fc_hba { - struct list_head link; + struct list_head list; struct cnic_dev *cnic; struct pci_dev *pcidev; - struct net_device *netdev; struct net_device *phys_dev; unsigned long reg_with_cnic; #define BNX2FC_CNIC_REGISTERED 1 - struct packet_type fcoe_packet_type; - struct packet_type fip_packet_type; struct bnx2fc_cmd_mgr *cmd_mgr; - struct workqueue_struct *timer_work_queue; - struct kref kref; spinlock_t hba_lock; struct mutex hba_mutex; unsigned long adapter_state; @@ -172,15 +167,9 @@ struct bnx2fc_hba { #define ADAPTER_STATE_GOING_DOWN 1 #define ADAPTER_STATE_LINK_DOWN 2 #define ADAPTER_STATE_READY 3 - u32 flags; - unsigned long init_done; - #define BNX2FC_FW_INIT_DONE 0 - #define BNX2FC_CTLR_INIT_DONE 1 - #define BNX2FC_CREATE_DONE 2 - struct fcoe_ctlr ctlr; - struct list_head vports; - u8 vlan_enabled; - int vlan_id; + unsigned long flags; + #define BNX2FC_FLAG_FW_INIT_DONE 0 + #define BNX2FC_FLAG_DESTROY_CMPL 1 u32 next_conn_id; struct fcoe_task_ctx_entry **task_ctx; dma_addr_t *task_ctx_dma; @@ -199,38 +188,41 @@ struct bnx2fc_hba { char *dummy_buffer; dma_addr_t dummy_buf_dma; + /* Active list of offloaded sessions */ + struct bnx2fc_rport **tgt_ofld_list; + + /* statistics */ struct fcoe_statistics_params *stats_buffer; dma_addr_t stats_buf_dma; - - /* - * PCI related info. - */ - u16 pci_did; - u16 pci_vid; - u16 pci_sdid; - u16 pci_svid; - u16 pci_func; - u16 pci_devno; - - struct task_struct *l2_thread; - - /* linkdown handling */ - wait_queue_head_t shutdown_wait; - int wait_for_link_down; + struct completion stat_req_done; /*destroy handling */ struct timer_list destroy_timer; wait_queue_head_t destroy_wait; - /* Active list of offloaded sessions */ - struct bnx2fc_rport *tgt_ofld_list[BNX2FC_NUM_MAX_SESS]; + /* linkdown handling */ + wait_queue_head_t shutdown_wait; + int wait_for_link_down; int num_ofld_sess; + struct list_head vports; +}; - /* statistics */ - struct completion stat_req_done; +struct bnx2fc_interface { + struct list_head list; + unsigned long if_flags; + #define BNX2FC_CTLR_INIT_DONE 0 + struct bnx2fc_hba *hba; + struct net_device *netdev; + struct packet_type fcoe_packet_type; + struct packet_type fip_packet_type; + struct workqueue_struct *timer_work_queue; + struct kref kref; + struct fcoe_ctlr ctlr; + u8 vlan_enabled; + int vlan_id; }; -#define bnx2fc_from_ctlr(fip) container_of(fip, struct bnx2fc_hba, ctlr) +#define bnx2fc_from_ctlr(fip) container_of(fip, struct bnx2fc_interface, ctlr) struct bnx2fc_lport { struct list_head list; @@ -262,10 +254,9 @@ struct bnx2fc_rport { #define BNX2FC_FLAG_DISABLED 0x3 #define BNX2FC_FLAG_DESTROYED 0x4 #define BNX2FC_FLAG_OFLD_REQ_CMPL 0x5 -#define BNX2FC_FLAG_DESTROY_CMPL 0x6 -#define BNX2FC_FLAG_CTX_ALLOC_FAILURE 0x7 -#define BNX2FC_FLAG_UPLD_REQ_COMPL 0x8 -#define BNX2FC_FLAG_EXPL_LOGO 0x9 +#define BNX2FC_FLAG_CTX_ALLOC_FAILURE 0x6 +#define BNX2FC_FLAG_UPLD_REQ_COMPL 0x7 +#define BNX2FC_FLAG_EXPL_LOGO 0x8 u8 src_addr[ETH_ALEN]; u32 max_sqes; @@ -327,12 +318,9 @@ struct bnx2fc_rport { spinlock_t cq_lock; atomic_t num_active_ios; u32 flush_in_prog; - unsigned long work_time_slice; unsigned long timestamp; struct list_head free_task_list; struct bnx2fc_cmd *pending_queue[BNX2FC_SQ_WQES_MAX+1]; - atomic_t pi; - atomic_t ci; struct list_head active_cmd_queue; struct list_head els_queue; struct list_head io_retire_queue; diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c index e3f18736ba37..5d7baa2371f8 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_els.c +++ b/drivers/scsi/bnx2fc/bnx2fc_els.c @@ -259,7 +259,7 @@ static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op, struct bnx2fc_els_cb_arg *cb_arg, u32 timer_msec) { struct fcoe_port *port = tgt->port; - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; struct fc_rport *rport = tgt->rport; struct fc_lport *lport = port->lport; struct bnx2fc_cmd *els_req; @@ -352,7 +352,8 @@ static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op, index = xid % BNX2FC_TASKS_PER_PAGE; /* Initialize task context for this IO request */ - task_page = (struct fcoe_task_ctx_entry *) hba->task_ctx[task_idx]; + task_page = (struct fcoe_task_ctx_entry *) + interface->hba->task_ctx[task_idx]; task = &(task_page[index]); bnx2fc_init_mp_task(els_req, task); @@ -496,8 +497,8 @@ struct fc_seq *bnx2fc_elsct_send(struct fc_lport *lport, u32 did, void *arg, u32 timeout) { struct fcoe_port *port = lport_priv(lport); - struct bnx2fc_hba *hba = port->priv; - struct fcoe_ctlr *fip = &hba->ctlr; + struct bnx2fc_interface *interface = port->priv; + struct fcoe_ctlr *fip = &interface->ctlr; struct fc_frame_header *fh = fc_frame_header_get(fp); switch (op) { diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index e70452174f20..65561fcaad03 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -15,6 +15,7 @@ #include "bnx2fc.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); @@ -61,7 +62,7 @@ static int bnx2fc_disable(struct net_device *netdev); static void bnx2fc_recv_frame(struct sk_buff *skb); -static void bnx2fc_start_disc(struct bnx2fc_hba *hba); +static void bnx2fc_start_disc(struct bnx2fc_interface *interface); static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev); static int bnx2fc_net_config(struct fc_lport *lp); static int bnx2fc_lport_config(struct fc_lport *lport); @@ -70,18 +71,20 @@ 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_hba *hba, +static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, struct device *parent, int npiv); static void bnx2fc_destroy_work(struct work_struct *work); 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 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_hba *hba); +static void bnx2fc_stop(struct bnx2fc_interface *interface); static int __init bnx2fc_mod_init(void); static void __exit bnx2fc_mod_exit(void); @@ -142,7 +145,8 @@ static void bnx2fc_abort_io(struct fc_lport *lport) static void bnx2fc_cleanup(struct fc_lport *lport) { struct fcoe_port *port = lport_priv(lport); - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; struct bnx2fc_rport *tgt; int i; @@ -219,7 +223,8 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) struct fcoe_crc_eof *cp; struct sk_buff *skb; struct fc_frame_header *fh; - struct bnx2fc_hba *hba; + struct bnx2fc_interface *interface; + struct bnx2fc_hba *hba; struct fcoe_port *port; struct fcoe_hdr *hp; struct bnx2fc_rport *tgt; @@ -230,7 +235,8 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) int wlen, rc = 0; port = (struct fcoe_port *)lport_priv(lport); - hba = port->priv; + interface = port->priv; + hba = interface->hba; fh = fc_frame_header_get(fp); @@ -242,12 +248,12 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) } if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ)) { - if (!hba->ctlr.sel_fcf) { + if (!interface->ctlr.sel_fcf) { BNX2FC_HBA_DBG(lport, "FCF not selected yet!\n"); kfree_skb(skb); return -EINVAL; } - if (fcoe_ctlr_els_send(&hba->ctlr, lport, skb)) + if (fcoe_ctlr_els_send(&interface->ctlr, lport, skb)) return 0; } @@ -316,19 +322,19 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) skb_reset_network_header(skb); skb->mac_len = elen; skb->protocol = htons(ETH_P_FCOE); - skb->dev = hba->netdev; + skb->dev = interface->netdev; /* fill up mac and fcoe headers */ eh = eth_hdr(skb); eh->h_proto = htons(ETH_P_FCOE); - if (hba->ctlr.map_dest) + if (interface->ctlr.map_dest) fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id); else /* insert GW address */ - memcpy(eh->h_dest, hba->ctlr.dest_addr, ETH_ALEN); + memcpy(eh->h_dest, interface->ctlr.dest_addr, ETH_ALEN); - if (unlikely(hba->ctlr.flogi_oxid != FC_XID_UNKNOWN)) - memcpy(eh->h_source, hba->ctlr.ctl_src_addr, ETH_ALEN); + if (unlikely(interface->ctlr.flogi_oxid != FC_XID_UNKNOWN)) + memcpy(eh->h_source, interface->ctlr.ctl_src_addr, ETH_ALEN); else memcpy(eh->h_source, port->data_src_addr, ETH_ALEN); @@ -377,14 +383,15 @@ 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_hba *hba; + struct bnx2fc_interface *interface; struct fc_frame_header *fh; struct fcoe_rcv_info *fr; struct fcoe_percpu_s *bg; unsigned short oxid; - hba = container_of(ptype, struct bnx2fc_hba, fcoe_packet_type); - lport = hba->ctlr.lp; + interface = container_of(ptype, struct bnx2fc_interface, + fcoe_packet_type); + lport = interface->ctlr.lp; if (unlikely(lport == NULL)) { printk(KERN_ERR PFX "bnx2fc_rcv: lport is NULL\n"); @@ -594,7 +601,8 @@ 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_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; struct fcoe_statistics_params *fw_stats; int rc = 0; @@ -631,7 +639,7 @@ static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost) static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev) { struct fcoe_port *port = lport_priv(lport); - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; struct Scsi_Host *shost = lport->host; int rc = 0; @@ -654,7 +662,7 @@ static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev) fc_host_max_npiv_vports(lport->host) = USHRT_MAX; sprintf(fc_host_symbolic_name(lport->host), "%s v%s over %s", BNX2FC_NAME, BNX2FC_VERSION, - hba->netdev->name); + interface->netdev->name); return 0; } @@ -662,8 +670,8 @@ static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev) static void bnx2fc_link_speed_update(struct fc_lport *lport) { struct fcoe_port *port = lport_priv(lport); - struct bnx2fc_hba *hba = port->priv; - struct net_device *netdev = hba->netdev; + struct bnx2fc_interface *interface = port->priv; + struct net_device *netdev = interface->netdev; struct ethtool_cmd ecmd; if (!dev_ethtool_get_settings(netdev, &ecmd)) { @@ -691,7 +699,8 @@ static void bnx2fc_link_speed_update(struct fc_lport *lport) static int bnx2fc_link_ok(struct fc_lport *lport) { struct fcoe_port *port = lport_priv(lport); - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; struct net_device *dev = hba->phys_dev; int rc = 0; @@ -713,7 +722,7 @@ static int bnx2fc_link_ok(struct fc_lport *lport) */ void bnx2fc_get_link_state(struct bnx2fc_hba *hba) { - if (test_bit(__LINK_STATE_NOCARRIER, &hba->netdev->state)) + 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); @@ -722,11 +731,13 @@ void bnx2fc_get_link_state(struct bnx2fc_hba *hba) static int bnx2fc_net_config(struct fc_lport *lport) { struct bnx2fc_hba *hba; + struct bnx2fc_interface *interface; struct fcoe_port *port; u64 wwnn, wwpn; port = lport_priv(lport); - hba = port->priv; + interface = port->priv; + hba = interface->hba; /* require support for get_pauseparam ethtool op. */ if (!hba->phys_dev->ethtool_ops || @@ -743,11 +754,11 @@ static int bnx2fc_net_config(struct fc_lport *lport) bnx2fc_link_speed_update(lport); if (!lport->vport) { - wwnn = fcoe_wwn_from_mac(hba->ctlr.ctl_src_addr, 1, 0); + wwnn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr, 1, 0); BNX2FC_HBA_DBG(lport, "WWNN = 0x%llx\n", wwnn); fc_set_wwnn(lport, wwnn); - wwpn = fcoe_wwn_from_mac(hba->ctlr.ctl_src_addr, 2, 0); + wwpn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr, 2, 0); BNX2FC_HBA_DBG(lport, "WWPN = 0x%llx\n", wwpn); fc_set_wwpn(lport, wwpn); } @@ -759,9 +770,9 @@ static void bnx2fc_destroy_timer(unsigned long data) { struct bnx2fc_hba *hba = (struct bnx2fc_hba *)data; - BNX2FC_HBA_DBG(hba->ctlr.lp, "ERROR:bnx2fc_destroy_timer - " + BNX2FC_MISC_DBG("ERROR:bnx2fc_destroy_timer - " "Destroy compl not received!!\n"); - hba->flags |= BNX2FC_FLAG_DESTROY_CMPL; + set_bit(BNX2FC_FLAG_DESTROY_CMPL, &hba->flags); wake_up_interruptible(&hba->destroy_wait); } @@ -779,54 +790,35 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, u16 vlan_id) { struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context; - struct fc_lport *lport = hba->ctlr.lp; + struct fc_lport *lport; struct fc_lport *vport; + struct bnx2fc_interface *interface; + int wait_for_upload = 0; u32 link_possible = 1; /* Ignore vlans for now */ if (vlan_id != 0) return; - if (!test_bit(BNX2FC_CREATE_DONE, &hba->init_done)) { - BNX2FC_MISC_DBG("driver not ready. event=%s %ld\n", - hba->netdev->name, event); - return; - } - - /* - * ASSUMPTION: - * indicate_netevent cannot be called from cnic unless bnx2fc - * does register_device - */ - BUG_ON(!lport); - - BNX2FC_HBA_DBG(lport, "enter netevent handler - event=%s %ld\n", - hba->netdev->name, event); - switch (event) { case NETDEV_UP: - BNX2FC_HBA_DBG(lport, "Port up, adapter_state = %ld\n", - hba->adapter_state); if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state)) printk(KERN_ERR "indicate_netevent: "\ - "adapter is not UP!!\n"); + "hba is not UP!!\n"); break; case NETDEV_DOWN: - BNX2FC_HBA_DBG(lport, "Port down\n"); 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: - BNX2FC_HBA_DBG(lport, "Port going down\n"); set_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state); link_possible = 0; break; case NETDEV_CHANGE: - BNX2FC_HBA_DBG(lport, "NETDEV_CHANGE\n"); break; default: @@ -834,15 +826,22 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, return; } - bnx2fc_link_speed_update(lport); + mutex_lock(&bnx2fc_dev_lock); + list_for_each_entry(interface, &if_list, list) { - if (link_possible && !bnx2fc_link_ok(lport)) { - printk(KERN_ERR "indicate_netevent: call ctlr_link_up\n"); - fcoe_ctlr_link_up(&hba->ctlr); - } else { - printk(KERN_ERR "indicate_netevent: call ctlr_link_down\n"); - if (fcoe_ctlr_link_down(&hba->ctlr)) { - clear_bit(ADAPTER_STATE_READY, &hba->adapter_state); + if (interface->hba != hba) + continue; + + lport = interface->ctlr.lp; + BNX2FC_HBA_DBG(lport, "netevent handler - event=%s %ld\n", + interface->netdev->name, event); + + bnx2fc_link_speed_update(lport); + + if (link_possible && !bnx2fc_link_ok(lport)) { + printk(KERN_ERR "indicate_netevent: ctlr_link_up\n"); + fcoe_ctlr_link_up(&interface->ctlr); + } else if (fcoe_ctlr_link_down(&interface->ctlr)) { mutex_lock(&lport->lp_mutex); list_for_each_entry(vport, &lport->vports, list) fc_host_port_type(vport->host) = @@ -853,24 +852,26 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, get_cpu())->LinkFailureCount++; put_cpu(); fcoe_clean_pending_queue(lport); + wait_for_upload = 1; + } + } + mutex_unlock(&bnx2fc_dev_lock); - init_waitqueue_head(&hba->shutdown_wait); - BNX2FC_HBA_DBG(lport, "indicate_netevent " - "num_ofld_sess = %d\n", - hba->num_ofld_sess); - hba->wait_for_link_down = 1; - BNX2FC_HBA_DBG(lport, "waiting for uploads to " - "compl proc = %s\n", - current->comm); - wait_event_interruptible(hba->shutdown_wait, - (hba->num_ofld_sess == 0)); - BNX2FC_HBA_DBG(lport, "wakeup - num_ofld_sess = %d\n", + 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; + hba->wait_for_link_down = 0; - if (signal_pending(current)) - flush_signals(current); - } + if (signal_pending(current)) + flush_signals(current); } } @@ -889,23 +890,12 @@ static int bnx2fc_libfc_config(struct fc_lport *lport) static int bnx2fc_em_config(struct fc_lport *lport) { - struct fcoe_port *port = lport_priv(lport); - struct bnx2fc_hba *hba = port->priv; - 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; } - hba->cmd_mgr = bnx2fc_cmd_mgr_alloc(hba, BNX2FC_MIN_XID, - BNX2FC_MAX_XID); - - if (!hba->cmd_mgr) { - printk(KERN_ERR PFX "em_config:bnx2fc_cmd_mgr_alloc failed\n"); - fc_exch_mgr_free(lport); - return -ENOMEM; - } return 0; } @@ -952,9 +942,10 @@ static int bnx2fc_fip_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev) { - struct bnx2fc_hba *hba; - hba = container_of(ptype, struct bnx2fc_hba, fip_packet_type); - fcoe_ctlr_recv(&hba->ctlr, skb); + struct bnx2fc_interface *interface; + interface = container_of(ptype, struct bnx2fc_interface, + fip_packet_type); + fcoe_ctlr_recv(&interface->ctlr, skb); return 0; } @@ -1005,17 +996,17 @@ 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_hba *hba = port->priv; - struct net_device *netdev = hba->netdev; + struct bnx2fc_interface *interface = port->priv; + struct net_device *netdev = interface->netdev; struct fc_lport *vn_port; - if (!test_bit(BNX2FC_FW_INIT_DONE, &hba->init_done)) { + if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags)) { printk(KERN_ERR PFX "vn ports cannot be created on" - "this hba\n"); + "this interface\n"); return -EIO; } mutex_lock(&bnx2fc_dev_lock); - vn_port = bnx2fc_if_create(hba, &vport->dev, 1); + vn_port = bnx2fc_if_create(interface, &vport->dev, 1); mutex_unlock(&bnx2fc_dev_lock); if (IS_ERR(vn_port)) { @@ -1065,10 +1056,10 @@ static int bnx2fc_vport_disable(struct fc_vport *vport, bool disable) } -static int bnx2fc_netdev_setup(struct bnx2fc_hba *hba) +static int bnx2fc_netdev_setup(struct bnx2fc_interface *interface) { - struct net_device *netdev = hba->netdev; - struct net_device *physdev = hba->phys_dev; + struct net_device *netdev = interface->netdev; + struct net_device *physdev = interface->hba->phys_dev; struct netdev_hw_addr *ha; int sel_san_mac = 0; @@ -1083,7 +1074,8 @@ static int bnx2fc_netdev_setup(struct bnx2fc_hba *hba) if ((ha->type == NETDEV_HW_ADDR_T_SAN) && (is_valid_ether_addr(ha->addr))) { - memcpy(hba->ctlr.ctl_src_addr, ha->addr, ETH_ALEN); + memcpy(interface->ctlr.ctl_src_addr, ha->addr, + ETH_ALEN); sel_san_mac = 1; BNX2FC_MISC_DBG("Found SAN MAC\n"); } @@ -1093,15 +1085,15 @@ static int bnx2fc_netdev_setup(struct bnx2fc_hba *hba) if (!sel_san_mac) return -ENODEV; - hba->fip_packet_type.func = bnx2fc_fip_recv; - hba->fip_packet_type.type = htons(ETH_P_FIP); - hba->fip_packet_type.dev = netdev; - dev_add_pack(&hba->fip_packet_type); + 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); - hba->fcoe_packet_type.func = bnx2fc_rcv; - hba->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE); - hba->fcoe_packet_type.dev = netdev; - dev_add_pack(&hba->fcoe_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; } @@ -1137,53 +1129,54 @@ static void bnx2fc_release_transport(void) static void bnx2fc_interface_release(struct kref *kref) { - struct bnx2fc_hba *hba; + struct bnx2fc_interface *interface; struct net_device *netdev; - struct net_device *phys_dev; - hba = container_of(kref, struct bnx2fc_hba, kref); + interface = container_of(kref, struct bnx2fc_interface, kref); BNX2FC_MISC_DBG("Interface is being released\n"); - netdev = hba->netdev; - phys_dev = hba->phys_dev; + netdev = interface->netdev; /* tear-down FIP controller */ - if (test_and_clear_bit(BNX2FC_CTLR_INIT_DONE, &hba->init_done)) - fcoe_ctlr_destroy(&hba->ctlr); + if (test_and_clear_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags)) + fcoe_ctlr_destroy(&interface->ctlr); + + kfree(interface); - /* Free the command manager */ - if (hba->cmd_mgr) { - bnx2fc_cmd_mgr_free(hba->cmd_mgr); - hba->cmd_mgr = NULL; - } dev_put(netdev); module_put(THIS_MODULE); } -static inline void bnx2fc_interface_get(struct bnx2fc_hba *hba) +static inline void bnx2fc_interface_get(struct bnx2fc_interface *interface) { - kref_get(&hba->kref); + kref_get(&interface->kref); } -static inline void bnx2fc_interface_put(struct bnx2fc_hba *hba) +static inline void bnx2fc_interface_put(struct bnx2fc_interface *interface) { - kref_put(&hba->kref, bnx2fc_interface_release); + kref_put(&interface->kref, bnx2fc_interface_release); } -static void bnx2fc_interface_destroy(struct bnx2fc_hba *hba) +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_interface_create - create a new fcoe instance + * bnx2fc_hba_create - create a new bnx2fc hba * * @cnic: pointer to cnic device * - * Creates a new FCoE instance on the given device which include allocating - * hba structure, scsi_host and lport structures. + * Creates a new FCoE hba on the given device. + * */ -static struct bnx2fc_hba *bnx2fc_interface_create(struct cnic_dev *cnic) +static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) { struct bnx2fc_hba *hba; int rc; @@ -1198,65 +1191,83 @@ static struct bnx2fc_hba *bnx2fc_interface_create(struct cnic_dev *cnic) hba->cnic = cnic; rc = bnx2fc_bind_pcidev(hba); - if (rc) + if (rc) { + printk(KERN_ERR PFX "create_adapter: bind error\n"); goto bind_err; + } hba->phys_dev = cnic->netdev; - /* will get overwritten after we do vlan discovery */ - hba->netdev = hba->phys_dev; + hba->next_conn_id = 0; + + hba->tgt_ofld_list = + kzalloc(sizeof(struct bnx2fc_rport *) * BNX2FC_NUM_MAX_SESS, + 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, BNX2FC_MIN_XID, + BNX2FC_MAX_XID); + if (!hba->cmd_mgr) { + printk(KERN_ERR PFX "em_config:bnx2fc_cmd_mgr_alloc failed\n"); + goto cmgr_err; + } 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: - printk(KERN_ERR PFX "create_interface: bind error\n"); kfree(hba); return NULL; } -static int bnx2fc_interface_setup(struct bnx2fc_hba *hba, - enum fip_state fip_mode) +struct bnx2fc_interface *bnx2fc_interface_create(struct bnx2fc_hba *hba, + struct net_device *netdev, + enum fip_state fip_mode) { + struct bnx2fc_interface *interface; int rc = 0; - struct net_device *netdev = hba->netdev; - struct fcoe_ctlr *fip = &hba->ctlr; + interface = kzalloc(sizeof(*interface), GFP_KERNEL); + if (!interface) { + printk(KERN_ERR PFX "Unable to allocate interface structure\n"); + return NULL; + } dev_hold(netdev); - kref_init(&hba->kref); - - hba->flags = 0; + kref_init(&interface->kref); + interface->hba = hba; + interface->netdev = netdev; /* Initialize FIP */ - memset(fip, 0, sizeof(*fip)); - fcoe_ctlr_init(fip, fip_mode); - hba->ctlr.send = bnx2fc_fip_send; - hba->ctlr.update_mac = bnx2fc_update_src_mac; - hba->ctlr.get_src_addr = bnx2fc_get_src_mac; - set_bit(BNX2FC_CTLR_INIT_DONE, &hba->init_done); - - INIT_LIST_HEAD(&hba->vports); - rc = bnx2fc_netdev_setup(hba); - if (rc) - goto setup_err; + fcoe_ctlr_init(&interface->ctlr, fip_mode); + interface->ctlr.send = bnx2fc_fip_send; + interface->ctlr.update_mac = bnx2fc_update_src_mac; + interface->ctlr.get_src_addr = bnx2fc_get_src_mac; + set_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags); - hba->next_conn_id = 0; + rc = bnx2fc_netdev_setup(interface); + if (!rc) + return interface; - memset(hba->tgt_ofld_list, 0, sizeof(hba->tgt_ofld_list)); - hba->num_ofld_sess = 0; - - return 0; - -setup_err: - fcoe_ctlr_destroy(&hba->ctlr); + fcoe_ctlr_destroy(&interface->ctlr); dev_put(netdev); - bnx2fc_interface_put(hba); - return rc; + kfree(interface); + return NULL; } /** * bnx2fc_if_create - Create FCoE instance on a given interface * - * @hba: FCoE interface to create a local port on + * @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 * @@ -1264,7 +1275,7 @@ setup_err: * * Returns: Allocated fc_lport or an error pointer */ -static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba, +static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, struct device *parent, int npiv) { struct fc_lport *lport, *n_port; @@ -1272,11 +1283,12 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba, struct Scsi_Host *shost; struct fc_vport *vport = dev_to_vport(parent); struct bnx2fc_lport *blport; + struct bnx2fc_hba *hba; int rc = 0; blport = kzalloc(sizeof(struct bnx2fc_lport), GFP_KERNEL); if (!blport) { - BNX2FC_HBA_DBG(hba->ctlr.lp, "Unable to alloc bnx2fc_lport\n"); + BNX2FC_HBA_DBG(interface->ctlr.lp, "Unable to alloc blport\n"); return NULL; } @@ -1293,7 +1305,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba, shost = lport->host; port = lport_priv(lport); port->lport = lport; - port->priv = hba; + port->priv = interface; INIT_WORK(&port->destroy_work, bnx2fc_destroy_work); /* Configure fcoe_port */ @@ -1317,7 +1329,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba, rc = bnx2fc_shost_config(lport, parent); if (rc) { printk(KERN_ERR PFX "Couldnt configure shost for %s\n", - hba->netdev->name); + interface->netdev->name); goto lp_config_err; } @@ -1343,8 +1355,9 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba, goto shost_err; } - bnx2fc_interface_get(hba); + bnx2fc_interface_get(interface); + hba = interface->hba; spin_lock_bh(&hba->hba_lock); blport->lport = lport; list_add_tail(&blport->list, &hba->vports); @@ -1361,21 +1374,19 @@ free_blport: return NULL; } -static void bnx2fc_netdev_cleanup(struct bnx2fc_hba *hba) +static void bnx2fc_netdev_cleanup(struct bnx2fc_interface *interface) { /* Dont listen for Ethernet packets anymore */ - __dev_remove_pack(&hba->fcoe_packet_type); - __dev_remove_pack(&hba->fip_packet_type); + __dev_remove_pack(&interface->fcoe_packet_type); + __dev_remove_pack(&interface->fip_packet_type); synchronize_net(); } -static void bnx2fc_if_destroy(struct fc_lport *lport) +static void bnx2fc_if_destroy(struct fc_lport *lport, struct bnx2fc_hba *hba) { struct fcoe_port *port = lport_priv(lport); - struct bnx2fc_hba *hba = port->priv; struct bnx2fc_lport *blport, *tmp; - BNX2FC_HBA_DBG(hba->ctlr.lp, "ENTERED bnx2fc_if_destroy\n"); /* Stop the transmit retry timer */ del_timer_sync(&port->timer); @@ -1409,8 +1420,6 @@ static void bnx2fc_if_destroy(struct fc_lport *lport) /* Release Scsi_Host */ scsi_host_put(lport->host); - - bnx2fc_interface_put(hba); } /** @@ -1425,46 +1434,31 @@ static void bnx2fc_if_destroy(struct fc_lport *lport) */ static int bnx2fc_destroy(struct net_device *netdev) { - struct bnx2fc_hba *hba = NULL; - struct net_device *phys_dev; + struct bnx2fc_interface *interface = NULL; + struct bnx2fc_hba *hba; + struct fc_lport *lport; int rc = 0; rtnl_lock(); - mutex_lock(&bnx2fc_dev_lock); - /* obtain physical netdev */ - if (netdev->priv_flags & IFF_802_1Q_VLAN) - phys_dev = vlan_dev_real_dev(netdev); - else { - printk(KERN_ERR PFX "Not a vlan device\n"); - rc = -ENODEV; - goto netdev_err; - } - hba = bnx2fc_hba_lookup(phys_dev); - if (!hba || !hba->ctlr.lp) { + interface = bnx2fc_interface_lookup(netdev); + if (!interface || !interface->ctlr.lp) { rc = -ENODEV; - printk(KERN_ERR PFX "bnx2fc_destroy: hba or lport not found\n"); - goto netdev_err; - } - - if (!test_bit(BNX2FC_CREATE_DONE, &hba->init_done)) { - printk(KERN_ERR PFX "bnx2fc_destroy: Create not called\n"); + printk(KERN_ERR PFX "bnx2fc_destroy: interface or lport not found\n"); goto netdev_err; } - bnx2fc_netdev_cleanup(hba); - - bnx2fc_stop(hba); - - bnx2fc_if_destroy(hba->ctlr.lp); + hba = interface->hba; - destroy_workqueue(hba->timer_work_queue); + bnx2fc_netdev_cleanup(interface); + lport = interface->ctlr.lp; + bnx2fc_stop(interface); + list_del(&interface->list); + destroy_workqueue(interface->timer_work_queue); + bnx2fc_interface_put(interface); + bnx2fc_if_destroy(lport, hba); - if (test_bit(BNX2FC_FW_INIT_DONE, &hba->init_done)) - bnx2fc_fw_destroy(hba); - - clear_bit(BNX2FC_CREATE_DONE, &hba->init_done); netdev_err: mutex_unlock(&bnx2fc_dev_lock); rtnl_unlock(); @@ -1475,16 +1469,20 @@ static void bnx2fc_destroy_work(struct work_struct *work) { struct fcoe_port *port; struct fc_lport *lport; + struct bnx2fc_interface *interface; + struct bnx2fc_hba *hba; port = container_of(work, struct fcoe_port, destroy_work); lport = port->lport; + interface = port->priv; + hba = interface->hba; BNX2FC_HBA_DBG(lport, "Entered bnx2fc_destroy_work\n"); bnx2fc_port_shutdown(lport); rtnl_lock(); mutex_lock(&bnx2fc_dev_lock); - bnx2fc_if_destroy(lport); + bnx2fc_if_destroy(lport, hba); mutex_unlock(&bnx2fc_dev_lock); rtnl_unlock(); } @@ -1556,28 +1554,27 @@ static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba) static void bnx2fc_ulp_start(void *handle) { struct bnx2fc_hba *hba = handle; - struct fc_lport *lport = hba->ctlr.lp; + struct bnx2fc_interface *interface; + struct fc_lport *lport; - BNX2FC_MISC_DBG("Entered %s\n", __func__); mutex_lock(&bnx2fc_dev_lock); - if (test_bit(BNX2FC_FW_INIT_DONE, &hba->init_done)) - goto start_disc; - - if (test_bit(BNX2FC_CREATE_DONE, &hba->init_done)) + if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags)) bnx2fc_fw_init(hba); -start_disc: - mutex_unlock(&bnx2fc_dev_lock); - BNX2FC_MISC_DBG("bnx2fc started.\n"); - /* Kick off Fabric discovery*/ - if (test_bit(BNX2FC_CREATE_DONE, &hba->init_done)) { - printk(KERN_ERR PFX "ulp_init: start discovery\n"); - lport->tt.frame_send = bnx2fc_xmit; - bnx2fc_start_disc(hba); + list_for_each_entry(interface, &if_list, list) { + if (interface->hba == hba) { + lport = interface->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) @@ -1587,37 +1584,25 @@ static void bnx2fc_port_shutdown(struct fc_lport *lport) fc_lport_destroy(lport); } -static void bnx2fc_stop(struct bnx2fc_hba *hba) +static void bnx2fc_stop(struct bnx2fc_interface *interface) { struct fc_lport *lport; struct fc_lport *vport; - BNX2FC_MISC_DBG("ENTERED %s - init_done = %ld\n", __func__, - hba->init_done); - if (test_bit(BNX2FC_FW_INIT_DONE, &hba->init_done) && - test_bit(BNX2FC_CREATE_DONE, &hba->init_done)) { - lport = hba->ctlr.lp; - bnx2fc_port_shutdown(lport); - BNX2FC_HBA_DBG(lport, "bnx2fc_stop: waiting for %d " - "offloaded sessions\n", - hba->num_ofld_sess); - wait_event_interruptible(hba->shutdown_wait, - (hba->num_ofld_sess == 0)); - 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(&hba->ctlr); - fcoe_clean_pending_queue(lport); - - mutex_lock(&hba->hba_mutex); - clear_bit(ADAPTER_STATE_UP, &hba->adapter_state); - clear_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state); + if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags)) + return; - clear_bit(ADAPTER_STATE_READY, &hba->adapter_state); - mutex_unlock(&hba->hba_mutex); - } + lport = interface->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(&interface->ctlr); + fcoe_clean_pending_queue(lport); } static int bnx2fc_fw_init(struct bnx2fc_hba *hba) @@ -1656,8 +1641,7 @@ static int bnx2fc_fw_init(struct bnx2fc_hba *hba) } - /* Mark HBA to indicate that the FW INIT is done */ - set_bit(BNX2FC_FW_INIT_DONE, &hba->init_done); + set_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags); return 0; err_unbind: @@ -1668,7 +1652,7 @@ err_out: static void bnx2fc_fw_destroy(struct bnx2fc_hba *hba) { - if (test_and_clear_bit(BNX2FC_FW_INIT_DONE, &hba->init_done)) { + if (test_and_clear_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags)) { if (bnx2fc_send_fw_fcoe_destroy_msg(hba) == 0) { init_timer(&hba->destroy_timer); hba->destroy_timer.expires = BNX2FC_FW_TIMEOUT + @@ -1677,8 +1661,8 @@ static void bnx2fc_fw_destroy(struct bnx2fc_hba *hba) hba->destroy_timer.data = (unsigned long)hba; add_timer(&hba->destroy_timer); wait_event_interruptible(hba->destroy_wait, - (hba->flags & - BNX2FC_FLAG_DESTROY_CMPL)); + test_bit(BNX2FC_FLAG_DESTROY_CMPL, + &hba->flags)); /* This should never happen */ if (signal_pending(current)) flush_signals(current); @@ -1699,40 +1683,57 @@ static void bnx2fc_fw_destroy(struct bnx2fc_hba *hba) */ static void bnx2fc_ulp_stop(void *handle) { - struct bnx2fc_hba *hba = (struct bnx2fc_hba *)handle; + struct bnx2fc_hba *hba = handle; + struct bnx2fc_interface *interface; printk(KERN_ERR "ULP_STOP\n"); mutex_lock(&bnx2fc_dev_lock); - bnx2fc_stop(hba); + 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_hba *hba) +static void bnx2fc_start_disc(struct bnx2fc_interface *interface) { struct fc_lport *lport; int wait_cnt = 0; BNX2FC_MISC_DBG("Entered %s\n", __func__); /* Kick off FIP/FLOGI */ - if (!test_bit(BNX2FC_FW_INIT_DONE, &hba->init_done)) { + if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags)) { printk(KERN_ERR PFX "Init not done yet\n"); return; } - lport = hba->ctlr.lp; + lport = interface->ctlr.lp; BNX2FC_HBA_DBG(lport, "calling fc_fabric_login\n"); if (!bnx2fc_link_ok(lport)) { BNX2FC_HBA_DBG(lport, "ctlr_link_up\n"); - fcoe_ctlr_link_up(&hba->ctlr); + fcoe_ctlr_link_up(&interface->ctlr); fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; - set_bit(ADAPTER_STATE_READY, &hba->adapter_state); + set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state); } /* wait for the FCF to be selected before issuing FLOGI */ - while (!hba->ctlr.sel_fcf) { + while (!interface->ctlr.sel_fcf) { msleep(250); /* give up after 3 secs */ if (++wait_cnt > 12) @@ -1758,15 +1759,15 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev) BNX2FC_MISC_DBG("Entered %s\n", __func__); /* bnx2fc works only when bnx2x is loaded */ - if (!test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { + 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\n", - dev->netdev->name, dev->flags); + " flags: %lx fcoe_conn: %d\n", + dev->netdev->name, dev->flags, dev->max_fcoe_conn); return; } - /* Configure FCoE interface */ - hba = bnx2fc_interface_create(dev); + hba = bnx2fc_hba_create(dev); if (!hba) { printk(KERN_ERR PFX "hba initialization failed\n"); return; @@ -1774,7 +1775,7 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev) /* Add HBA to the adapter list */ mutex_lock(&bnx2fc_dev_lock); - list_add_tail(&hba->link, &adapter_list); + list_add_tail(&hba->list, &adapter_list); adapter_count++; mutex_unlock(&bnx2fc_dev_lock); @@ -1790,52 +1791,21 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev) static int bnx2fc_disable(struct net_device *netdev) { - struct bnx2fc_hba *hba; - struct net_device *phys_dev; - struct ethtool_drvinfo drvinfo; + struct bnx2fc_interface *interface; int rc = 0; rtnl_lock(); - mutex_lock(&bnx2fc_dev_lock); - /* obtain physical netdev */ - if (netdev->priv_flags & IFF_802_1Q_VLAN) - phys_dev = vlan_dev_real_dev(netdev); - else { - printk(KERN_ERR PFX "Not a vlan device\n"); - rc = -ENODEV; - goto nodev; - } - - /* 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 (strcmp(drvinfo.driver, "bnx2x")) { - printk(KERN_ERR PFX "Not a netxtreme2 device\n"); - rc = -ENODEV; - goto nodev; - } - } else { - printk(KERN_ERR PFX "unable to obtain drv_info\n"); - rc = -ENODEV; - goto nodev; - } - - printk(KERN_ERR PFX "phys_dev is netxtreme2 device\n"); - - /* obtain hba and initialize rest of the structure */ - hba = bnx2fc_hba_lookup(phys_dev); - if (!hba || !hba->ctlr.lp) { + interface = bnx2fc_interface_lookup(netdev); + if (!interface || !interface->ctlr.lp) { rc = -ENODEV; - printk(KERN_ERR PFX "bnx2fc_disable: hba or lport not found\n"); + printk(KERN_ERR PFX "bnx2fc_disable: interface or lport not found\n"); } else { - fcoe_ctlr_link_down(&hba->ctlr); - fcoe_clean_pending_queue(hba->ctlr.lp); + fcoe_ctlr_link_down(&interface->ctlr); + fcoe_clean_pending_queue(interface->ctlr.lp); } -nodev: mutex_unlock(&bnx2fc_dev_lock); rtnl_unlock(); return rc; @@ -1844,48 +1814,19 @@ nodev: static int bnx2fc_enable(struct net_device *netdev) { - struct bnx2fc_hba *hba; - struct net_device *phys_dev; - struct ethtool_drvinfo drvinfo; + struct bnx2fc_interface *interface; int rc = 0; rtnl_lock(); - - BNX2FC_MISC_DBG("Entered %s\n", __func__); mutex_lock(&bnx2fc_dev_lock); - /* obtain physical netdev */ - if (netdev->priv_flags & IFF_802_1Q_VLAN) - phys_dev = vlan_dev_real_dev(netdev); - else { - printk(KERN_ERR PFX "Not a vlan device\n"); - rc = -ENODEV; - goto nodev; - } - /* 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 (strcmp(drvinfo.driver, "bnx2x")) { - printk(KERN_ERR PFX "Not a netxtreme2 device\n"); - rc = -ENODEV; - goto nodev; - } - } else { - printk(KERN_ERR PFX "unable to obtain drv_info\n"); + interface = bnx2fc_interface_lookup(netdev); + if (!interface || !interface->ctlr.lp) { rc = -ENODEV; - goto nodev; - } - - /* obtain hba and initialize rest of the structure */ - hba = bnx2fc_hba_lookup(phys_dev); - if (!hba || !hba->ctlr.lp) { - rc = -ENODEV; - printk(KERN_ERR PFX "bnx2fc_enable: hba or lport not found\n"); - } else if (!bnx2fc_link_ok(hba->ctlr.lp)) - fcoe_ctlr_link_up(&hba->ctlr); + printk(KERN_ERR PFX "bnx2fc_enable: interface or lport not found\n"); + } else if (!bnx2fc_link_ok(interface->ctlr.lp)) + fcoe_ctlr_link_up(&interface->ctlr); -nodev: mutex_unlock(&bnx2fc_dev_lock); rtnl_unlock(); return rc; @@ -1903,6 +1844,7 @@ nodev: */ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) { + struct bnx2fc_interface *interface; struct bnx2fc_hba *hba; struct net_device *phys_dev; struct fc_lport *lport; @@ -1938,7 +1880,7 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) 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 (strcmp(drvinfo.driver, "bnx2x")) { + if (strncmp(drvinfo.driver, "bnx2x", strlen("bnx2x"))) { printk(KERN_ERR PFX "Not a netxtreme2 device\n"); rc = -EINVAL; goto netdev_err; @@ -1949,7 +1891,7 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) goto netdev_err; } - /* obtain hba and initialize rest of the structure */ + /* obtain interface and initialize rest of the structure */ hba = bnx2fc_hba_lookup(phys_dev); if (!hba) { rc = -ENODEV; @@ -1957,67 +1899,61 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) goto netdev_err; } - if (!test_bit(BNX2FC_FW_INIT_DONE, &hba->init_done)) { - rc = bnx2fc_fw_init(hba); - if (rc) - goto netdev_err; - } - - if (test_bit(BNX2FC_CREATE_DONE, &hba->init_done)) { + if (bnx2fc_interface_lookup(netdev)) { rc = -EEXIST; goto netdev_err; } - /* update netdev with vlan netdev */ - hba->netdev = netdev; - hba->vlan_id = vlan_id; - hba->vlan_enabled = 1; - - rc = bnx2fc_interface_setup(hba, fip_mode); - if (rc) { - printk(KERN_ERR PFX "bnx2fc_interface_setup failed\n"); + interface = bnx2fc_interface_create(hba, netdev, fip_mode); + if (!interface) { + printk(KERN_ERR PFX "bnx2fc_interface_create failed\n"); goto ifput_err; } - hba->timer_work_queue = + interface->vlan_id = vlan_id; + interface->vlan_enabled = 1; + + interface->timer_work_queue = create_singlethread_workqueue("bnx2fc_timer_wq"); - if (!hba->timer_work_queue) { + 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(hba, &hba->pcidev->dev, 0); + lport = bnx2fc_if_create(interface, &interface->hba->pcidev->dev, 0); if (!lport) { printk(KERN_ERR PFX "Failed to create interface (%s)\n", netdev->name); - bnx2fc_netdev_cleanup(hba); + bnx2fc_netdev_cleanup(interface); 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 */ - hba->ctlr.lp = lport; + interface->ctlr.lp = lport; - set_bit(BNX2FC_CREATE_DONE, &hba->init_done); - printk(KERN_ERR PFX "create: START DISC\n"); - bnx2fc_start_disc(hba); + BNX2FC_HBA_DBG(lport, "create: START DISC\n"); + bnx2fc_start_disc(interface); /* * Release from kref_init in bnx2fc_interface_setup, on success * lport should be holding a reference taken in bnx2fc_if_create */ - bnx2fc_interface_put(hba); + 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(hba->timer_work_queue); + destroy_workqueue(interface->timer_work_queue); ifput_err: - bnx2fc_interface_put(hba); + bnx2fc_interface_put(interface); netdev_err: module_put(THIS_MODULE); mod_err: @@ -2027,7 +1963,7 @@ mod_err: } /** - * bnx2fc_find_hba_for_cnic - maps cnic instance to bnx2fc adapter instance + * bnx2fc_find_hba_for_cnic - maps cnic instance to bnx2fc hba instance * * @cnic: Pointer to cnic device instance * @@ -2047,19 +1983,30 @@ static struct bnx2fc_hba *bnx2fc_find_hba_for_cnic(struct cnic_dev *cnic) return NULL; } -static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device *phys_dev) +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 list_head *list; - struct list_head *temp; struct bnx2fc_hba *hba; /* Called with bnx2fc_dev_lock held */ - list_for_each_safe(list, temp, &adapter_list) { - hba = (struct bnx2fc_hba *)list; + list_for_each_entry(hba, &adapter_list, list) { if (hba->phys_dev == phys_dev) return hba; } - printk(KERN_ERR PFX "hba_lookup: hba NULL\n"); + printk(KERN_ERR PFX "adapter_lookup: hba NULL\n"); return NULL; } @@ -2071,6 +2018,8 @@ static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device *phys_dev) static void bnx2fc_ulp_exit(struct cnic_dev *dev) { struct bnx2fc_hba *hba; + struct bnx2fc_interface *interface, *tmp; + struct fc_lport *lport; BNX2FC_MISC_DBG("Entered bnx2fc_ulp_exit\n"); @@ -2089,13 +2038,20 @@ static void bnx2fc_ulp_exit(struct cnic_dev *dev) return; } - list_del_init(&hba->link); + list_del_init(&hba->list); adapter_count--; - if (test_bit(BNX2FC_CREATE_DONE, &hba->init_done)) { + list_for_each_entry_safe(interface, tmp, &if_list, list) { /* destroy not called yet, move to quiesced list */ - bnx2fc_netdev_cleanup(hba); - bnx2fc_if_destroy(hba->ctlr.lp); + if (interface->hba == hba) { + bnx2fc_netdev_cleanup(interface); + bnx2fc_stop(interface); + + list_del(&interface->list); + lport = interface->ctlr.lp; + bnx2fc_interface_put(interface); + bnx2fc_if_destroy(lport, hba); + } } mutex_unlock(&bnx2fc_dev_lock); @@ -2103,7 +2059,7 @@ static void bnx2fc_ulp_exit(struct cnic_dev *dev) /* 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_interface_destroy(hba); + bnx2fc_hba_destroy(hba); } /** @@ -2259,6 +2215,7 @@ static int __init bnx2fc_mod_init(void) } INIT_LIST_HEAD(&adapter_list); + INIT_LIST_HEAD(&if_list); mutex_init(&bnx2fc_dev_lock); adapter_count = 0; @@ -2336,16 +2293,17 @@ static void __exit bnx2fc_mod_exit(void) mutex_unlock(&bnx2fc_dev_lock); /* Unregister with cnic */ - list_for_each_entry_safe(hba, next, &to_be_deleted, link) { - list_del_init(&hba->link); - printk(KERN_ERR PFX "MOD_EXIT:destroy hba = 0x%p, kref = %d\n", - hba, atomic_read(&hba->kref.refcount)); + 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_interface_destroy(hba); + hba->cnic->unregister_device(hba->cnic, + CNIC_ULP_FCOE); + bnx2fc_hba_destroy(hba); } cnic_unregister_driver(CNIC_ULP_FCOE); diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c index b41deb64aff1..ee1674b794b1 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c @@ -23,7 +23,7 @@ static void bnx2fc_process_enable_conn_cmpl(struct bnx2fc_hba *hba, struct fcoe_kcqe *ofld_kcqe); static void bnx2fc_init_failure(struct bnx2fc_hba *hba, u32 err_code); static void bnx2fc_process_conn_destroy_cmpl(struct bnx2fc_hba *hba, - struct fcoe_kcqe *conn_destroy); + struct fcoe_kcqe *destroy_kcqe); int bnx2fc_send_stat_req(struct bnx2fc_hba *hba) { @@ -67,7 +67,7 @@ int bnx2fc_send_fw_fcoe_init_msg(struct bnx2fc_hba *hba) int rc = 0; if (!hba->cnic) { - printk(KERN_ALERT PFX "hba->cnic NULL during fcoe fw init\n"); + printk(KERN_ERR PFX "hba->cnic NULL during fcoe fw init\n"); return -ENODEV; } @@ -103,6 +103,7 @@ int bnx2fc_send_fw_fcoe_init_msg(struct bnx2fc_hba *hba) fcoe_init2.hsi_major_version = FCOE_HSI_MAJOR_VERSION; fcoe_init2.hsi_minor_version = FCOE_HSI_MINOR_VERSION; + fcoe_init2.hash_tbl_pbl_addr_lo = (u32) hba->hash_tbl_pbl_dma; fcoe_init2.hash_tbl_pbl_addr_hi = (u32) ((u64) hba->hash_tbl_pbl_dma >> 32); @@ -165,7 +166,8 @@ int bnx2fc_send_session_ofld_req(struct fcoe_port *port, struct bnx2fc_rport *tgt) { struct fc_lport *lport = port->lport; - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; struct kwqe *kwqe_arr[4]; struct fcoe_kwqe_conn_offload1 ofld_req1; struct fcoe_kwqe_conn_offload2 ofld_req2; @@ -227,7 +229,7 @@ int bnx2fc_send_session_ofld_req(struct fcoe_port *port, ofld_req3.hdr.flags = (FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT); - ofld_req3.vlan_tag = hba->vlan_id << + ofld_req3.vlan_tag = interface->vlan_id << FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT; ofld_req3.vlan_tag |= 3 << FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT; @@ -278,7 +280,7 @@ int bnx2fc_send_session_ofld_req(struct fcoe_port *port, FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT_SHIFT); /* vlan flag */ - ofld_req3.flags |= (hba->vlan_enabled << + ofld_req3.flags |= (interface->vlan_enabled << FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT); /* C2_VALID and ACK flags are not set as they are not suppported */ @@ -300,12 +302,13 @@ int bnx2fc_send_session_ofld_req(struct fcoe_port *port, ofld_req4.src_mac_addr_mid[1] = port->data_src_addr[2]; ofld_req4.src_mac_addr_hi[0] = port->data_src_addr[1]; ofld_req4.src_mac_addr_hi[1] = port->data_src_addr[0]; - ofld_req4.dst_mac_addr_lo[0] = hba->ctlr.dest_addr[5];/* fcf mac */ - ofld_req4.dst_mac_addr_lo[1] = hba->ctlr.dest_addr[4]; - ofld_req4.dst_mac_addr_mid[0] = hba->ctlr.dest_addr[3]; - ofld_req4.dst_mac_addr_mid[1] = hba->ctlr.dest_addr[2]; - ofld_req4.dst_mac_addr_hi[0] = hba->ctlr.dest_addr[1]; - ofld_req4.dst_mac_addr_hi[1] = hba->ctlr.dest_addr[0]; + ofld_req4.dst_mac_addr_lo[0] = interface->ctlr.dest_addr[5]; + /* fcf mac */ + ofld_req4.dst_mac_addr_lo[1] = interface->ctlr.dest_addr[4]; + ofld_req4.dst_mac_addr_mid[0] = interface->ctlr.dest_addr[3]; + ofld_req4.dst_mac_addr_mid[1] = interface->ctlr.dest_addr[2]; + ofld_req4.dst_mac_addr_hi[0] = interface->ctlr.dest_addr[1]; + ofld_req4.dst_mac_addr_hi[1] = interface->ctlr.dest_addr[0]; ofld_req4.lcq_addr_lo = (u32) tgt->lcq_dma; ofld_req4.lcq_addr_hi = (u32)((u64) tgt->lcq_dma >> 32); @@ -335,7 +338,8 @@ static int bnx2fc_send_session_enable_req(struct fcoe_port *port, struct bnx2fc_rport *tgt) { struct kwqe *kwqe_arr[2]; - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; struct fcoe_kwqe_conn_enable_disable enbl_req; struct fc_lport *lport = port->lport; struct fc_rport *rport = tgt->rport; @@ -358,12 +362,12 @@ static int bnx2fc_send_session_enable_req(struct fcoe_port *port, enbl_req.src_mac_addr_hi[1] = port->data_src_addr[0]; memcpy(tgt->src_addr, port->data_src_addr, ETH_ALEN); - enbl_req.dst_mac_addr_lo[0] = hba->ctlr.dest_addr[5];/* fcf mac */ - enbl_req.dst_mac_addr_lo[1] = hba->ctlr.dest_addr[4]; - enbl_req.dst_mac_addr_mid[0] = hba->ctlr.dest_addr[3]; - enbl_req.dst_mac_addr_mid[1] = hba->ctlr.dest_addr[2]; - enbl_req.dst_mac_addr_hi[0] = hba->ctlr.dest_addr[1]; - enbl_req.dst_mac_addr_hi[1] = hba->ctlr.dest_addr[0]; + enbl_req.dst_mac_addr_lo[0] = interface->ctlr.dest_addr[5]; + enbl_req.dst_mac_addr_lo[1] = interface->ctlr.dest_addr[4]; + enbl_req.dst_mac_addr_mid[0] = interface->ctlr.dest_addr[3]; + enbl_req.dst_mac_addr_mid[1] = interface->ctlr.dest_addr[2]; + enbl_req.dst_mac_addr_hi[0] = interface->ctlr.dest_addr[1]; + enbl_req.dst_mac_addr_hi[1] = interface->ctlr.dest_addr[0]; port_id = fc_host_port_id(lport->host); if (port_id != tgt->sid) { @@ -379,10 +383,10 @@ static int bnx2fc_send_session_enable_req(struct fcoe_port *port, enbl_req.d_id[0] = (port_id & 0x000000FF); enbl_req.d_id[1] = (port_id & 0x0000FF00) >> 8; enbl_req.d_id[2] = (port_id & 0x00FF0000) >> 16; - enbl_req.vlan_tag = hba->vlan_id << + enbl_req.vlan_tag = interface->vlan_id << FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT; enbl_req.vlan_tag |= 3 << FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT; - enbl_req.vlan_flag = hba->vlan_enabled; + enbl_req.vlan_flag = interface->vlan_enabled; enbl_req.context_id = tgt->context_id; enbl_req.conn_id = tgt->fcoe_conn_id; @@ -402,7 +406,8 @@ static int bnx2fc_send_session_enable_req(struct fcoe_port *port, int bnx2fc_send_session_disable_req(struct fcoe_port *port, struct bnx2fc_rport *tgt) { - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; struct fcoe_kwqe_conn_enable_disable disable_req; struct kwqe *kwqe_arr[2]; struct fc_rport *rport = tgt->rport; @@ -423,12 +428,12 @@ int bnx2fc_send_session_disable_req(struct fcoe_port *port, disable_req.src_mac_addr_hi[0] = tgt->src_addr[1]; disable_req.src_mac_addr_hi[1] = tgt->src_addr[0]; - disable_req.dst_mac_addr_lo[0] = hba->ctlr.dest_addr[5];/* fcf mac */ - disable_req.dst_mac_addr_lo[1] = hba->ctlr.dest_addr[4]; - disable_req.dst_mac_addr_mid[0] = hba->ctlr.dest_addr[3]; - disable_req.dst_mac_addr_mid[1] = hba->ctlr.dest_addr[2]; - disable_req.dst_mac_addr_hi[0] = hba->ctlr.dest_addr[1]; - disable_req.dst_mac_addr_hi[1] = hba->ctlr.dest_addr[0]; + disable_req.dst_mac_addr_lo[0] = interface->ctlr.dest_addr[5]; + disable_req.dst_mac_addr_lo[1] = interface->ctlr.dest_addr[4]; + disable_req.dst_mac_addr_mid[0] = interface->ctlr.dest_addr[3]; + disable_req.dst_mac_addr_mid[1] = interface->ctlr.dest_addr[2]; + disable_req.dst_mac_addr_hi[0] = interface->ctlr.dest_addr[1]; + disable_req.dst_mac_addr_hi[1] = interface->ctlr.dest_addr[0]; port_id = tgt->sid; disable_req.s_id[0] = (port_id & 0x000000FF); @@ -442,11 +447,11 @@ int bnx2fc_send_session_disable_req(struct fcoe_port *port, disable_req.d_id[2] = (port_id & 0x00FF0000) >> 16; disable_req.context_id = tgt->context_id; disable_req.conn_id = tgt->fcoe_conn_id; - disable_req.vlan_tag = hba->vlan_id << + disable_req.vlan_tag = interface->vlan_id << FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT; disable_req.vlan_tag |= 3 << FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT; - disable_req.vlan_flag = hba->vlan_enabled; + disable_req.vlan_flag = interface->vlan_enabled; kwqe_arr[0] = (struct kwqe *) &disable_req; @@ -525,7 +530,7 @@ void bnx2fc_process_l2_frame_compl(struct bnx2fc_rport *tgt, { struct fcoe_port *port = tgt->port; struct fc_lport *lport = port->lport; - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; struct bnx2fc_unsol_els *unsol_els; struct fc_frame_header *fh; struct fc_frame *fp; @@ -586,7 +591,7 @@ void bnx2fc_process_l2_frame_compl(struct bnx2fc_rport *tgt, fr_eof(fp) = FC_EOF_T; fr_crc(fp) = cpu_to_le32(~crc); unsol_els->lport = lport; - unsol_els->hba = hba; + unsol_els->hba = interface->hba; unsol_els->fp = fp; INIT_WORK(&unsol_els->unsol_els_work, bnx2fc_unsol_els_work); queue_work(bnx2fc_wq, &unsol_els->unsol_els_work); @@ -608,7 +613,8 @@ static void bnx2fc_process_unsol_compl(struct bnx2fc_rport *tgt, u16 wqe) u32 frame_len, len; struct bnx2fc_cmd *io_req = NULL; struct fcoe_task_ctx_entry *task, *task_page; - struct bnx2fc_hba *hba = tgt->port->priv; + struct bnx2fc_interface *interface = tgt->port->priv; + struct bnx2fc_hba *hba = interface->hba; int task_idx, index; int rc = 0; @@ -685,7 +691,7 @@ static void bnx2fc_process_unsol_compl(struct bnx2fc_rport *tgt, u16 wqe) task_idx = xid / BNX2FC_TASKS_PER_PAGE; index = xid % BNX2FC_TASKS_PER_PAGE; task_page = (struct fcoe_task_ctx_entry *) - hba->task_ctx[task_idx]; + hba->task_ctx[task_idx]; task = &(task_page[index]); io_req = (struct bnx2fc_cmd *)hba->cmd_mgr->cmds[xid]; @@ -770,7 +776,8 @@ void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe) struct fcoe_task_ctx_entry *task; struct fcoe_task_ctx_entry *task_page; struct fcoe_port *port = tgt->port; - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; struct bnx2fc_cmd *io_req; int task_idx, index; u16 xid; @@ -1004,6 +1011,7 @@ static void bnx2fc_process_ofld_cmpl(struct bnx2fc_hba *hba, { struct bnx2fc_rport *tgt; struct fcoe_port *port; + struct bnx2fc_interface *interface; u32 conn_id; u32 context_id; int rc; @@ -1012,14 +1020,15 @@ static void bnx2fc_process_ofld_cmpl(struct bnx2fc_hba *hba, context_id = ofld_kcqe->fcoe_conn_context_id; tgt = hba->tgt_ofld_list[conn_id]; if (!tgt) { - printk(KERN_ERR PFX "ERROR:ofld_cmpl: No pending ofld req\n"); + printk(KERN_ALERT PFX "ERROR:ofld_cmpl: No pending ofld req\n"); return; } BNX2FC_TGT_DBG(tgt, "Entered ofld compl - context_id = 0x%x\n", ofld_kcqe->fcoe_conn_context_id); port = tgt->port; - if (hba != tgt->port->priv) { - printk(KERN_ALERT PFX "ERROR:ofld_cmpl: HBA mis-match\n"); + interface = tgt->port->priv; + if (hba != interface->hba) { + printk(KERN_ERR PFX "ERROR:ofld_cmpl: HBA mis-match\n"); goto ofld_cmpl_err; } /* @@ -1063,6 +1072,7 @@ static void bnx2fc_process_enable_conn_cmpl(struct bnx2fc_hba *hba, struct fcoe_kcqe *ofld_kcqe) { struct bnx2fc_rport *tgt; + struct bnx2fc_interface *interface; u32 conn_id; u32 context_id; @@ -1085,13 +1095,14 @@ static void bnx2fc_process_enable_conn_cmpl(struct bnx2fc_hba *hba, printk(KERN_ERR PFX "context id mis-match\n"); return; } - if (hba != tgt->port->priv) { - printk(KERN_ALERT PFX "bnx2fc-enbl_cmpl: HBA mis-match\n"); + interface = tgt->port->priv; + if (hba != interface->hba) { + printk(KERN_ERR PFX "bnx2fc-enbl_cmpl: HBA mis-match\n"); goto enbl_cmpl_err; } - if (ofld_kcqe->completion_status) { + if (ofld_kcqe->completion_status) goto enbl_cmpl_err; - } else { + else { /* enable successful - rport ready for issuing IOs */ set_bit(BNX2FC_FLAG_OFFLOADED, &tgt->flags); set_bit(BNX2FC_FLAG_OFLD_REQ_CMPL, &tgt->flags); @@ -1241,7 +1252,7 @@ void bnx2fc_indicate_kcqe(void *context, struct kcqe *kcq[], } else { printk(KERN_ERR PFX "DESTROY success\n"); } - hba->flags |= BNX2FC_FLAG_DESTROY_CMPL; + set_bit(BNX2FC_FLAG_DESTROY_CMPL, &hba->flags); wake_up_interruptible(&hba->destroy_wait); break; @@ -1306,7 +1317,8 @@ int bnx2fc_map_doorbell(struct bnx2fc_rport *tgt) struct fcoe_port *port = tgt->port; u32 reg_off; resource_size_t reg_base; - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; reg_base = pci_resource_start(hba->pcidev, BNX2X_DOORBELL_PCI_BAR); diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 8f988c2e6717..e711ea3dd900 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -29,10 +29,11 @@ static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, void bnx2fc_cmd_timer_set(struct bnx2fc_cmd *io_req, unsigned int timer_msec) { - struct bnx2fc_hba *hba = io_req->port->priv; + struct bnx2fc_interface *interface = io_req->port->priv; - if (queue_delayed_work(hba->timer_work_queue, &io_req->timeout_work, - msecs_to_jiffies(timer_msec))) + if (queue_delayed_work(interface->timer_work_queue, + &io_req->timeout_work, + msecs_to_jiffies(timer_msec))) kref_get(&io_req->refcount); } @@ -419,8 +420,8 @@ free_cmgr: struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type) { struct fcoe_port *port = tgt->port; - struct bnx2fc_hba *hba = port->priv; - struct bnx2fc_cmd_mgr *cmd_mgr = hba->cmd_mgr; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_cmd_mgr *cmd_mgr = interface->hba->cmd_mgr; struct bnx2fc_cmd *io_req; struct list_head *listp; struct io_bdt *bd_tbl; @@ -485,11 +486,12 @@ struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type) kref_init(&io_req->refcount); return io_req; } -static struct bnx2fc_cmd *bnx2fc_cmd_alloc(struct bnx2fc_rport *tgt) + +struct bnx2fc_cmd *bnx2fc_cmd_alloc(struct bnx2fc_rport *tgt) { struct fcoe_port *port = tgt->port; - struct bnx2fc_hba *hba = port->priv; - struct bnx2fc_cmd_mgr *cmd_mgr = hba->cmd_mgr; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_cmd_mgr *cmd_mgr = interface->hba->cmd_mgr; struct bnx2fc_cmd *io_req; struct list_head *listp; struct io_bdt *bd_tbl; @@ -570,7 +572,8 @@ void bnx2fc_cmd_release(struct kref *ref) static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req) { struct bnx2fc_mp_req *mp_req = &(io_req->mp_req); - struct bnx2fc_hba *hba = io_req->port->priv; + struct bnx2fc_interface *interface = io_req->port->priv; + struct bnx2fc_hba *hba = interface->hba; size_t sz = sizeof(struct fcoe_bd_ctx); /* clear tm flags */ @@ -606,7 +609,8 @@ int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req) struct bnx2fc_mp_req *mp_req; struct fcoe_bd_ctx *mp_req_bd; struct fcoe_bd_ctx *mp_resp_bd; - struct bnx2fc_hba *hba = io_req->port->priv; + struct bnx2fc_interface *interface = io_req->port->priv; + struct bnx2fc_hba *hba = interface->hba; dma_addr_t addr; size_t sz; @@ -682,7 +686,7 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device)); struct fc_rport_libfc_priv *rp = rport->dd_data; struct fcoe_port *port; - struct bnx2fc_hba *hba; + struct bnx2fc_interface *interface; struct bnx2fc_rport *tgt; struct bnx2fc_cmd *io_req; struct bnx2fc_mp_req *tm_req; @@ -699,7 +703,7 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) lport = shost_priv(host); port = lport_priv(lport); - hba = port->priv; + interface = port->priv; if (rport == NULL) { printk(KERN_ERR PFX "device_reset: rport is NULL\n"); @@ -774,7 +778,8 @@ retry_tmf: index = xid % BNX2FC_TASKS_PER_PAGE; /* Initialize task context for this IO request */ - task_page = (struct fcoe_task_ctx_entry *) hba->task_ctx[task_idx]; + task_page = (struct fcoe_task_ctx_entry *) + interface->hba->task_ctx[task_idx]; task = &(task_page[index]); bnx2fc_init_mp_task(io_req, task); @@ -822,7 +827,7 @@ int bnx2fc_initiate_abts(struct bnx2fc_cmd *io_req) struct bnx2fc_rport *tgt = io_req->tgt; struct fc_rport *rport = tgt->rport; struct fc_rport_priv *rdata = tgt->rdata; - struct bnx2fc_hba *hba; + struct bnx2fc_interface *interface; struct fcoe_port *port; struct bnx2fc_cmd *abts_io_req; struct fcoe_task_ctx_entry *task; @@ -839,7 +844,7 @@ int bnx2fc_initiate_abts(struct bnx2fc_cmd *io_req) BNX2FC_IO_DBG(io_req, "Entered bnx2fc_initiate_abts\n"); port = io_req->port; - hba = port->priv; + interface = port->priv; lport = port->lport; if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) { @@ -896,7 +901,8 @@ int bnx2fc_initiate_abts(struct bnx2fc_cmd *io_req) index = xid % BNX2FC_TASKS_PER_PAGE; /* Initialize task context for this IO request */ - task_page = (struct fcoe_task_ctx_entry *) hba->task_ctx[task_idx]; + task_page = (struct fcoe_task_ctx_entry *) + interface->hba->task_ctx[task_idx]; task = &(task_page[index]); bnx2fc_init_mp_task(abts_io_req, task); @@ -928,7 +934,7 @@ int bnx2fc_initiate_cleanup(struct bnx2fc_cmd *io_req) { struct fc_lport *lport; struct bnx2fc_rport *tgt = io_req->tgt; - struct bnx2fc_hba *hba; + struct bnx2fc_interface *interface; struct fcoe_port *port; struct bnx2fc_cmd *cleanup_io_req; struct fcoe_task_ctx_entry *task; @@ -941,7 +947,7 @@ int bnx2fc_initiate_cleanup(struct bnx2fc_cmd *io_req) BNX2FC_IO_DBG(io_req, "Entered bnx2fc_initiate_cleanup\n"); port = io_req->port; - hba = port->priv; + interface = port->priv; lport = port->lport; cleanup_io_req = bnx2fc_elstm_alloc(tgt, BNX2FC_CLEANUP); @@ -963,7 +969,8 @@ int bnx2fc_initiate_cleanup(struct bnx2fc_cmd *io_req) index = xid % BNX2FC_TASKS_PER_PAGE; /* Initialize task context for this IO request */ - task_page = (struct fcoe_task_ctx_entry *) hba->task_ctx[task_idx]; + task_page = (struct fcoe_task_ctx_entry *) + interface->hba->task_ctx[task_idx]; task = &(task_page[index]); orig_xid = io_req->xid; @@ -1796,7 +1803,8 @@ static int bnx2fc_post_io_req(struct bnx2fc_rport *tgt, struct fcoe_task_ctx_entry *task_page; struct scsi_cmnd *sc_cmd = io_req->sc_cmd; struct fcoe_port *port = tgt->port; - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; struct fc_lport *lport = port->lport; struct fcoe_dev_stats *stats; int task_idx, index; diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c index 4be391edd0c6..263c2678ff62 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c @@ -65,7 +65,8 @@ static void bnx2fc_offload_session(struct fcoe_port *port, { struct fc_lport *lport = rdata->local_port; struct fc_rport *rport = rdata->rport; - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; int rval; int i = 0; @@ -237,7 +238,8 @@ void bnx2fc_flush_active_ios(struct bnx2fc_rport *tgt) static void bnx2fc_upload_session(struct fcoe_port *port, struct bnx2fc_rport *tgt) { - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; BNX2FC_TGT_DBG(tgt, "upload_session: active_ios = %d\n", tgt->num_active_ios.counter); @@ -316,7 +318,8 @@ static int bnx2fc_init_tgt(struct bnx2fc_rport *tgt, { struct fc_rport *rport = rdata->rport; - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; struct b577xx_doorbell_set_prod *sq_db = &tgt->sq_db; struct b577xx_fcoe_rx_doorbell *rx_db = &tgt->rx_db; @@ -392,7 +395,8 @@ void bnx2fc_rport_event_handler(struct fc_lport *lport, enum fc_rport_event event) { struct fcoe_port *port = lport_priv(lport); - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; struct fc_rport *rport = rdata->rport; struct fc_rport_libfc_priv *rp; struct bnx2fc_rport *tgt; @@ -537,7 +541,8 @@ void bnx2fc_rport_event_handler(struct fc_lport *lport, struct bnx2fc_rport *bnx2fc_tgt_lookup(struct fcoe_port *port, u32 port_id) { - struct bnx2fc_hba *hba = port->priv; + struct bnx2fc_interface *interface = port->priv; + struct bnx2fc_hba *hba = interface->hba; struct bnx2fc_rport *tgt; struct fc_rport_priv *rdata; int i; @@ -552,7 +557,7 @@ struct bnx2fc_rport *bnx2fc_tgt_lookup(struct fcoe_port *port, "obtained\n"); return tgt; } else { - printk(KERN_ERR PFX "rport 0x%x " + BNX2FC_TGT_DBG(tgt, "rport 0x%x " "is in DELETED state\n", rdata->ids.port_id); return NULL; |