aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/emulex
diff options
context:
space:
mode:
authorPadmanabh Ratnakar <padmanabh.ratnakar@broadcom.com>2016-02-03 09:49:22 +0530
committerDavid S. Miller <davem@davemloft.net>2016-02-07 13:55:22 -0500
commit972f37b424e65f9ef1ce143b8658d9ed50db9f42 (patch)
tree63058b8e5b7384c61a05a1a2aae829f3706cee06 /drivers/net/ethernet/emulex
parentbe2net: Fix Lancer error recovery (diff)
downloadlinux-dev-972f37b424e65f9ef1ce143b8658d9ed50db9f42.tar.xz
linux-dev-972f37b424e65f9ef1ce143b8658d9ed50db9f42.zip
be2net: Add retry in case of error recovery failure
Retry error recovery MAX_ERR_RECOVERY_RETRY_COUNT times in case of failure during error recovery. Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@broadcom.com> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.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.h5
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c23
2 files changed, 22 insertions, 6 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index de88c30bc029..515e206589cc 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -397,6 +397,10 @@ enum vf_state {
#define BE_UC_PMAC_COUNT 30
#define BE_VF_UC_PMAC_COUNT 2
+#define MAX_ERR_RECOVERY_RETRY_COUNT 3
+#define ERR_DETECTION_DELAY 1000
+#define ERR_RECOVERY_RETRY_DELAY 30000
+
/* Ethtool set_dump flags */
#define LANCER_INITIATE_FW_DUMP 0x1
#define LANCER_DELETE_FW_DUMP 0x2
@@ -534,6 +538,7 @@ struct be_adapter {
u16 work_counter;
struct delayed_work be_err_detection_work;
+ u8 recovery_retries;
u8 err_flags;
u32 flags;
u32 cmd_privileges;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 6eb3aba832fc..d5286d3c9356 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -4265,10 +4265,10 @@ static void be_schedule_worker(struct be_adapter *adapter)
adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
}
-static void be_schedule_err_detection(struct be_adapter *adapter)
+static void be_schedule_err_detection(struct be_adapter *adapter, u32 delay)
{
schedule_delayed_work(&adapter->be_err_detection_work,
- msecs_to_jiffies(1000));
+ msecs_to_jiffies(delay));
adapter->flags |= BE_FLAGS_ERR_DETECTION_SCHEDULED;
}
@@ -4890,6 +4890,7 @@ static void be_err_detection_task(struct work_struct *work)
be_err_detection_work.work);
struct device *dev = &adapter->pdev->dev;
int recovery_status;
+ int delay = ERR_DETECTION_DELAY;
be_detect_error(adapter);
@@ -4899,6 +4900,7 @@ static void be_err_detection_task(struct work_struct *work)
goto reschedule_task;
if (!recovery_status) {
+ adapter->recovery_retries = 0;
dev_info(dev, "Adapter recovery successful\n");
goto reschedule_task;
} else if (be_virtfn(adapter)) {
@@ -4907,13 +4909,22 @@ static void be_err_detection_task(struct work_struct *work)
*/
dev_err(dev, "Re-trying adapter recovery\n");
goto reschedule_task;
+ } else if (adapter->recovery_retries++ <
+ MAX_ERR_RECOVERY_RETRY_COUNT) {
+ /* In case of another error during recovery, it takes 30 sec
+ * for adapter to come out of error. Retry error recovery after
+ * this time interval.
+ */
+ dev_err(&adapter->pdev->dev, "Re-trying adapter recovery\n");
+ delay = ERR_RECOVERY_RETRY_DELAY;
+ goto reschedule_task;
} else {
dev_err(dev, "Adapter recovery failed\n");
}
return;
reschedule_task:
- be_schedule_err_detection(adapter);
+ be_schedule_err_detection(adapter, delay);
}
static void be_log_sfp_info(struct be_adapter *adapter)
@@ -5309,7 +5320,7 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
be_roce_dev_add(adapter);
- be_schedule_err_detection(adapter);
+ be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
/* On Die temperature not supported for VF. */
if (be_physfn(adapter) && IS_ENABLED(CONFIG_BE2NET_HWMON)) {
@@ -5376,7 +5387,7 @@ static int be_pci_resume(struct pci_dev *pdev)
if (status)
return status;
- be_schedule_err_detection(adapter);
+ be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
if (adapter->wol_en)
be_setup_wol(adapter, false);
@@ -5476,7 +5487,7 @@ static void be_eeh_resume(struct pci_dev *pdev)
if (status)
goto err;
- be_schedule_err_detection(adapter);
+ be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
return;
err:
dev_err(&adapter->pdev->dev, "EEH resume failed\n");