diff options
author | Sathya Perla <sathya.perla@emulex.com> | 2011-11-10 14:18:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-12 17:59:36 -0500 |
commit | 6589ade019dcab245d3bb847370f855b56cdf6ad (patch) | |
tree | fa23308e00b3cbc50faecc45b98b6133743bf72e | |
parent | 434b3648e9a58600cea5f3a1a0a7a89048e4df61 (diff) |
be2net: stop issuing FW cmds if any cmd times out
A FW cmd timeout (with a sufficiently large timeout value in the
order of tens of seconds) indicates an unresponsive FW. In this state
issuing further cmds and waiting for a completion will only stall the process.
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 29 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 2 |
3 files changed, 20 insertions, 19 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 4163980d6bcd..34f162db9f2e 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -350,6 +350,8 @@ struct be_adapter { | |||
350 | u32 beacon_state; /* for set_phys_id */ | 350 | u32 beacon_state; /* for set_phys_id */ |
351 | 351 | ||
352 | bool eeh_err; | 352 | bool eeh_err; |
353 | bool ue_detected; | ||
354 | bool fw_timeout; | ||
353 | u32 port_num; | 355 | u32 port_num; |
354 | bool promiscuous; | 356 | bool promiscuous; |
355 | bool wol; | 357 | bool wol; |
@@ -357,7 +359,6 @@ struct be_adapter { | |||
357 | u32 function_caps; | 359 | u32 function_caps; |
358 | u32 rx_fc; /* Rx flow control */ | 360 | u32 rx_fc; /* Rx flow control */ |
359 | u32 tx_fc; /* Tx flow control */ | 361 | u32 tx_fc; /* Tx flow control */ |
360 | bool ue_detected; | ||
361 | bool stats_cmd_sent; | 362 | bool stats_cmd_sent; |
362 | int link_speed; | 363 | int link_speed; |
363 | u8 port_type; | 364 | u8 port_type; |
@@ -522,6 +523,11 @@ static inline bool be_multi_rxq(const struct be_adapter *adapter) | |||
522 | return adapter->num_rx_qs > 1; | 523 | return adapter->num_rx_qs > 1; |
523 | } | 524 | } |
524 | 525 | ||
526 | static inline bool be_error(struct be_adapter *adapter) | ||
527 | { | ||
528 | return adapter->eeh_err || adapter->ue_detected || adapter->fw_timeout; | ||
529 | } | ||
530 | |||
525 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, | 531 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, |
526 | u16 num_popped); | 532 | u16 num_popped); |
527 | extern void be_link_status_update(struct be_adapter *adapter, u32 link_status); | 533 | extern void be_link_status_update(struct be_adapter *adapter, u32 link_status); |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 94cd77ca367a..ad3eef0beea0 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -31,7 +31,7 @@ static void be_mcc_notify(struct be_adapter *adapter) | |||
31 | struct be_queue_info *mccq = &adapter->mcc_obj.q; | 31 | struct be_queue_info *mccq = &adapter->mcc_obj.q; |
32 | u32 val = 0; | 32 | u32 val = 0; |
33 | 33 | ||
34 | if (adapter->eeh_err) | 34 | if (be_error(adapter)) |
35 | return; | 35 | return; |
36 | 36 | ||
37 | val |= mccq->id & DB_MCCQ_RING_ID_MASK; | 37 | val |= mccq->id & DB_MCCQ_RING_ID_MASK; |
@@ -263,10 +263,10 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) | |||
263 | int i, num, status = 0; | 263 | int i, num, status = 0; |
264 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; | 264 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; |
265 | 265 | ||
266 | if (adapter->eeh_err) | ||
267 | return -EIO; | ||
268 | |||
269 | for (i = 0; i < mcc_timeout; i++) { | 266 | for (i = 0; i < mcc_timeout; i++) { |
267 | if (be_error(adapter)) | ||
268 | return -EIO; | ||
269 | |||
270 | num = be_process_mcc(adapter, &status); | 270 | num = be_process_mcc(adapter, &status); |
271 | if (num) | 271 | if (num) |
272 | be_cq_notify(adapter, mcc_obj->cq.id, | 272 | be_cq_notify(adapter, mcc_obj->cq.id, |
@@ -277,7 +277,8 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) | |||
277 | udelay(100); | 277 | udelay(100); |
278 | } | 278 | } |
279 | if (i == mcc_timeout) { | 279 | if (i == mcc_timeout) { |
280 | dev_err(&adapter->pdev->dev, "mccq poll timed out\n"); | 280 | dev_err(&adapter->pdev->dev, "FW not responding\n"); |
281 | adapter->fw_timeout = true; | ||
281 | return -1; | 282 | return -1; |
282 | } | 283 | } |
283 | return status; | 284 | return status; |
@@ -295,10 +296,10 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) | |||
295 | int msecs = 0; | 296 | int msecs = 0; |
296 | u32 ready; | 297 | u32 ready; |
297 | 298 | ||
298 | if (adapter->eeh_err) | ||
299 | return -EIO; | ||
300 | |||
301 | do { | 299 | do { |
300 | if (be_error(adapter)) | ||
301 | return -EIO; | ||
302 | |||
302 | ready = ioread32(db); | 303 | ready = ioread32(db); |
303 | if (ready == 0xffffffff) | 304 | if (ready == 0xffffffff) |
304 | return -1; | 305 | return -1; |
@@ -308,7 +309,8 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) | |||
308 | break; | 309 | break; |
309 | 310 | ||
310 | if (msecs > 4000) { | 311 | if (msecs > 4000) { |
311 | dev_err(&adapter->pdev->dev, "mbox poll timed out\n"); | 312 | dev_err(&adapter->pdev->dev, "FW not responding\n"); |
313 | adapter->fw_timeout = true; | ||
312 | be_detect_dump_ue(adapter); | 314 | be_detect_dump_ue(adapter); |
313 | return -1; | 315 | return -1; |
314 | } | 316 | } |
@@ -546,9 +548,6 @@ int be_cmd_fw_clean(struct be_adapter *adapter) | |||
546 | u8 *wrb; | 548 | u8 *wrb; |
547 | int status; | 549 | int status; |
548 | 550 | ||
549 | if (adapter->eeh_err) | ||
550 | return -EIO; | ||
551 | |||
552 | if (mutex_lock_interruptible(&adapter->mbox_lock)) | 551 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
553 | return -1; | 552 | return -1; |
554 | 553 | ||
@@ -1012,9 +1011,6 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, | |||
1012 | u8 subsys = 0, opcode = 0; | 1011 | u8 subsys = 0, opcode = 0; |
1013 | int status; | 1012 | int status; |
1014 | 1013 | ||
1015 | if (adapter->eeh_err) | ||
1016 | return -EIO; | ||
1017 | |||
1018 | if (mutex_lock_interruptible(&adapter->mbox_lock)) | 1014 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
1019 | return -1; | 1015 | return -1; |
1020 | 1016 | ||
@@ -1136,9 +1132,6 @@ int be_cmd_if_destroy(struct be_adapter *adapter, int interface_id, u32 domain) | |||
1136 | struct be_cmd_req_if_destroy *req; | 1132 | struct be_cmd_req_if_destroy *req; |
1137 | int status; | 1133 | int status; |
1138 | 1134 | ||
1139 | if (adapter->eeh_err) | ||
1140 | return -EIO; | ||
1141 | |||
1142 | if (interface_id == -1) | 1135 | if (interface_id == -1) |
1143 | return 0; | 1136 | return 0; |
1144 | 1137 | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 0e97b6d01c79..ce20d64d1f95 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -3569,6 +3569,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev) | |||
3569 | 3569 | ||
3570 | dev_info(&adapter->pdev->dev, "EEH reset\n"); | 3570 | dev_info(&adapter->pdev->dev, "EEH reset\n"); |
3571 | adapter->eeh_err = false; | 3571 | adapter->eeh_err = false; |
3572 | adapter->ue_detected = false; | ||
3573 | adapter->fw_timeout = false; | ||
3572 | 3574 | ||
3573 | status = pci_enable_device(pdev); | 3575 | status = pci_enable_device(pdev); |
3574 | if (status) | 3576 | if (status) |