diff options
| -rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 7022a16b14f6..4834d3c130d6 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
| @@ -74,6 +74,7 @@ static int fcoe_rcv(struct sk_buff *, struct net_device *, | |||
| 74 | static int fcoe_percpu_receive_thread(void *); | 74 | static int fcoe_percpu_receive_thread(void *); |
| 75 | static void fcoe_clean_pending_queue(struct fc_lport *); | 75 | static void fcoe_clean_pending_queue(struct fc_lport *); |
| 76 | static void fcoe_percpu_clean(struct fc_lport *); | 76 | static void fcoe_percpu_clean(struct fc_lport *); |
| 77 | static int fcoe_link_speed_update(struct fc_lport *); | ||
| 77 | static int fcoe_link_ok(struct fc_lport *); | 78 | static int fcoe_link_ok(struct fc_lport *); |
| 78 | 79 | ||
| 79 | static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); | 80 | static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); |
| @@ -631,6 +632,8 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) | |||
| 631 | port->fcoe_pending_queue_active = 0; | 632 | port->fcoe_pending_queue_active = 0; |
| 632 | setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lport); | 633 | setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lport); |
| 633 | 634 | ||
| 635 | fcoe_link_speed_update(lport); | ||
| 636 | |||
| 634 | if (!lport->vport) { | 637 | if (!lport->vport) { |
| 635 | /* | 638 | /* |
| 636 | * Use NAA 1&2 (FC-FS Rev. 2.0, Sec. 15) to generate WWNN/WWPN: | 639 | * Use NAA 1&2 (FC-FS Rev. 2.0, Sec. 15) to generate WWNN/WWPN: |
| @@ -1829,6 +1832,9 @@ static int fcoe_device_notification(struct notifier_block *notifier, | |||
| 1829 | FCOE_NETDEV_DBG(netdev, "Unknown event %ld " | 1832 | FCOE_NETDEV_DBG(netdev, "Unknown event %ld " |
| 1830 | "from netdev netlink\n", event); | 1833 | "from netdev netlink\n", event); |
| 1831 | } | 1834 | } |
| 1835 | |||
| 1836 | fcoe_link_speed_update(lport); | ||
| 1837 | |||
| 1832 | if (link_possible && !fcoe_link_ok(lport)) | 1838 | if (link_possible && !fcoe_link_ok(lport)) |
| 1833 | fcoe_ctlr_link_up(&fcoe->ctlr); | 1839 | fcoe_ctlr_link_up(&fcoe->ctlr); |
| 1834 | else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { | 1840 | else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { |
| @@ -2128,26 +2134,19 @@ out_nomod: | |||
| 2128 | } | 2134 | } |
| 2129 | 2135 | ||
| 2130 | /** | 2136 | /** |
| 2131 | * fcoe_link_ok() - Check if the link is OK for a local port | 2137 | * fcoe_link_speed_update() - Update the supported and actual link speeds |
| 2132 | * @lport: The local port to check link on | 2138 | * @lport: The local port to update speeds for |
| 2133 | * | ||
| 2134 | * Any permanently-disqualifying conditions have been previously checked. | ||
| 2135 | * This also updates the speed setting, which may change with link for 100/1000. | ||
| 2136 | * | ||
| 2137 | * This function should probably be checking for PAUSE support at some point | ||
| 2138 | * in the future. Currently Per-priority-pause is not determinable using | ||
| 2139 | * ethtool, so we shouldn't be restrictive until that problem is resolved. | ||
| 2140 | * | ||
| 2141 | * Returns: 0 if link is OK for use by FCoE. | ||
| 2142 | * | 2139 | * |
| 2140 | * Returns: 0 if the ethtool query was successful | ||
| 2141 | * -1 if the ethtool query failed | ||
| 2143 | */ | 2142 | */ |
| 2144 | int fcoe_link_ok(struct fc_lport *lport) | 2143 | int fcoe_link_speed_update(struct fc_lport *lport) |
| 2145 | { | 2144 | { |
| 2146 | struct fcoe_port *port = lport_priv(lport); | 2145 | struct fcoe_port *port = lport_priv(lport); |
| 2147 | struct net_device *netdev = port->fcoe->netdev; | 2146 | struct net_device *netdev = port->fcoe->netdev; |
| 2148 | struct ethtool_cmd ecmd = { ETHTOOL_GSET }; | 2147 | struct ethtool_cmd ecmd = { ETHTOOL_GSET }; |
| 2149 | 2148 | ||
| 2150 | if (netif_oper_up(netdev) && !dev_ethtool_get_settings(netdev, &ecmd)) { | 2149 | if (!dev_ethtool_get_settings(netdev, &ecmd)) { |
| 2151 | lport->link_supported_speeds &= | 2150 | lport->link_supported_speeds &= |
| 2152 | ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT); | 2151 | ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT); |
| 2153 | if (ecmd.supported & (SUPPORTED_1000baseT_Half | | 2152 | if (ecmd.supported & (SUPPORTED_1000baseT_Half | |
| @@ -2167,6 +2166,23 @@ int fcoe_link_ok(struct fc_lport *lport) | |||
| 2167 | } | 2166 | } |
| 2168 | 2167 | ||
| 2169 | /** | 2168 | /** |
| 2169 | * fcoe_link_ok() - Check if the link is OK for a local port | ||
| 2170 | * @lport: The local port to check link on | ||
| 2171 | * | ||
| 2172 | * Returns: 0 if link is UP and OK, -1 if not | ||
| 2173 | * | ||
| 2174 | */ | ||
| 2175 | int fcoe_link_ok(struct fc_lport *lport) | ||
| 2176 | { | ||
| 2177 | struct fcoe_port *port = lport_priv(lport); | ||
| 2178 | struct net_device *netdev = port->fcoe->netdev; | ||
| 2179 | |||
| 2180 | if (netif_oper_up(netdev)) | ||
| 2181 | return 0; | ||
| 2182 | return -1; | ||
| 2183 | } | ||
| 2184 | |||
| 2185 | /** | ||
| 2170 | * fcoe_percpu_clean() - Clear all pending skbs for an local port | 2186 | * fcoe_percpu_clean() - Clear all pending skbs for an local port |
| 2171 | * @lport: The local port whose skbs are to be cleared | 2187 | * @lport: The local port whose skbs are to be cleared |
| 2172 | * | 2188 | * |
