aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Bottomley <JBottomley@Parallels.com>2013-03-01 04:09:51 -0500
committerJames Bottomley <JBottomley@Parallels.com>2013-03-01 04:10:08 -0500
commit3e34c1fc2b51f117045e4a2472572f14ac91df6e (patch)
tree12c7c79931e657483f965bc944861bc8a6a9694d /drivers/scsi
parentc157750a901d767ecb95f1dbabd0972dee396b1e (diff)
parent1f953b0dbc2549318afcc0a70af5542dffbce34a (diff)
[SCSI] Merge tag 'fcoe-02-19-13' into for-linus
FCoE Updates for 3.9 Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_fcoe.c256
-rw-r--r--drivers/scsi/fcoe/fcoe.c266
-rw-r--r--drivers/scsi/fcoe/fcoe.h6
-rw-r--r--drivers/scsi/fcoe/fcoe_ctlr.c45
-rw-r--r--drivers/scsi/fcoe/fcoe_sysfs.c186
-rw-r--r--drivers/scsi/fcoe/fcoe_transport.c199
-rw-r--r--drivers/scsi/fcoe/libfcoe.h20
-rw-r--r--drivers/scsi/libfc/fc_fcp.c6
-rw-r--r--drivers/scsi/libfc/fc_libfc.h38
-rw-r--r--drivers/scsi/libfc/fc_rport.c2
10 files changed, 736 insertions, 288 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index 6401db494ef5..2daf4b0da434 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);
62static int bnx2fc_enable(struct net_device *netdev); 62static int bnx2fc_enable(struct net_device *netdev);
63static int bnx2fc_disable(struct net_device *netdev); 63static int bnx2fc_disable(struct net_device *netdev);
64 64
65/* fcoe_syfs control interface handlers */
66static int bnx2fc_ctlr_alloc(struct net_device *netdev);
67static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev);
68
65static void bnx2fc_recv_frame(struct sk_buff *skb); 69static void bnx2fc_recv_frame(struct sk_buff *skb);
66 70
67static void bnx2fc_start_disc(struct bnx2fc_interface *interface); 71static void bnx2fc_start_disc(struct bnx2fc_interface *interface);
@@ -89,7 +93,6 @@ static void bnx2fc_port_shutdown(struct fc_lport *lport);
89static void bnx2fc_stop(struct bnx2fc_interface *interface); 93static void bnx2fc_stop(struct bnx2fc_interface *interface);
90static int __init bnx2fc_mod_init(void); 94static int __init bnx2fc_mod_init(void);
91static void __exit bnx2fc_mod_exit(void); 95static void __exit bnx2fc_mod_exit(void);
92static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev);
93 96
94unsigned int bnx2fc_debug_level; 97unsigned int bnx2fc_debug_level;
95module_param_named(debug_logging, bnx2fc_debug_level, int, S_IRUGO|S_IWUSR); 98module_param_named(debug_logging, bnx2fc_debug_level, int, S_IRUGO|S_IWUSR);
@@ -107,44 +110,6 @@ static inline struct net_device *bnx2fc_netdev(const struct fc_lport *lport)
107 ((struct fcoe_port *)lport_priv(lport))->priv)->netdev; 110 ((struct fcoe_port *)lport_priv(lport))->priv)->netdev;
108} 111}
109 112
110/**
111 * bnx2fc_get_lesb() - Fill the FCoE Link Error Status Block
112 * @lport: the local port
113 * @fc_lesb: the link error status block
114 */
115static void bnx2fc_get_lesb(struct fc_lport *lport,
116 struct fc_els_lesb *fc_lesb)
117{
118 struct net_device *netdev = bnx2fc_netdev(lport);
119
120 __fcoe_get_lesb(lport, fc_lesb, netdev);
121}
122
123static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
124{
125 struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
126 struct net_device *netdev = bnx2fc_netdev(fip->lp);
127 struct fcoe_fc_els_lesb *fcoe_lesb;
128 struct fc_els_lesb fc_lesb;
129
130 __fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
131 fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);
132
133 ctlr_dev->lesb.lesb_link_fail =
134 ntohl(fcoe_lesb->lesb_link_fail);
135 ctlr_dev->lesb.lesb_vlink_fail =
136 ntohl(fcoe_lesb->lesb_vlink_fail);
137 ctlr_dev->lesb.lesb_miss_fka =
138 ntohl(fcoe_lesb->lesb_miss_fka);
139 ctlr_dev->lesb.lesb_symb_err =
140 ntohl(fcoe_lesb->lesb_symb_err);
141 ctlr_dev->lesb.lesb_err_block =
142 ntohl(fcoe_lesb->lesb_err_block);
143 ctlr_dev->lesb.lesb_fcs_error =
144 ntohl(fcoe_lesb->lesb_fcs_error);
145}
146EXPORT_SYMBOL(bnx2fc_ctlr_get_lesb);
147
148static void bnx2fc_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev) 113static void bnx2fc_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev)
149{ 114{
150 struct fcoe_ctlr_device *ctlr_dev = 115 struct fcoe_ctlr_device *ctlr_dev =
@@ -741,35 +706,6 @@ static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev)
741 return 0; 706 return 0;
742} 707}
743 708
744static void bnx2fc_link_speed_update(struct fc_lport *lport)
745{
746 struct fcoe_port *port = lport_priv(lport);
747 struct bnx2fc_interface *interface = port->priv;
748 struct net_device *netdev = interface->netdev;
749 struct ethtool_cmd ecmd;
750
751 if (!__ethtool_get_settings(netdev, &ecmd)) {
752 lport->link_supported_speeds &=
753 ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
754 if (ecmd.supported & (SUPPORTED_1000baseT_Half |
755 SUPPORTED_1000baseT_Full))
756 lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
757 if (ecmd.supported & SUPPORTED_10000baseT_Full)
758 lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
759
760 switch (ethtool_cmd_speed(&ecmd)) {
761 case SPEED_1000:
762 lport->link_speed = FC_PORTSPEED_1GBIT;
763 break;
764 case SPEED_2500:
765 lport->link_speed = FC_PORTSPEED_2GBIT;
766 break;
767 case SPEED_10000:
768 lport->link_speed = FC_PORTSPEED_10GBIT;
769 break;
770 }
771 }
772}
773static int bnx2fc_link_ok(struct fc_lport *lport) 709static int bnx2fc_link_ok(struct fc_lport *lport)
774{ 710{
775 struct fcoe_port *port = lport_priv(lport); 711 struct fcoe_port *port = lport_priv(lport);
@@ -827,7 +763,7 @@ static int bnx2fc_net_config(struct fc_lport *lport, struct net_device *netdev)
827 port->fcoe_pending_queue_active = 0; 763 port->fcoe_pending_queue_active = 0;
828 setup_timer(&port->timer, fcoe_queue_timer, (unsigned long) lport); 764 setup_timer(&port->timer, fcoe_queue_timer, (unsigned long) lport);
829 765
830 bnx2fc_link_speed_update(lport); 766 fcoe_link_speed_update(lport);
831 767
832 if (!lport->vport) { 768 if (!lport->vport) {
833 if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) 769 if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN))
@@ -871,6 +807,7 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event,
871 u16 vlan_id) 807 u16 vlan_id)
872{ 808{
873 struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context; 809 struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context;
810 struct fcoe_ctlr_device *cdev;
874 struct fc_lport *lport; 811 struct fc_lport *lport;
875 struct fc_lport *vport; 812 struct fc_lport *vport;
876 struct bnx2fc_interface *interface, *tmp; 813 struct bnx2fc_interface *interface, *tmp;
@@ -930,30 +867,47 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event,
930 BNX2FC_HBA_DBG(lport, "netevent handler - event=%s %ld\n", 867 BNX2FC_HBA_DBG(lport, "netevent handler - event=%s %ld\n",
931 interface->netdev->name, event); 868 interface->netdev->name, event);
932 869
933 bnx2fc_link_speed_update(lport); 870 fcoe_link_speed_update(lport);
871
872 cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
934 873
935 if (link_possible && !bnx2fc_link_ok(lport)) { 874 if (link_possible && !bnx2fc_link_ok(lport)) {
936 /* Reset max recv frame size to default */ 875 switch (cdev->enabled) {
937 fc_set_mfs(lport, BNX2FC_MFS); 876 case FCOE_CTLR_DISABLED:
938 /* 877 pr_info("Link up while interface is disabled.\n");
939 * ctlr link up will only be handled during 878 break;
940 * enable to avoid sending discovery solicitation 879 case FCOE_CTLR_ENABLED:
941 * on a stale vlan 880 case FCOE_CTLR_UNUSED:
942 */ 881 /* Reset max recv frame size to default */
943 if (interface->enabled) 882 fc_set_mfs(lport, BNX2FC_MFS);
944 fcoe_ctlr_link_up(ctlr); 883 /*
884 * ctlr link up will only be handled during
885 * enable to avoid sending discovery
886 * solicitation on a stale vlan
887 */
888 if (interface->enabled)
889 fcoe_ctlr_link_up(ctlr);
890 };
945 } else if (fcoe_ctlr_link_down(ctlr)) { 891 } else if (fcoe_ctlr_link_down(ctlr)) {
946 mutex_lock(&lport->lp_mutex); 892 switch (cdev->enabled) {
947 list_for_each_entry(vport, &lport->vports, list) 893 case FCOE_CTLR_DISABLED:
948 fc_host_port_type(vport->host) = 894 pr_info("Link down while interface is disabled.\n");
949 FC_PORTTYPE_UNKNOWN; 895 break;
950 mutex_unlock(&lport->lp_mutex); 896 case FCOE_CTLR_ENABLED:
951 fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN; 897 case FCOE_CTLR_UNUSED:
952 per_cpu_ptr(lport->stats, 898 mutex_lock(&lport->lp_mutex);
953 get_cpu())->LinkFailureCount++; 899 list_for_each_entry(vport, &lport->vports, list)
954 put_cpu(); 900 fc_host_port_type(vport->host) =
955 fcoe_clean_pending_queue(lport); 901 FC_PORTTYPE_UNKNOWN;
956 wait_for_upload = 1; 902 mutex_unlock(&lport->lp_mutex);
903 fc_host_port_type(lport->host) =
904 FC_PORTTYPE_UNKNOWN;
905 per_cpu_ptr(lport->stats,
906 get_cpu())->LinkFailureCount++;
907 put_cpu();
908 fcoe_clean_pending_queue(lport);
909 wait_for_upload = 1;
910 };
957 } 911 }
958 } 912 }
959 mutex_unlock(&bnx2fc_dev_lock); 913 mutex_unlock(&bnx2fc_dev_lock);
@@ -1484,6 +1438,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface,
1484 port = lport_priv(lport); 1438 port = lport_priv(lport);
1485 port->lport = lport; 1439 port->lport = lport;
1486 port->priv = interface; 1440 port->priv = interface;
1441 port->get_netdev = bnx2fc_netdev;
1487 INIT_WORK(&port->destroy_work, bnx2fc_destroy_work); 1442 INIT_WORK(&port->destroy_work, bnx2fc_destroy_work);
1488 1443
1489 /* Configure fcoe_port */ 1444 /* Configure fcoe_port */
@@ -2003,7 +1958,9 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev)
2003 set_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic); 1958 set_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic);
2004} 1959}
2005 1960
2006 1961/**
1962 * Deperecated: Use bnx2fc_enabled()
1963 */
2007static int bnx2fc_disable(struct net_device *netdev) 1964static int bnx2fc_disable(struct net_device *netdev)
2008{ 1965{
2009 struct bnx2fc_interface *interface; 1966 struct bnx2fc_interface *interface;
@@ -2029,7 +1986,9 @@ static int bnx2fc_disable(struct net_device *netdev)
2029 return rc; 1986 return rc;
2030} 1987}
2031 1988
2032 1989/**
1990 * Deprecated: Use bnx2fc_enabled()
1991 */
2033static int bnx2fc_enable(struct net_device *netdev) 1992static int bnx2fc_enable(struct net_device *netdev)
2034{ 1993{
2035 struct bnx2fc_interface *interface; 1994 struct bnx2fc_interface *interface;
@@ -2055,17 +2014,57 @@ static int bnx2fc_enable(struct net_device *netdev)
2055} 2014}
2056 2015
2057/** 2016/**
2058 * bnx2fc_create - Create bnx2fc FCoE interface 2017 * bnx2fc_ctlr_enabled() - Enable or disable an FCoE Controller
2018 * @cdev: The FCoE Controller that is being enabled or disabled
2019 *
2020 * fcoe_sysfs will ensure that the state of 'enabled' has
2021 * changed, so no checking is necessary here. This routine simply
2022 * calls fcoe_enable or fcoe_disable, both of which are deprecated.
2023 * When those routines are removed the functionality can be merged
2024 * here.
2025 */
2026static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev)
2027{
2028 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev);
2029 struct fc_lport *lport = ctlr->lp;
2030 struct net_device *netdev = bnx2fc_netdev(lport);
2031
2032 switch (cdev->enabled) {
2033 case FCOE_CTLR_ENABLED:
2034 return bnx2fc_enable(netdev);
2035 case FCOE_CTLR_DISABLED:
2036 return bnx2fc_disable(netdev);
2037 case FCOE_CTLR_UNUSED:
2038 default:
2039 return -ENOTSUPP;
2040 };
2041}
2042
2043enum bnx2fc_create_link_state {
2044 BNX2FC_CREATE_LINK_DOWN,
2045 BNX2FC_CREATE_LINK_UP,
2046};
2047
2048/**
2049 * _bnx2fc_create() - Create bnx2fc FCoE interface
2050 * @netdev : The net_device object the Ethernet interface to create on
2051 * @fip_mode: The FIP mode for this creation
2052 * @link_state: The ctlr link state on creation
2059 * 2053 *
2060 * @buffer: The name of Ethernet interface to create on 2054 * Called from either the libfcoe 'create' module parameter
2061 * @kp: The associated kernel param 2055 * via fcoe_create or from fcoe_syfs's ctlr_create file.
2062 * 2056 *
2063 * Called from sysfs. 2057 * libfcoe's 'create' module parameter is deprecated so some
2058 * consolidation of code can be done when that interface is
2059 * removed.
2064 * 2060 *
2065 * Returns: 0 for success 2061 * Returns: 0 for success
2066 */ 2062 */
2067static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) 2063static int _bnx2fc_create(struct net_device *netdev,
2064 enum fip_state fip_mode,
2065 enum bnx2fc_create_link_state link_state)
2068{ 2066{
2067 struct fcoe_ctlr_device *cdev;
2069 struct fcoe_ctlr *ctlr; 2068 struct fcoe_ctlr *ctlr;
2070 struct bnx2fc_interface *interface; 2069 struct bnx2fc_interface *interface;
2071 struct bnx2fc_hba *hba; 2070 struct bnx2fc_hba *hba;
@@ -2160,7 +2159,15 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
2160 /* Make this master N_port */ 2159 /* Make this master N_port */
2161 ctlr->lp = lport; 2160 ctlr->lp = lport;
2162 2161
2163 if (!bnx2fc_link_ok(lport)) { 2162 cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
2163
2164 if (link_state == BNX2FC_CREATE_LINK_UP)
2165 cdev->enabled = FCOE_CTLR_ENABLED;
2166 else
2167 cdev->enabled = FCOE_CTLR_DISABLED;
2168
2169 if (link_state == BNX2FC_CREATE_LINK_UP &&
2170 !bnx2fc_link_ok(lport)) {
2164 fcoe_ctlr_link_up(ctlr); 2171 fcoe_ctlr_link_up(ctlr);
2165 fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; 2172 fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
2166 set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state); 2173 set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state);
@@ -2168,7 +2175,10 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
2168 2175
2169 BNX2FC_HBA_DBG(lport, "create: START DISC\n"); 2176 BNX2FC_HBA_DBG(lport, "create: START DISC\n");
2170 bnx2fc_start_disc(interface); 2177 bnx2fc_start_disc(interface);
2171 interface->enabled = true; 2178
2179 if (link_state == BNX2FC_CREATE_LINK_UP)
2180 interface->enabled = true;
2181
2172 /* 2182 /*
2173 * Release from kref_init in bnx2fc_interface_setup, on success 2183 * Release from kref_init in bnx2fc_interface_setup, on success
2174 * lport should be holding a reference taken in bnx2fc_if_create 2184 * lport should be holding a reference taken in bnx2fc_if_create
@@ -2194,6 +2204,37 @@ mod_err:
2194} 2204}
2195 2205
2196/** 2206/**
2207 * bnx2fc_create() - Create a bnx2fc interface
2208 * @netdev : The net_device object the Ethernet interface to create on
2209 * @fip_mode: The FIP mode for this creation
2210 *
2211 * Called from fcoe transport
2212 *
2213 * Returns: 0 for success
2214 */
2215static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
2216{
2217 return _bnx2fc_create(netdev, fip_mode, BNX2FC_CREATE_LINK_UP);
2218}
2219
2220/**
2221 * bnx2fc_ctlr_alloc() - Allocate a bnx2fc interface from fcoe_sysfs
2222 * @netdev: The net_device to be used by the allocated FCoE Controller
2223 *
2224 * This routine is called from fcoe_sysfs. It will start the fcoe_ctlr
2225 * in a link_down state. The allows the user an opportunity to configure
2226 * the FCoE Controller from sysfs before enabling the FCoE Controller.
2227 *
2228 * Creating in with this routine starts the FCoE Controller in Fabric
2229 * mode. The user can change to VN2VN or another mode before enabling.
2230 */
2231static int bnx2fc_ctlr_alloc(struct net_device *netdev)
2232{
2233 return _bnx2fc_create(netdev, FIP_MODE_FABRIC,
2234 BNX2FC_CREATE_LINK_DOWN);
2235}
2236
2237/**
2197 * bnx2fc_find_hba_for_cnic - maps cnic instance to bnx2fc hba instance 2238 * bnx2fc_find_hba_for_cnic - maps cnic instance to bnx2fc hba instance
2198 * 2239 *
2199 * @cnic: Pointer to cnic device instance 2240 * @cnic: Pointer to cnic device instance
@@ -2318,6 +2359,7 @@ static struct fcoe_transport bnx2fc_transport = {
2318 .name = {"bnx2fc"}, 2359 .name = {"bnx2fc"},
2319 .attached = false, 2360 .attached = false,
2320 .list = LIST_HEAD_INIT(bnx2fc_transport.list), 2361 .list = LIST_HEAD_INIT(bnx2fc_transport.list),
2362 .alloc = bnx2fc_ctlr_alloc,
2321 .match = bnx2fc_match, 2363 .match = bnx2fc_match,
2322 .create = bnx2fc_create, 2364 .create = bnx2fc_create,
2323 .destroy = bnx2fc_destroy, 2365 .destroy = bnx2fc_destroy,
@@ -2562,13 +2604,13 @@ module_init(bnx2fc_mod_init);
2562module_exit(bnx2fc_mod_exit); 2604module_exit(bnx2fc_mod_exit);
2563 2605
2564static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = { 2606static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = {
2565 .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode, 2607 .set_fcoe_ctlr_enabled = bnx2fc_ctlr_enabled,
2566 .get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb, 2608 .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
2567 .get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb, 2609 .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
2568 .get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb, 2610 .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
2569 .get_fcoe_ctlr_symb_err = bnx2fc_ctlr_get_lesb, 2611 .get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb,
2570 .get_fcoe_ctlr_err_block = bnx2fc_ctlr_get_lesb, 2612 .get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb,
2571 .get_fcoe_ctlr_fcs_error = bnx2fc_ctlr_get_lesb, 2613 .get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb,
2572 2614
2573 .get_fcoe_fcf_selected = fcoe_fcf_get_selected, 2615 .get_fcoe_fcf_selected = fcoe_fcf_get_selected,
2574 .get_fcoe_fcf_vlan_id = bnx2fc_fcf_get_vlan_id, 2616 .get_fcoe_fcf_vlan_id = bnx2fc_fcf_get_vlan_id,
@@ -2675,7 +2717,7 @@ static struct libfc_function_template bnx2fc_libfc_fcn_templ = {
2675 .elsct_send = bnx2fc_elsct_send, 2717 .elsct_send = bnx2fc_elsct_send,
2676 .fcp_abort_io = bnx2fc_abort_io, 2718 .fcp_abort_io = bnx2fc_abort_io,
2677 .fcp_cleanup = bnx2fc_cleanup, 2719 .fcp_cleanup = bnx2fc_cleanup,
2678 .get_lesb = bnx2fc_get_lesb, 2720 .get_lesb = fcoe_get_lesb,
2679 .rport_event_callback = bnx2fc_rport_event_handler, 2721 .rport_event_callback = bnx2fc_rport_event_handler,
2680}; 2722};
2681 2723
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 666b7ac4475f..b5d92fc93c70 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -82,11 +82,11 @@ static int fcoe_rcv(struct sk_buff *, struct net_device *,
82 struct packet_type *, struct net_device *); 82 struct packet_type *, struct net_device *);
83static int fcoe_percpu_receive_thread(void *); 83static int fcoe_percpu_receive_thread(void *);
84static void fcoe_percpu_clean(struct fc_lport *); 84static void fcoe_percpu_clean(struct fc_lport *);
85static int fcoe_link_speed_update(struct fc_lport *);
86static int fcoe_link_ok(struct fc_lport *); 85static int fcoe_link_ok(struct fc_lport *);
87 86
88static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); 87static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
89static int fcoe_hostlist_add(const struct fc_lport *); 88static int fcoe_hostlist_add(const struct fc_lport *);
89static void fcoe_hostlist_del(const struct fc_lport *);
90 90
91static int fcoe_device_notification(struct notifier_block *, ulong, void *); 91static int fcoe_device_notification(struct notifier_block *, ulong, void *);
92static void fcoe_dev_setup(void); 92static void fcoe_dev_setup(void);
@@ -117,6 +117,11 @@ static int fcoe_destroy(struct net_device *netdev);
117static int fcoe_enable(struct net_device *netdev); 117static int fcoe_enable(struct net_device *netdev);
118static int fcoe_disable(struct net_device *netdev); 118static int fcoe_disable(struct net_device *netdev);
119 119
120/* fcoe_syfs control interface handlers */
121static int fcoe_ctlr_alloc(struct net_device *netdev);
122static int fcoe_ctlr_enabled(struct fcoe_ctlr_device *cdev);
123
124
120static struct fc_seq *fcoe_elsct_send(struct fc_lport *, 125static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
121 u32 did, struct fc_frame *, 126 u32 did, struct fc_frame *,
122 unsigned int op, 127 unsigned int op,
@@ -126,8 +131,6 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
126 void *, u32 timeout); 131 void *, u32 timeout);
127static void fcoe_recv_frame(struct sk_buff *skb); 132static void fcoe_recv_frame(struct sk_buff *skb);
128 133
129static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);
130
131/* notification function for packets from net device */ 134/* notification function for packets from net device */
132static struct notifier_block fcoe_notifier = { 135static struct notifier_block fcoe_notifier = {
133 .notifier_call = fcoe_device_notification, 136 .notifier_call = fcoe_device_notification,
@@ -151,11 +154,11 @@ static int fcoe_vport_create(struct fc_vport *, bool disabled);
151static int fcoe_vport_disable(struct fc_vport *, bool disable); 154static int fcoe_vport_disable(struct fc_vport *, bool disable);
152static void fcoe_set_vport_symbolic_name(struct fc_vport *); 155static void fcoe_set_vport_symbolic_name(struct fc_vport *);
153static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); 156static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *);
154static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *);
155static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *); 157static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *);
156 158
157static struct fcoe_sysfs_function_template fcoe_sysfs_templ = { 159static struct fcoe_sysfs_function_template fcoe_sysfs_templ = {
158 .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode, 160 .set_fcoe_ctlr_mode = fcoe_ctlr_set_fip_mode,
161 .set_fcoe_ctlr_enabled = fcoe_ctlr_enabled,
159 .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb, 162 .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
160 .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb, 163 .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
161 .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb, 164 .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
@@ -1112,10 +1115,17 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
1112 port = lport_priv(lport); 1115 port = lport_priv(lport);
1113 port->lport = lport; 1116 port->lport = lport;
1114 port->priv = fcoe; 1117 port->priv = fcoe;
1118 port->get_netdev = fcoe_netdev;
1115 port->max_queue_depth = FCOE_MAX_QUEUE_DEPTH; 1119 port->max_queue_depth = FCOE_MAX_QUEUE_DEPTH;
1116 port->min_queue_depth = FCOE_MIN_QUEUE_DEPTH; 1120 port->min_queue_depth = FCOE_MIN_QUEUE_DEPTH;
1117 INIT_WORK(&port->destroy_work, fcoe_destroy_work); 1121 INIT_WORK(&port->destroy_work, fcoe_destroy_work);
1118 1122
1123 /*
1124 * Need to add the lport to the hostlist
1125 * so we catch NETDEV_CHANGE events.
1126 */
1127 fcoe_hostlist_add(lport);
1128
1119 /* configure a fc_lport including the exchange manager */ 1129 /* configure a fc_lport including the exchange manager */
1120 rc = fcoe_lport_config(lport); 1130 rc = fcoe_lport_config(lport);
1121 if (rc) { 1131 if (rc) {
@@ -1187,6 +1197,7 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
1187out_lp_destroy: 1197out_lp_destroy:
1188 fc_exch_mgr_free(lport); 1198 fc_exch_mgr_free(lport);
1189out_host_put: 1199out_host_put:
1200 fcoe_hostlist_del(lport);
1190 scsi_host_put(lport->host); 1201 scsi_host_put(lport->host);
1191out: 1202out:
1192 return ERR_PTR(rc); 1203 return ERR_PTR(rc);
@@ -1964,6 +1975,7 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier,
1964static int fcoe_device_notification(struct notifier_block *notifier, 1975static int fcoe_device_notification(struct notifier_block *notifier,
1965 ulong event, void *ptr) 1976 ulong event, void *ptr)
1966{ 1977{
1978 struct fcoe_ctlr_device *cdev;
1967 struct fc_lport *lport = NULL; 1979 struct fc_lport *lport = NULL;
1968 struct net_device *netdev = ptr; 1980 struct net_device *netdev = ptr;
1969 struct fcoe_ctlr *ctlr; 1981 struct fcoe_ctlr *ctlr;
@@ -2020,13 +2032,29 @@ static int fcoe_device_notification(struct notifier_block *notifier,
2020 2032
2021 fcoe_link_speed_update(lport); 2033 fcoe_link_speed_update(lport);
2022 2034
2023 if (link_possible && !fcoe_link_ok(lport)) 2035 cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
2024 fcoe_ctlr_link_up(ctlr); 2036
2025 else if (fcoe_ctlr_link_down(ctlr)) { 2037 if (link_possible && !fcoe_link_ok(lport)) {
2026 stats = per_cpu_ptr(lport->stats, get_cpu()); 2038 switch (cdev->enabled) {
2027 stats->LinkFailureCount++; 2039 case FCOE_CTLR_DISABLED:
2028 put_cpu(); 2040 pr_info("Link up while interface is disabled.\n");
2029 fcoe_clean_pending_queue(lport); 2041 break;
2042 case FCOE_CTLR_ENABLED:
2043 case FCOE_CTLR_UNUSED:
2044 fcoe_ctlr_link_up(ctlr);
2045 };
2046 } else if (fcoe_ctlr_link_down(ctlr)) {
2047 switch (cdev->enabled) {
2048 case FCOE_CTLR_DISABLED:
2049 pr_info("Link down while interface is disabled.\n");
2050 break;
2051 case FCOE_CTLR_ENABLED:
2052 case FCOE_CTLR_UNUSED:
2053 stats = per_cpu_ptr(lport->stats, get_cpu());
2054 stats->LinkFailureCount++;
2055 put_cpu();
2056 fcoe_clean_pending_queue(lport);
2057 };
2030 } 2058 }
2031out: 2059out:
2032 return rc; 2060 return rc;
@@ -2039,6 +2067,8 @@ out:
2039 * Called from fcoe transport. 2067 * Called from fcoe transport.
2040 * 2068 *
2041 * Returns: 0 for success 2069 * Returns: 0 for success
2070 *
2071 * Deprecated: use fcoe_ctlr_enabled()
2042 */ 2072 */
2043static int fcoe_disable(struct net_device *netdev) 2073static int fcoe_disable(struct net_device *netdev)
2044{ 2074{
@@ -2098,6 +2128,33 @@ out:
2098} 2128}
2099 2129
2100/** 2130/**
2131 * fcoe_ctlr_enabled() - Enable or disable an FCoE Controller
2132 * @cdev: The FCoE Controller that is being enabled or disabled
2133 *
2134 * fcoe_sysfs will ensure that the state of 'enabled' has
2135 * changed, so no checking is necessary here. This routine simply
2136 * calls fcoe_enable or fcoe_disable, both of which are deprecated.
2137 * When those routines are removed the functionality can be merged
2138 * here.
2139 */
2140static int fcoe_ctlr_enabled(struct fcoe_ctlr_device *cdev)
2141{
2142 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev);
2143 struct fc_lport *lport = ctlr->lp;
2144 struct net_device *netdev = fcoe_netdev(lport);
2145
2146 switch (cdev->enabled) {
2147 case FCOE_CTLR_ENABLED:
2148 return fcoe_enable(netdev);
2149 case FCOE_CTLR_DISABLED:
2150 return fcoe_disable(netdev);
2151 case FCOE_CTLR_UNUSED:
2152 default:
2153 return -ENOTSUPP;
2154 };
2155}
2156
2157/**
2101 * fcoe_destroy() - Destroy a FCoE interface 2158 * fcoe_destroy() - Destroy a FCoE interface
2102 * @netdev : The net_device object the Ethernet interface to create on 2159 * @netdev : The net_device object the Ethernet interface to create on
2103 * 2160 *
@@ -2139,8 +2196,31 @@ static void fcoe_destroy_work(struct work_struct *work)
2139{ 2196{
2140 struct fcoe_port *port; 2197 struct fcoe_port *port;
2141 struct fcoe_interface *fcoe; 2198 struct fcoe_interface *fcoe;
2199 struct Scsi_Host *shost;
2200 struct fc_host_attrs *fc_host;
2201 unsigned long flags;
2202 struct fc_vport *vport;
2203 struct fc_vport *next_vport;
2142 2204
2143 port = container_of(work, struct fcoe_port, destroy_work); 2205 port = container_of(work, struct fcoe_port, destroy_work);
2206 shost = port->lport->host;
2207 fc_host = shost_to_fc_host(shost);
2208
2209 /* Loop through all the vports and mark them for deletion */
2210 spin_lock_irqsave(shost->host_lock, flags);
2211 list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) {
2212 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) {
2213 continue;
2214 } else {
2215 vport->flags |= FC_VPORT_DELETING;
2216 queue_work(fc_host_work_q(shost),
2217 &vport->vport_delete_work);
2218 }
2219 }
2220 spin_unlock_irqrestore(shost->host_lock, flags);
2221
2222 flush_workqueue(fc_host_work_q(shost));
2223
2144 mutex_lock(&fcoe_config_mutex); 2224 mutex_lock(&fcoe_config_mutex);
2145 2225
2146 fcoe = port->priv; 2226 fcoe = port->priv;
@@ -2204,16 +2284,26 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
2204#endif 2284#endif
2205} 2285}
2206 2286
2287enum fcoe_create_link_state {
2288 FCOE_CREATE_LINK_DOWN,
2289 FCOE_CREATE_LINK_UP,
2290};
2291
2207/** 2292/**
2208 * fcoe_create() - Create a fcoe interface 2293 * _fcoe_create() - (internal) Create a fcoe interface
2209 * @netdev : The net_device object the Ethernet interface to create on 2294 * @netdev : The net_device object the Ethernet interface to create on
2210 * @fip_mode: The FIP mode for this creation 2295 * @fip_mode: The FIP mode for this creation
2296 * @link_state: The ctlr link state on creation
2211 * 2297 *
2212 * Called from fcoe transport 2298 * Called from either the libfcoe 'create' module parameter
2299 * via fcoe_create or from fcoe_syfs's ctlr_create file.
2213 * 2300 *
2214 * Returns: 0 for success 2301 * libfcoe's 'create' module parameter is deprecated so some
2302 * consolidation of code can be done when that interface is
2303 * removed.
2215 */ 2304 */
2216static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) 2305static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode,
2306 enum fcoe_create_link_state link_state)
2217{ 2307{
2218 int rc = 0; 2308 int rc = 0;
2219 struct fcoe_ctlr_device *ctlr_dev; 2309 struct fcoe_ctlr_device *ctlr_dev;
@@ -2254,13 +2344,29 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
2254 /* setup DCB priority attributes. */ 2344 /* setup DCB priority attributes. */
2255 fcoe_dcb_create(fcoe); 2345 fcoe_dcb_create(fcoe);
2256 2346
2257 /* add to lports list */
2258 fcoe_hostlist_add(lport);
2259
2260 /* start FIP Discovery and FLOGI */ 2347 /* start FIP Discovery and FLOGI */
2261 lport->boot_time = jiffies; 2348 lport->boot_time = jiffies;
2262 fc_fabric_login(lport); 2349 fc_fabric_login(lport);
2263 if (!fcoe_link_ok(lport)) { 2350
2351 /*
2352 * If the fcoe_ctlr_device is to be set to DISABLED
2353 * it must be done after the lport is added to the
2354 * hostlist, but before the rtnl_lock is released.
2355 * This is because the rtnl_lock protects the
2356 * hostlist that fcoe_device_notification uses. If
2357 * the FCoE Controller is intended to be created
2358 * DISABLED then 'enabled' needs to be considered
2359 * handling link events. 'enabled' must be set
2360 * before the lport can be found in the hostlist
2361 * when a link up event is received.
2362 */
2363 if (link_state == FCOE_CREATE_LINK_UP)
2364 ctlr_dev->enabled = FCOE_CTLR_ENABLED;
2365 else
2366 ctlr_dev->enabled = FCOE_CTLR_DISABLED;
2367
2368 if (link_state == FCOE_CREATE_LINK_UP &&
2369 !fcoe_link_ok(lport)) {
2264 rtnl_unlock(); 2370 rtnl_unlock();
2265 fcoe_ctlr_link_up(ctlr); 2371 fcoe_ctlr_link_up(ctlr);
2266 mutex_unlock(&fcoe_config_mutex); 2372 mutex_unlock(&fcoe_config_mutex);
@@ -2275,37 +2381,34 @@ out_nortnl:
2275} 2381}
2276 2382
2277/** 2383/**
2278 * fcoe_link_speed_update() - Update the supported and actual link speeds 2384 * fcoe_create() - Create a fcoe interface
2279 * @lport: The local port to update speeds for 2385 * @netdev : The net_device object the Ethernet interface to create on
2386 * @fip_mode: The FIP mode for this creation
2387 *
2388 * Called from fcoe transport
2389 *
2390 * Returns: 0 for success
2391 */
2392static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
2393{
2394 return _fcoe_create(netdev, fip_mode, FCOE_CREATE_LINK_UP);
2395}
2396
2397/**
2398 * fcoe_ctlr_alloc() - Allocate a fcoe interface from fcoe_sysfs
2399 * @netdev: The net_device to be used by the allocated FCoE Controller
2280 * 2400 *
2281 * Returns: 0 if the ethtool query was successful 2401 * This routine is called from fcoe_sysfs. It will start the fcoe_ctlr
2282 * -1 if the ethtool query failed 2402 * in a link_down state. The allows the user an opportunity to configure
2403 * the FCoE Controller from sysfs before enabling the FCoE Controller.
2404 *
2405 * Creating in with this routine starts the FCoE Controller in Fabric
2406 * mode. The user can change to VN2VN or another mode before enabling.
2283 */ 2407 */
2284static int fcoe_link_speed_update(struct fc_lport *lport) 2408static int fcoe_ctlr_alloc(struct net_device *netdev)
2285{ 2409{
2286 struct net_device *netdev = fcoe_netdev(lport); 2410 return _fcoe_create(netdev, FIP_MODE_FABRIC,
2287 struct ethtool_cmd ecmd; 2411 FCOE_CREATE_LINK_DOWN);
2288
2289 if (!__ethtool_get_settings(netdev, &ecmd)) {
2290 lport->link_supported_speeds &=
2291 ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
2292 if (ecmd.supported & (SUPPORTED_1000baseT_Half |
2293 SUPPORTED_1000baseT_Full))
2294 lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
2295 if (ecmd.supported & SUPPORTED_10000baseT_Full)
2296 lport->link_supported_speeds |=
2297 FC_PORTSPEED_10GBIT;
2298 switch (ethtool_cmd_speed(&ecmd)) {
2299 case SPEED_1000:
2300 lport->link_speed = FC_PORTSPEED_1GBIT;
2301 break;
2302 case SPEED_10000:
2303 lport->link_speed = FC_PORTSPEED_10GBIT;
2304 break;
2305 }
2306 return 0;
2307 }
2308 return -1;
2309} 2412}
2310 2413
2311/** 2414/**
@@ -2375,10 +2478,13 @@ static int fcoe_reset(struct Scsi_Host *shost)
2375 struct fcoe_port *port = lport_priv(lport); 2478 struct fcoe_port *port = lport_priv(lport);
2376 struct fcoe_interface *fcoe = port->priv; 2479 struct fcoe_interface *fcoe = port->priv;
2377 struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); 2480 struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
2481 struct fcoe_ctlr_device *cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
2378 2482
2379 fcoe_ctlr_link_down(ctlr); 2483 fcoe_ctlr_link_down(ctlr);
2380 fcoe_clean_pending_queue(ctlr->lp); 2484 fcoe_clean_pending_queue(ctlr->lp);
2381 if (!fcoe_link_ok(ctlr->lp)) 2485
2486 if (cdev->enabled != FCOE_CTLR_DISABLED &&
2487 !fcoe_link_ok(ctlr->lp))
2382 fcoe_ctlr_link_up(ctlr); 2488 fcoe_ctlr_link_up(ctlr);
2383 return 0; 2489 return 0;
2384} 2490}
@@ -2445,12 +2551,31 @@ static int fcoe_hostlist_add(const struct fc_lport *lport)
2445 return 0; 2551 return 0;
2446} 2552}
2447 2553
2554/**
2555 * fcoe_hostlist_del() - Remove the FCoE interface identified by a local
2556 * port to the hostlist
2557 * @lport: The local port that identifies the FCoE interface to be added
2558 *
2559 * Locking: must be called with the RTNL mutex held
2560 *
2561 */
2562static void fcoe_hostlist_del(const struct fc_lport *lport)
2563{
2564 struct fcoe_interface *fcoe;
2565 struct fcoe_port *port;
2566
2567 port = lport_priv(lport);
2568 fcoe = port->priv;
2569 list_del(&fcoe->list);
2570 return;
2571}
2448 2572
2449static struct fcoe_transport fcoe_sw_transport = { 2573static struct fcoe_transport fcoe_sw_transport = {
2450 .name = {FCOE_TRANSPORT_DEFAULT}, 2574 .name = {FCOE_TRANSPORT_DEFAULT},
2451 .attached = false, 2575 .attached = false,
2452 .list = LIST_HEAD_INIT(fcoe_sw_transport.list), 2576 .list = LIST_HEAD_INIT(fcoe_sw_transport.list),
2453 .match = fcoe_match, 2577 .match = fcoe_match,
2578 .alloc = fcoe_ctlr_alloc,
2454 .create = fcoe_create, 2579 .create = fcoe_create,
2455 .destroy = fcoe_destroy, 2580 .destroy = fcoe_destroy,
2456 .enable = fcoe_enable, 2581 .enable = fcoe_enable,
@@ -2534,9 +2659,9 @@ static void __exit fcoe_exit(void)
2534 /* releases the associated fcoe hosts */ 2659 /* releases the associated fcoe hosts */
2535 rtnl_lock(); 2660 rtnl_lock();
2536 list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) { 2661 list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) {
2537 list_del(&fcoe->list);
2538 ctlr = fcoe_to_ctlr(fcoe); 2662 ctlr = fcoe_to_ctlr(fcoe);
2539 port = lport_priv(ctlr->lp); 2663 port = lport_priv(ctlr->lp);
2664 fcoe_hostlist_del(port->lport);
2540 queue_work(fcoe_wq, &port->destroy_work); 2665 queue_work(fcoe_wq, &port->destroy_work);
2541 } 2666 }
2542 rtnl_unlock(); 2667 rtnl_unlock();
@@ -2776,43 +2901,6 @@ static void fcoe_set_vport_symbolic_name(struct fc_vport *vport)
2776 NULL, NULL, 3 * lport->r_a_tov); 2901 NULL, NULL, 3 * lport->r_a_tov);
2777} 2902}
2778 2903
2779/**
2780 * fcoe_get_lesb() - Fill the FCoE Link Error Status Block
2781 * @lport: the local port
2782 * @fc_lesb: the link error status block
2783 */
2784static void fcoe_get_lesb(struct fc_lport *lport,
2785 struct fc_els_lesb *fc_lesb)
2786{
2787 struct net_device *netdev = fcoe_netdev(lport);
2788
2789 __fcoe_get_lesb(lport, fc_lesb, netdev);
2790}
2791
2792static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
2793{
2794 struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
2795 struct net_device *netdev = fcoe_netdev(fip->lp);
2796 struct fcoe_fc_els_lesb *fcoe_lesb;
2797 struct fc_els_lesb fc_lesb;
2798
2799 __fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
2800 fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);
2801
2802 ctlr_dev->lesb.lesb_link_fail =
2803 ntohl(fcoe_lesb->lesb_link_fail);
2804 ctlr_dev->lesb.lesb_vlink_fail =
2805 ntohl(fcoe_lesb->lesb_vlink_fail);
2806 ctlr_dev->lesb.lesb_miss_fka =
2807 ntohl(fcoe_lesb->lesb_miss_fka);
2808 ctlr_dev->lesb.lesb_symb_err =
2809 ntohl(fcoe_lesb->lesb_symb_err);
2810 ctlr_dev->lesb.lesb_err_block =
2811 ntohl(fcoe_lesb->lesb_err_block);
2812 ctlr_dev->lesb.lesb_fcs_error =
2813 ntohl(fcoe_lesb->lesb_fcs_error);
2814}
2815
2816static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev) 2904static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev)
2817{ 2905{
2818 struct fcoe_ctlr_device *ctlr_dev = 2906 struct fcoe_ctlr_device *ctlr_dev =
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h
index b42dc32cb5eb..2b53672bf932 100644
--- a/drivers/scsi/fcoe/fcoe.h
+++ b/drivers/scsi/fcoe/fcoe.h
@@ -55,12 +55,12 @@ do { \
55 55
56#define FCOE_DBG(fmt, args...) \ 56#define FCOE_DBG(fmt, args...) \
57 FCOE_CHECK_LOGGING(FCOE_LOGGING, \ 57 FCOE_CHECK_LOGGING(FCOE_LOGGING, \
58 printk(KERN_INFO "fcoe: " fmt, ##args);) 58 pr_info("fcoe: " fmt, ##args);)
59 59
60#define FCOE_NETDEV_DBG(netdev, fmt, args...) \ 60#define FCOE_NETDEV_DBG(netdev, fmt, args...) \
61 FCOE_CHECK_LOGGING(FCOE_NETDEV_LOGGING, \ 61 FCOE_CHECK_LOGGING(FCOE_NETDEV_LOGGING, \
62 printk(KERN_INFO "fcoe: %s: " fmt, \ 62 pr_info("fcoe: %s: " fmt, \
63 netdev->name, ##args);) 63 netdev->name, ##args);)
64 64
65/** 65/**
66 * struct fcoe_interface - A FCoE interface 66 * struct fcoe_interface - A FCoE interface
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
index 4a909d7cfde1..08c3bc398da2 100644
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -1291,8 +1291,16 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
1291 1291
1292 LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n"); 1292 LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n");
1293 1293
1294 if (!fcf || !lport->port_id) 1294 if (!fcf || !lport->port_id) {
1295 /*
1296 * We are yet to select best FCF, but we got CVL in the
1297 * meantime. reset the ctlr and let it rediscover the FCF
1298 */
1299 mutex_lock(&fip->ctlr_mutex);
1300 fcoe_ctlr_reset(fip);
1301 mutex_unlock(&fip->ctlr_mutex);
1295 return; 1302 return;
1303 }
1296 1304
1297 /* 1305 /*
1298 * mask of required descriptors. Validating each one clears its bit. 1306 * mask of required descriptors. Validating each one clears its bit.
@@ -1551,15 +1559,6 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
1551 fcf->fabric_name, fcf->vfid, fcf->fcf_mac, 1559 fcf->fabric_name, fcf->vfid, fcf->fcf_mac,
1552 fcf->fc_map, fcoe_ctlr_mtu_valid(fcf), 1560 fcf->fc_map, fcoe_ctlr_mtu_valid(fcf),
1553 fcf->flogi_sent, fcf->pri); 1561 fcf->flogi_sent, fcf->pri);
1554 if (fcf->fabric_name != first->fabric_name ||
1555 fcf->vfid != first->vfid ||
1556 fcf->fc_map != first->fc_map) {
1557 LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
1558 "or FC-MAP\n");
1559 return NULL;
1560 }
1561 if (fcf->flogi_sent)
1562 continue;
1563 if (!fcoe_ctlr_fcf_usable(fcf)) { 1562 if (!fcoe_ctlr_fcf_usable(fcf)) {
1564 LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx " 1563 LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx "
1565 "map %x %svalid %savailable\n", 1564 "map %x %svalid %savailable\n",
@@ -1569,6 +1568,15 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
1569 "" : "un"); 1568 "" : "un");
1570 continue; 1569 continue;
1571 } 1570 }
1571 if (fcf->fabric_name != first->fabric_name ||
1572 fcf->vfid != first->vfid ||
1573 fcf->fc_map != first->fc_map) {
1574 LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
1575 "or FC-MAP\n");
1576 return NULL;
1577 }
1578 if (fcf->flogi_sent)
1579 continue;
1572 if (!best || fcf->pri < best->pri || best->flogi_sent) 1580 if (!best || fcf->pri < best->pri || best->flogi_sent)
1573 best = fcf; 1581 best = fcf;
1574 } 1582 }
@@ -2864,22 +2872,21 @@ void fcoe_fcf_get_selected(struct fcoe_fcf_device *fcf_dev)
2864} 2872}
2865EXPORT_SYMBOL(fcoe_fcf_get_selected); 2873EXPORT_SYMBOL(fcoe_fcf_get_selected);
2866 2874
2867void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *ctlr_dev) 2875void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev)
2868{ 2876{
2869 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); 2877 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
2870 2878
2871 mutex_lock(&ctlr->ctlr_mutex); 2879 mutex_lock(&ctlr->ctlr_mutex);
2872 switch (ctlr->mode) { 2880 switch (ctlr_dev->mode) {
2873 case FIP_MODE_FABRIC: 2881 case FIP_CONN_TYPE_VN2VN:
2874 ctlr_dev->mode = FIP_CONN_TYPE_FABRIC; 2882 ctlr->mode = FIP_MODE_VN2VN;
2875 break;
2876 case FIP_MODE_VN2VN:
2877 ctlr_dev->mode = FIP_CONN_TYPE_VN2VN;
2878 break; 2883 break;
2884 case FIP_CONN_TYPE_FABRIC:
2879 default: 2885 default:
2880 ctlr_dev->mode = FIP_CONN_TYPE_UNKNOWN; 2886 ctlr->mode = FIP_MODE_FABRIC;
2881 break; 2887 break;
2882 } 2888 }
2889
2883 mutex_unlock(&ctlr->ctlr_mutex); 2890 mutex_unlock(&ctlr->ctlr_mutex);
2884} 2891}
2885EXPORT_SYMBOL(fcoe_ctlr_get_fip_mode); 2892EXPORT_SYMBOL(fcoe_ctlr_set_fip_mode);
diff --git a/drivers/scsi/fcoe/fcoe_sysfs.c b/drivers/scsi/fcoe/fcoe_sysfs.c
index 5e751689a089..8c05ae017f5b 100644
--- a/drivers/scsi/fcoe/fcoe_sysfs.c
+++ b/drivers/scsi/fcoe/fcoe_sysfs.c
@@ -21,8 +21,17 @@
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/etherdevice.h> 23#include <linux/etherdevice.h>
24#include <linux/ctype.h>
24 25
25#include <scsi/fcoe_sysfs.h> 26#include <scsi/fcoe_sysfs.h>
27#include <scsi/libfcoe.h>
28
29/*
30 * OK to include local libfcoe.h for debug_logging, but cannot include
31 * <scsi/libfcoe.h> otherwise non-netdev based fcoe solutions would have
32 * have to include more than fcoe_sysfs.h.
33 */
34#include "libfcoe.h"
26 35
27static atomic_t ctlr_num; 36static atomic_t ctlr_num;
28static atomic_t fcf_num; 37static atomic_t fcf_num;
@@ -71,6 +80,8 @@ MODULE_PARM_DESC(fcf_dev_loss_tmo,
71 ((x)->lesb.lesb_err_block) 80 ((x)->lesb.lesb_err_block)
72#define fcoe_ctlr_fcs_error(x) \ 81#define fcoe_ctlr_fcs_error(x) \
73 ((x)->lesb.lesb_fcs_error) 82 ((x)->lesb.lesb_fcs_error)
83#define fcoe_ctlr_enabled(x) \
84 ((x)->enabled)
74#define fcoe_fcf_state(x) \ 85#define fcoe_fcf_state(x) \
75 ((x)->state) 86 ((x)->state)
76#define fcoe_fcf_fabric_name(x) \ 87#define fcoe_fcf_fabric_name(x) \
@@ -210,25 +221,34 @@ static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \
210#define fcoe_enum_name_search(title, table_type, table) \ 221#define fcoe_enum_name_search(title, table_type, table) \
211static const char *get_fcoe_##title##_name(enum table_type table_key) \ 222static const char *get_fcoe_##title##_name(enum table_type table_key) \
212{ \ 223{ \
213 int i; \ 224 if (table_key < 0 || table_key >= ARRAY_SIZE(table)) \
214 char *name = NULL; \ 225 return NULL; \
215 \ 226 return table[table_key]; \
216 for (i = 0; i < ARRAY_SIZE(table); i++) { \ 227}
217 if (table[i].value == table_key) { \ 228
218 name = table[i].name; \ 229static char *fip_conn_type_names[] = {
219 break; \ 230 [ FIP_CONN_TYPE_UNKNOWN ] = "Unknown",
220 } \ 231 [ FIP_CONN_TYPE_FABRIC ] = "Fabric",
221 } \ 232 [ FIP_CONN_TYPE_VN2VN ] = "VN2VN",
222 return name; \ 233};
234fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
235
236static enum fip_conn_type fcoe_parse_mode(const char *buf)
237{
238 int i;
239
240 for (i = 0; i < ARRAY_SIZE(fip_conn_type_names); i++) {
241 if (strcasecmp(buf, fip_conn_type_names[i]) == 0)
242 return i;
243 }
244
245 return FIP_CONN_TYPE_UNKNOWN;
223} 246}
224 247
225static struct { 248static char *fcf_state_names[] = {
226 enum fcf_state value; 249 [ FCOE_FCF_STATE_UNKNOWN ] = "Unknown",
227 char *name; 250 [ FCOE_FCF_STATE_DISCONNECTED ] = "Disconnected",
228} fcf_state_names[] = { 251 [ FCOE_FCF_STATE_CONNECTED ] = "Connected",
229 { FCOE_FCF_STATE_UNKNOWN, "Unknown" },
230 { FCOE_FCF_STATE_DISCONNECTED, "Disconnected" },
231 { FCOE_FCF_STATE_CONNECTED, "Connected" },
232}; 252};
233fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names) 253fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names)
234#define FCOE_FCF_STATE_MAX_NAMELEN 50 254#define FCOE_FCF_STATE_MAX_NAMELEN 50
@@ -246,17 +266,7 @@ static ssize_t show_fcf_state(struct device *dev,
246} 266}
247static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL); 267static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL);
248 268
249static struct { 269#define FCOE_MAX_MODENAME_LEN 20
250 enum fip_conn_type value;
251 char *name;
252} fip_conn_type_names[] = {
253 { FIP_CONN_TYPE_UNKNOWN, "Unknown" },
254 { FIP_CONN_TYPE_FABRIC, "Fabric" },
255 { FIP_CONN_TYPE_VN2VN, "VN2VN" },
256};
257fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
258#define FCOE_CTLR_MODE_MAX_NAMELEN 50
259
260static ssize_t show_ctlr_mode(struct device *dev, 270static ssize_t show_ctlr_mode(struct device *dev,
261 struct device_attribute *attr, 271 struct device_attribute *attr,
262 char *buf) 272 char *buf)
@@ -264,17 +274,116 @@ static ssize_t show_ctlr_mode(struct device *dev,
264 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 274 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
265 const char *name; 275 const char *name;
266 276
267 if (ctlr->f->get_fcoe_ctlr_mode)
268 ctlr->f->get_fcoe_ctlr_mode(ctlr);
269
270 name = get_fcoe_ctlr_mode_name(ctlr->mode); 277 name = get_fcoe_ctlr_mode_name(ctlr->mode);
271 if (!name) 278 if (!name)
272 return -EINVAL; 279 return -EINVAL;
273 return snprintf(buf, FCOE_CTLR_MODE_MAX_NAMELEN, 280 return snprintf(buf, FCOE_MAX_MODENAME_LEN,
281 "%s\n", name);
282}
283
284static ssize_t store_ctlr_mode(struct device *dev,
285 struct device_attribute *attr,
286 const char *buf, size_t count)
287{
288 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
289 char mode[FCOE_MAX_MODENAME_LEN + 1];
290
291 if (count > FCOE_MAX_MODENAME_LEN)
292 return -EINVAL;
293
294 strncpy(mode, buf, count);
295
296 if (mode[count - 1] == '\n')
297 mode[count - 1] = '\0';
298 else
299 mode[count] = '\0';
300
301 switch (ctlr->enabled) {
302 case FCOE_CTLR_ENABLED:
303 LIBFCOE_SYSFS_DBG(ctlr, "Cannot change mode when enabled.");
304 return -EBUSY;
305 case FCOE_CTLR_DISABLED:
306 if (!ctlr->f->set_fcoe_ctlr_mode) {
307 LIBFCOE_SYSFS_DBG(ctlr,
308 "Mode change not supported by LLD.");
309 return -ENOTSUPP;
310 }
311
312 ctlr->mode = fcoe_parse_mode(mode);
313 if (ctlr->mode == FIP_CONN_TYPE_UNKNOWN) {
314 LIBFCOE_SYSFS_DBG(ctlr,
315 "Unknown mode %s provided.", buf);
316 return -EINVAL;
317 }
318
319 ctlr->f->set_fcoe_ctlr_mode(ctlr);
320 LIBFCOE_SYSFS_DBG(ctlr, "Mode changed to %s.", buf);
321
322 return count;
323 case FCOE_CTLR_UNUSED:
324 default:
325 LIBFCOE_SYSFS_DBG(ctlr, "Mode change not supported.");
326 return -ENOTSUPP;
327 };
328}
329
330static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO | S_IWUSR,
331 show_ctlr_mode, store_ctlr_mode);
332
333static ssize_t store_ctlr_enabled(struct device *dev,
334 struct device_attribute *attr,
335 const char *buf, size_t count)
336{
337 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
338 int rc;
339
340 switch (ctlr->enabled) {
341 case FCOE_CTLR_ENABLED:
342 if (*buf == '1')
343 return count;
344 ctlr->enabled = FCOE_CTLR_DISABLED;
345 break;
346 case FCOE_CTLR_DISABLED:
347 if (*buf == '0')
348 return count;
349 ctlr->enabled = FCOE_CTLR_ENABLED;
350 break;
351 case FCOE_CTLR_UNUSED:
352 return -ENOTSUPP;
353 };
354
355 rc = ctlr->f->set_fcoe_ctlr_enabled(ctlr);
356 if (rc)
357 return rc;
358
359 return count;
360}
361
362static char *ctlr_enabled_state_names[] = {
363 [ FCOE_CTLR_ENABLED ] = "1",
364 [ FCOE_CTLR_DISABLED ] = "0",
365};
366fcoe_enum_name_search(ctlr_enabled_state, ctlr_enabled_state,
367 ctlr_enabled_state_names)
368#define FCOE_CTLR_ENABLED_MAX_NAMELEN 50
369
370static ssize_t show_ctlr_enabled_state(struct device *dev,
371 struct device_attribute *attr,
372 char *buf)
373{
374 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
375 const char *name;
376
377 name = get_fcoe_ctlr_enabled_state_name(ctlr->enabled);
378 if (!name)
379 return -EINVAL;
380 return snprintf(buf, FCOE_CTLR_ENABLED_MAX_NAMELEN,
274 "%s\n", name); 381 "%s\n", name);
275} 382}
276static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO, 383
277 show_ctlr_mode, NULL); 384static FCOE_DEVICE_ATTR(ctlr, enabled, S_IRUGO | S_IWUSR,
385 show_ctlr_enabled_state,
386 store_ctlr_enabled);
278 387
279static ssize_t 388static ssize_t
280store_private_fcoe_ctlr_fcf_dev_loss_tmo(struct device *dev, 389store_private_fcoe_ctlr_fcf_dev_loss_tmo(struct device *dev,
@@ -359,6 +468,7 @@ static struct attribute_group fcoe_ctlr_lesb_attr_group = {
359 468
360static struct attribute *fcoe_ctlr_attrs[] = { 469static struct attribute *fcoe_ctlr_attrs[] = {
361 &device_attr_fcoe_ctlr_fcf_dev_loss_tmo.attr, 470 &device_attr_fcoe_ctlr_fcf_dev_loss_tmo.attr,
471 &device_attr_fcoe_ctlr_enabled.attr,
362 &device_attr_fcoe_ctlr_mode.attr, 472 &device_attr_fcoe_ctlr_mode.attr,
363 NULL, 473 NULL,
364}; 474};
@@ -443,9 +553,16 @@ struct device_type fcoe_fcf_device_type = {
443 .release = fcoe_fcf_device_release, 553 .release = fcoe_fcf_device_release,
444}; 554};
445 555
556struct bus_attribute fcoe_bus_attr_group[] = {
557 __ATTR(ctlr_create, S_IWUSR, NULL, fcoe_ctlr_create_store),
558 __ATTR(ctlr_destroy, S_IWUSR, NULL, fcoe_ctlr_destroy_store),
559 __ATTR_NULL
560};
561
446struct bus_type fcoe_bus_type = { 562struct bus_type fcoe_bus_type = {
447 .name = "fcoe", 563 .name = "fcoe",
448 .match = &fcoe_bus_match, 564 .match = &fcoe_bus_match,
565 .bus_attrs = fcoe_bus_attr_group,
449}; 566};
450 567
451/** 568/**
@@ -566,6 +683,7 @@ struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent,
566 683
567 ctlr->id = atomic_inc_return(&ctlr_num) - 1; 684 ctlr->id = atomic_inc_return(&ctlr_num) - 1;
568 ctlr->f = f; 685 ctlr->f = f;
686 ctlr->mode = FIP_CONN_TYPE_FABRIC;
569 INIT_LIST_HEAD(&ctlr->fcfs); 687 INIT_LIST_HEAD(&ctlr->fcfs);
570 mutex_init(&ctlr->lock); 688 mutex_init(&ctlr->lock);
571 ctlr->dev.parent = parent; 689 ctlr->dev.parent = parent;
diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c
index ac76d8a042d7..f3a5a53e8631 100644
--- a/drivers/scsi/fcoe/fcoe_transport.c
+++ b/drivers/scsi/fcoe/fcoe_transport.c
@@ -83,6 +83,50 @@ static struct notifier_block libfcoe_notifier = {
83 .notifier_call = libfcoe_device_notification, 83 .notifier_call = libfcoe_device_notification,
84}; 84};
85 85
86/**
87 * fcoe_link_speed_update() - Update the supported and actual link speeds
88 * @lport: The local port to update speeds for
89 *
90 * Returns: 0 if the ethtool query was successful
91 * -1 if the ethtool query failed
92 */
93int fcoe_link_speed_update(struct fc_lport *lport)
94{
95 struct net_device *netdev = fcoe_get_netdev(lport);
96 struct ethtool_cmd ecmd;
97
98 if (!__ethtool_get_settings(netdev, &ecmd)) {
99 lport->link_supported_speeds &=
100 ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
101 if (ecmd.supported & (SUPPORTED_1000baseT_Half |
102 SUPPORTED_1000baseT_Full))
103 lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
104 if (ecmd.supported & SUPPORTED_10000baseT_Full)
105 lport->link_supported_speeds |=
106 FC_PORTSPEED_10GBIT;
107 switch (ethtool_cmd_speed(&ecmd)) {
108 case SPEED_1000:
109 lport->link_speed = FC_PORTSPEED_1GBIT;
110 break;
111 case SPEED_10000:
112 lport->link_speed = FC_PORTSPEED_10GBIT;
113 break;
114 }
115 return 0;
116 }
117 return -1;
118}
119EXPORT_SYMBOL_GPL(fcoe_link_speed_update);
120
121/**
122 * __fcoe_get_lesb() - Get the Link Error Status Block (LESB) for a given lport
123 * @lport: The local port to update speeds for
124 * @fc_lesb: Pointer to the LESB to be filled up
125 * @netdev: Pointer to the netdev that is associated with the lport
126 *
127 * Note, the Link Error Status Block (LESB) for FCoE is defined in FC-BB-6
128 * Clause 7.11 in v1.04.
129 */
86void __fcoe_get_lesb(struct fc_lport *lport, 130void __fcoe_get_lesb(struct fc_lport *lport,
87 struct fc_els_lesb *fc_lesb, 131 struct fc_els_lesb *fc_lesb,
88 struct net_device *netdev) 132 struct net_device *netdev)
@@ -112,6 +156,51 @@ void __fcoe_get_lesb(struct fc_lport *lport,
112} 156}
113EXPORT_SYMBOL_GPL(__fcoe_get_lesb); 157EXPORT_SYMBOL_GPL(__fcoe_get_lesb);
114 158
159/**
160 * fcoe_get_lesb() - Fill the FCoE Link Error Status Block
161 * @lport: the local port
162 * @fc_lesb: the link error status block
163 */
164void fcoe_get_lesb(struct fc_lport *lport,
165 struct fc_els_lesb *fc_lesb)
166{
167 struct net_device *netdev = fcoe_get_netdev(lport);
168
169 __fcoe_get_lesb(lport, fc_lesb, netdev);
170}
171EXPORT_SYMBOL_GPL(fcoe_get_lesb);
172
173/**
174 * fcoe_ctlr_get_lesb() - Get the Link Error Status Block (LESB) for a given
175 * fcoe controller device
176 * @ctlr_dev: The given fcoe controller device
177 *
178 */
179void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
180{
181 struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
182 struct net_device *netdev = fcoe_get_netdev(fip->lp);
183 struct fcoe_fc_els_lesb *fcoe_lesb;
184 struct fc_els_lesb fc_lesb;
185
186 __fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
187 fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);
188
189 ctlr_dev->lesb.lesb_link_fail =
190 ntohl(fcoe_lesb->lesb_link_fail);
191 ctlr_dev->lesb.lesb_vlink_fail =
192 ntohl(fcoe_lesb->lesb_vlink_fail);
193 ctlr_dev->lesb.lesb_miss_fka =
194 ntohl(fcoe_lesb->lesb_miss_fka);
195 ctlr_dev->lesb.lesb_symb_err =
196 ntohl(fcoe_lesb->lesb_symb_err);
197 ctlr_dev->lesb.lesb_err_block =
198 ntohl(fcoe_lesb->lesb_err_block);
199 ctlr_dev->lesb.lesb_fcs_error =
200 ntohl(fcoe_lesb->lesb_fcs_error);
201}
202EXPORT_SYMBOL_GPL(fcoe_ctlr_get_lesb);
203
115void fcoe_wwn_to_str(u64 wwn, char *buf, int len) 204void fcoe_wwn_to_str(u64 wwn, char *buf, int len)
116{ 205{
117 u8 wwpn[8]; 206 u8 wwpn[8];
@@ -627,6 +716,110 @@ static int libfcoe_device_notification(struct notifier_block *notifier,
627 return NOTIFY_OK; 716 return NOTIFY_OK;
628} 717}
629 718
719ssize_t fcoe_ctlr_create_store(struct bus_type *bus,
720 const char *buf, size_t count)
721{
722 struct net_device *netdev = NULL;
723 struct fcoe_transport *ft = NULL;
724 struct fcoe_ctlr_device *ctlr_dev = NULL;
725 int rc = 0;
726 int err;
727
728 mutex_lock(&ft_mutex);
729
730 netdev = fcoe_if_to_netdev(buf);
731 if (!netdev) {
732 LIBFCOE_TRANSPORT_DBG("Invalid device %s.\n", buf);
733 rc = -ENODEV;
734 goto out_nodev;
735 }
736
737 ft = fcoe_netdev_map_lookup(netdev);
738 if (ft) {
739 LIBFCOE_TRANSPORT_DBG("transport %s already has existing "
740 "FCoE instance on %s.\n",
741 ft->name, netdev->name);
742 rc = -EEXIST;
743 goto out_putdev;
744 }
745
746 ft = fcoe_transport_lookup(netdev);
747 if (!ft) {
748 LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
749 netdev->name);
750 rc = -ENODEV;
751 goto out_putdev;
752 }
753
754 /* pass to transport create */
755 err = ft->alloc ? ft->alloc(netdev) : -ENODEV;
756 if (err) {
757 fcoe_del_netdev_mapping(netdev);
758 rc = -ENOMEM;
759 goto out_putdev;
760 }
761
762 err = fcoe_add_netdev_mapping(netdev, ft);
763 if (err) {
764 LIBFCOE_TRANSPORT_DBG("failed to add new netdev mapping "
765 "for FCoE transport %s for %s.\n",
766 ft->name, netdev->name);
767 rc = -ENODEV;
768 goto out_putdev;
769 }
770
771 LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n",
772 ft->name, (ctlr_dev) ? "succeeded" : "failed",
773 netdev->name);
774
775out_putdev:
776 dev_put(netdev);
777out_nodev:
778 mutex_unlock(&ft_mutex);
779 if (rc)
780 return rc;
781 return count;
782}
783
784ssize_t fcoe_ctlr_destroy_store(struct bus_type *bus,
785 const char *buf, size_t count)
786{
787 int rc = -ENODEV;
788 struct net_device *netdev = NULL;
789 struct fcoe_transport *ft = NULL;
790
791 mutex_lock(&ft_mutex);
792
793 netdev = fcoe_if_to_netdev(buf);
794 if (!netdev) {
795 LIBFCOE_TRANSPORT_DBG("invalid device %s.\n", buf);
796 goto out_nodev;
797 }
798
799 ft = fcoe_netdev_map_lookup(netdev);
800 if (!ft) {
801 LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
802 netdev->name);
803 goto out_putdev;
804 }
805
806 /* pass to transport destroy */
807 rc = ft->destroy(netdev);
808 if (rc)
809 goto out_putdev;
810
811 fcoe_del_netdev_mapping(netdev);
812 LIBFCOE_TRANSPORT_DBG("transport %s %s to destroy fcoe on %s.\n",
813 ft->name, (rc) ? "failed" : "succeeded",
814 netdev->name);
815 rc = count; /* required for successful return */
816out_putdev:
817 dev_put(netdev);
818out_nodev:
819 mutex_unlock(&ft_mutex);
820 return rc;
821}
822EXPORT_SYMBOL(fcoe_ctlr_destroy_store);
630 823
631/** 824/**
632 * fcoe_transport_create() - Create a fcoe interface 825 * fcoe_transport_create() - Create a fcoe interface
@@ -769,11 +962,7 @@ out_putdev:
769 dev_put(netdev); 962 dev_put(netdev);
770out_nodev: 963out_nodev:
771 mutex_unlock(&ft_mutex); 964 mutex_unlock(&ft_mutex);
772 965 return rc;
773 if (rc == -ERESTARTSYS)
774 return restart_syscall();
775 else
776 return rc;
777} 966}
778 967
779/** 968/**
diff --git a/drivers/scsi/fcoe/libfcoe.h b/drivers/scsi/fcoe/libfcoe.h
index 6af5fc3a17d8..d3bb16d11401 100644
--- a/drivers/scsi/fcoe/libfcoe.h
+++ b/drivers/scsi/fcoe/libfcoe.h
@@ -2,9 +2,10 @@
2#define _FCOE_LIBFCOE_H_ 2#define _FCOE_LIBFCOE_H_
3 3
4extern unsigned int libfcoe_debug_logging; 4extern unsigned int libfcoe_debug_logging;
5#define LIBFCOE_LOGGING 0x01 /* General logging, not categorized */ 5#define LIBFCOE_LOGGING 0x01 /* General logging, not categorized */
6#define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */ 6#define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */
7#define LIBFCOE_TRANSPORT_LOGGING 0x04 /* FCoE transport logging */ 7#define LIBFCOE_TRANSPORT_LOGGING 0x04 /* FCoE transport logging */
8#define LIBFCOE_SYSFS_LOGGING 0x08 /* fcoe_sysfs logging */
8 9
9#define LIBFCOE_CHECK_LOGGING(LEVEL, CMD) \ 10#define LIBFCOE_CHECK_LOGGING(LEVEL, CMD) \
10do { \ 11do { \
@@ -16,16 +17,19 @@ do { \
16 17
17#define LIBFCOE_DBG(fmt, args...) \ 18#define LIBFCOE_DBG(fmt, args...) \
18 LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING, \ 19 LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING, \
19 printk(KERN_INFO "libfcoe: " fmt, ##args);) 20 pr_info("libfcoe: " fmt, ##args);)
20 21
21#define LIBFCOE_FIP_DBG(fip, fmt, args...) \ 22#define LIBFCOE_FIP_DBG(fip, fmt, args...) \
22 LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING, \ 23 LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING, \
23 printk(KERN_INFO "host%d: fip: " fmt, \ 24 pr_info("host%d: fip: " fmt, \
24 (fip)->lp->host->host_no, ##args);) 25 (fip)->lp->host->host_no, ##args);)
25 26
26#define LIBFCOE_TRANSPORT_DBG(fmt, args...) \ 27#define LIBFCOE_TRANSPORT_DBG(fmt, args...) \
27 LIBFCOE_CHECK_LOGGING(LIBFCOE_TRANSPORT_LOGGING, \ 28 LIBFCOE_CHECK_LOGGING(LIBFCOE_TRANSPORT_LOGGING, \
28 printk(KERN_INFO "%s: " fmt, \ 29 pr_info("%s: " fmt, __func__, ##args);)
29 __func__, ##args);) 30
31#define LIBFCOE_SYSFS_DBG(cdev, fmt, args...) \
32 LIBFCOE_CHECK_LOGGING(LIBFCOE_SYSFS_LOGGING, \
33 pr_info("ctlr_%d: " fmt, cdev->id, ##args);)
30 34
31#endif /* _FCOE_LIBFCOE_H_ */ 35#endif /* _FCOE_LIBFCOE_H_ */
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index fcb9d0b20ee4..09c81b2f2169 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -1381,10 +1381,10 @@ static void fc_fcp_timeout(unsigned long data)
1381 1381
1382 fsp->state |= FC_SRB_FCP_PROCESSING_TMO; 1382 fsp->state |= FC_SRB_FCP_PROCESSING_TMO;
1383 1383
1384 if (fsp->state & FC_SRB_RCV_STATUS) 1384 if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
1385 fc_fcp_complete_locked(fsp);
1386 else if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
1387 fc_fcp_rec(fsp); 1385 fc_fcp_rec(fsp);
1386 else if (fsp->state & FC_SRB_RCV_STATUS)
1387 fc_fcp_complete_locked(fsp);
1388 else 1388 else
1389 fc_fcp_recovery(fsp, FC_TIMED_OUT); 1389 fc_fcp_recovery(fsp, FC_TIMED_OUT);
1390 fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO; 1390 fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO;
diff --git a/drivers/scsi/libfc/fc_libfc.h b/drivers/scsi/libfc/fc_libfc.h
index c2830cc66d6a..b74189d89322 100644
--- a/drivers/scsi/libfc/fc_libfc.h
+++ b/drivers/scsi/libfc/fc_libfc.h
@@ -41,25 +41,25 @@ extern unsigned int fc_debug_logging;
41 41
42#define FC_LIBFC_DBG(fmt, args...) \ 42#define FC_LIBFC_DBG(fmt, args...) \
43 FC_CHECK_LOGGING(FC_LIBFC_LOGGING, \ 43 FC_CHECK_LOGGING(FC_LIBFC_LOGGING, \
44 printk(KERN_INFO "libfc: " fmt, ##args)) 44 pr_info("libfc: " fmt, ##args))
45 45
46#define FC_LPORT_DBG(lport, fmt, args...) \ 46#define FC_LPORT_DBG(lport, fmt, args...) \
47 FC_CHECK_LOGGING(FC_LPORT_LOGGING, \ 47 FC_CHECK_LOGGING(FC_LPORT_LOGGING, \
48 printk(KERN_INFO "host%u: lport %6.6x: " fmt, \ 48 pr_info("host%u: lport %6.6x: " fmt, \
49 (lport)->host->host_no, \ 49 (lport)->host->host_no, \
50 (lport)->port_id, ##args)) 50 (lport)->port_id, ##args))
51 51
52#define FC_DISC_DBG(disc, fmt, args...) \ 52#define FC_DISC_DBG(disc, fmt, args...) \
53 FC_CHECK_LOGGING(FC_DISC_LOGGING, \ 53 FC_CHECK_LOGGING(FC_DISC_LOGGING, \
54 printk(KERN_INFO "host%u: disc: " fmt, \ 54 pr_info("host%u: disc: " fmt, \
55 fc_disc_lport(disc)->host->host_no, \ 55 fc_disc_lport(disc)->host->host_no, \
56 ##args)) 56 ##args))
57 57
58#define FC_RPORT_ID_DBG(lport, port_id, fmt, args...) \ 58#define FC_RPORT_ID_DBG(lport, port_id, fmt, args...) \
59 FC_CHECK_LOGGING(FC_RPORT_LOGGING, \ 59 FC_CHECK_LOGGING(FC_RPORT_LOGGING, \
60 printk(KERN_INFO "host%u: rport %6.6x: " fmt, \ 60 pr_info("host%u: rport %6.6x: " fmt, \
61 (lport)->host->host_no, \ 61 (lport)->host->host_no, \
62 (port_id), ##args)) 62 (port_id), ##args))
63 63
64#define FC_RPORT_DBG(rdata, fmt, args...) \ 64#define FC_RPORT_DBG(rdata, fmt, args...) \
65 FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args) 65 FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args)
@@ -70,13 +70,13 @@ extern unsigned int fc_debug_logging;
70 if ((pkt)->seq_ptr) { \ 70 if ((pkt)->seq_ptr) { \
71 struct fc_exch *_ep = NULL; \ 71 struct fc_exch *_ep = NULL; \
72 _ep = fc_seq_exch((pkt)->seq_ptr); \ 72 _ep = fc_seq_exch((pkt)->seq_ptr); \
73 printk(KERN_INFO "host%u: fcp: %6.6x: " \ 73 pr_info("host%u: fcp: %6.6x: " \
74 "xid %04x-%04x: " fmt, \ 74 "xid %04x-%04x: " fmt, \
75 (pkt)->lp->host->host_no, \ 75 (pkt)->lp->host->host_no, \
76 (pkt)->rport->port_id, \ 76 (pkt)->rport->port_id, \
77 (_ep)->oxid, (_ep)->rxid, ##args); \ 77 (_ep)->oxid, (_ep)->rxid, ##args); \
78 } else { \ 78 } else { \
79 printk(KERN_INFO "host%u: fcp: %6.6x: " fmt, \ 79 pr_info("host%u: fcp: %6.6x: " fmt, \
80 (pkt)->lp->host->host_no, \ 80 (pkt)->lp->host->host_no, \
81 (pkt)->rport->port_id, ##args); \ 81 (pkt)->rport->port_id, ##args); \
82 } \ 82 } \
@@ -84,14 +84,14 @@ extern unsigned int fc_debug_logging;
84 84
85#define FC_EXCH_DBG(exch, fmt, args...) \ 85#define FC_EXCH_DBG(exch, fmt, args...) \
86 FC_CHECK_LOGGING(FC_EXCH_LOGGING, \ 86 FC_CHECK_LOGGING(FC_EXCH_LOGGING, \
87 printk(KERN_INFO "host%u: xid %4x: " fmt, \ 87 pr_info("host%u: xid %4x: " fmt, \
88 (exch)->lp->host->host_no, \ 88 (exch)->lp->host->host_no, \
89 exch->xid, ##args)) 89 exch->xid, ##args))
90 90
91#define FC_SCSI_DBG(lport, fmt, args...) \ 91#define FC_SCSI_DBG(lport, fmt, args...) \
92 FC_CHECK_LOGGING(FC_SCSI_LOGGING, \ 92 FC_CHECK_LOGGING(FC_SCSI_LOGGING, \
93 printk(KERN_INFO "host%u: scsi: " fmt, \ 93 pr_info("host%u: scsi: " fmt, \
94 (lport)->host->host_no, ##args)) 94 (lport)->host->host_no, ##args))
95 95
96/* 96/*
97 * FC-4 Providers. 97 * FC-4 Providers.
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 83aa1efec875..d518d17e940f 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -582,7 +582,7 @@ static void fc_rport_error(struct fc_rport_priv *rdata, struct fc_frame *fp)
582static void fc_rport_error_retry(struct fc_rport_priv *rdata, 582static void fc_rport_error_retry(struct fc_rport_priv *rdata,
583 struct fc_frame *fp) 583 struct fc_frame *fp)
584{ 584{
585 unsigned long delay = FC_DEF_E_D_TOV; 585 unsigned long delay = msecs_to_jiffies(FC_DEF_E_D_TOV);
586 586
587 /* make sure this isn't an FC_EX_CLOSED error, never retry those */ 587 /* make sure this isn't an FC_EX_CLOSED error, never retry those */
588 if (PTR_ERR(fp) == -FC_EX_CLOSED) 588 if (PTR_ERR(fp) == -FC_EX_CLOSED)