Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d55e507 authored by Robert Love's avatar Robert Love Committed by James Bottomley
Browse files

[SCSI] fcoe, bnx2fc, libfcoe: SW FCoE and bnx2fc use FCoE Syfs



This patch has the SW FCoE driver and the bnx2fc
driver make use of the new fcoe_sysfs API added
earlier in this patch series.

After this patch a fcoe_ctlr_device is allocated with
private data in this order.

+------------------+   +------------------+
| fcoe_ctlr_device |   | fcoe_ctlr_device |
+------------------+   +------------------+
| fcoe_ctlr        |   | fcoe_ctlr        |
+------------------+   +------------------+
| fcoe_interface   |   | bnx2fc_interface |
+------------------+   +------------------+

libfcoe also takes part in this new model since it
discovers and manages fcoe_fcf instances. The memory
allocation is different for FCFs. I didn't want to
impact libfcoe's fcoe_fcf processing, so this patch
creates fcoe_fcf_device instances for each discovered
fcoe_fcf. The two are paired using a (void * priv)
member of the fcoe_ctlr_device. This allows libfcoe
to continue maintaining its list of fcoe_fcf instances
and simply attaches and detaches them from existing
or new fcoe_fcf_device instances.

Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
Tested-by: default avatarRoss Brattain <ross.b.brattain@intel.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 9a74e884
Loading
Loading
Loading
Loading
+59 −4
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ static struct cnic_ulp_ops bnx2fc_cnic_cb;
static struct libfc_function_template bnx2fc_libfc_fcn_templ;
static struct scsi_host_template bnx2fc_shost_template;
static struct fc_function_template bnx2fc_transport_function;
static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ;
static struct fc_function_template bnx2fc_vport_xport_function;
static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode);
static void __bnx2fc_destroy(struct bnx2fc_interface *interface);
@@ -88,6 +89,7 @@ static void bnx2fc_port_shutdown(struct fc_lport *lport);
static void bnx2fc_stop(struct bnx2fc_interface *interface);
static int __init bnx2fc_mod_init(void);
static void __exit bnx2fc_mod_exit(void);
static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev);

unsigned int bnx2fc_debug_level;
module_param_named(debug_logging, bnx2fc_debug_level, int, S_IRUGO|S_IWUSR);
@@ -118,6 +120,41 @@ static void bnx2fc_get_lesb(struct fc_lport *lport,
	__fcoe_get_lesb(lport, fc_lesb, netdev);
}

static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
{
	struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
	struct net_device *netdev = bnx2fc_netdev(fip->lp);
	struct fcoe_fc_els_lesb *fcoe_lesb;
	struct fc_els_lesb fc_lesb;

	__fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
	fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);

	ctlr_dev->lesb.lesb_link_fail =
		ntohl(fcoe_lesb->lesb_link_fail);
	ctlr_dev->lesb.lesb_vlink_fail =
		ntohl(fcoe_lesb->lesb_vlink_fail);
	ctlr_dev->lesb.lesb_miss_fka =
		ntohl(fcoe_lesb->lesb_miss_fka);
	ctlr_dev->lesb.lesb_symb_err =
		ntohl(fcoe_lesb->lesb_symb_err);
	ctlr_dev->lesb.lesb_err_block =
		ntohl(fcoe_lesb->lesb_err_block);
	ctlr_dev->lesb.lesb_fcs_error =
		ntohl(fcoe_lesb->lesb_fcs_error);
}
EXPORT_SYMBOL(bnx2fc_ctlr_get_lesb);

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

	fcf_dev->vlan_id = fcoe->vlan_id;
}

static void bnx2fc_clean_rx_queue(struct fc_lport *lp)
{
	struct fcoe_percpu_s *bg;
@@ -1235,6 +1272,7 @@ static void bnx2fc_release_transport(void)

static void bnx2fc_interface_release(struct kref *kref)
{
	struct fcoe_ctlr_device *ctlr_dev;
	struct bnx2fc_interface *interface;
	struct fcoe_ctlr *ctlr;
	struct net_device *netdev;
@@ -1243,13 +1281,14 @@ static void bnx2fc_interface_release(struct kref *kref)
	BNX2FC_MISC_DBG("Interface is being released\n");

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

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

	kfree(ctlr);
	fcoe_ctlr_device_delete(ctlr_dev);

	dev_put(netdev);
	module_put(THIS_MODULE);
@@ -1342,17 +1381,20 @@ struct bnx2fc_interface *bnx2fc_interface_create(struct bnx2fc_hba *hba,
				      struct net_device *netdev,
				      enum fip_state fip_mode)
{
	struct fcoe_ctlr_device *ctlr_dev;
	struct bnx2fc_interface *interface;
	struct fcoe_ctlr *ctlr;
	int size;
	int rc = 0;

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

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

@@ -2471,6 +2513,19 @@ static void __exit bnx2fc_mod_exit(void)
module_init(bnx2fc_mod_init);
module_exit(bnx2fc_mod_exit);

static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = {
	.get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode,
	.get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb,
	.get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb,
	.get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb,
	.get_fcoe_ctlr_symb_err = bnx2fc_ctlr_get_lesb,
	.get_fcoe_ctlr_err_block = bnx2fc_ctlr_get_lesb,
	.get_fcoe_ctlr_fcs_error = bnx2fc_ctlr_get_lesb,

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

static struct fc_function_template bnx2fc_transport_function = {
	.show_host_node_name = 1,
	.show_host_port_name = 1,
+64 −7
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@

#include <scsi/fc/fc_encaps.h>
#include <scsi/fc/fc_fip.h>
#include <scsi/fc/fc_fcoe.h>

#include <scsi/libfc.h>
#include <scsi/fc_frame.h>
@@ -150,6 +151,21 @@ static int fcoe_vport_create(struct fc_vport *, bool disabled);
static int fcoe_vport_disable(struct fc_vport *, bool disable);
static void fcoe_set_vport_symbolic_name(struct fc_vport *);
static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *);
static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *);
static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *);

static struct fcoe_sysfs_function_template fcoe_sysfs_templ = {
	.get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode,
	.get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb,

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

static struct libfc_function_template fcoe_libfc_fcn_templ = {
	.frame_send = fcoe_xmit,
@@ -366,6 +382,7 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe,
static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
						    enum fip_state fip_mode)
{
	struct fcoe_ctlr_device *ctlr_dev;
	struct fcoe_ctlr *ctlr;
	struct fcoe_interface *fcoe;
	int size;
@@ -379,14 +396,17 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
	}

	size = sizeof(struct fcoe_ctlr) + sizeof(struct fcoe_interface);
	ctlr = kzalloc(size, GFP_KERNEL);
	fcoe = fcoe_ctlr_priv(ctlr);
	if (!fcoe) {
		FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n");
	ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &fcoe_sysfs_templ,
					size);
	if (!ctlr_dev) {
		FCOE_DBG("Failed to add fcoe_ctlr_device\n");
		fcoe = ERR_PTR(-ENOMEM);
		goto out_putmod;
	}

	ctlr = fcoe_ctlr_device_priv(ctlr_dev);
	fcoe = fcoe_ctlr_priv(ctlr);

	dev_hold(netdev);

	/*
@@ -400,6 +420,7 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
	err = fcoe_interface_setup(fcoe, netdev);
	if (err) {
		fcoe_ctlr_destroy(ctlr);
		fcoe_ctlr_device_delete(ctlr_dev);
		dev_put(netdev);
		fcoe = ERR_PTR(err);
		goto out_putmod;
@@ -466,6 +487,7 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
{
	struct net_device *netdev = fcoe->netdev;
	struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
	struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);

	rtnl_lock();
	if (!fcoe->removed)
@@ -476,7 +498,7 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
	/* tear-down the FCoE controller */
	fcoe_ctlr_destroy(fip);
	scsi_host_put(fip->lp->host);
	kfree(fip);
	fcoe_ctlr_device_delete(ctlr_dev);
	dev_put(netdev);
	module_put(THIS_MODULE);
}
@@ -2196,6 +2218,7 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
{
	int rc = 0;
	struct fcoe_ctlr_device *ctlr_dev;
	struct fcoe_ctlr *ctlr;
	struct fcoe_interface *fcoe;
	struct fc_lport *lport;
@@ -2216,8 +2239,8 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
	}

	ctlr = fcoe_to_ctlr(fcoe);

	lport = fcoe_if_create(fcoe, &netdev->dev, 0);
	ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr);
	lport = fcoe_if_create(fcoe, &ctlr_dev->dev, 0);
	if (IS_ERR(lport)) {
		printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
		       netdev->name);
@@ -2768,6 +2791,40 @@ static void fcoe_get_lesb(struct fc_lport *lport,
	__fcoe_get_lesb(lport, fc_lesb, netdev);
}

static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
{
	struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
	struct net_device *netdev = fcoe_netdev(fip->lp);
	struct fcoe_fc_els_lesb *fcoe_lesb;
	struct fc_els_lesb fc_lesb;

	__fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
	fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);

	ctlr_dev->lesb.lesb_link_fail =
		ntohl(fcoe_lesb->lesb_link_fail);
	ctlr_dev->lesb.lesb_vlink_fail =
		ntohl(fcoe_lesb->lesb_vlink_fail);
	ctlr_dev->lesb.lesb_miss_fka =
		ntohl(fcoe_lesb->lesb_miss_fka);
	ctlr_dev->lesb.lesb_symb_err =
		ntohl(fcoe_lesb->lesb_symb_err);
	ctlr_dev->lesb.lesb_err_block =
		ntohl(fcoe_lesb->lesb_err_block);
	ctlr_dev->lesb.lesb_fcs_error =
		ntohl(fcoe_lesb->lesb_fcs_error);
}

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

	fcf_dev->vlan_id = vlan_dev_vlan_id(fcoe->netdev);
}

/**
 * fcoe_set_port_id() - Callback from libfc when Port_ID is set.
 * @lport: the local port
+145 −14
Original line number Diff line number Diff line
@@ -160,6 +160,76 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_state mode)
}
EXPORT_SYMBOL(fcoe_ctlr_init);

static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new)
{
	struct fcoe_ctlr *fip = new->fip;
	struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);
	struct fcoe_fcf_device temp, *fcf_dev;
	int rc = 0;

	LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n",
			new->fabric_name, new->fcf_mac);

	mutex_lock(&ctlr_dev->lock);

	temp.fabric_name = new->fabric_name;
	temp.switch_name = new->switch_name;
	temp.fc_map = new->fc_map;
	temp.vfid = new->vfid;
	memcpy(temp.mac, new->fcf_mac, ETH_ALEN);
	temp.priority = new->pri;
	temp.fka_period = new->fka_period;
	temp.selected = 0; /* default to unselected */

	fcf_dev = fcoe_fcf_device_add(ctlr_dev, &temp);
	if (unlikely(!fcf_dev)) {
		rc = -ENOMEM;
		goto out;
	}

	/*
	 * The fcoe_sysfs layer can return a CONNECTED fcf that
	 * has a priv (fcf was never deleted) or a CONNECTED fcf
	 * that doesn't have a priv (fcf was deleted). However,
	 * libfcoe will always delete FCFs before trying to add
	 * them. This is ensured because both recv_adv and
	 * age_fcfs are protected by the the fcoe_ctlr's mutex.
	 * This means that we should never get a FCF with a
	 * non-NULL priv pointer.
	 */
	BUG_ON(fcf_dev->priv);

	fcf_dev->priv = new;
	new->fcf_dev = fcf_dev;

	list_add(&new->list, &fip->fcfs);
	fip->fcf_count++;

out:
	mutex_unlock(&ctlr_dev->lock);
	return rc;
}

static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new)
{
	struct fcoe_ctlr *fip = new->fip;
	struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);
	struct fcoe_fcf_device *fcf_dev;

	list_del(&new->list);
	fip->fcf_count--;

	mutex_lock(&ctlr_dev->lock);

	fcf_dev = fcoe_fcf_to_fcf_dev(new);
	WARN_ON(!fcf_dev);
	new->fcf_dev = NULL;
	fcoe_fcf_device_delete(fcf_dev);
	kfree(new);

	mutex_unlock(&ctlr_dev->lock);
}

/**
 * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller
 * @fip: The FCoE controller whose FCFs are to be reset
@@ -173,10 +243,10 @@ static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip)

	fip->sel_fcf = NULL;
	list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
		list_del(&fcf->list);
		kfree(fcf);
		fcoe_sysfs_fcf_del(fcf);
	}
	fip->fcf_count = 0;
	WARN_ON(fip->fcf_count);

	fip->sel_time = 0;
}

@@ -717,8 +787,11 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
	unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
	unsigned long deadline;
	unsigned long sel_time = 0;
	struct list_head del_list;
	struct fcoe_dev_stats *stats;

	INIT_LIST_HEAD(&del_list);

	stats = per_cpu_ptr(fip->lp->dev_stats, get_cpu());

	list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
@@ -739,10 +812,13 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
		if (time_after_eq(jiffies, deadline)) {
			if (fip->sel_fcf == fcf)
				fip->sel_fcf = NULL;
			/*
			 * Move to delete list so we can call
			 * fcoe_sysfs_fcf_del (which can sleep)
			 * after the put_cpu().
			 */
			list_del(&fcf->list);
			WARN_ON(!fip->fcf_count);
			fip->fcf_count--;
			kfree(fcf);
			list_add(&fcf->list, &del_list);
			stats->VLinkFailureCount++;
		} else {
			if (time_after(next_timer, deadline))
@@ -753,6 +829,12 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
		}
	}
	put_cpu();

	list_for_each_entry_safe(fcf, next, &del_list, list) {
		/* Removes fcf from current list */
		fcoe_sysfs_fcf_del(fcf);
	}

	if (sel_time && !fip->sel_fcf && !fip->sel_time) {
		sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY);
		fip->sel_time = sel_time;
@@ -903,23 +985,23 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
	struct fcoe_fcf *fcf;
	struct fcoe_fcf new;
	struct fcoe_fcf *found;
	unsigned long sol_tov = msecs_to_jiffies(FCOE_CTRL_SOL_TOV);
	int first = 0;
	int mtu_valid;
	int found = 0;
	int rc = 0;

	if (fcoe_ctlr_parse_adv(fip, skb, &new))
		return;

	mutex_lock(&fip->ctlr_mutex);
	first = list_empty(&fip->fcfs);
	found = NULL;
	list_for_each_entry(fcf, &fip->fcfs, list) {
		if (fcf->switch_name == new.switch_name &&
		    fcf->fabric_name == new.fabric_name &&
		    fcf->fc_map == new.fc_map &&
		    compare_ether_addr(fcf->fcf_mac, new.fcf_mac) == 0) {
			found = fcf;
			found = 1;
			break;
		}
	}
@@ -931,9 +1013,16 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
		if (!fcf)
			goto out;

		fip->fcf_count++;
		memcpy(fcf, &new, sizeof(new));
		list_add(&fcf->list, &fip->fcfs);
		fcf->fip = fip;
		rc = fcoe_sysfs_fcf_add(fcf);
		if (rc) {
			printk(KERN_ERR "Failed to allocate sysfs instance "
			       "for FCF, fab %16.16llx mac %pM\n",
			       new.fabric_name, new.fcf_mac);
			kfree(fcf);
			goto out;
		}
	} else {
		/*
		 * Update the FCF's keep-alive descriptor flags.
@@ -954,6 +1043,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
		fcf->fka_period = new.fka_period;
		memcpy(fcf->fcf_mac, new.fcf_mac, ETH_ALEN);
	}

	mtu_valid = fcoe_ctlr_mtu_valid(fcf);
	fcf->time = jiffies;
	if (!found)
@@ -996,6 +1086,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
		    time_before(fip->sel_time, fip->timer.expires))
			mod_timer(&fip->timer, fip->sel_time);
	}

out:
	mutex_unlock(&fip->ctlr_mutex);
}
@@ -2718,7 +2809,7 @@ static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *fip)

/**
 * fcoe_libfc_config() - Sets up libfc related properties for local port
 * @lp: The local port to configure libfc for
 * @lport:    The local port to configure libfc for
 * @fip:      The FCoE controller in use by the local port
 * @tt:       The libfc function template
 * @init_fcp: If non-zero, the FCP portion of libfc should be initialized
@@ -2753,3 +2844,43 @@ int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip,
	return 0;
}
EXPORT_SYMBOL_GPL(fcoe_libfc_config);

void fcoe_fcf_get_selected(struct fcoe_fcf_device *fcf_dev)
{
	struct fcoe_ctlr_device *ctlr_dev = fcoe_fcf_dev_to_ctlr_dev(fcf_dev);
	struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
	struct fcoe_fcf *fcf;

	mutex_lock(&fip->ctlr_mutex);
	mutex_lock(&ctlr_dev->lock);

	fcf = fcoe_fcf_device_priv(fcf_dev);
	if (fcf)
		fcf_dev->selected = (fcf == fip->sel_fcf) ? 1 : 0;
	else
		fcf_dev->selected = 0;

	mutex_unlock(&ctlr_dev->lock);
	mutex_unlock(&fip->ctlr_mutex);
}
EXPORT_SYMBOL(fcoe_fcf_get_selected);

void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *ctlr_dev)
{
	struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);

	mutex_lock(&ctlr->ctlr_mutex);
	switch (ctlr->mode) {
	case FIP_MODE_FABRIC:
		ctlr_dev->mode = FIP_CONN_TYPE_FABRIC;
		break;
	case FIP_MODE_VN2VN:
		ctlr_dev->mode = FIP_CONN_TYPE_VN2VN;
		break;
	default:
		ctlr_dev->mode = FIP_CONN_TYPE_UNKNOWN;
		break;
	}
	mutex_unlock(&ctlr->ctlr_mutex);
}
EXPORT_SYMBOL(fcoe_ctlr_get_fip_mode);
+17 −0
Original line number Diff line number Diff line
@@ -168,9 +168,16 @@ static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr)
	return (void *)(ctlr + 1);
}

#define fcoe_ctlr_to_ctlr_dev(x)					\
	(struct fcoe_ctlr_device *)(((struct fcoe_ctlr_device *)(x)) - 1)

/**
 * struct fcoe_fcf - Fibre-Channel Forwarder
 * @list:	 list linkage
 * @event_work:  Work for FC Transport actions queue
 * @event:       The event to be processed
 * @fip:         The controller that the FCF was discovered on
 * @fcf_dev:     The associated fcoe_fcf_device instance
 * @time:	 system time (jiffies) when an advertisement was last received
 * @switch_name: WWN of switch from advertisement
 * @fabric_name: WWN of fabric from advertisement
@@ -192,6 +199,9 @@ static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr)
 */
struct fcoe_fcf {
	struct list_head list;
	struct work_struct event_work;
	struct fcoe_ctlr *fip;
	struct fcoe_fcf_device *fcf_dev;
	unsigned long time;

	u64 switch_name;
@@ -208,6 +218,9 @@ struct fcoe_fcf {
	u8 fd_flags:1;
};

#define fcoe_fcf_to_fcf_dev(x)			\
	((x)->fcf_dev)

/**
 * struct fcoe_rport - VN2VN remote port
 * @time:	time of create or last beacon packet received from node
@@ -343,6 +356,10 @@ void fcoe_queue_timer(ulong lport);
int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen,
			   struct fcoe_percpu_s *fps);

/* FCoE Sysfs helpers */
void fcoe_fcf_get_selected(struct fcoe_fcf_device *);
void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *);

/**
 * struct netdev_list
 * A mapping from netdevice to fcoe_transport