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

Commit 435c8667 authored by Robert Love's avatar Robert Love
Browse files

fcoe: Use the fcoe_sysfs control interface



This patch adds support for the new fcoe_sysfs
control interface to fcoe.ko. It keeps the deprecated
interface in tact and therefore either the legacy
or the new control interfaces can be used. A mixed mode
is not supported. A user must either use the new
interfaces or the old ones, but not both.

The fcoe_ctlr's link state is now driven by both the
netdev link state as well as the fcoe_ctlr_device's
enabled attribute. The link must be up and the
fcoe_ctlr_device must be enabled before the FCoE
Controller starts discovery or login.

Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
Acked-by: default avatarNeil Horman <nhorman@tuxdriver.com>
parent 6a891b07
Loading
Loading
Loading
Loading
+132 −15
Original line number Original line Diff line number Diff line
@@ -117,6 +117,11 @@ static int fcoe_destroy(struct net_device *netdev);
static int fcoe_enable(struct net_device *netdev);
static int fcoe_enable(struct net_device *netdev);
static int fcoe_disable(struct net_device *netdev);
static int fcoe_disable(struct net_device *netdev);


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


static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
				      u32 did, struct fc_frame *,
				      u32 did, struct fc_frame *,
				      unsigned int op,
				      unsigned int op,
@@ -155,6 +160,8 @@ static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *);
static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *);
static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *);


static struct fcoe_sysfs_function_template fcoe_sysfs_templ = {
static struct fcoe_sysfs_function_template fcoe_sysfs_templ = {
	.set_fcoe_ctlr_mode = fcoe_ctlr_set_fip_mode,
	.set_fcoe_ctlr_enabled = fcoe_ctlr_enabled,
	.get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
	.get_fcoe_ctlr_vlink_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_miss_fka = fcoe_ctlr_get_lesb,
@@ -1963,6 +1970,7 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier,
static int fcoe_device_notification(struct notifier_block *notifier,
static int fcoe_device_notification(struct notifier_block *notifier,
				    ulong event, void *ptr)
				    ulong event, void *ptr)
{
{
	struct fcoe_ctlr_device *cdev;
	struct fc_lport *lport = NULL;
	struct fc_lport *lport = NULL;
	struct net_device *netdev = ptr;
	struct net_device *netdev = ptr;
	struct fcoe_ctlr *ctlr;
	struct fcoe_ctlr *ctlr;
@@ -2019,13 +2027,29 @@ static int fcoe_device_notification(struct notifier_block *notifier,


	fcoe_link_speed_update(lport);
	fcoe_link_speed_update(lport);


	if (link_possible && !fcoe_link_ok(lport))
	cdev = fcoe_ctlr_to_ctlr_dev(ctlr);

	if (link_possible && !fcoe_link_ok(lport)) {
		switch (cdev->enabled) {
		case FCOE_CTLR_DISABLED:
			pr_info("Link up while interface is disabled.\n");
			break;
		case FCOE_CTLR_ENABLED:
		case FCOE_CTLR_UNUSED:
			fcoe_ctlr_link_up(ctlr);
			fcoe_ctlr_link_up(ctlr);
	else if (fcoe_ctlr_link_down(ctlr)) {
		};
	} else if (fcoe_ctlr_link_down(ctlr)) {
		switch (cdev->enabled) {
		case FCOE_CTLR_DISABLED:
			pr_info("Link down while interface is disabled.\n");
			break;
		case FCOE_CTLR_ENABLED:
		case FCOE_CTLR_UNUSED:
			stats = per_cpu_ptr(lport->stats, get_cpu());
			stats = per_cpu_ptr(lport->stats, get_cpu());
			stats->LinkFailureCount++;
			stats->LinkFailureCount++;
			put_cpu();
			put_cpu();
			fcoe_clean_pending_queue(lport);
			fcoe_clean_pending_queue(lport);
		};
	}
	}
out:
out:
	return rc;
	return rc;
@@ -2038,6 +2062,8 @@ static int fcoe_device_notification(struct notifier_block *notifier,
 * Called from fcoe transport.
 * Called from fcoe transport.
 *
 *
 * Returns: 0 for success
 * Returns: 0 for success
 *
 * Deprecated: use fcoe_ctlr_enabled()
 */
 */
static int fcoe_disable(struct net_device *netdev)
static int fcoe_disable(struct net_device *netdev)
{
{
@@ -2096,6 +2122,33 @@ static int fcoe_enable(struct net_device *netdev)
	return rc;
	return rc;
}
}


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

	switch (cdev->enabled) {
	case FCOE_CTLR_ENABLED:
		return fcoe_enable(netdev);
	case FCOE_CTLR_DISABLED:
		return fcoe_disable(netdev);
	case FCOE_CTLR_UNUSED:
	default:
		return -ENOTSUPP;
	};
}

/**
/**
 * fcoe_destroy() - Destroy a FCoE interface
 * fcoe_destroy() - Destroy a FCoE interface
 * @netdev  : The net_device object the Ethernet interface to create on
 * @netdev  : The net_device object the Ethernet interface to create on
@@ -2203,16 +2256,26 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
#endif
#endif
}
}


enum fcoe_create_link_state {
	FCOE_CREATE_LINK_DOWN,
	FCOE_CREATE_LINK_UP,
};

/**
/**
 * fcoe_create() - Create a fcoe interface
 * _fcoe_create() - (internal) Create a fcoe interface
 * @netdev  :   The net_device object the Ethernet interface to create on
 * @netdev  :   The net_device object the Ethernet interface to create on
 * @fip_mode:   The FIP mode for this creation
 * @fip_mode:   The FIP mode for this creation
 * @link_state: The ctlr link state on creation
 *
 *
 * Called from fcoe transport
 * Called from either the libfcoe 'create' module parameter
 * via fcoe_create or from fcoe_syfs's ctlr_create file.
 *
 *
 * Returns: 0 for success
 * libfcoe's 'create' module parameter is deprecated so some
 * consolidation of code can be done when that interface is
 * removed.
 */
 */
static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode,
			enum fcoe_create_link_state link_state)
{
{
	int rc = 0;
	int rc = 0;
	struct fcoe_ctlr_device *ctlr_dev;
	struct fcoe_ctlr_device *ctlr_dev;
@@ -2259,7 +2322,26 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
	/* start FIP Discovery and FLOGI */
	/* start FIP Discovery and FLOGI */
	lport->boot_time = jiffies;
	lport->boot_time = jiffies;
	fc_fabric_login(lport);
	fc_fabric_login(lport);
	if (!fcoe_link_ok(lport)) {

	/*
	 * If the fcoe_ctlr_device is to be set to DISABLED
	 * it must be done after the lport is added to the
	 * hostlist, but before the rtnl_lock is released.
	 * This is because the rtnl_lock protects the
	 * hostlist that fcoe_device_notification uses. If
	 * the FCoE Controller is intended to be created
	 * DISABLED then 'enabled' needs to be considered
	 * handling link events. 'enabled' must be set
	 * before the lport can be found in the hostlist
	 * when a link up event is received.
	 */
	if (link_state == FCOE_CREATE_LINK_UP)
		ctlr_dev->enabled = FCOE_CTLR_ENABLED;
	else
		ctlr_dev->enabled = FCOE_CTLR_DISABLED;

	if (link_state == FCOE_CREATE_LINK_UP &&
	    !fcoe_link_ok(lport)) {
		rtnl_unlock();
		rtnl_unlock();
		fcoe_ctlr_link_up(ctlr);
		fcoe_ctlr_link_up(ctlr);
		mutex_unlock(&fcoe_config_mutex);
		mutex_unlock(&fcoe_config_mutex);
@@ -2273,6 +2355,37 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
	return rc;
	return rc;
}
}


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

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

/**
/**
 * fcoe_link_speed_update() - Update the supported and actual link speeds
 * fcoe_link_speed_update() - Update the supported and actual link speeds
 * @lport: The local port to update speeds for
 * @lport: The local port to update speeds for
@@ -2374,10 +2487,13 @@ static int fcoe_reset(struct Scsi_Host *shost)
	struct fcoe_port *port = lport_priv(lport);
	struct fcoe_port *port = lport_priv(lport);
	struct fcoe_interface *fcoe = port->priv;
	struct fcoe_interface *fcoe = port->priv;
	struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
	struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
	struct fcoe_ctlr_device *cdev = fcoe_ctlr_to_ctlr_dev(ctlr);


	fcoe_ctlr_link_down(ctlr);
	fcoe_ctlr_link_down(ctlr);
	fcoe_clean_pending_queue(ctlr->lp);
	fcoe_clean_pending_queue(ctlr->lp);
	if (!fcoe_link_ok(ctlr->lp))

	if (cdev->enabled != FCOE_CTLR_DISABLED &&
	    !fcoe_link_ok(ctlr->lp))
		fcoe_ctlr_link_up(ctlr);
		fcoe_ctlr_link_up(ctlr);
	return 0;
	return 0;
}
}
@@ -2450,6 +2566,7 @@ static struct fcoe_transport fcoe_sw_transport = {
	.attached = false,
	.attached = false,
	.list = LIST_HEAD_INIT(fcoe_sw_transport.list),
	.list = LIST_HEAD_INIT(fcoe_sw_transport.list),
	.match = fcoe_match,
	.match = fcoe_match,
	.alloc = fcoe_ctlr_alloc,
	.create = fcoe_create,
	.create = fcoe_create,
	.destroy = fcoe_destroy,
	.destroy = fcoe_destroy,
	.enable = fcoe_enable,
	.enable = fcoe_enable,
+8 −9
Original line number Original line Diff line number Diff line
@@ -2864,22 +2864,21 @@ void fcoe_fcf_get_selected(struct fcoe_fcf_device *fcf_dev)
}
}
EXPORT_SYMBOL(fcoe_fcf_get_selected);
EXPORT_SYMBOL(fcoe_fcf_get_selected);


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


	mutex_lock(&ctlr->ctlr_mutex);
	mutex_lock(&ctlr->ctlr_mutex);
	switch (ctlr->mode) {
	switch (ctlr_dev->mode) {
	case FIP_MODE_FABRIC:
	case FIP_CONN_TYPE_VN2VN:
		ctlr_dev->mode = FIP_CONN_TYPE_FABRIC;
		ctlr->mode = FIP_MODE_VN2VN;
		break;
	case FIP_MODE_VN2VN:
		ctlr_dev->mode = FIP_CONN_TYPE_VN2VN;
		break;
		break;
	case FIP_CONN_TYPE_FABRIC:
	default:
	default:
		ctlr_dev->mode = FIP_CONN_TYPE_UNKNOWN;
		ctlr->mode = FIP_MODE_FABRIC;
		break;
		break;
	}
	}

	mutex_unlock(&ctlr->ctlr_mutex);
	mutex_unlock(&ctlr->ctlr_mutex);
}
}
EXPORT_SYMBOL(fcoe_ctlr_get_fip_mode);
EXPORT_SYMBOL(fcoe_ctlr_set_fip_mode);