diff options
author | Robert Love <robert.w.love@intel.com> | 2012-11-27 01:53:40 -0500 |
---|---|---|
committer | Robert Love <robert.w.love@intel.com> | 2012-12-14 13:38:55 -0500 |
commit | 6e89ea3f1032d5c762f1ae9b0bd2039794596813 (patch) | |
tree | 8454705e08cf841d3488c4fe738df21a6f37b154 /drivers | |
parent | 435c86679a24ead623c8a47ca31038e250a75e05 (diff) |
bnx2fc: Use the fcoe_sysfs control interface
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.
Signed-off-by: Robert Love <robert.w.love@intel.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 168 |
1 files changed, 139 insertions, 29 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 9b38794d5665..8d975ef4eb69 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c | |||
@@ -62,6 +62,10 @@ static int bnx2fc_destroy(struct net_device *net_device); | |||
62 | static int bnx2fc_enable(struct net_device *netdev); | 62 | static int bnx2fc_enable(struct net_device *netdev); |
63 | static int bnx2fc_disable(struct net_device *netdev); | 63 | static int bnx2fc_disable(struct net_device *netdev); |
64 | 64 | ||
65 | /* fcoe_syfs control interface handlers */ | ||
66 | static int bnx2fc_ctlr_alloc(struct net_device *netdev); | ||
67 | static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev); | ||
68 | |||
65 | static void bnx2fc_recv_frame(struct sk_buff *skb); | 69 | static void bnx2fc_recv_frame(struct sk_buff *skb); |
66 | 70 | ||
67 | static void bnx2fc_start_disc(struct bnx2fc_interface *interface); | 71 | static void bnx2fc_start_disc(struct bnx2fc_interface *interface); |
@@ -864,6 +868,7 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, | |||
864 | u16 vlan_id) | 868 | u16 vlan_id) |
865 | { | 869 | { |
866 | struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context; | 870 | struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context; |
871 | struct fcoe_ctlr_device *cdev; | ||
867 | struct fc_lport *lport; | 872 | struct fc_lport *lport; |
868 | struct fc_lport *vport; | 873 | struct fc_lport *vport; |
869 | struct bnx2fc_interface *interface, *tmp; | 874 | struct bnx2fc_interface *interface, *tmp; |
@@ -925,28 +930,45 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, | |||
925 | 930 | ||
926 | bnx2fc_link_speed_update(lport); | 931 | bnx2fc_link_speed_update(lport); |
927 | 932 | ||
933 | cdev = fcoe_ctlr_to_ctlr_dev(ctlr); | ||
934 | |||
928 | if (link_possible && !bnx2fc_link_ok(lport)) { | 935 | if (link_possible && !bnx2fc_link_ok(lport)) { |
929 | /* Reset max recv frame size to default */ | 936 | switch (cdev->enabled) { |
930 | fc_set_mfs(lport, BNX2FC_MFS); | 937 | case FCOE_CTLR_DISABLED: |
931 | /* | 938 | pr_info("Link up while interface is disabled.\n"); |
932 | * ctlr link up will only be handled during | 939 | break; |
933 | * enable to avoid sending discovery solicitation | 940 | case FCOE_CTLR_ENABLED: |
934 | * on a stale vlan | 941 | case FCOE_CTLR_UNUSED: |
935 | */ | 942 | /* Reset max recv frame size to default */ |
936 | if (interface->enabled) | 943 | fc_set_mfs(lport, BNX2FC_MFS); |
937 | fcoe_ctlr_link_up(ctlr); | 944 | /* |
945 | * ctlr link up will only be handled during | ||
946 | * enable to avoid sending discovery | ||
947 | * solicitation on a stale vlan | ||
948 | */ | ||
949 | if (interface->enabled) | ||
950 | fcoe_ctlr_link_up(ctlr); | ||
951 | }; | ||
938 | } else if (fcoe_ctlr_link_down(ctlr)) { | 952 | } else if (fcoe_ctlr_link_down(ctlr)) { |
939 | mutex_lock(&lport->lp_mutex); | 953 | switch (cdev->enabled) { |
940 | list_for_each_entry(vport, &lport->vports, list) | 954 | case FCOE_CTLR_DISABLED: |
941 | fc_host_port_type(vport->host) = | 955 | pr_info("Link down while interface is disabled.\n"); |
942 | FC_PORTTYPE_UNKNOWN; | 956 | break; |
943 | mutex_unlock(&lport->lp_mutex); | 957 | case FCOE_CTLR_ENABLED: |
944 | fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN; | 958 | case FCOE_CTLR_UNUSED: |
945 | per_cpu_ptr(lport->stats, | 959 | mutex_lock(&lport->lp_mutex); |
946 | get_cpu())->LinkFailureCount++; | 960 | list_for_each_entry(vport, &lport->vports, list) |
947 | put_cpu(); | 961 | fc_host_port_type(vport->host) = |
948 | fcoe_clean_pending_queue(lport); | 962 | FC_PORTTYPE_UNKNOWN; |
949 | wait_for_upload = 1; | 963 | mutex_unlock(&lport->lp_mutex); |
964 | fc_host_port_type(lport->host) = | ||
965 | FC_PORTTYPE_UNKNOWN; | ||
966 | per_cpu_ptr(lport->stats, | ||
967 | get_cpu())->LinkFailureCount++; | ||
968 | put_cpu(); | ||
969 | fcoe_clean_pending_queue(lport); | ||
970 | wait_for_upload = 1; | ||
971 | }; | ||
950 | } | 972 | } |
951 | } | 973 | } |
952 | mutex_unlock(&bnx2fc_dev_lock); | 974 | mutex_unlock(&bnx2fc_dev_lock); |
@@ -1996,7 +2018,9 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev) | |||
1996 | set_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic); | 2018 | set_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic); |
1997 | } | 2019 | } |
1998 | 2020 | ||
1999 | 2021 | /** | |
2022 | * Deperecated: Use bnx2fc_enabled() | ||
2023 | */ | ||
2000 | static int bnx2fc_disable(struct net_device *netdev) | 2024 | static int bnx2fc_disable(struct net_device *netdev) |
2001 | { | 2025 | { |
2002 | struct bnx2fc_interface *interface; | 2026 | struct bnx2fc_interface *interface; |
@@ -2022,7 +2046,9 @@ static int bnx2fc_disable(struct net_device *netdev) | |||
2022 | return rc; | 2046 | return rc; |
2023 | } | 2047 | } |
2024 | 2048 | ||
2025 | 2049 | /** | |
2050 | * Deprecated: Use bnx2fc_enabled() | ||
2051 | */ | ||
2026 | static int bnx2fc_enable(struct net_device *netdev) | 2052 | static int bnx2fc_enable(struct net_device *netdev) |
2027 | { | 2053 | { |
2028 | struct bnx2fc_interface *interface; | 2054 | struct bnx2fc_interface *interface; |
@@ -2048,17 +2074,57 @@ static int bnx2fc_enable(struct net_device *netdev) | |||
2048 | } | 2074 | } |
2049 | 2075 | ||
2050 | /** | 2076 | /** |
2051 | * bnx2fc_create - Create bnx2fc FCoE interface | 2077 | * bnx2fc_ctlr_enabled() - Enable or disable an FCoE Controller |
2078 | * @cdev: The FCoE Controller that is being enabled or disabled | ||
2052 | * | 2079 | * |
2053 | * @buffer: The name of Ethernet interface to create on | 2080 | * fcoe_sysfs will ensure that the state of 'enabled' has |
2054 | * @kp: The associated kernel param | 2081 | * changed, so no checking is necessary here. This routine simply |
2082 | * calls fcoe_enable or fcoe_disable, both of which are deprecated. | ||
2083 | * When those routines are removed the functionality can be merged | ||
2084 | * here. | ||
2085 | */ | ||
2086 | static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev) | ||
2087 | { | ||
2088 | struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev); | ||
2089 | struct fc_lport *lport = ctlr->lp; | ||
2090 | struct net_device *netdev = bnx2fc_netdev(lport); | ||
2091 | |||
2092 | switch (cdev->enabled) { | ||
2093 | case FCOE_CTLR_ENABLED: | ||
2094 | return bnx2fc_enable(netdev); | ||
2095 | case FCOE_CTLR_DISABLED: | ||
2096 | return bnx2fc_disable(netdev); | ||
2097 | case FCOE_CTLR_UNUSED: | ||
2098 | default: | ||
2099 | return -ENOTSUPP; | ||
2100 | }; | ||
2101 | } | ||
2102 | |||
2103 | enum bnx2fc_create_link_state { | ||
2104 | BNX2FC_CREATE_LINK_DOWN, | ||
2105 | BNX2FC_CREATE_LINK_UP, | ||
2106 | }; | ||
2107 | |||
2108 | /** | ||
2109 | * _bnx2fc_create() - Create bnx2fc FCoE interface | ||
2110 | * @netdev : The net_device object the Ethernet interface to create on | ||
2111 | * @fip_mode: The FIP mode for this creation | ||
2112 | * @link_state: The ctlr link state on creation | ||
2055 | * | 2113 | * |
2056 | * Called from sysfs. | 2114 | * Called from either the libfcoe 'create' module parameter |
2115 | * via fcoe_create or from fcoe_syfs's ctlr_create file. | ||
2116 | * | ||
2117 | * libfcoe's 'create' module parameter is deprecated so some | ||
2118 | * consolidation of code can be done when that interface is | ||
2119 | * removed. | ||
2057 | * | 2120 | * |
2058 | * Returns: 0 for success | 2121 | * Returns: 0 for success |
2059 | */ | 2122 | */ |
2060 | static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) | 2123 | static int _bnx2fc_create(struct net_device *netdev, |
2124 | enum fip_state fip_mode, | ||
2125 | enum bnx2fc_create_link_state link_state) | ||
2061 | { | 2126 | { |
2127 | struct fcoe_ctlr_device *cdev; | ||
2062 | struct fcoe_ctlr *ctlr; | 2128 | struct fcoe_ctlr *ctlr; |
2063 | struct bnx2fc_interface *interface; | 2129 | struct bnx2fc_interface *interface; |
2064 | struct bnx2fc_hba *hba; | 2130 | struct bnx2fc_hba *hba; |
@@ -2153,7 +2219,15 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) | |||
2153 | /* Make this master N_port */ | 2219 | /* Make this master N_port */ |
2154 | ctlr->lp = lport; | 2220 | ctlr->lp = lport; |
2155 | 2221 | ||
2156 | if (!bnx2fc_link_ok(lport)) { | 2222 | cdev = fcoe_ctlr_to_ctlr_dev(ctlr); |
2223 | |||
2224 | if (link_state == BNX2FC_CREATE_LINK_UP) | ||
2225 | cdev->enabled = FCOE_CTLR_ENABLED; | ||
2226 | else | ||
2227 | cdev->enabled = FCOE_CTLR_DISABLED; | ||
2228 | |||
2229 | if (link_state == BNX2FC_CREATE_LINK_UP && | ||
2230 | !bnx2fc_link_ok(lport)) { | ||
2157 | fcoe_ctlr_link_up(ctlr); | 2231 | fcoe_ctlr_link_up(ctlr); |
2158 | fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; | 2232 | fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; |
2159 | set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state); | 2233 | 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) | |||
2161 | 2235 | ||
2162 | BNX2FC_HBA_DBG(lport, "create: START DISC\n"); | 2236 | BNX2FC_HBA_DBG(lport, "create: START DISC\n"); |
2163 | bnx2fc_start_disc(interface); | 2237 | bnx2fc_start_disc(interface); |
2164 | interface->enabled = true; | 2238 | |
2239 | if (link_state == BNX2FC_CREATE_LINK_UP) | ||
2240 | interface->enabled = true; | ||
2241 | |||
2165 | /* | 2242 | /* |
2166 | * Release from kref_init in bnx2fc_interface_setup, on success | 2243 | * Release from kref_init in bnx2fc_interface_setup, on success |
2167 | * lport should be holding a reference taken in bnx2fc_if_create | 2244 | * lport should be holding a reference taken in bnx2fc_if_create |
@@ -2187,6 +2264,37 @@ mod_err: | |||
2187 | } | 2264 | } |
2188 | 2265 | ||
2189 | /** | 2266 | /** |
2267 | * bnx2fc_create() - Create a bnx2fc interface | ||
2268 | * @netdev : The net_device object the Ethernet interface to create on | ||
2269 | * @fip_mode: The FIP mode for this creation | ||
2270 | * | ||
2271 | * Called from fcoe transport | ||
2272 | * | ||
2273 | * Returns: 0 for success | ||
2274 | */ | ||
2275 | static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) | ||
2276 | { | ||
2277 | return _bnx2fc_create(netdev, fip_mode, BNX2FC_CREATE_LINK_UP); | ||
2278 | } | ||
2279 | |||
2280 | /** | ||
2281 | * bnx2fc_ctlr_alloc() - Allocate a bnx2fc interface from fcoe_sysfs | ||
2282 | * @netdev: The net_device to be used by the allocated FCoE Controller | ||
2283 | * | ||
2284 | * This routine is called from fcoe_sysfs. It will start the fcoe_ctlr | ||
2285 | * in a link_down state. The allows the user an opportunity to configure | ||
2286 | * the FCoE Controller from sysfs before enabling the FCoE Controller. | ||
2287 | * | ||
2288 | * Creating in with this routine starts the FCoE Controller in Fabric | ||
2289 | * mode. The user can change to VN2VN or another mode before enabling. | ||
2290 | */ | ||
2291 | static int bnx2fc_ctlr_alloc(struct net_device *netdev) | ||
2292 | { | ||
2293 | return _bnx2fc_create(netdev, FIP_MODE_FABRIC, | ||
2294 | BNX2FC_CREATE_LINK_DOWN); | ||
2295 | } | ||
2296 | |||
2297 | /** | ||
2190 | * bnx2fc_find_hba_for_cnic - maps cnic instance to bnx2fc hba instance | 2298 | * bnx2fc_find_hba_for_cnic - maps cnic instance to bnx2fc hba instance |
2191 | * | 2299 | * |
2192 | * @cnic: Pointer to cnic device instance | 2300 | * @cnic: Pointer to cnic device instance |
@@ -2311,6 +2419,7 @@ static struct fcoe_transport bnx2fc_transport = { | |||
2311 | .name = {"bnx2fc"}, | 2419 | .name = {"bnx2fc"}, |
2312 | .attached = false, | 2420 | .attached = false, |
2313 | .list = LIST_HEAD_INIT(bnx2fc_transport.list), | 2421 | .list = LIST_HEAD_INIT(bnx2fc_transport.list), |
2422 | .alloc = bnx2fc_ctlr_alloc, | ||
2314 | .match = bnx2fc_match, | 2423 | .match = bnx2fc_match, |
2315 | .create = bnx2fc_create, | 2424 | .create = bnx2fc_create, |
2316 | .destroy = bnx2fc_destroy, | 2425 | .destroy = bnx2fc_destroy, |
@@ -2555,6 +2664,7 @@ module_init(bnx2fc_mod_init); | |||
2555 | module_exit(bnx2fc_mod_exit); | 2664 | module_exit(bnx2fc_mod_exit); |
2556 | 2665 | ||
2557 | static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = { | 2666 | static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = { |
2667 | .set_fcoe_ctlr_enabled = bnx2fc_ctlr_enabled, | ||
2558 | .get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb, | 2668 | .get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb, |
2559 | .get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb, | 2669 | .get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb, |
2560 | .get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb, | 2670 | .get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb, |