aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/emulex
diff options
context:
space:
mode:
authorPadmanabh Ratnakar <padmanabh.ratnakar@emulex.com>2011-11-25 00:48:23 -0500
committerDavid S. Miller <davem@davemloft.net>2011-11-26 14:52:29 -0500
commitd8110f62c020ebc49108de57510a1482bfcbe86a (patch)
tree1aa4e4223ffd5bf0554c782f649576f3251a2a58 /drivers/net/ethernet/emulex
parent3bb62f4f95ba004048bafb460179b5db33aff787 (diff)
be2net: Add error handling for Lancer
Detect error in Lancer by polling a HW register and recover from this error if it is recoverable. Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/emulex')
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c155
1 files changed, 106 insertions, 49 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index a1b8ebc6c5f2..66429ea60bb2 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2044,52 +2044,6 @@ void be_detect_dump_ue(struct be_adapter *adapter)
2044 } 2044 }
2045} 2045}
2046 2046
2047static void be_worker(struct work_struct *work)
2048{
2049 struct be_adapter *adapter =
2050 container_of(work, struct be_adapter, work.work);
2051 struct be_rx_obj *rxo;
2052 int i;
2053
2054 be_detect_dump_ue(adapter);
2055
2056 /* when interrupts are not yet enabled, just reap any pending
2057 * mcc completions */
2058 if (!netif_running(adapter->netdev)) {
2059 int mcc_compl, status = 0;
2060
2061 mcc_compl = be_process_mcc(adapter, &status);
2062
2063 if (mcc_compl) {
2064 struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
2065 be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl);
2066 }
2067
2068 goto reschedule;
2069 }
2070
2071 if (!adapter->stats_cmd_sent) {
2072 if (lancer_chip(adapter))
2073 lancer_cmd_get_pport_stats(adapter,
2074 &adapter->stats_cmd);
2075 else
2076 be_cmd_get_stats(adapter, &adapter->stats_cmd);
2077 }
2078
2079 for_all_rx_queues(adapter, rxo, i) {
2080 be_rx_eqd_update(adapter, rxo);
2081
2082 if (rxo->rx_post_starved) {
2083 rxo->rx_post_starved = false;
2084 be_post_rx_frags(rxo, GFP_KERNEL);
2085 }
2086 }
2087
2088reschedule:
2089 adapter->work_counter++;
2090 schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
2091}
2092
2093static void be_msix_disable(struct be_adapter *adapter) 2047static void be_msix_disable(struct be_adapter *adapter)
2094{ 2048{
2095 if (msix_enabled(adapter)) { 2049 if (msix_enabled(adapter)) {
@@ -3328,7 +3282,7 @@ static int be_dev_family_check(struct be_adapter *adapter)
3328 3282
3329static int lancer_wait_ready(struct be_adapter *adapter) 3283static int lancer_wait_ready(struct be_adapter *adapter)
3330{ 3284{
3331#define SLIPORT_READY_TIMEOUT 500 3285#define SLIPORT_READY_TIMEOUT 30
3332 u32 sliport_status; 3286 u32 sliport_status;
3333 int status = 0, i; 3287 int status = 0, i;
3334 3288
@@ -3337,7 +3291,7 @@ static int lancer_wait_ready(struct be_adapter *adapter)
3337 if (sliport_status & SLIPORT_STATUS_RDY_MASK) 3291 if (sliport_status & SLIPORT_STATUS_RDY_MASK)
3338 break; 3292 break;
3339 3293
3340 msleep(20); 3294 msleep(1000);
3341 } 3295 }
3342 3296
3343 if (i == SLIPORT_READY_TIMEOUT) 3297 if (i == SLIPORT_READY_TIMEOUT)
@@ -3374,6 +3328,104 @@ static int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
3374 return status; 3328 return status;
3375} 3329}
3376 3330
3331static void lancer_test_and_recover_fn_err(struct be_adapter *adapter)
3332{
3333 int status;
3334 u32 sliport_status;
3335
3336 if (adapter->eeh_err || adapter->ue_detected)
3337 return;
3338
3339 sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
3340
3341 if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
3342 dev_err(&adapter->pdev->dev,
3343 "Adapter in error state."
3344 "Trying to recover.\n");
3345
3346 status = lancer_test_and_set_rdy_state(adapter);
3347 if (status)
3348 goto err;
3349
3350 netif_device_detach(adapter->netdev);
3351
3352 if (netif_running(adapter->netdev))
3353 be_close(adapter->netdev);
3354
3355 be_clear(adapter);
3356
3357 adapter->fw_timeout = false;
3358
3359 status = be_setup(adapter);
3360 if (status)
3361 goto err;
3362
3363 if (netif_running(adapter->netdev)) {
3364 status = be_open(adapter->netdev);
3365 if (status)
3366 goto err;
3367 }
3368
3369 netif_device_attach(adapter->netdev);
3370
3371 dev_err(&adapter->pdev->dev,
3372 "Adapter error recovery succeeded\n");
3373 }
3374 return;
3375err:
3376 dev_err(&adapter->pdev->dev,
3377 "Adapter error recovery failed\n");
3378}
3379
3380static void be_worker(struct work_struct *work)
3381{
3382 struct be_adapter *adapter =
3383 container_of(work, struct be_adapter, work.work);
3384 struct be_rx_obj *rxo;
3385 int i;
3386
3387 if (lancer_chip(adapter))
3388 lancer_test_and_recover_fn_err(adapter);
3389
3390 be_detect_dump_ue(adapter);
3391
3392 /* when interrupts are not yet enabled, just reap any pending
3393 * mcc completions */
3394 if (!netif_running(adapter->netdev)) {
3395 int mcc_compl, status = 0;
3396
3397 mcc_compl = be_process_mcc(adapter, &status);
3398
3399 if (mcc_compl) {
3400 struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
3401 be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl);
3402 }
3403
3404 goto reschedule;
3405 }
3406
3407 if (!adapter->stats_cmd_sent) {
3408 if (lancer_chip(adapter))
3409 lancer_cmd_get_pport_stats(adapter,
3410 &adapter->stats_cmd);
3411 else
3412 be_cmd_get_stats(adapter, &adapter->stats_cmd);
3413 }
3414
3415 for_all_rx_queues(adapter, rxo, i) {
3416 be_rx_eqd_update(adapter, rxo);
3417
3418 if (rxo->rx_post_starved) {
3419 rxo->rx_post_starved = false;
3420 be_post_rx_frags(rxo, GFP_KERNEL);
3421 }
3422 }
3423
3424reschedule:
3425 adapter->work_counter++;
3426 schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
3427}
3428
3377static int __devinit be_probe(struct pci_dev *pdev, 3429static int __devinit be_probe(struct pci_dev *pdev,
3378 const struct pci_device_id *pdev_id) 3430 const struct pci_device_id *pdev_id)
3379{ 3431{
@@ -3426,7 +3478,12 @@ static int __devinit be_probe(struct pci_dev *pdev,
3426 goto disable_sriov; 3478 goto disable_sriov;
3427 3479
3428 if (lancer_chip(adapter)) { 3480 if (lancer_chip(adapter)) {
3429 status = lancer_test_and_set_rdy_state(adapter); 3481 status = lancer_wait_ready(adapter);
3482 if (!status) {
3483 iowrite32(SLI_PORT_CONTROL_IP_MASK,
3484 adapter->db + SLIPORT_CONTROL_OFFSET);
3485 status = lancer_test_and_set_rdy_state(adapter);
3486 }
3430 if (status) { 3487 if (status) {
3431 dev_err(&pdev->dev, "Adapter in non recoverable error\n"); 3488 dev_err(&pdev->dev, "Adapter in non recoverable error\n");
3432 goto ctrl_clean; 3489 goto ctrl_clean;