Skip to contentSkip to conversation

libfc, libfcoe and fcoe updates for 3.8

PATCH In review Robert Love 4 participants 23 messages Dec 12, 2012 – Dec 17, 2012

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover libfc, libfcoe and fcoe updates for 3.8

There are two primary changes within this update. Additionally there are two or three fix/cleanup patches.

The first change is the addition of the fcoe_sysfs "control" interfaces. These patches were well vetted on the scsi mailing list and have only seen validation and a minor fix or two, as the result testing, since the last RFC posting.

The second change is a cleanup/consolidation series from Yi that touches libfcoe.ko, fcoe.ko and bnx2fc.ko. These patches were well vetted on the fcoe mailing list and should be good to go as well. They make no functional change.

I will compose a pull-request and send it soon, but I wanted to make sure the most recent versions of these patches were posted to linux-scsi first.

---

Al Viro (1):
debris left by "[SCSI] libfcoe: Remove mutex_trylock/restart_syscall checks"

Robert Love (7):
Documentation: Add missing devices/ to devices path
libfcoe: Save some memory and optimize name lookups
libfcoe: Add fcoe_sysfs debug logging level libfcoe, fcoe, bnx2fc: Add new fcoe control interface
fcoe: Use the fcoe_sysfs control interface
bnx2fc: Use the fcoe_sysfs control interface libfc, libfcoe, fcoe: Convert debug_logging macros to pr_info

Vasu Dev (1):
libfc: fix REC handling

Yi Zou (7):
fcoe: prep work to start consolidate the usage of fcoe_netdev
fcoe: add support to the get_netdev() for fcoe_interface libfcoe, fcoe: move fcoe_link_speed_update() to libfcoe and export it libfcoe, fcoe: consolidate the fcoe_ctlr_get_lesb/fcoe_get_lesb
bnx2fc: add support to get_netdev for bnx2f_interface
bnx2fc: use fcoe_link_speed_update() from the exported symbol in libfcoe
bnx2fc: use fcoe_get_lesb/fcoe_ctlr_get_lesb() directly from libfcoe

 Documentation/ABI/testing/sysfs-bus-fcoe |   45 +++++
 drivers/scsi/bnx2fc/bnx2fc_fcoe.c        |  256 +++++++++++++++++-------------
 drivers/scsi/fcoe/fcoe.c                 |  212 +++++++++++++++----------
 drivers/scsi/fcoe/fcoe.h                 |    6 -
 drivers/scsi/fcoe/fcoe_ctlr.c            |   17 +-
 drivers/scsi/fcoe/fcoe_sysfs.c           |  186 ++++++++++++++++++----
 drivers/scsi/fcoe/fcoe_transport.c       |  199 +++++++++++++++++++++++
 drivers/scsi/fcoe/libfcoe.h              |   20 +-
 drivers/scsi/libfc/fc_fcp.c              |    6 -
 drivers/scsi/libfc/fc_libfc.h            |   38 ++--
 include/scsi/fcoe_sysfs.h                |   11 +
 include/scsi/libfcoe.h                   |   32 ++++
 12 files changed, 749 insertions(+), 279 deletions(-)
Signature · 1 line
Thanks, //Rob
#1 lore raw

PATCH 1/16 libfc: fix REC handling

From: Vasu Dev <[email protected]>

Currently fc_fcp_timeout doesn't check FC_RP_FLAGS_REC_SUPPORTED flag first, this prevents REC request ever going out at all to the target having REC support. So this patches fixes the fc_fcp_timeout by checking FC_RP_FLAGS_REC_SUPPORTED flag first.

The changed order won't cause any issue during clearing FC_RP_FLAGS_REC_SUPPORTED on failed IO with target not supporting FC_RP_FLAGS_REC_SUPPORTED, since retry on failed IO would succeed.

---
 drivers/scsi/libfc/fc_fcp.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/scsi/libfc/fc_fcp.c +3 -3
index fcb9d0b..09c81b2 100644
@@ -1381,10 +1381,10 @@ static void fc_fcp_timeout(unsigned long data)
 
 	fsp->state |= FC_SRB_FCP_PROCESSING_TMO;
 
-	if (fsp->state & FC_SRB_RCV_STATUS)
-		fc_fcp_complete_locked(fsp);
-	else if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
+	if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
 		fc_fcp_rec(fsp);
+	else if (fsp->state & FC_SRB_RCV_STATUS)
+		fc_fcp_complete_locked(fsp);
 	else
 		fc_fcp_recovery(fsp, FC_TIMED_OUT);
 	fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO;
#2 lore raw

PATCH 2/16 Documentation: Add missing devices/ to devices path

In reply to Robert Love

Add missing 'devices/ subdirectory to /sys/bus/fcoe/devices/ctlr_X and /sys/bus/fcoe/devices/fcf_X references.

---
 Documentation/ABI/testing/sysfs-bus-fcoe |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
Documentation/ABI/testing/sysfs-bus-fcoe +2 -2
index 50e2a80..971dc22 100644
@@ -1,4 +1,4 @@
-What:		/sys/bus/fcoe/ctlr_X
+What:		/sys/bus/fcoe/devices/ctlr_X
 Date:		March 2012
 KernelVersion:	TBD
 Contact:	Robert Love <[email protected]>, [email protected]
@@ -26,7 +26,7 @@ Attributes:
 
 Notes: ctlr_X (global increment starting at 0)
 
-What:		/sys/bus/fcoe/fcf_X
+What:		/sys/bus/fcoe/devices/fcf_X
 Date:		March 2012
 KernelVersion:	TBD
 Contact:	Robert Love <[email protected]>, [email protected]
#3 lore raw

PATCH 3/16 libfcoe: Save some memory and optimize name lookups

In reply to Robert Love

Instead of creating a structure with an enum and a pointer to a string, simply allocate an array of strings and use the enum values for the indicies.

This means that we do not need to iterate through the list of entries when looking up a string name by its enum key.

This will also help with a latter patch that will add more fcoe_sysfs attributes that will also use the fcoe_enum_name_search macro. One attribute will also do a reverse lookup which requires less code when the enum-to-string mappings are organized as this patch makes them to be.

---
 drivers/scsi/fcoe/fcoe_sysfs.c |   44 +++++++++++++++-------------------------
 1 file changed, 16 insertions(+), 28 deletions(-)
drivers/scsi/fcoe/fcoe_sysfs.c +16 -28
index 5e75168..5a74a47 100644
@@ -210,25 +210,23 @@ static ssize_t show_fcoe_fcf_device_##field(struct device *dev,	\
 #define fcoe_enum_name_search(title, table_type, table)			\
 static const char *get_fcoe_##title##_name(enum table_type table_key)	\
 {									\
-	int i;								\
-	char *name = NULL;						\
-									\
-	for (i = 0; i < ARRAY_SIZE(table); i++) {			\
-		if (table[i].value == table_key) {			\
-			name = table[i].name;				\
-			break;						\
-		}							\
-	}								\
-	return name;							\
+	if (table_key >= ARRAY_SIZE(table))				\
+		return NULL;						\
+	return table[table_key];					\
 }
 
-static struct {
-	enum fcf_state value;
-	char           *name;
-} fcf_state_names[] = {
-	{ FCOE_FCF_STATE_UNKNOWN,      "Unknown" },
-	{ FCOE_FCF_STATE_DISCONNECTED, "Disconnected" },
-	{ FCOE_FCF_STATE_CONNECTED,    "Connected" },
+static char *fip_conn_type_names[] = {
+	[ FIP_CONN_TYPE_UNKNOWN ] = "Unknown",
+        [ FIP_CONN_TYPE_FABRIC ]  = "Fabric",
+	[ FIP_CONN_TYPE_VN2VN ]   = "VN2VN",
+};
+fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
+#define FCOE_CTLR_MODE_MAX_NAMELEN 50
+
+static char *fcf_state_names[] = {
+	[ FCOE_FCF_STATE_UNKNOWN ]      = "Unknown",
+	[ FCOE_FCF_STATE_DISCONNECTED ] = "Disconnected",
+	[ FCOE_FCF_STATE_CONNECTED ]    = "Connected",
 };
 fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names)
 #define FCOE_FCF_STATE_MAX_NAMELEN 50
@@ -246,17 +244,7 @@ static ssize_t show_fcf_state(struct device *dev,
 }
 static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL);
 
-static struct {
-	enum fip_conn_type value;
-	char               *name;
-} fip_conn_type_names[] = {
-	{ FIP_CONN_TYPE_UNKNOWN, "Unknown" },
-	{ FIP_CONN_TYPE_FABRIC, "Fabric" },
-	{ FIP_CONN_TYPE_VN2VN, "VN2VN" },
-};
-fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
-#define FCOE_CTLR_MODE_MAX_NAMELEN 50
-
+#define FCOE_MAX_MODENAME_LEN 20
 static ssize_t show_ctlr_mode(struct device *dev,
 			      struct device_attribute *attr,
 			      char *buf)
#4 lore raw

Re: [PATCH 03/16] libfcoe: Save some memory and optimize name lookups

Quoted 8 lines · Robert Love
drivers/scsi/fcoe/fcoe_sysfs.c +0 -4
@@ -210,25 +210,23 @@ static ssize_t show_fcoe_fcf_device_##field(struct device *dev,	\
  #define fcoe_enum_name_search(title, table_type, table)			\
  static const char *get_fcoe_##title##_name(enum table_type table_key)	\
  {									\
-	int i;								\
-	char *name = NULL;						\
-									\
-	for (i = 0; i < ARRAY_SIZE(table); i++) {			\

drivers/scsi/fcoe/fcoe_sysfs.c static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \ · line 216

Quoted 10 lines
drivers/scsi/fcoe/fcoe_sysfs.c +3 -6
-		if (table[i].value == table_key) {			\
-			name = table[i].name;				\
-			break;						\
-		}							\
-	}								\
-	return name;							\
+	if (table_key >= ARRAY_SIZE(table))				\
+		return NULL;						\
+	return table[table_key];					\
  }

The old code was safe if table_key < 0 but the new code not. Can table_key be negative ?

drivers/scsi/fcoe/fcoe_sysfs.c static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \ · line 222

Quoted 5 lines
drivers/scsi/fcoe/fcoe_sysfs.c +5 -0
+static char *fip_conn_type_names[] = {
+	[ FIP_CONN_TYPE_UNKNOWN ] = "Unknown",
+        [ FIP_CONN_TYPE_FABRIC ]  = "Fabric",
+	[ FIP_CONN_TYPE_VN2VN ]   = "VN2VN",
+};

A minor nit: indentation style is inconsistent here. Two elements are indented with a tab and another with eight spaces.

Bart.

#5 lore raw

Re: [PATCH 03/16] libfcoe: Save some memory and optimize name lookups

Quoted 34 lines · Bart Van Assche
Quoted 10 lines · Robert Love
drivers/scsi/fcoe/fcoe_sysfs.c +0 -4
@@ -210,25 +210,23 @@ static ssize_t
 show_fcoe_fcf_device_##field(struct device *dev,    \
  #define fcoe_enum_name_search(title, table_type, table)            \
  static const char *get_fcoe_##title##_name(enum table_type
 table_key)    \
  {                                    \
-    int i;                                \
-    char *name = NULL;                        \
-                                    \
-    for (i = 0; i < ARRAY_SIZE(table); i++) {            \

drivers/scsi/fcoe/fcoe_sysfs.c static ssize_t · line 218

Quoted 10 lines
drivers/scsi/fcoe/fcoe_sysfs.c +3 -6
-        if (table[i].value == table_key) {            \
-            name = table[i].name;                \
-            break;                        \
-        }                            \
-    }                                \
-    return name;                            \
+    if (table_key >= ARRAY_SIZE(table))                \
+        return NULL;                        \
+    return table[table_key];                    \
  }

The old code was safe if table_key < 0 but the new code not. Can table_key be negative ?

drivers/scsi/fcoe/fcoe_sysfs.c static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \ · line 222

Quoted 5 lines
drivers/scsi/fcoe/fcoe_sysfs.c +5 -0
+static char *fip_conn_type_names[] = {
+    [ FIP_CONN_TYPE_UNKNOWN ] = "Unknown",
+        [ FIP_CONN_TYPE_FABRIC ]  = "Fabric",
+    [ FIP_CONN_TYPE_VN2VN ]   = "VN2VN",
+};

A minor nit: indentation style is inconsistent here. Two elements are indented with a tab and another with eight spaces.

Quoted 1 line

Bart.

Thanks for the review and comments, Bart. I agree with both of your points. I'll send an updated patch shortly. //Rob

#6 lore raw

PATCH v2 1/1 libfcoe: Save some memory and optimize name lookups

In reply to Robert Love

Instead of creating a structure with an enum and a pointer to a string, simply allocate an array of strings and use the enum values for the indicies.

This means that we do not need to iterate through the list of entries when looking up a string name by its enum key.

This will also help with a latter patch that will add more fcoe_sysfs attributes that will also use the fcoe_enum_name_search macro. One attribute will also do a reverse lookup which requires less code when the enum-to-string mappings are organized as this patch makes them to be.

---
 drivers/scsi/fcoe/fcoe_sysfs.c |   44 +++++++++++++++-------------------------
 1 file changed, 16 insertions(+), 28 deletions(-)
drivers/scsi/fcoe/fcoe_sysfs.c +16 -28
index 5e75168..e6fce28 100644
@@ -210,25 +210,23 @@ static ssize_t show_fcoe_fcf_device_##field(struct device *dev,	\
 #define fcoe_enum_name_search(title, table_type, table)			\
 static const char *get_fcoe_##title##_name(enum table_type table_key)	\
 {									\
-	int i;								\
-	char *name = NULL;						\
-									\
-	for (i = 0; i < ARRAY_SIZE(table); i++) {			\
-		if (table[i].value == table_key) {			\
-			name = table[i].name;				\
-			break;						\
-		}							\
-	}								\
-	return name;							\
+	if (table_key < 0 || table_key >= ARRAY_SIZE(table))		\
+		return NULL;						\
+	return table[table_key];					\
 }
 
-static struct {
-	enum fcf_state value;
-	char           *name;
-} fcf_state_names[] = {
-	{ FCOE_FCF_STATE_UNKNOWN,      "Unknown" },
-	{ FCOE_FCF_STATE_DISCONNECTED, "Disconnected" },
-	{ FCOE_FCF_STATE_CONNECTED,    "Connected" },
+static char *fip_conn_type_names[] = {
+	[ FIP_CONN_TYPE_UNKNOWN ] = "Unknown",
+	[ FIP_CONN_TYPE_FABRIC ]  = "Fabric",
+	[ FIP_CONN_TYPE_VN2VN ]   = "VN2VN",
+};
+fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
+#define FCOE_CTLR_MODE_MAX_NAMELEN 50
+
+static char *fcf_state_names[] = {
+	[ FCOE_FCF_STATE_UNKNOWN ]      = "Unknown",
+	[ FCOE_FCF_STATE_DISCONNECTED ] = "Disconnected",
+	[ FCOE_FCF_STATE_CONNECTED ]    = "Connected",
 };
 fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names)
 #define FCOE_FCF_STATE_MAX_NAMELEN 50
@@ -246,17 +244,7 @@ static ssize_t show_fcf_state(struct device *dev,
 }
 static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL);
 
-static struct {
-	enum fip_conn_type value;
-	char               *name;
-} fip_conn_type_names[] = {
-	{ FIP_CONN_TYPE_UNKNOWN, "Unknown" },
-	{ FIP_CONN_TYPE_FABRIC, "Fabric" },
-	{ FIP_CONN_TYPE_VN2VN, "VN2VN" },
-};
-fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
-#define FCOE_CTLR_MODE_MAX_NAMELEN 50
-
+#define FCOE_MAX_MODENAME_LEN 20
 static ssize_t show_ctlr_mode(struct device *dev,
 			      struct device_attribute *attr,
 			      char *buf)
Acked-by on v2 1/1
#7 lore raw

Re: [PATCH v2] libfcoe: Save some memory and optimize name lookups

Quoted 76 lines · Robert Love

Instead of creating a structure with an enum and a pointer to a string, simply allocate an array of strings and use the enum values for the indicies.

This means that we do not need to iterate through the list of entries when looking up a string name by its enum key.

This will also help with a latter patch that will add more fcoe_sysfs attributes that will also use the fcoe_enum_name_search macro. One attribute will also do a reverse lookup which requires less code when the enum-to-string mappings are organized as this patch makes them to be.

---
 drivers/scsi/fcoe/fcoe_sysfs.c |   44 +++++++++++++++-------------------------
 1 file changed, 16 insertions(+), 28 deletions(-)
drivers/scsi/fcoe/fcoe_sysfs.c +15 -22
index 5e75168..e6fce28 100644
@@ -210,25 +210,23 @@ static ssize_t show_fcoe_fcf_device_##field(struct device *dev,	\
 #define fcoe_enum_name_search(title, table_type, table)			\
 static const char *get_fcoe_##title##_name(enum table_type table_key)	\
 {									\
-	int i;								\
-	char *name = NULL;						\
-									\
-	for (i = 0; i < ARRAY_SIZE(table); i++) {			\
-		if (table[i].value == table_key) {			\
-			name = table[i].name;				\
-			break;						\
-		}							\
-	}								\
-	return name;							\
+	if (table_key < 0 || table_key >= ARRAY_SIZE(table))		\
+		return NULL;						\
+	return table[table_key];					\
 }
 
-static struct {
-	enum fcf_state value;
-	char           *name;
-} fcf_state_names[] = {
-	{ FCOE_FCF_STATE_UNKNOWN,      "Unknown" },
-	{ FCOE_FCF_STATE_DISCONNECTED, "Disconnected" },
-	{ FCOE_FCF_STATE_CONNECTED,    "Connected" },
+static char *fip_conn_type_names[] = {
+	[ FIP_CONN_TYPE_UNKNOWN ] = "Unknown",
+	[ FIP_CONN_TYPE_FABRIC ]  = "Fabric",
+	[ FIP_CONN_TYPE_VN2VN ]   = "VN2VN",
+};
+fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
+#define FCOE_CTLR_MODE_MAX_NAMELEN 50
+
+static char *fcf_state_names[] = {
+	[ FCOE_FCF_STATE_UNKNOWN ]      = "Unknown",
+	[ FCOE_FCF_STATE_DISCONNECTED ] = "Disconnected",
+	[ FCOE_FCF_STATE_CONNECTED ]    = "Connected",
 };
 fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names)
 #define FCOE_FCF_STATE_MAX_NAMELEN 50
@@ -246,17 +244,7 @@ static ssize_t show_fcf_state(struct device *dev,
 }
 static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL);
 
-static struct {
-	enum fip_conn_type value;
-	char               *name;
-} fip_conn_type_names[] = {
-	{ FIP_CONN_TYPE_UNKNOWN, "Unknown" },

drivers/scsi/fcoe/fcoe_sysfs.c static ssize_t show_fcf_state(struct device *dev, · line 250

Quoted 10 lines
drivers/scsi/fcoe/fcoe_sysfs.c +1 -6
-	{ FIP_CONN_TYPE_FABRIC, "Fabric" },
-	{ FIP_CONN_TYPE_VN2VN, "VN2VN" },
-};
-fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
-#define FCOE_CTLR_MODE_MAX_NAMELEN 50
-
+#define FCOE_MAX_MODENAME_LEN 20
 static ssize_t show_ctlr_mode(struct device *dev,
 			      struct device_attribute *attr,
 			      char *buf)
#8 lore raw

PATCH 4/16 libfcoe: Add fcoe_sysfs debug logging level

In reply to Robert Love

Add a macro to print fcoe_sysfs debug statements.

---
 drivers/scsi/fcoe/fcoe_sysfs.c |    7 +++++++
 drivers/scsi/fcoe/libfcoe.h    |   11 ++++++++---
 2 files changed, 15 insertions(+), 3 deletions(-)
drivers/scsi/fcoe/fcoe_sysfs.c +7 -0
index 5a74a47..638e8a2 100644
@@ -24,6 +24,13 @@
 
 #include <scsi/fcoe_sysfs.h>
 
+/*
+ * OK to include local libfcoe.h for debug_logging, but cannot include
+ * <scsi/libfcoe.h> otherwise non-netdev based fcoe solutions would have
+ * have to include more than fcoe_sysfs.h.
+ */
+#include "libfcoe.h"
+
 static atomic_t ctlr_num;
 static atomic_t fcf_num;
 
drivers/scsi/fcoe/libfcoe.h +8 -3
index 6af5fc3..63d8fae 100644
@@ -2,9 +2,10 @@
 #define _FCOE_LIBFCOE_H_
 
 extern unsigned int libfcoe_debug_logging;
-#define LIBFCOE_LOGGING	    0x01 /* General logging, not categorized */
-#define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */
-#define LIBFCOE_TRANSPORT_LOGGING	0x04 /* FCoE transport logging */
+#define LIBFCOE_LOGGING	          0x01 /* General logging, not categorized */
+#define LIBFCOE_FIP_LOGGING       0x02 /* FIP logging */
+#define LIBFCOE_TRANSPORT_LOGGING 0x04 /* FCoE transport logging */
+#define LIBFCOE_SYSFS_LOGGING     0x08 /* fcoe_sysfs logging */
 
 #define LIBFCOE_CHECK_LOGGING(LEVEL, CMD)		\
 do {							\
@@ -28,4 +29,8 @@ do {							\
 			      printk(KERN_INFO "%s: " fmt,		\
 				     __func__, ##args);)
 
+#define LIBFCOE_SYSFS_DBG(cdev, fmt, args...)				\
+	LIBFCOE_CHECK_LOGGING(LIBFCOE_SYSFS_LOGGING,			\
+			      pr_info("ctlr_%d: " fmt, cdev->id, ##args);)
+
 #endif /* _FCOE_LIBFCOE_H_ */
#9 lore raw

PATCH 5/16 libfcoe, fcoe, bnx2fc: Add new fcoe control interface

In reply to Robert Love

This patch does a few things.

1) Makes /sys/bus/fcoe/ctlr_{create,destroy} interfaces. These interfaces take an <ifname> and will either create an FCoE Controller or destroy an FCoE Controller depending on which file is written to.

The new FCoE Controller will start in a DISABLED state and will not do discovery or login until it is ENABLED. This pause will allow us to configure the FCoE Controller before enabling it.

2) Makes the 'mode' attribute of a fcoe_ctlr_device writale. This allows the user to configure the mode in which the FCoE Controller will start in when it is ENABLED.

Possible modes are 'Fabric', or 'VN2VN'.

The default mode for a fcoe_ctlr{,_device} is 'Fabric'. Drivers must implement the set_fcoe_ctlr_mode routine to support this feature.

libfcoe offers an exported routine to set a FCoE Controller's mode. The mode can only be changed when the FCoE Controller is DISABLED.

This patch also removes the get_fcoe_ctlr_mode pointer in the fcoe_sysfs function template, the code in fcoe_ctlr.c to get the mode and the assignment of the fcoe_sysfs function pointer to the fcoe_ctlr.c implementation (in fcoe and bnx2fc). fcoe_sysfs can return that value for the mode without consulting the LLD.

3) Make a 'enabled' attribute of a fcoe_ctlr_device. On a read, fcoe_sysfs will return the attribute's value. On a write, fcoe_sysfs will call the LLD (if there is a callback) to notifiy that the enalbed state has changed.

This patch maintains the old FCoE control interfaces as module parameters, but it adds comments pointing out that the old interfaces are deprecated.

---
 Documentation/ABI/testing/sysfs-bus-fcoe |   41 +++++++++
 drivers/scsi/bnx2fc/bnx2fc_fcoe.c        |    1 
 drivers/scsi/fcoe/fcoe.c                 |    1 
 drivers/scsi/fcoe/fcoe_sysfs.c           |  137 ++++++++++++++++++++++++++++--
 drivers/scsi/fcoe/fcoe_transport.c       |  104 +++++++++++++++++++++++
 include/scsi/fcoe_sysfs.h                |   11 ++
 include/scsi/libfcoe.h                   |   16 +++-
 7 files changed, 298 insertions(+), 13 deletions(-)
Documentation/ABI/testing/sysfs-bus-fcoe +40 -1
index 971dc22..21640ea 100644
@@ -1,14 +1,53 @@
+What:		/sys/bus/fcoe/
+Date:		August 2012
+KernelVersion:	TBD
+Contact:	Robert Love <[email protected]>, [email protected]
+Description:	The FCoE bus. Attributes in this directory are control interfaces.
+Attributes:
+
+	ctlr_create: 'FCoE Controller' instance creation interface. Writing an
+		     <ifname> to this file will allocate and populate sysfs with a
+		     fcoe_ctlr_device (ctlr_X). The user can then configure any
+		     per-port settings and finally write to the fcoe_ctlr_device's
+		     'start' attribute to begin the kernel's discovery and login
+		     process.
+
+	ctlr_destroy: 'FCoE Controller' instance removal interface. Writing a
+		       fcoe_ctlr_device's sysfs name to this file will log the
+		       fcoe_ctlr_device out of the fabric or otherwise connected
+		       FCoE devices. It will also free all kernel memory allocated
+		       for this fcoe_ctlr_device and any structures associated
+		       with it, this includes the scsi_host.
+
 What:		/sys/bus/fcoe/devices/ctlr_X
 Date:		March 2012
 KernelVersion:	TBD
 Contact:	Robert Love <[email protected]>, [email protected]
-Description:	'FCoE Controller' instances on the fcoe bus
+Description:	'FCoE Controller' instances on the fcoe bus.
+		The FCoE Controller now has a three stage creation process.
+		1) Write interface name to ctlr_create 2) Configure the FCoE
+		Controller (ctlr_X) 3) Enable the FCoE Controller to begin
+		discovery and login. The FCoE Controller is destroyed by
+		writing it's name, i.e. ctlr_X to the ctlr_delete file.
+
 Attributes:
 
 	fcf_dev_loss_tmo: Device loss timeout peroid (see below). Changing
 			  this value will change the dev_loss_tmo for all
 			  FCFs discovered by this controller.
 
+	mode:		  Display or change the FCoE Controller's mode. Possible
+			  modes are 'Fabric' and 'VN2VN'. If a FCoE Controller
+			  is started in 'Fabric' mode then FIP FCF discovery is
+			  initiated and ultimately a fabric login is attempted.
+			  If a FCoE Controller is started in 'VN2VN' mode then
+			  FIP VN2VN discovery and login is performed. A FCoE
+			  Controller only supports one mode at a time.
+
+	enabled:	  Whether an FCoE controller is enabled or disabled.
+			  0 if disabled, 1 if enabled. Writing either 0 or 1
+			  to this file will enable or disable the FCoE controller.
+
 	lesb/link_fail:   Link Error Status Block (LESB) link failure count.
 
 	lesb/vlink_fail:  Link Error Status Block (LESB) virtual link
drivers/scsi/bnx2fc/bnx2fc_fcoe.c +0 -1
index e055865..9b38794 100644
@@ -2555,7 +2555,6 @@ 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,
drivers/scsi/fcoe/fcoe.c +0 -1
index 666b7ac..9bd982d 100644
@@ -155,7 +155,6 @@ 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,
drivers/scsi/fcoe/fcoe_sysfs.c +130 -7

189 lines not on this page · raw message

drivers/scsi/fcoe/fcoe_transport.c +104 -0

110 lines not on this page · raw message

include/scsi/fcoe_sysfs.h +10 -1
index 604cb9b..7e23148 100644
@@ -34,7 +34,8 @@ struct fcoe_sysfs_function_template {
 	void (*get_fcoe_ctlr_symb_err)(struct fcoe_ctlr_device *);
 	void (*get_fcoe_ctlr_err_block)(struct fcoe_ctlr_device *);
 	void (*get_fcoe_ctlr_fcs_error)(struct fcoe_ctlr_device *);
-	void (*get_fcoe_ctlr_mode)(struct fcoe_ctlr_device *);
+	void (*set_fcoe_ctlr_mode)(struct fcoe_ctlr_device *);
+	int  (*set_fcoe_ctlr_enabled)(struct fcoe_ctlr_device *);
 	void (*get_fcoe_fcf_selected)(struct fcoe_fcf_device *);
 	void (*get_fcoe_fcf_vlan_id)(struct fcoe_fcf_device *);
 };
@@ -48,6 +49,12 @@ enum fip_conn_type {
 	FIP_CONN_TYPE_VN2VN,
 };
 
+enum ctlr_enabled_state {
+	FCOE_CTLR_ENABLED,
+	FCOE_CTLR_DISABLED,
+	FCOE_CTLR_UNUSED,
+};
+
 struct fcoe_ctlr_device {
 	u32				id;
 
@@ -64,6 +71,8 @@ struct fcoe_ctlr_device {
 	int                             fcf_dev_loss_tmo;
 	enum fip_conn_type              mode;
 
+	enum ctlr_enabled_state         enabled;
+
 	/* expected in host order for displaying */
 	struct fcoe_fc_els_lesb         lesb;
 };
include/scsi/libfcoe.h +14 -2
index 8742d85..6add37a 100644
@@ -289,8 +289,11 @@ static inline bool is_fip_mode(struct fcoe_ctlr *fip)
  * @attached:	whether this transport is already attached
  * @list:	list linkage to all attached transports
  * @match:	handler to allow the transport driver to match up a given netdev
+ * @alloc:      handler to allocate per-instance FCoE structures
+ *		(no discovery or login)
  * @create:	handler to sysfs entry of create for FCoE instances
- * @destroy:	handler to sysfs entry of destroy for FCoE instances
+ * @destroy:    handler to delete per-instance FCoE structures
+ *		(frees all memory)
  * @enable:	handler to sysfs entry of enable for FCoE instances
  * @disable:	handler to sysfs entry of disable for FCoE instances
  */
@@ -299,6 +302,7 @@ struct fcoe_transport {
 	bool attached;
 	struct list_head list;
 	bool (*match) (struct net_device *device);
+	int (*alloc) (struct net_device *device);
 	int (*create) (struct net_device *device, enum fip_state fip_mode);
 	int (*destroy) (struct net_device *device);
 	int (*enable) (struct net_device *device);
@@ -356,7 +360,7 @@ int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen,
 
 /* FCoE Sysfs helpers */
 void fcoe_fcf_get_selected(struct fcoe_fcf_device *);
-void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *);
+void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *);
 
 /**
  * struct netdev_list
@@ -372,4 +376,12 @@ struct fcoe_netdev_mapping {
 int fcoe_transport_attach(struct fcoe_transport *ft);
 int fcoe_transport_detach(struct fcoe_transport *ft);
 
+/* sysfs store handler for ctrl_control interface */
+ssize_t fcoe_ctlr_create_store(struct bus_type *bus,
+			       const char *buf, size_t count);
+ssize_t fcoe_ctlr_destroy_store(struct bus_type *bus,
+				const char *buf, size_t count);
+
 #endif /* _LIBFCOE_H */
+
+
#10 lore raw

Re: [PATCH 05/16] libfcoe, fcoe, bnx2fc: Add new fcoe control interface

Quoted 45 lines · Robert Love
drivers/scsi/fcoe/fcoe_transport.c +45 -0
+ssize_t fcoe_ctlr_create_store(struct bus_type *bus,
+			       const char *buf, size_t count)
+{
+	struct net_device *netdev = NULL;
+	struct fcoe_transport *ft = NULL;
+	struct fcoe_ctlr_device *ctlr_dev = NULL;
+	int rc = 0;
+	int err;
+
+	mutex_lock(&ft_mutex);
+
+	netdev = fcoe_if_to_netdev(buf);
+	if (!netdev) {
+		LIBFCOE_TRANSPORT_DBG("Invalid device %s.\n", buf);
+		rc = -ENODEV;
+		goto out_nodev;
+	}
+
+	ft = fcoe_netdev_map_lookup(netdev);
+	if (ft) {
+		LIBFCOE_TRANSPORT_DBG("transport %s already has existing "
+				      "FCoE instance on %s.\n",
+				      ft->name, netdev->name);
+		rc = -EEXIST;
+		goto out_putdev;
+	}
+
+	ft = fcoe_transport_lookup(netdev);
+	if (!ft) {
+		LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
+				      netdev->name);
+		rc = -ENODEV;
+		goto out_putdev;
+	}
+
+	/* pass to transport create */
+	err = ft->alloc ? ft->alloc(netdev) : -ENODEV;
+	if (err) {
+		fcoe_del_netdev_mapping(netdev);
+		rc = -ENOMEM;
+		goto out_putdev;
+	}
+
+	err = fcoe_add_netdev_mapping(netdev, ft);
+	if (err) {

drivers/scsi/fcoe/fcoe_transport.c static int libfcoe_device_notification(struct notifier_block *notifier, · line 684

Quoted 10 lines
drivers/scsi/fcoe/fcoe_transport.c +10 -0
+		LIBFCOE_TRANSPORT_DBG("failed to add new netdev mapping "
+				      "for FCoE transport %s for %s.\n",
+				      ft->name, netdev->name);
+		rc = -ENODEV;
+		goto out_putdev;
+	}
+
+	LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n",
+			      ft->name, (ctlr_dev) ? "succeeded" : "failed",
+			      netdev->name);

ctlr_dev is initialized to NULL and not updated anywhere in this function, and hence the above debug statement will always say that 'create' failed.

Quoted 10 lines
drivers/scsi/fcoe/fcoe_transport.c +9 -0
+
+out_putdev:
+	dev_put(netdev);
+out_nodev:
+	mutex_unlock(&ft_mutex);
+	if (rc)
+		return rc;
+	return count;
+}
#11 lore raw

PATCH 6/16 fcoe: Use the fcoe_sysfs control interface

In reply to Robert Love

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.

---
 drivers/scsi/fcoe/fcoe.c      |  147 +++++++++++++++++++++++++++++++++++++----
 drivers/scsi/fcoe/fcoe_ctlr.c |   17 ++---
 2 files changed, 140 insertions(+), 24 deletions(-)
drivers/scsi/fcoe/fcoe.c +132 -15
index 9bd982d..21927f7 100644
@@ -117,6 +117,11 @@ static int fcoe_destroy(struct net_device *netdev);
 static int fcoe_enable(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 *,
 				      u32 did, struct fc_frame *,
 				      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 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_vlink_fail = 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,
 				    ulong event, void *ptr)
 {
+	struct fcoe_ctlr_device *cdev;
 	struct fc_lport *lport = NULL;
 	struct net_device *netdev = ptr;
 	struct fcoe_ctlr *ctlr;
@@ -2019,13 +2027,29 @@ static int fcoe_device_notification(struct notifier_block *notifier,
 
 	fcoe_link_speed_update(lport);
 
-	if (link_possible && !fcoe_link_ok(lport))
-		fcoe_ctlr_link_up(ctlr);
-	else if (fcoe_ctlr_link_down(ctlr)) {
-		stats = per_cpu_ptr(lport->stats, get_cpu());
-		stats->LinkFailureCount++;
-		put_cpu();
-		fcoe_clean_pending_queue(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);
+		};
+	} 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->LinkFailureCount++;
+			put_cpu();
+			fcoe_clean_pending_queue(lport);
+		};
 	}
 out:
 	return rc;
@@ -2038,6 +2062,8 @@ out:
  * Called from fcoe transport.
  *
  * Returns: 0 for success
+ *
+ * Deprecated: use fcoe_ctlr_enabled()
  */
 static int fcoe_disable(struct net_device *netdev)
 {
@@ -2097,6 +2123,33 @@ out:
 }
 
 /**
+ * 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
  * @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
 }
 
+enum fcoe_create_link_state {
+	FCOE_CREATE_LINK_DOWN,
+	FCOE_CREATE_LINK_UP,
+};
+
 /**
- * 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
+ * _fcoe_create() - (internal) Create a fcoe interface
+ * @netdev  :   The net_device object the Ethernet interface to create on
+ * @fip_mode:   The FIP mode for this creation
+ * @link_state: The ctlr link state on creation
  *
- * Called from 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;
 	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 */
 	lport->boot_time = jiffies;
 	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();
 		fcoe_ctlr_link_up(ctlr);
 		mutex_unlock(&fcoe_config_mutex);
@@ -2274,6 +2356,37 @@ out_nortnl:
 }
 
 /**
+ * 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
  * @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_interface *fcoe = port->priv;
 	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_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);
 	return 0;
 }
@@ -2450,6 +2566,7 @@ static struct fcoe_transport fcoe_sw_transport = {
 	.attached = false,
 	.list = LIST_HEAD_INIT(fcoe_sw_transport.list),
 	.match = fcoe_match,
+	.alloc = fcoe_ctlr_alloc,
 	.create = fcoe_create,
 	.destroy = fcoe_destroy,
 	.enable = fcoe_enable,
drivers/scsi/fcoe/fcoe_ctlr.c +8 -9
index 2ebe03a..7583425 100644
@@ -2864,22 +2864,21 @@ void fcoe_fcf_get_selected(struct fcoe_fcf_device *fcf_dev)
 }
 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);
 
 	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;
+	switch (ctlr_dev->mode) {
+	case FIP_CONN_TYPE_VN2VN:
+		ctlr->mode = FIP_MODE_VN2VN;
 		break;
+	case FIP_CONN_TYPE_FABRIC:
 	default:
-		ctlr_dev->mode = FIP_CONN_TYPE_UNKNOWN;
+		ctlr->mode = FIP_MODE_FABRIC;
 		break;
 	}
+
 	mutex_unlock(&ctlr->ctlr_mutex);
 }
-EXPORT_SYMBOL(fcoe_ctlr_get_fip_mode);
+EXPORT_SYMBOL(fcoe_ctlr_set_fip_mode);
#12 lore raw

PATCH 7/16 bnx2fc: Use the fcoe_sysfs control interface

In reply to Robert Love

This patch adds support for the new fcoe_sysfs control interface to bnx2fc.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.

---
 drivers/scsi/bnx2fc/bnx2fc_fcoe.c |  168 +++++++++++++++++++++++++++++++------
 1 file changed, 139 insertions(+), 29 deletions(-)
drivers/scsi/bnx2fc/bnx2fc_fcoe.c +139 -29
index 9b38794..8d975ef 100644
@@ -62,6 +62,10 @@ static int bnx2fc_destroy(struct net_device *net_device);
 static int bnx2fc_enable(struct net_device *netdev);
 static int bnx2fc_disable(struct net_device *netdev);
 
+/* fcoe_syfs control interface handlers */
+static int bnx2fc_ctlr_alloc(struct net_device *netdev);
+static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev);
+
 static void bnx2fc_recv_frame(struct sk_buff *skb);
 
 static void bnx2fc_start_disc(struct bnx2fc_interface *interface);
@@ -864,6 +868,7 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event,
 				     u16 vlan_id)
 {
 	struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context;
+	struct fcoe_ctlr_device *cdev;
 	struct fc_lport *lport;
 	struct fc_lport *vport;
 	struct bnx2fc_interface *interface, *tmp;
@@ -925,28 +930,45 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event,
 
 		bnx2fc_link_speed_update(lport);
 
+		cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
+
 		if (link_possible && !bnx2fc_link_ok(lport)) {
-			/* Reset max recv frame size to default */
-			fc_set_mfs(lport, BNX2FC_MFS);
-			/*
-			 * ctlr link up will only be handled during
-			 * enable to avoid sending discovery solicitation
-			 * on a stale vlan
-			 */
-			if (interface->enabled)
-				fcoe_ctlr_link_up(ctlr);
+			switch (cdev->enabled) {
+			case FCOE_CTLR_DISABLED:
+				pr_info("Link up while interface is disabled.\n");
+				break;
+			case FCOE_CTLR_ENABLED:
+			case FCOE_CTLR_UNUSED:
+				/* Reset max recv frame size to default */
+				fc_set_mfs(lport, BNX2FC_MFS);
+				/*
+				 * ctlr link up will only be handled during
+				 * enable to avoid sending discovery
+				 * solicitation on a stale vlan
+				 */
+				if (interface->enabled)
+					fcoe_ctlr_link_up(ctlr);
+			};
 		} else if (fcoe_ctlr_link_down(ctlr)) {
-			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;
-			per_cpu_ptr(lport->stats,
-				    get_cpu())->LinkFailureCount++;
-			put_cpu();
-			fcoe_clean_pending_queue(lport);
-			wait_for_upload = 1;
+			switch (cdev->enabled) {
+			case FCOE_CTLR_DISABLED:
+				pr_info("Link down while interface is disabled.\n");
+				break;
+			case FCOE_CTLR_ENABLED:
+			case FCOE_CTLR_UNUSED:
+				mutex_lock(&lport->lp_mutex);
+				list_for_each_entry(vport, &lport->vports, list)
+					fc_host_port_type(vport->host) =
+					FC_PORTTYPE_UNKNOWN;
+				mutex_unlock(&lport->lp_mutex);
+				fc_host_port_type(lport->host) =
+					FC_PORTTYPE_UNKNOWN;
+				per_cpu_ptr(lport->stats,
+					    get_cpu())->LinkFailureCount++;
+				put_cpu();
+				fcoe_clean_pending_queue(lport);
+				wait_for_upload = 1;
+			};
 		}
 	}
 	mutex_unlock(&bnx2fc_dev_lock);
@@ -1996,7 +2018,9 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev)
 		set_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic);
 }
 
-
+/**
+ * Deperecated: Use bnx2fc_enabled()
+ */
 static int bnx2fc_disable(struct net_device *netdev)
 {
 	struct bnx2fc_interface *interface;
@@ -2022,7 +2046,9 @@ static int bnx2fc_disable(struct net_device *netdev)
 	return rc;
 }
 
-
+/**
+ * Deprecated: Use bnx2fc_enabled()
+ */
 static int bnx2fc_enable(struct net_device *netdev)
 {
 	struct bnx2fc_interface *interface;
@@ -2048,17 +2074,57 @@ static int bnx2fc_enable(struct net_device *netdev)
 }
 
 /**
- * bnx2fc_create - Create bnx2fc FCoE interface
+ * bnx2fc_ctlr_enabled() - Enable or disable an FCoE Controller
+ * @cdev: The FCoE Controller that is being enabled or disabled
  *
- * @buffer: The name of Ethernet interface to create on
- * @kp:     The associated kernel param
+ * fcoe_sysfs will ensure that the state of 'enabled' has
+ * changed, so no checking is necessary here. This routine simply
+ * calls fcoe_enable or fcoe_disable, both of which are deprecated.
+ * When those routines are removed the functionality can be merged
+ * here.
+ */
+static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev)
+{
+	struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev);
+	struct fc_lport *lport = ctlr->lp;
+	struct net_device *netdev = bnx2fc_netdev(lport);
+
+	switch (cdev->enabled) {
+	case FCOE_CTLR_ENABLED:
+		return bnx2fc_enable(netdev);
+	case FCOE_CTLR_DISABLED:
+		return bnx2fc_disable(netdev);
+	case FCOE_CTLR_UNUSED:
+	default:
+		return -ENOTSUPP;
+	};
+}
+
+enum bnx2fc_create_link_state {
+	BNX2FC_CREATE_LINK_DOWN,
+	BNX2FC_CREATE_LINK_UP,
+};
+
+/**
+ * _bnx2fc_create() - Create bnx2fc FCoE interface
+ * @netdev  :   The net_device object the Ethernet interface to create on
+ * @fip_mode:   The FIP mode for this creation
+ * @link_state: The ctlr link state on creation
  *
- * Called from sysfs.
+ * Called from either the libfcoe 'create' module parameter
+ * via fcoe_create or from fcoe_syfs's ctlr_create file.
+ *
+ * libfcoe's 'create' module parameter is deprecated so some
+ * consolidation of code can be done when that interface is
+ * removed.
  *
  * Returns: 0 for success
  */
-static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
+static int _bnx2fc_create(struct net_device *netdev,
+			  enum fip_state fip_mode,
+			  enum bnx2fc_create_link_state link_state)
 {
+	struct fcoe_ctlr_device *cdev;
 	struct fcoe_ctlr *ctlr;
 	struct bnx2fc_interface *interface;
 	struct bnx2fc_hba *hba;
@@ -2153,7 +2219,15 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
 	/* Make this master N_port */
 	ctlr->lp = lport;
 
-	if (!bnx2fc_link_ok(lport)) {
+	cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
+
+	if (link_state == BNX2FC_CREATE_LINK_UP)
+		cdev->enabled = FCOE_CTLR_ENABLED;
+	else
+		cdev->enabled = FCOE_CTLR_DISABLED;
+
+	if (link_state == BNX2FC_CREATE_LINK_UP &&
+	    !bnx2fc_link_ok(lport)) {
 		fcoe_ctlr_link_up(ctlr);
 		fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
 		set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state);
@@ -2161,7 +2235,10 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
 
 	BNX2FC_HBA_DBG(lport, "create: START DISC\n");
 	bnx2fc_start_disc(interface);
-	interface->enabled = true;
+
+	if (link_state == BNX2FC_CREATE_LINK_UP)
+		interface->enabled = true;
+
 	/*
 	 * Release from kref_init in bnx2fc_interface_setup, on success
 	 * lport should be holding a reference taken in bnx2fc_if_create
@@ -2187,6 +2264,37 @@ mod_err:
 }
 
 /**
+ * bnx2fc_create() - Create a bnx2fc interface
+ * @netdev  : The net_device object the Ethernet interface to create on
+ * @fip_mode: The FIP mode for this creation
+ *
+ * Called from fcoe transport
+ *
+ * Returns: 0 for success
+ */
+static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
+{
+	return _bnx2fc_create(netdev, fip_mode, BNX2FC_CREATE_LINK_UP);
+}
+
+/**
+ * bnx2fc_ctlr_alloc() - Allocate a bnx2fc interface from fcoe_sysfs
+ * @netdev: The net_device to be used by the allocated FCoE Controller
+ *
+ * This routine is called from fcoe_sysfs. It will start the fcoe_ctlr
+ * in a link_down state. The allows the user an opportunity to configure
+ * the FCoE Controller from sysfs before enabling the FCoE Controller.
+ *
+ * Creating in with this routine starts the FCoE Controller in Fabric
+ * mode. The user can change to VN2VN or another mode before enabling.
+ */
+static int bnx2fc_ctlr_alloc(struct net_device *netdev)
+{
+	return _bnx2fc_create(netdev, FIP_MODE_FABRIC,
+			      BNX2FC_CREATE_LINK_DOWN);
+}
+
+/**
  * bnx2fc_find_hba_for_cnic - maps cnic instance to bnx2fc hba instance
  *
  * @cnic:	Pointer to cnic device instance
@@ -2311,6 +2419,7 @@ static struct fcoe_transport bnx2fc_transport = {
 	.name = {"bnx2fc"},
 	.attached = false,
 	.list = LIST_HEAD_INIT(bnx2fc_transport.list),
+	.alloc = bnx2fc_ctlr_alloc,
 	.match = bnx2fc_match,
 	.create = bnx2fc_create,
 	.destroy = bnx2fc_destroy,
@@ -2555,6 +2664,7 @@ module_init(bnx2fc_mod_init);
 module_exit(bnx2fc_mod_exit);
 
 static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = {
+	.set_fcoe_ctlr_enabled = bnx2fc_ctlr_enabled,
 	.get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb,
 	.get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb,
 	.get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb,
#13 lore raw

PATCH 8/16 libfc, libfcoe, fcoe: Convert debug_logging macros to pr_info

In reply to Robert Love

Convert libfc, libfcoe and fcoe's debug_logging macros to use pr_info() instead of printk(KERN_INFO, ...). checkpatch.pl now complains about this, so convert libfcoe to preferred method.

---
 drivers/scsi/fcoe/fcoe.h      |    6 +++---
 drivers/scsi/fcoe/libfcoe.h   |    9 ++++-----
 drivers/scsi/libfc/fc_libfc.h |   38 +++++++++++++++++++-------------------
 3 files changed, 26 insertions(+), 27 deletions(-)
drivers/scsi/fcoe/fcoe.h +3 -3
index b42dc32..2b53672 100644
@@ -55,12 +55,12 @@ do {                                                            	\
 
 #define FCOE_DBG(fmt, args...)						\
 	FCOE_CHECK_LOGGING(FCOE_LOGGING,				\
-			   printk(KERN_INFO "fcoe: " fmt, ##args);)
+			   pr_info("fcoe: " fmt, ##args);)
 
 #define FCOE_NETDEV_DBG(netdev, fmt, args...)			\
 	FCOE_CHECK_LOGGING(FCOE_NETDEV_LOGGING,			\
-			   printk(KERN_INFO "fcoe: %s: " fmt,	\
-				  netdev->name, ##args);)
+			   pr_info("fcoe: %s: " fmt,		\
+				   netdev->name, ##args);)
 
 /**
  * struct fcoe_interface - A FCoE interface
drivers/scsi/fcoe/libfcoe.h +4 -5
index 63d8fae..d3bb16d 100644
@@ -17,17 +17,16 @@ do {							\
 
 #define LIBFCOE_DBG(fmt, args...)					\
 	LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING,				\
-			      printk(KERN_INFO "libfcoe: " fmt, ##args);)
+			      pr_info("libfcoe: " fmt, ##args);)
 
 #define LIBFCOE_FIP_DBG(fip, fmt, args...)				\
 	LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING,			\
-			      printk(KERN_INFO "host%d: fip: " fmt,	\
-				     (fip)->lp->host->host_no, ##args);)
+			      pr_info("host%d: fip: " fmt,		\
+				      (fip)->lp->host->host_no, ##args);)
 
 #define LIBFCOE_TRANSPORT_DBG(fmt, args...)				\
 	LIBFCOE_CHECK_LOGGING(LIBFCOE_TRANSPORT_LOGGING,		\
-			      printk(KERN_INFO "%s: " fmt,		\
-				     __func__, ##args);)
+			      pr_info("%s: " fmt, __func__, ##args);)
 
 #define LIBFCOE_SYSFS_DBG(cdev, fmt, args...)				\
 	LIBFCOE_CHECK_LOGGING(LIBFCOE_SYSFS_LOGGING,			\
drivers/scsi/libfc/fc_libfc.h +19 -19
index c2830cc..b74189d 100644
@@ -41,25 +41,25 @@ extern unsigned int fc_debug_logging;
 
 #define FC_LIBFC_DBG(fmt, args...)					\
 	FC_CHECK_LOGGING(FC_LIBFC_LOGGING,				\
-			 printk(KERN_INFO "libfc: " fmt, ##args))
+			 pr_info("libfc: " fmt, ##args))
 
 #define FC_LPORT_DBG(lport, fmt, args...)				\
 	FC_CHECK_LOGGING(FC_LPORT_LOGGING,				\
-			 printk(KERN_INFO "host%u: lport %6.6x: " fmt,	\
-				(lport)->host->host_no,			\
-				(lport)->port_id, ##args))
+			 pr_info("host%u: lport %6.6x: " fmt,		\
+				 (lport)->host->host_no,		\
+				 (lport)->port_id, ##args))
 
-#define FC_DISC_DBG(disc, fmt, args...)				\
-	FC_CHECK_LOGGING(FC_DISC_LOGGING,			\
-			 printk(KERN_INFO "host%u: disc: " fmt,	\
-				fc_disc_lport(disc)->host->host_no,	\
-				##args))
+#define FC_DISC_DBG(disc, fmt, args...)					\
+	FC_CHECK_LOGGING(FC_DISC_LOGGING,				\
+			 pr_info("host%u: disc: " fmt,			\
+				 fc_disc_lport(disc)->host->host_no,	\
+				 ##args))
 
 #define FC_RPORT_ID_DBG(lport, port_id, fmt, args...)			\
 	FC_CHECK_LOGGING(FC_RPORT_LOGGING,				\
-			 printk(KERN_INFO "host%u: rport %6.6x: " fmt,	\
-				(lport)->host->host_no,			\
-				(port_id), ##args))
+			 pr_info("host%u: rport %6.6x: " fmt,		\
+				 (lport)->host->host_no,		\
+				 (port_id), ##args))
 
 #define FC_RPORT_DBG(rdata, fmt, args...)				\
 	FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args)
@@ -70,13 +70,13 @@ extern unsigned int fc_debug_logging;
 		if ((pkt)->seq_ptr) {					\
 			struct fc_exch *_ep = NULL;			\
 			_ep = fc_seq_exch((pkt)->seq_ptr);		\
-			printk(KERN_INFO "host%u: fcp: %6.6x: "		\
+			pr_info("host%u: fcp: %6.6x: "			\
 				"xid %04x-%04x: " fmt,			\
 				(pkt)->lp->host->host_no,		\
 				(pkt)->rport->port_id,			\
 				(_ep)->oxid, (_ep)->rxid, ##args);	\
 		} else {						\
-			printk(KERN_INFO "host%u: fcp: %6.6x: " fmt,	\
+			pr_info("host%u: fcp: %6.6x: " fmt,		\
 				(pkt)->lp->host->host_no,		\
 				(pkt)->rport->port_id, ##args);		\
 		}							\
@@ -84,14 +84,14 @@ extern unsigned int fc_debug_logging;
 
 #define FC_EXCH_DBG(exch, fmt, args...)					\
 	FC_CHECK_LOGGING(FC_EXCH_LOGGING,				\
-			 printk(KERN_INFO "host%u: xid %4x: " fmt,	\
-				(exch)->lp->host->host_no,		\
-				exch->xid, ##args))
+			 pr_info("host%u: xid %4x: " fmt,		\
+				 (exch)->lp->host->host_no,		\
+				 exch->xid, ##args))
 
 #define FC_SCSI_DBG(lport, fmt, args...)				\
 	FC_CHECK_LOGGING(FC_SCSI_LOGGING,				\
-			 printk(KERN_INFO "host%u: scsi: " fmt,		\
-				(lport)->host->host_no,	##args))
+			 pr_info("host%u: scsi: " fmt,			\
+				 (lport)->host->host_no, ##args))
 
 /*
  * FC-4 Providers.
#14 lore raw

PATCH 9/16 fcoe: prep work to start consolidate the usage of fcoe_netdev

In reply to Robert Love

From: Yi Zou <[email protected]>

Currently, in the default kernel fcoe driver, it is needed to get to the underlying private per fcoe transport's private structure, e.g., fcoe_interface in fcoe.ko, and returns the associated netdev. The similar logic exists in other fcoe drivers, e.g., bnx2fc, so we add a function pointer into the common fcoe_port struct to allow individual fcoe transport implementaion (fcoe and bnx2fc) to get the corresponding netdev associated with a give lport.

Then a inline fcoe_get_netdev() is added as part of libfcoe for all underlying fcoe transport drivers to use regardless of its individual fcoe transport driver, and also allows move more common code such as fcoe_link_speed_update or fcoe_ctlr_get_lesb to be in libfcoe, rather than specific to fcoe.

This patch is a prep work that adds aforementioned fucntion pointer, and followed by the actual code changes to make use of it.

---
 include/scsi/libfcoe.h |    1 +
 1 file changed, 1 insertion(+)
include/scsi/libfcoe.h +1 -0
index 6add37a..52bba71 100644
@@ -351,6 +351,7 @@ struct fcoe_port {
 	struct timer_list     timer;
 	struct work_struct    destroy_work;
 	u8		      data_src_addr[ETH_ALEN];
+	struct net_device * (*get_netdev)(const struct fc_lport *lport);
 };
 void fcoe_clean_pending_queue(struct fc_lport *);
 void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb);
#15 lore raw

PATCH 10/16 fcoe: add support to the get_netdev() for fcoe_interface

In reply to Robert Love

From: Yi Zou <[email protected]>

Adds support to fcoe_port's newly added get_netdev fucntion pointer.

---
 drivers/scsi/fcoe/fcoe.c |    1 +
 include/scsi/libfcoe.h   |   12 ++++++++++++
 2 files changed, 13 insertions(+)
drivers/scsi/fcoe/fcoe.c +1 -0
index 21927f7..4cec9dd 100644
@@ -1118,6 +1118,7 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
 	port = lport_priv(lport);
 	port->lport = lport;
 	port->priv = fcoe;
+	port->get_netdev = fcoe_netdev;
 	port->max_queue_depth = FCOE_MAX_QUEUE_DEPTH;
 	port->min_queue_depth = FCOE_MIN_QUEUE_DEPTH;
 	INIT_WORK(&port->destroy_work, fcoe_destroy_work);
include/scsi/libfcoe.h +12 -0
index 52bba71..746bc58 100644
@@ -353,6 +353,18 @@ struct fcoe_port {
 	u8		      data_src_addr[ETH_ALEN];
 	struct net_device * (*get_netdev)(const struct fc_lport *lport);
 };
+
+/**
+ * fcoe_get_netdev() - Return the net device associated with a local port
+ * @lport: The local port to get the net device from
+ */
+static inline struct net_device *fcoe_get_netdev(const struct fc_lport *lport)
+{
+	struct fcoe_port *port = ((struct fcoe_port *)lport_priv(lport));
+
+	return (port->get_netdev) ? port->get_netdev(lport) : NULL;
+}
+
 void fcoe_clean_pending_queue(struct fc_lport *);
 void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb);
 void fcoe_queue_timer(ulong lport);
#16 lore raw

PATCH 11/16 libfcoe, fcoe: move fcoe_link_speed_update() to libfcoe and export it

In reply to Robert Love

From: Yi Zou <[email protected]>

With the previous patch, fcoe_link_speed_update() can be moved into libfcoe and exported to used by fcoe, bnx2fc, and etc.

---
 drivers/scsi/fcoe/fcoe.c           |   35 -----------------------------------
 drivers/scsi/fcoe/fcoe_transport.c |   35 +++++++++++++++++++++++++++++++++++
 include/scsi/libfcoe.h             |    1 +
 3 files changed, 36 insertions(+), 35 deletions(-)
drivers/scsi/fcoe/fcoe.c +0 -35
index 4cec9dd..64bb531 100644
@@ -82,7 +82,6 @@ static int fcoe_rcv(struct sk_buff *, struct net_device *,
 		    struct packet_type *, struct net_device *);
 static int fcoe_percpu_receive_thread(void *);
 static void fcoe_percpu_clean(struct fc_lport *);
-static int fcoe_link_speed_update(struct fc_lport *);
 static int fcoe_link_ok(struct fc_lport *);
 
 static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
@@ -2388,40 +2387,6 @@ static int fcoe_ctlr_alloc(struct net_device *netdev)
 }
 
 /**
- * fcoe_link_speed_update() - Update the supported and actual link speeds
- * @lport: The local port to update speeds for
- *
- * Returns: 0 if the ethtool query was successful
- *          -1 if the ethtool query failed
- */
-static int fcoe_link_speed_update(struct fc_lport *lport)
-{
-	struct net_device *netdev = fcoe_netdev(lport);
-	struct ethtool_cmd ecmd;
-
-	if (!__ethtool_get_settings(netdev, &ecmd)) {
-		lport->link_supported_speeds &=
-			~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
-		if (ecmd.supported & (SUPPORTED_1000baseT_Half |
-				      SUPPORTED_1000baseT_Full))
-			lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
-		if (ecmd.supported & SUPPORTED_10000baseT_Full)
-			lport->link_supported_speeds |=
-				FC_PORTSPEED_10GBIT;
-		switch (ethtool_cmd_speed(&ecmd)) {
-		case SPEED_1000:
-			lport->link_speed = FC_PORTSPEED_1GBIT;
-			break;
-		case SPEED_10000:
-			lport->link_speed = FC_PORTSPEED_10GBIT;
-			break;
-		}
-		return 0;
-	}
-	return -1;
-}
-
-/**
  * fcoe_link_ok() - Check if the link is OK for a local port
  * @lport: The local port to check link on
  *
drivers/scsi/fcoe/fcoe_transport.c +35 -0
index 83e78f9..3c6846f 100644
@@ -83,6 +83,41 @@ static struct notifier_block libfcoe_notifier = {
 	.notifier_call = libfcoe_device_notification,
 };
 
+/**
+ * fcoe_link_speed_update() - Update the supported and actual link speeds
+ * @lport: The local port to update speeds for
+ *
+ * Returns: 0 if the ethtool query was successful
+ *          -1 if the ethtool query failed
+ */
+int fcoe_link_speed_update(struct fc_lport *lport)
+{
+	struct net_device *netdev = fcoe_get_netdev(lport);
+	struct ethtool_cmd ecmd;
+
+	if (!__ethtool_get_settings(netdev, &ecmd)) {
+		lport->link_supported_speeds &=
+			~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
+		if (ecmd.supported & (SUPPORTED_1000baseT_Half |
+				      SUPPORTED_1000baseT_Full))
+			lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
+		if (ecmd.supported & SUPPORTED_10000baseT_Full)
+			lport->link_supported_speeds |=
+				FC_PORTSPEED_10GBIT;
+		switch (ethtool_cmd_speed(&ecmd)) {
+		case SPEED_1000:
+			lport->link_speed = FC_PORTSPEED_1GBIT;
+			break;
+		case SPEED_10000:
+			lport->link_speed = FC_PORTSPEED_10GBIT;
+			break;
+		}
+		return 0;
+	}
+	return -1;
+}
+EXPORT_SYMBOL_GPL(fcoe_link_speed_update);
+
 void __fcoe_get_lesb(struct fc_lport *lport,
 		     struct fc_els_lesb *fc_lesb,
 		     struct net_device *netdev)
include/scsi/libfcoe.h +1 -0
index 746bc58..6c59ba7 100644
@@ -260,6 +260,7 @@ void __fcoe_get_lesb(struct fc_lport *lport, struct fc_els_lesb *fc_lesb,
 		     struct net_device *netdev);
 void fcoe_wwn_to_str(u64 wwn, char *buf, int len);
 int fcoe_validate_vport_create(struct fc_vport *vport);
+int fcoe_link_speed_update(struct fc_lport *);
 
 /**
  * is_fip_mode() - returns true if FIP mode selected.
#17 lore raw

PATCH 12/16 libfcoe, fcoe: consolidate the fcoe_ctlr_get_lesb/fcoe_get_lesb

In reply to Robert Love

From: Yi Zou <[email protected]>

Similarly they can be moved into libfcoe instead of being private to fcoe now. Also add comments particularly on the term LESB to the corresponding function.

---
 drivers/scsi/fcoe/fcoe.c           |   40 ---------------------------
 drivers/scsi/fcoe/fcoe_transport.c |   54 ++++++++++++++++++++++++++++++++++++
 include/scsi/libfcoe.h             |    2 +
 3 files changed, 56 insertions(+), 40 deletions(-)
drivers/scsi/fcoe/fcoe.c +0 -40
index 64bb531..0b33368 100644
@@ -130,8 +130,6 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
 				      void *, u32 timeout);
 static void fcoe_recv_frame(struct sk_buff *skb);
 
-static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);
-
 /* notification function for packets from net device */
 static struct notifier_block fcoe_notifier = {
 	.notifier_call = fcoe_device_notification,
@@ -155,7 +153,6 @@ 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 = {
@@ -2858,43 +2855,6 @@ static void fcoe_set_vport_symbolic_name(struct fc_vport *vport)
 			     NULL, NULL, 3 * lport->r_a_tov);
 }
 
-/**
- * fcoe_get_lesb() - Fill the FCoE Link Error Status Block
- * @lport: the local port
- * @fc_lesb: the link error status block
- */
-static void fcoe_get_lesb(struct fc_lport *lport,
-			 struct fc_els_lesb *fc_lesb)
-{
-	struct net_device *netdev = fcoe_netdev(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 =
drivers/scsi/fcoe/fcoe_transport.c +54 -0

66 lines not on this page · raw message

include/scsi/libfcoe.h +2 -0
index 6c59ba7..4427393 100644
@@ -261,6 +261,8 @@ void __fcoe_get_lesb(struct fc_lport *lport, struct fc_els_lesb *fc_lesb,
 void fcoe_wwn_to_str(u64 wwn, char *buf, int len);
 int fcoe_validate_vport_create(struct fc_vport *vport);
 int fcoe_link_speed_update(struct fc_lport *);
+void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);
+void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev);
 
 /**
  * is_fip_mode() - returns true if FIP mode selected.
#18 lore raw

PATCH 13/16 bnx2fc: add support to get_netdev for bnx2f_interface

In reply to Robert Love

From: Yi Zou <[email protected]>

Adds support to fcoe_port's newly added get_netdev fucntion pointer for bnx2fc.

---
 drivers/scsi/bnx2fc/bnx2fc_fcoe.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/scsi/bnx2fc/bnx2fc_fcoe.c +3 -2
index 8d975ef..9b9ccc9 100644
@@ -119,7 +119,7 @@ static inline struct net_device *bnx2fc_netdev(const struct fc_lport *lport)
 static void bnx2fc_get_lesb(struct fc_lport *lport,
 			    struct fc_els_lesb *fc_lesb)
 {
-	struct net_device *netdev = bnx2fc_netdev(lport);
+	struct net_device *netdev = fcoe_get_netdev(lport);
 
 	__fcoe_get_lesb(lport, fc_lesb, netdev);
 }
@@ -127,7 +127,7 @@ static void bnx2fc_get_lesb(struct fc_lport *lport,
 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 net_device *netdev = fcoe_get_netdev(fip->lp);
 	struct fcoe_fc_els_lesb *fcoe_lesb;
 	struct fc_els_lesb fc_lesb;
 
@@ -1499,6 +1499,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface,
 	port = lport_priv(lport);
 	port->lport = lport;
 	port->priv = interface;
+	port->get_netdev = bnx2fc_netdev;
 	INIT_WORK(&port->destroy_work, bnx2fc_destroy_work);
 
 	/* Configure fcoe_port */
#19 lore raw

PATCH 14/16 bnx2fc: use fcoe_link_speed_update() from the exported symbol in libfcoe

In reply to Robert Love

From: Yi Zou <[email protected]>

We have fcoe_link_speed_update() in libfcoe ready for use now, take out the bnx2fc version which is almost the same.

---
 drivers/scsi/bnx2fc/bnx2fc_fcoe.c |   33 ++-------------------------------
 1 file changed, 2 insertions(+), 31 deletions(-)
drivers/scsi/bnx2fc/bnx2fc_fcoe.c +2 -31
index 9b9ccc9..a1c687c 100644
@@ -738,35 +738,6 @@ static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev)
 	return 0;
 }
 
-static void bnx2fc_link_speed_update(struct fc_lport *lport)
-{
-	struct fcoe_port *port = lport_priv(lport);
-	struct bnx2fc_interface *interface = port->priv;
-	struct net_device *netdev = interface->netdev;
-	struct ethtool_cmd ecmd;
-
-	if (!__ethtool_get_settings(netdev, &ecmd)) {
-		lport->link_supported_speeds &=
-			~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
-		if (ecmd.supported & (SUPPORTED_1000baseT_Half |
-				      SUPPORTED_1000baseT_Full))
-			lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
-		if (ecmd.supported & SUPPORTED_10000baseT_Full)
-			lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
-
-		switch (ethtool_cmd_speed(&ecmd)) {
-		case SPEED_1000:
-			lport->link_speed = FC_PORTSPEED_1GBIT;
-			break;
-		case SPEED_2500:
-			lport->link_speed = FC_PORTSPEED_2GBIT;
-			break;
-		case SPEED_10000:
-			lport->link_speed = FC_PORTSPEED_10GBIT;
-			break;
-		}
-	}
-}
 static int bnx2fc_link_ok(struct fc_lport *lport)
 {
 	struct fcoe_port *port = lport_priv(lport);
@@ -824,7 +795,7 @@ static int bnx2fc_net_config(struct fc_lport *lport, struct net_device *netdev)
 	port->fcoe_pending_queue_active = 0;
 	setup_timer(&port->timer, fcoe_queue_timer, (unsigned long) lport);
 
-	bnx2fc_link_speed_update(lport);
+	fcoe_link_speed_update(lport);
 
 	if (!lport->vport) {
 		if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN))
@@ -928,7 +899,7 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event,
 		BNX2FC_HBA_DBG(lport, "netevent handler - event=%s %ld\n",
 				interface->netdev->name, event);
 
-		bnx2fc_link_speed_update(lport);
+		fcoe_link_speed_update(lport);
 
 		cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
 
#20 lore raw

PATCH 15/16 bnx2fc: use fcoe_get_lesb/fcoe_ctlr_get_lesb() directly from libfcoe

In reply to Robert Love

From: Yi Zou <[email protected]>

Drop the bnx2fc_xxx versions as they are basically the same.

---
 drivers/scsi/bnx2fc/bnx2fc_fcoe.c |   53 +++++--------------------------------
 1 file changed, 7 insertions(+), 46 deletions(-)
drivers/scsi/bnx2fc/bnx2fc_fcoe.c +7 -46
index a1c687c..4d5c721 100644
@@ -93,7 +93,6 @@ 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);
@@ -111,44 +110,6 @@ static inline struct net_device *bnx2fc_netdev(const struct fc_lport *lport)
 		((struct fcoe_port *)lport_priv(lport))->priv)->netdev;
 }
 
-/**
- * bnx2fc_get_lesb() - Fill the FCoE Link Error Status Block
- * @lport: the local port
- * @fc_lesb: the link error status block
- */
-static void bnx2fc_get_lesb(struct fc_lport *lport,
-			    struct fc_els_lesb *fc_lesb)
-{
-	struct net_device *netdev = fcoe_get_netdev(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 = fcoe_get_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 =
@@ -2637,12 +2598,12 @@ module_exit(bnx2fc_mod_exit);
 
 static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = {
 	.set_fcoe_ctlr_enabled = bnx2fc_ctlr_enabled,
-	.get_fcoe_ctlr_link_fail = 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_ctlr_link_fail = fcoe_ctlr_get_lesb,
+	.get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
+	.get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
+	.get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb,
+	.get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb,
+	.get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb,
 
 	.get_fcoe_fcf_selected = fcoe_fcf_get_selected,
 	.get_fcoe_fcf_vlan_id = bnx2fc_fcf_get_vlan_id,
@@ -2749,7 +2710,7 @@ static struct libfc_function_template bnx2fc_libfc_fcn_templ = {
 	.elsct_send		= bnx2fc_elsct_send,
 	.fcp_abort_io		= bnx2fc_abort_io,
 	.fcp_cleanup		= bnx2fc_cleanup,
-	.get_lesb		= bnx2fc_get_lesb,
+	.get_lesb		= fcoe_get_lesb,
 	.rport_event_callback	= bnx2fc_rport_event_handler,
 };
 
#21 lore raw

PATCH 16/16 debris left by "[SCSI] libfcoe: Remove mutex_trylock/restart_syscall checks"

In reply to Robert Love

From: Al Viro <[email protected]>

AFAICS, the situation for fcoe_transport_disable() seems to be
the same as for fcoe_transport_enable(). IOW, shouldn't it have restart_syscall() removed as well? I don't see any in-tree ->disable() instances that could return -ERESTARTSYS, anyway...

---
 drivers/scsi/fcoe/fcoe_transport.c |    6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/scsi/fcoe/fcoe_transport.c +1 -5
index dd1aeb4..f3a5a53 100644
@@ -962,11 +962,7 @@ out_putdev:
 	dev_put(netdev);
 out_nodev:
 	mutex_unlock(&ft_mutex);
-
-	if (rc == -ERESTARTSYS)
-		return restart_syscall();
-	else
-		return rc;
+	return rc;
 }
 
 /**
Reviewed-by on the v1 series
#22 lore raw
In reply to Robert Love
Quoted 35 lines · Robert Love

There are two primary changes within this update. Additionally there are two or three fix/cleanup patches.

The first change is the addition of the fcoe_sysfs "control" interfaces. These patches were well vetted on the scsi mailing list and have only seen validation and a minor fix or two, as the result testing, since the last RFC posting.

The second change is a cleanup/consolidation series from Yi that touches libfcoe.ko, fcoe.ko and bnx2fc.ko. These patches were well vetted on the fcoe mailing list and should be good to go as well. They make no functional change.

I will compose a pull-request and send it soon, but I wanted to make sure the most recent versions of these patches were posted to linux-scsi first.

---

Al Viro (1):
debris left by "[SCSI] libfcoe: Remove mutex_trylock/restart_syscall checks"

Robert Love (7):
Documentation: Add missing devices/ to devices path
libfcoe: Save some memory and optimize name lookups
libfcoe: Add fcoe_sysfs debug logging level libfcoe, fcoe, bnx2fc: Add new fcoe control interface
fcoe: Use the fcoe_sysfs control interface
bnx2fc: Use the fcoe_sysfs control interface libfc, libfcoe, fcoe: Convert debug_logging macros to pr_info

Vasu Dev (1):
libfc: fix REC handling

Yi Zou (7):
fcoe: prep work to start consolidate the usage of fcoe_netdev
fcoe: add support to the get_netdev() for fcoe_interface libfcoe, fcoe: move fcoe_link_speed_update() to libfcoe and export it libfcoe, fcoe: consolidate the fcoe_ctlr_get_lesb/fcoe_get_lesb
bnx2fc: add support to get_netdev for bnx2f_interface
bnx2fc: use fcoe_link_speed_update() from the exported symbol in libfcoe
bnx2fc: use fcoe_get_lesb/fcoe_ctlr_get_lesb() directly from libfcoe

Quoted 14 lines
  Documentation/ABI/testing/sysfs-bus-fcoe |   45 +++++
  drivers/scsi/bnx2fc/bnx2fc_fcoe.c        |  256 +++++++++++++++++-------------
  drivers/scsi/fcoe/fcoe.c                 |  212 +++++++++++++++----------
  drivers/scsi/fcoe/fcoe.h                 |    6 -
  drivers/scsi/fcoe/fcoe_ctlr.c            |   17 +-
  drivers/scsi/fcoe/fcoe_sysfs.c           |  186 ++++++++++++++++++----
  drivers/scsi/fcoe/fcoe_transport.c       |  199 +++++++++++++++++++++++
  drivers/scsi/fcoe/libfcoe.h              |   20 +-
  drivers/scsi/libfc/fc_fcp.c              |    6 -
  drivers/scsi/libfc/fc_libfc.h            |   38 ++--
  include/scsi/fcoe_sysfs.h                |   11 +
  include/scsi/libfcoe.h                   |   32 ++++
  12 files changed, 749 insertions(+), 279 deletions(-)

Changes look good to me, except for the minor comment in patch 5.