Commit aea71a02 authored by Bhanu Prakash Gollapudi's avatar Bhanu Prakash Gollapudi Committed by James Bottomley

[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: default avatarBhanu Prakash Gollapudi <bprakash@broadcom.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent f6e76055
......@@ -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;
......
......@@ -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) {
......
......@@ -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 @@ static int bnx2fc_interface_setup(struct bnx2fc_hba *hba,
*
* 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 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba,
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 @@ static int bnx2fc_fw_init(struct bnx2fc_hba *hba)
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 @@ static int bnx2fc_disable(struct net_device *netdev)
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 @@ static int bnx2fc_enable(struct net_device *netdev)
*/
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 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
}
/**
* 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);
......
......@@ -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);
......
......@@ -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 @@ void bnx2fc_cmd_mgr_free(struct bnx2fc_cmd_mgr *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 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
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;
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment