diff options
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 21 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_ethtool.c | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 24 |
5 files changed, 45 insertions, 19 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 995198d72b84..cbdec2536da6 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -299,6 +299,8 @@ struct be_vf_cfg { | |||
299 | u32 tx_rate; | 299 | u32 tx_rate; |
300 | }; | 300 | }; |
301 | 301 | ||
302 | #define BE_FLAGS_LINK_STATUS_INIT 1 | ||
303 | |||
302 | struct be_adapter { | 304 | struct be_adapter { |
303 | struct pci_dev *pdev; | 305 | struct pci_dev *pdev; |
304 | struct net_device *netdev; | 306 | struct net_device *netdev; |
@@ -347,6 +349,7 @@ struct be_adapter { | |||
347 | struct delayed_work work; | 349 | struct delayed_work work; |
348 | u16 work_counter; | 350 | u16 work_counter; |
349 | 351 | ||
352 | u32 flags; | ||
350 | /* Ethtool knobs and info */ | 353 | /* Ethtool knobs and info */ |
351 | char fw_ver[FW_VER_LEN]; | 354 | char fw_ver[FW_VER_LEN]; |
352 | int if_handle; /* Used to configure filtering */ | 355 | int if_handle; /* Used to configure filtering */ |
@@ -538,7 +541,7 @@ static inline bool be_error(struct be_adapter *adapter) | |||
538 | 541 | ||
539 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, | 542 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, |
540 | u16 num_popped); | 543 | u16 num_popped); |
541 | extern void be_link_status_update(struct be_adapter *adapter, u32 link_status); | 544 | extern void be_link_status_update(struct be_adapter *adapter, u8 link_status); |
542 | extern void be_parse_stats(struct be_adapter *adapter); | 545 | extern void be_parse_stats(struct be_adapter *adapter); |
543 | extern int be_load_fw(struct be_adapter *adapter, u8 *func); | 546 | extern int be_load_fw(struct be_adapter *adapter, u8 *func); |
544 | #endif /* BE_H */ | 547 | #endif /* BE_H */ |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 62868ea48295..0fcb45624796 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -125,7 +125,14 @@ done: | |||
125 | static void be_async_link_state_process(struct be_adapter *adapter, | 125 | static void be_async_link_state_process(struct be_adapter *adapter, |
126 | struct be_async_event_link_state *evt) | 126 | struct be_async_event_link_state *evt) |
127 | { | 127 | { |
128 | be_link_status_update(adapter, evt->port_link_status); | 128 | /* When link status changes, link speed must be re-queried from FW */ |
129 | adapter->link_speed = -1; | ||
130 | |||
131 | /* For the initial link status do not rely on the ASYNC event as | ||
132 | * it may not be received in some cases. | ||
133 | */ | ||
134 | if (adapter->flags & BE_FLAGS_LINK_STATUS_INIT) | ||
135 | be_link_status_update(adapter, evt->port_link_status); | ||
129 | } | 136 | } |
130 | 137 | ||
131 | /* Grp5 CoS Priority evt */ | 138 | /* Grp5 CoS Priority evt */ |
@@ -1232,7 +1239,7 @@ err: | |||
1232 | 1239 | ||
1233 | /* Uses synchronous mcc */ | 1240 | /* Uses synchronous mcc */ |
1234 | int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed, | 1241 | int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed, |
1235 | u16 *link_speed, u32 dom) | 1242 | u16 *link_speed, u8 *link_status, u32 dom) |
1236 | { | 1243 | { |
1237 | struct be_mcc_wrb *wrb; | 1244 | struct be_mcc_wrb *wrb; |
1238 | struct be_cmd_req_link_status *req; | 1245 | struct be_cmd_req_link_status *req; |
@@ -1240,6 +1247,9 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed, | |||
1240 | 1247 | ||
1241 | spin_lock_bh(&adapter->mcc_lock); | 1248 | spin_lock_bh(&adapter->mcc_lock); |
1242 | 1249 | ||
1250 | if (link_status) | ||
1251 | *link_status = LINK_DOWN; | ||
1252 | |||
1243 | wrb = wrb_from_mccq(adapter); | 1253 | wrb = wrb_from_mccq(adapter); |
1244 | if (!wrb) { | 1254 | if (!wrb) { |
1245 | status = -EBUSY; | 1255 | status = -EBUSY; |
@@ -1247,7 +1257,7 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed, | |||
1247 | } | 1257 | } |
1248 | req = embedded_payload(wrb); | 1258 | req = embedded_payload(wrb); |
1249 | 1259 | ||
1250 | if (lancer_chip(adapter)) | 1260 | if (adapter->generation == BE_GEN3 || lancer_chip(adapter)) |
1251 | req->hdr.version = 1; | 1261 | req->hdr.version = 1; |
1252 | 1262 | ||
1253 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 1263 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
@@ -1257,10 +1267,13 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed, | |||
1257 | if (!status) { | 1267 | if (!status) { |
1258 | struct be_cmd_resp_link_status *resp = embedded_payload(wrb); | 1268 | struct be_cmd_resp_link_status *resp = embedded_payload(wrb); |
1259 | if (resp->mac_speed != PHY_LINK_SPEED_ZERO) { | 1269 | if (resp->mac_speed != PHY_LINK_SPEED_ZERO) { |
1260 | *link_speed = le16_to_cpu(resp->link_speed); | 1270 | if (link_speed) |
1271 | *link_speed = le16_to_cpu(resp->link_speed); | ||
1261 | if (mac_speed) | 1272 | if (mac_speed) |
1262 | *mac_speed = resp->mac_speed; | 1273 | *mac_speed = resp->mac_speed; |
1263 | } | 1274 | } |
1275 | if (link_status) | ||
1276 | *link_status = resp->logical_link_status; | ||
1264 | } | 1277 | } |
1265 | 1278 | ||
1266 | err: | 1279 | err: |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 0b694c640642..dca89249088f 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -960,7 +960,8 @@ struct be_cmd_resp_link_status { | |||
960 | u8 mgmt_mac_duplex; | 960 | u8 mgmt_mac_duplex; |
961 | u8 mgmt_mac_speed; | 961 | u8 mgmt_mac_speed; |
962 | u16 link_speed; | 962 | u16 link_speed; |
963 | u32 rsvd0; | 963 | u8 logical_link_status; |
964 | u8 rsvd1[3]; | ||
964 | } __packed; | 965 | } __packed; |
965 | 966 | ||
966 | /******************** Port Identification ***************************/ | 967 | /******************** Port Identification ***************************/ |
@@ -1507,8 +1508,8 @@ extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, | |||
1507 | int type); | 1508 | int type); |
1508 | extern int be_cmd_rxq_destroy(struct be_adapter *adapter, | 1509 | extern int be_cmd_rxq_destroy(struct be_adapter *adapter, |
1509 | struct be_queue_info *q); | 1510 | struct be_queue_info *q); |
1510 | extern int be_cmd_link_status_query(struct be_adapter *adapter, | 1511 | extern int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed, |
1511 | u8 *mac_speed, u16 *link_speed, u32 dom); | 1512 | u16 *link_speed, u8 *link_status, u32 dom); |
1512 | extern int be_cmd_reset(struct be_adapter *adapter); | 1513 | extern int be_cmd_reset(struct be_adapter *adapter); |
1513 | extern int be_cmd_get_stats(struct be_adapter *adapter, | 1514 | extern int be_cmd_get_stats(struct be_adapter *adapter, |
1514 | struct be_dma_mem *nonemb_cmd); | 1515 | struct be_dma_mem *nonemb_cmd); |
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index 6ba2dc6bdf7b..6db6b6ae5e9b 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c | |||
@@ -429,11 +429,14 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
429 | struct be_phy_info phy_info; | 429 | struct be_phy_info phy_info; |
430 | u8 mac_speed = 0; | 430 | u8 mac_speed = 0; |
431 | u16 link_speed = 0; | 431 | u16 link_speed = 0; |
432 | u8 link_status; | ||
432 | int status; | 433 | int status; |
433 | 434 | ||
434 | if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) { | 435 | if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) { |
435 | status = be_cmd_link_status_query(adapter, &mac_speed, | 436 | status = be_cmd_link_status_query(adapter, &mac_speed, |
436 | &link_speed, 0); | 437 | &link_speed, &link_status, 0); |
438 | if (!status) | ||
439 | be_link_status_update(adapter, link_status); | ||
437 | 440 | ||
438 | /* link_speed is in units of 10 Mbps */ | 441 | /* link_speed is in units of 10 Mbps */ |
439 | if (link_speed) { | 442 | if (link_speed) { |
@@ -700,7 +703,7 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) | |||
700 | } | 703 | } |
701 | 704 | ||
702 | if (be_cmd_link_status_query(adapter, &mac_speed, | 705 | if (be_cmd_link_status_query(adapter, &mac_speed, |
703 | &qos_link_speed, 0) != 0) { | 706 | &qos_link_speed, NULL, 0) != 0) { |
704 | test->flags |= ETH_TEST_FL_FAILED; | 707 | test->flags |= ETH_TEST_FL_FAILED; |
705 | data[4] = -1; | 708 | data[4] = -1; |
706 | } else if (!mac_speed) { | 709 | } else if (!mac_speed) { |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index fe702c1c866d..6c46753aeb43 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -496,19 +496,19 @@ static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev, | |||
496 | return stats; | 496 | return stats; |
497 | } | 497 | } |
498 | 498 | ||
499 | void be_link_status_update(struct be_adapter *adapter, u32 link_status) | 499 | void be_link_status_update(struct be_adapter *adapter, u8 link_status) |
500 | { | 500 | { |
501 | struct net_device *netdev = adapter->netdev; | 501 | struct net_device *netdev = adapter->netdev; |
502 | 502 | ||
503 | /* when link status changes, link speed must be re-queried from card */ | 503 | if (!(adapter->flags & BE_FLAGS_LINK_STATUS_INIT)) { |
504 | adapter->link_speed = -1; | ||
505 | if ((link_status & LINK_STATUS_MASK) == LINK_UP) { | ||
506 | netif_carrier_on(netdev); | ||
507 | dev_info(&adapter->pdev->dev, "%s: Link up\n", netdev->name); | ||
508 | } else { | ||
509 | netif_carrier_off(netdev); | 504 | netif_carrier_off(netdev); |
510 | dev_info(&adapter->pdev->dev, "%s: Link down\n", netdev->name); | 505 | adapter->flags |= BE_FLAGS_LINK_STATUS_INIT; |
511 | } | 506 | } |
507 | |||
508 | if ((link_status & LINK_STATUS_MASK) == LINK_UP) | ||
509 | netif_carrier_on(netdev); | ||
510 | else | ||
511 | netif_carrier_off(netdev); | ||
512 | } | 512 | } |
513 | 513 | ||
514 | static void be_tx_stats_update(struct be_tx_obj *txo, | 514 | static void be_tx_stats_update(struct be_tx_obj *txo, |
@@ -2414,6 +2414,7 @@ static int be_open(struct net_device *netdev) | |||
2414 | struct be_adapter *adapter = netdev_priv(netdev); | 2414 | struct be_adapter *adapter = netdev_priv(netdev); |
2415 | struct be_eq_obj *tx_eq = &adapter->tx_eq; | 2415 | struct be_eq_obj *tx_eq = &adapter->tx_eq; |
2416 | struct be_rx_obj *rxo; | 2416 | struct be_rx_obj *rxo; |
2417 | u8 link_status; | ||
2417 | int status, i; | 2418 | int status, i; |
2418 | 2419 | ||
2419 | status = be_rx_queues_setup(adapter); | 2420 | status = be_rx_queues_setup(adapter); |
@@ -2437,6 +2438,11 @@ static int be_open(struct net_device *netdev) | |||
2437 | /* Now that interrupts are on we can process async mcc */ | 2438 | /* Now that interrupts are on we can process async mcc */ |
2438 | be_async_mcc_enable(adapter); | 2439 | be_async_mcc_enable(adapter); |
2439 | 2440 | ||
2441 | status = be_cmd_link_status_query(adapter, NULL, NULL, | ||
2442 | &link_status, 0); | ||
2443 | if (!status) | ||
2444 | be_link_status_update(adapter, link_status); | ||
2445 | |||
2440 | return 0; | 2446 | return 0; |
2441 | err: | 2447 | err: |
2442 | be_close(adapter->netdev); | 2448 | be_close(adapter->netdev); |
@@ -2584,7 +2590,7 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
2584 | 2590 | ||
2585 | for_all_vfs(adapter, vf_cfg, vf) { | 2591 | for_all_vfs(adapter, vf_cfg, vf) { |
2586 | status = be_cmd_link_status_query(adapter, NULL, &lnk_speed, | 2592 | status = be_cmd_link_status_query(adapter, NULL, &lnk_speed, |
2587 | vf + 1); | 2593 | NULL, vf + 1); |
2588 | if (status) | 2594 | if (status) |
2589 | goto err; | 2595 | goto err; |
2590 | vf_cfg->tx_rate = lnk_speed * 10; | 2596 | vf_cfg->tx_rate = lnk_speed * 10; |