diff options
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 135 |
1 files changed, 131 insertions, 4 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index a30ffaa1222c..e3896fcb06e3 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -101,6 +101,8 @@ static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *); | |||
101 | 101 | ||
102 | static int fcoe_create(const char *, struct kernel_param *); | 102 | static int fcoe_create(const char *, struct kernel_param *); |
103 | static int fcoe_destroy(const char *, struct kernel_param *); | 103 | static int fcoe_destroy(const char *, struct kernel_param *); |
104 | static int fcoe_enable(const char *, struct kernel_param *); | ||
105 | static int fcoe_disable(const char *, struct kernel_param *); | ||
104 | 106 | ||
105 | static struct fc_seq *fcoe_elsct_send(struct fc_lport *, | 107 | static struct fc_seq *fcoe_elsct_send(struct fc_lport *, |
106 | u32 did, struct fc_frame *, | 108 | u32 did, struct fc_frame *, |
@@ -115,10 +117,16 @@ static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *); | |||
115 | 117 | ||
116 | module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR); | 118 | module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR); |
117 | __MODULE_PARM_TYPE(create, "string"); | 119 | __MODULE_PARM_TYPE(create, "string"); |
118 | MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in."); | 120 | MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface"); |
119 | module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); | 121 | module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); |
120 | __MODULE_PARM_TYPE(destroy, "string"); | 122 | __MODULE_PARM_TYPE(destroy, "string"); |
121 | MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe"); | 123 | MODULE_PARM_DESC(destroy, " Destroys fcoe instance on a ethernet interface"); |
124 | module_param_call(enable, fcoe_enable, NULL, NULL, S_IWUSR); | ||
125 | __MODULE_PARM_TYPE(enable, "string"); | ||
126 | MODULE_PARM_DESC(enable, " Enables fcoe on a ethernet interface."); | ||
127 | module_param_call(disable, fcoe_disable, NULL, NULL, S_IWUSR); | ||
128 | __MODULE_PARM_TYPE(disable, "string"); | ||
129 | MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface."); | ||
122 | 130 | ||
123 | /* notification function for packets from net device */ | 131 | /* notification function for packets from net device */ |
124 | static struct notifier_block fcoe_notifier = { | 132 | static struct notifier_block fcoe_notifier = { |
@@ -545,6 +553,23 @@ static void fcoe_queue_timer(ulong lport) | |||
545 | } | 553 | } |
546 | 554 | ||
547 | /** | 555 | /** |
556 | * fcoe_get_wwn() - Get the world wide name from LLD if it supports it | ||
557 | * @netdev: the associated net device | ||
558 | * @wwn: the output WWN | ||
559 | * @type: the type of WWN (WWPN or WWNN) | ||
560 | * | ||
561 | * Returns: 0 for success | ||
562 | */ | ||
563 | static int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type) | ||
564 | { | ||
565 | const struct net_device_ops *ops = netdev->netdev_ops; | ||
566 | |||
567 | if (ops->ndo_fcoe_get_wwn) | ||
568 | return ops->ndo_fcoe_get_wwn(netdev, wwn, type); | ||
569 | return -EINVAL; | ||
570 | } | ||
571 | |||
572 | /** | ||
548 | * fcoe_netdev_config() - Set up net devive for SW FCoE | 573 | * fcoe_netdev_config() - Set up net devive for SW FCoE |
549 | * @lport: The local port that is associated with the net device | 574 | * @lport: The local port that is associated with the net device |
550 | * @netdev: The associated net device | 575 | * @netdev: The associated net device |
@@ -611,9 +636,13 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) | |||
611 | */ | 636 | */ |
612 | if (netdev->priv_flags & IFF_802_1Q_VLAN) | 637 | if (netdev->priv_flags & IFF_802_1Q_VLAN) |
613 | vid = vlan_dev_vlan_id(netdev); | 638 | vid = vlan_dev_vlan_id(netdev); |
614 | wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0); | 639 | |
640 | if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) | ||
641 | wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0); | ||
615 | fc_set_wwnn(lport, wwnn); | 642 | fc_set_wwnn(lport, wwnn); |
616 | wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 2, vid); | 643 | if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN)) |
644 | wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, | ||
645 | 2, vid); | ||
617 | fc_set_wwpn(lport, wwpn); | 646 | fc_set_wwpn(lport, wwpn); |
618 | } | 647 | } |
619 | 648 | ||
@@ -1838,6 +1867,104 @@ static struct net_device *fcoe_if_to_netdev(const char *buffer) | |||
1838 | } | 1867 | } |
1839 | 1868 | ||
1840 | /** | 1869 | /** |
1870 | * fcoe_disable() - Disables a FCoE interface | ||
1871 | * @buffer: The name of the Ethernet interface to be disabled | ||
1872 | * @kp: The associated kernel parameter | ||
1873 | * | ||
1874 | * Called from sysfs. | ||
1875 | * | ||
1876 | * Returns: 0 for success | ||
1877 | */ | ||
1878 | static int fcoe_disable(const char *buffer, struct kernel_param *kp) | ||
1879 | { | ||
1880 | struct fcoe_interface *fcoe; | ||
1881 | struct net_device *netdev; | ||
1882 | int rc = 0; | ||
1883 | |||
1884 | mutex_lock(&fcoe_config_mutex); | ||
1885 | #ifdef CONFIG_FCOE_MODULE | ||
1886 | /* | ||
1887 | * Make sure the module has been initialized, and is not about to be | ||
1888 | * removed. Module paramter sysfs files are writable before the | ||
1889 | * module_init function is called and after module_exit. | ||
1890 | */ | ||
1891 | if (THIS_MODULE->state != MODULE_STATE_LIVE) { | ||
1892 | rc = -ENODEV; | ||
1893 | goto out_nodev; | ||
1894 | } | ||
1895 | #endif | ||
1896 | |||
1897 | netdev = fcoe_if_to_netdev(buffer); | ||
1898 | if (!netdev) { | ||
1899 | rc = -ENODEV; | ||
1900 | goto out_nodev; | ||
1901 | } | ||
1902 | |||
1903 | rtnl_lock(); | ||
1904 | fcoe = fcoe_hostlist_lookup_port(netdev); | ||
1905 | rtnl_unlock(); | ||
1906 | |||
1907 | if (fcoe) | ||
1908 | fc_fabric_logoff(fcoe->ctlr.lp); | ||
1909 | else | ||
1910 | rc = -ENODEV; | ||
1911 | |||
1912 | dev_put(netdev); | ||
1913 | out_nodev: | ||
1914 | mutex_unlock(&fcoe_config_mutex); | ||
1915 | return rc; | ||
1916 | } | ||
1917 | |||
1918 | /** | ||
1919 | * fcoe_enable() - Enables a FCoE interface | ||
1920 | * @buffer: The name of the Ethernet interface to be enabled | ||
1921 | * @kp: The associated kernel parameter | ||
1922 | * | ||
1923 | * Called from sysfs. | ||
1924 | * | ||
1925 | * Returns: 0 for success | ||
1926 | */ | ||
1927 | static int fcoe_enable(const char *buffer, struct kernel_param *kp) | ||
1928 | { | ||
1929 | struct fcoe_interface *fcoe; | ||
1930 | struct net_device *netdev; | ||
1931 | int rc = 0; | ||
1932 | |||
1933 | mutex_lock(&fcoe_config_mutex); | ||
1934 | #ifdef CONFIG_FCOE_MODULE | ||
1935 | /* | ||
1936 | * Make sure the module has been initialized, and is not about to be | ||
1937 | * removed. Module paramter sysfs files are writable before the | ||
1938 | * module_init function is called and after module_exit. | ||
1939 | */ | ||
1940 | if (THIS_MODULE->state != MODULE_STATE_LIVE) { | ||
1941 | rc = -ENODEV; | ||
1942 | goto out_nodev; | ||
1943 | } | ||
1944 | #endif | ||
1945 | |||
1946 | netdev = fcoe_if_to_netdev(buffer); | ||
1947 | if (!netdev) { | ||
1948 | rc = -ENODEV; | ||
1949 | goto out_nodev; | ||
1950 | } | ||
1951 | |||
1952 | rtnl_lock(); | ||
1953 | fcoe = fcoe_hostlist_lookup_port(netdev); | ||
1954 | rtnl_unlock(); | ||
1955 | |||
1956 | if (fcoe) | ||
1957 | rc = fc_fabric_login(fcoe->ctlr.lp); | ||
1958 | else | ||
1959 | rc = -ENODEV; | ||
1960 | |||
1961 | dev_put(netdev); | ||
1962 | out_nodev: | ||
1963 | mutex_unlock(&fcoe_config_mutex); | ||
1964 | return rc; | ||
1965 | } | ||
1966 | |||
1967 | /** | ||
1841 | * fcoe_destroy() - Destroy a FCoE interface | 1968 | * fcoe_destroy() - Destroy a FCoE interface |
1842 | * @buffer: The name of the Ethernet interface to be destroyed | 1969 | * @buffer: The name of the Ethernet interface to be destroyed |
1843 | * @kp: The associated kernel parameter | 1970 | * @kp: The associated kernel parameter |