|
@@ -101,10 +101,11 @@ static int fcoe_ddp_done(struct fc_lport *, u16);
|
|
|
|
|
|
static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *);
|
|
|
|
|
|
-static int fcoe_create(const char *, struct kernel_param *);
|
|
|
-static int fcoe_destroy(const char *, struct kernel_param *);
|
|
|
-static int fcoe_enable(const char *, struct kernel_param *);
|
|
|
-static int fcoe_disable(const char *, struct kernel_param *);
|
|
|
+static bool fcoe_match(struct net_device *netdev);
|
|
|
+static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode);
|
|
|
+static int fcoe_destroy(struct net_device *netdev);
|
|
|
+static int fcoe_enable(struct net_device *netdev);
|
|
|
+static int fcoe_disable(struct net_device *netdev);
|
|
|
|
|
|
static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
|
|
|
u32 did, struct fc_frame *,
|
|
@@ -117,24 +118,6 @@ static void fcoe_recv_frame(struct sk_buff *skb);
|
|
|
|
|
|
static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);
|
|
|
|
|
|
-module_param_call(create, fcoe_create, NULL, (void *)FIP_MODE_FABRIC, S_IWUSR);
|
|
|
-__MODULE_PARM_TYPE(create, "string");
|
|
|
-MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface");
|
|
|
-module_param_call(create_vn2vn, fcoe_create, NULL,
|
|
|
- (void *)FIP_MODE_VN2VN, S_IWUSR);
|
|
|
-__MODULE_PARM_TYPE(create_vn2vn, "string");
|
|
|
-MODULE_PARM_DESC(create_vn2vn, " Creates a VN_node to VN_node FCoE instance "
|
|
|
- "on an Ethernet interface");
|
|
|
-module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
|
|
|
-__MODULE_PARM_TYPE(destroy, "string");
|
|
|
-MODULE_PARM_DESC(destroy, " Destroys fcoe instance on a ethernet interface");
|
|
|
-module_param_call(enable, fcoe_enable, NULL, NULL, S_IWUSR);
|
|
|
-__MODULE_PARM_TYPE(enable, "string");
|
|
|
-MODULE_PARM_DESC(enable, " Enables fcoe on a ethernet interface.");
|
|
|
-module_param_call(disable, fcoe_disable, NULL, NULL, S_IWUSR);
|
|
|
-__MODULE_PARM_TYPE(disable, "string");
|
|
|
-MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface.");
|
|
|
-
|
|
|
/* notification function for packets from net device */
|
|
|
static struct notifier_block fcoe_notifier = {
|
|
|
.notifier_call = fcoe_device_notification,
|
|
@@ -1938,40 +1921,17 @@ out:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * fcoe_if_to_netdev() - Parse a name buffer to get a net device
|
|
|
- * @buffer: The name of the net device
|
|
|
- *
|
|
|
- * Returns: NULL or a ptr to net_device
|
|
|
- */
|
|
|
-static struct net_device *fcoe_if_to_netdev(const char *buffer)
|
|
|
-{
|
|
|
- char *cp;
|
|
|
- char ifname[IFNAMSIZ + 2];
|
|
|
-
|
|
|
- if (buffer) {
|
|
|
- strlcpy(ifname, buffer, IFNAMSIZ);
|
|
|
- cp = ifname + strlen(ifname);
|
|
|
- while (--cp >= ifname && *cp == '\n')
|
|
|
- *cp = '\0';
|
|
|
- return dev_get_by_name(&init_net, ifname);
|
|
|
- }
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* fcoe_disable() - Disables a FCoE interface
|
|
|
- * @buffer: The name of the Ethernet interface to be disabled
|
|
|
- * @kp: The associated kernel parameter
|
|
|
+ * @netdev : The net_device object the Ethernet interface to create on
|
|
|
*
|
|
|
- * Called from sysfs.
|
|
|
+ * Called from fcoe transport.
|
|
|
*
|
|
|
* Returns: 0 for success
|
|
|
*/
|
|
|
-static int fcoe_disable(const char *buffer, struct kernel_param *kp)
|
|
|
+static int fcoe_disable(struct net_device *netdev)
|
|
|
{
|
|
|
struct fcoe_interface *fcoe;
|
|
|
- struct net_device *netdev;
|
|
|
int rc = 0;
|
|
|
|
|
|
mutex_lock(&fcoe_config_mutex);
|
|
@@ -1987,16 +1947,9 @@ static int fcoe_disable(const char *buffer, struct kernel_param *kp)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
- netdev = fcoe_if_to_netdev(buffer);
|
|
|
- if (!netdev) {
|
|
|
- rc = -ENODEV;
|
|
|
- goto out_nodev;
|
|
|
- }
|
|
|
-
|
|
|
if (!rtnl_trylock()) {
|
|
|
- dev_put(netdev);
|
|
|
mutex_unlock(&fcoe_config_mutex);
|
|
|
- return restart_syscall();
|
|
|
+ return -ERESTARTSYS;
|
|
|
}
|
|
|
|
|
|
fcoe = fcoe_hostlist_lookup_port(netdev);
|
|
@@ -2008,7 +1961,6 @@ static int fcoe_disable(const char *buffer, struct kernel_param *kp)
|
|
|
} else
|
|
|
rc = -ENODEV;
|
|
|
|
|
|
- dev_put(netdev);
|
|
|
out_nodev:
|
|
|
mutex_unlock(&fcoe_config_mutex);
|
|
|
return rc;
|
|
@@ -2016,17 +1968,15 @@ out_nodev:
|
|
|
|
|
|
/**
|
|
|
* fcoe_enable() - Enables a FCoE interface
|
|
|
- * @buffer: The name of the Ethernet interface to be enabled
|
|
|
- * @kp: The associated kernel parameter
|
|
|
+ * @netdev : The net_device object the Ethernet interface to create on
|
|
|
*
|
|
|
- * Called from sysfs.
|
|
|
+ * Called from fcoe transport.
|
|
|
*
|
|
|
* Returns: 0 for success
|
|
|
*/
|
|
|
-static int fcoe_enable(const char *buffer, struct kernel_param *kp)
|
|
|
+static int fcoe_enable(struct net_device *netdev)
|
|
|
{
|
|
|
struct fcoe_interface *fcoe;
|
|
|
- struct net_device *netdev;
|
|
|
int rc = 0;
|
|
|
|
|
|
mutex_lock(&fcoe_config_mutex);
|
|
@@ -2041,17 +1991,9 @@ static int fcoe_enable(const char *buffer, struct kernel_param *kp)
|
|
|
goto out_nodev;
|
|
|
}
|
|
|
#endif
|
|
|
-
|
|
|
- netdev = fcoe_if_to_netdev(buffer);
|
|
|
- if (!netdev) {
|
|
|
- rc = -ENODEV;
|
|
|
- goto out_nodev;
|
|
|
- }
|
|
|
-
|
|
|
if (!rtnl_trylock()) {
|
|
|
- dev_put(netdev);
|
|
|
mutex_unlock(&fcoe_config_mutex);
|
|
|
- return restart_syscall();
|
|
|
+ return -ERESTARTSYS;
|
|
|
}
|
|
|
|
|
|
fcoe = fcoe_hostlist_lookup_port(netdev);
|
|
@@ -2062,7 +2004,6 @@ static int fcoe_enable(const char *buffer, struct kernel_param *kp)
|
|
|
else if (!fcoe_link_ok(fcoe->ctlr.lp))
|
|
|
fcoe_ctlr_link_up(&fcoe->ctlr);
|
|
|
|
|
|
- dev_put(netdev);
|
|
|
out_nodev:
|
|
|
mutex_unlock(&fcoe_config_mutex);
|
|
|
return rc;
|
|
@@ -2070,17 +2011,15 @@ out_nodev:
|
|
|
|
|
|
/**
|
|
|
* fcoe_destroy() - Destroy a FCoE interface
|
|
|
- * @buffer: The name of the Ethernet interface to be destroyed
|
|
|
- * @kp: The associated kernel parameter
|
|
|
+ * @netdev : The net_device object the Ethernet interface to create on
|
|
|
*
|
|
|
- * Called from sysfs.
|
|
|
+ * Called from fcoe transport
|
|
|
*
|
|
|
* Returns: 0 for success
|
|
|
*/
|
|
|
-static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
|
|
|
+static int fcoe_destroy(struct net_device *netdev)
|
|
|
{
|
|
|
struct fcoe_interface *fcoe;
|
|
|
- struct net_device *netdev;
|
|
|
int rc = 0;
|
|
|
|
|
|
mutex_lock(&fcoe_config_mutex);
|
|
@@ -2095,32 +2034,21 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
|
|
|
goto out_nodev;
|
|
|
}
|
|
|
#endif
|
|
|
-
|
|
|
- netdev = fcoe_if_to_netdev(buffer);
|
|
|
- if (!netdev) {
|
|
|
- rc = -ENODEV;
|
|
|
- goto out_nodev;
|
|
|
- }
|
|
|
-
|
|
|
if (!rtnl_trylock()) {
|
|
|
- dev_put(netdev);
|
|
|
mutex_unlock(&fcoe_config_mutex);
|
|
|
- return restart_syscall();
|
|
|
+ return -ERESTARTSYS;
|
|
|
}
|
|
|
|
|
|
fcoe = fcoe_hostlist_lookup_port(netdev);
|
|
|
if (!fcoe) {
|
|
|
rtnl_unlock();
|
|
|
rc = -ENODEV;
|
|
|
- goto out_putdev;
|
|
|
+ goto out_nodev;
|
|
|
}
|
|
|
fcoe_interface_cleanup(fcoe);
|
|
|
list_del(&fcoe->list);
|
|
|
/* RTNL mutex is dropped by fcoe_if_destroy */
|
|
|
fcoe_if_destroy(fcoe->ctlr.lp);
|
|
|
-
|
|
|
-out_putdev:
|
|
|
- dev_put(netdev);
|
|
|
out_nodev:
|
|
|
mutex_unlock(&fcoe_config_mutex);
|
|
|
return rc;
|
|
@@ -2142,28 +2070,40 @@ static void fcoe_destroy_work(struct work_struct *work)
|
|
|
mutex_unlock(&fcoe_config_mutex);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * fcoe_match() - Check if the FCoE is supported on the given netdevice
|
|
|
+ * @netdev : The net_device object the Ethernet interface to create on
|
|
|
+ *
|
|
|
+ * Called from fcoe transport.
|
|
|
+ *
|
|
|
+ * Returns: always returns true as this is the default FCoE transport,
|
|
|
+ * i.e., support all netdevs.
|
|
|
+ */
|
|
|
+static bool fcoe_match(struct net_device *netdev)
|
|
|
+{
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* fcoe_create() - Create a fcoe interface
|
|
|
- * @buffer: The name of the Ethernet interface to create on
|
|
|
- * @kp: The associated kernel param
|
|
|
+ * @netdev : The net_device object the Ethernet interface to create on
|
|
|
+ * @fip_mode: The FIP mode for this creation
|
|
|
*
|
|
|
- * Called from sysfs.
|
|
|
+ * Called from fcoe transport
|
|
|
*
|
|
|
* Returns: 0 for success
|
|
|
*/
|
|
|
-static int fcoe_create(const char *buffer, struct kernel_param *kp)
|
|
|
+static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
|
|
|
{
|
|
|
- enum fip_state fip_mode = (enum fip_state)(long)kp->arg;
|
|
|
int rc;
|
|
|
struct fcoe_interface *fcoe;
|
|
|
struct fc_lport *lport;
|
|
|
- struct net_device *netdev;
|
|
|
|
|
|
mutex_lock(&fcoe_config_mutex);
|
|
|
|
|
|
if (!rtnl_trylock()) {
|
|
|
mutex_unlock(&fcoe_config_mutex);
|
|
|
- return restart_syscall();
|
|
|
+ return -ERESTARTSYS;
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_FCOE_MODULE
|
|
@@ -2178,22 +2118,16 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
- netdev = fcoe_if_to_netdev(buffer);
|
|
|
- if (!netdev) {
|
|
|
- rc = -ENODEV;
|
|
|
- goto out_nodev;
|
|
|
- }
|
|
|
-
|
|
|
/* look for existing lport */
|
|
|
if (fcoe_hostlist_lookup(netdev)) {
|
|
|
rc = -EEXIST;
|
|
|
- goto out_putdev;
|
|
|
+ goto out_nodev;
|
|
|
}
|
|
|
|
|
|
fcoe = fcoe_interface_create(netdev, fip_mode);
|
|
|
if (IS_ERR(fcoe)) {
|
|
|
rc = PTR_ERR(fcoe);
|
|
|
- goto out_putdev;
|
|
|
+ goto out_nodev;
|
|
|
}
|
|
|
|
|
|
lport = fcoe_if_create(fcoe, &netdev->dev, 0);
|
|
@@ -2222,15 +2156,12 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
|
|
|
* should be holding a reference taken in fcoe_if_create().
|
|
|
*/
|
|
|
fcoe_interface_put(fcoe);
|
|
|
- dev_put(netdev);
|
|
|
rtnl_unlock();
|
|
|
mutex_unlock(&fcoe_config_mutex);
|
|
|
|
|
|
return 0;
|
|
|
out_free:
|
|
|
fcoe_interface_put(fcoe);
|
|
|
-out_putdev:
|
|
|
- dev_put(netdev);
|
|
|
out_nodev:
|
|
|
rtnl_unlock();
|
|
|
mutex_unlock(&fcoe_config_mutex);
|
|
@@ -2433,6 +2364,18 @@ static int fcoe_hostlist_add(const struct fc_lport *lport)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+static struct fcoe_transport fcoe_sw_transport = {
|
|
|
+ .name = {FCOE_TRANSPORT_DEFAULT},
|
|
|
+ .attached = false,
|
|
|
+ .list = LIST_HEAD_INIT(fcoe_sw_transport.list),
|
|
|
+ .match = fcoe_match,
|
|
|
+ .create = fcoe_create,
|
|
|
+ .destroy = fcoe_destroy,
|
|
|
+ .enable = fcoe_enable,
|
|
|
+ .disable = fcoe_disable,
|
|
|
+};
|
|
|
+
|
|
|
/**
|
|
|
* fcoe_init() - Initialize fcoe.ko
|
|
|
*
|
|
@@ -2444,6 +2387,14 @@ static int __init fcoe_init(void)
|
|
|
unsigned int cpu;
|
|
|
int rc = 0;
|
|
|
|
|
|
+ /* register as a fcoe transport */
|
|
|
+ rc = fcoe_transport_attach(&fcoe_sw_transport);
|
|
|
+ if (rc) {
|
|
|
+ printk(KERN_ERR "failed to register an fcoe transport, check "
|
|
|
+ "if libfcoe is loaded\n");
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
mutex_lock(&fcoe_config_mutex);
|
|
|
|
|
|
for_each_possible_cpu(cpu) {
|
|
@@ -2520,6 +2471,9 @@ static void __exit fcoe_exit(void)
|
|
|
/* detach from scsi transport
|
|
|
* must happen after all destroys are done, therefor after the flush */
|
|
|
fcoe_if_exit();
|
|
|
+
|
|
|
+ /* detach from fcoe transport */
|
|
|
+ fcoe_transport_detach(&fcoe_sw_transport);
|
|
|
}
|
|
|
module_exit(fcoe_exit);
|
|
|
|