diff options
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
| -rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 137 |
1 files changed, 132 insertions, 5 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index a30ffaa1222c..10be9f36a4cc 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 | ||
| @@ -1231,7 +1260,7 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, | |||
| 1231 | "CPU.\n"); | 1260 | "CPU.\n"); |
| 1232 | 1261 | ||
| 1233 | spin_unlock_bh(&fps->fcoe_rx_list.lock); | 1262 | spin_unlock_bh(&fps->fcoe_rx_list.lock); |
| 1234 | cpu = first_cpu(cpu_online_map); | 1263 | cpu = cpumask_first(cpu_online_mask); |
| 1235 | fps = &per_cpu(fcoe_percpu, cpu); | 1264 | fps = &per_cpu(fcoe_percpu, cpu); |
| 1236 | spin_lock_bh(&fps->fcoe_rx_list.lock); | 1265 | spin_lock_bh(&fps->fcoe_rx_list.lock); |
| 1237 | if (!fps->thread) { | 1266 | if (!fps->thread) { |
| @@ -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 |
