Commit f67ef7ba authored by Padmanabh Ratnakar's avatar Padmanabh Ratnakar Committed by David S. Miller

be2net: Activate new FW after FW download for Lancer

After FW download, activate new FW by invoking FW reset.
Recreate rings once new FW is operational.
Signed-off-by: default avatarPadmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bf99e50d
...@@ -389,6 +389,7 @@ struct be_adapter { ...@@ -389,6 +389,7 @@ struct be_adapter {
struct delayed_work work; struct delayed_work work;
u16 work_counter; u16 work_counter;
struct delayed_work func_recovery_work;
u32 flags; u32 flags;
/* Ethtool knobs and info */ /* Ethtool knobs and info */
char fw_ver[FW_VER_LEN]; char fw_ver[FW_VER_LEN];
...@@ -396,9 +397,10 @@ struct be_adapter { ...@@ -396,9 +397,10 @@ struct be_adapter {
u32 *pmac_id; /* MAC addr handle used by BE card */ u32 *pmac_id; /* MAC addr handle used by BE card */
u32 beacon_state; /* for set_phys_id */ u32 beacon_state; /* for set_phys_id */
bool eeh_err; bool eeh_error;
bool ue_detected;
bool fw_timeout; bool fw_timeout;
bool hw_error;
u32 port_num; u32 port_num;
bool promiscuous; bool promiscuous;
u32 function_mode; u32 function_mode;
...@@ -599,7 +601,19 @@ static inline bool be_multi_rxq(const struct be_adapter *adapter) ...@@ -599,7 +601,19 @@ static inline bool be_multi_rxq(const struct be_adapter *adapter)
static inline bool be_error(struct be_adapter *adapter) static inline bool be_error(struct be_adapter *adapter)
{ {
return adapter->eeh_err || adapter->ue_detected || adapter->fw_timeout; return adapter->eeh_error || adapter->hw_error || adapter->fw_timeout;
}
static inline bool be_crit_error(struct be_adapter *adapter)
{
return adapter->eeh_error || adapter->hw_error;
}
static inline void be_clear_all_error(struct be_adapter *adapter)
{
adapter->eeh_error = false;
adapter->hw_error = false;
adapter->fw_timeout = false;
} }
static inline bool be_is_wol_excluded(struct be_adapter *adapter) static inline bool be_is_wol_excluded(struct be_adapter *adapter)
......
...@@ -349,7 +349,7 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) ...@@ -349,7 +349,7 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
if (msecs > 4000) { if (msecs > 4000) {
dev_err(&adapter->pdev->dev, "FW not responding\n"); dev_err(&adapter->pdev->dev, "FW not responding\n");
adapter->fw_timeout = true; adapter->fw_timeout = true;
be_detect_dump_ue(adapter); be_detect_error(adapter);
return -1; return -1;
} }
...@@ -1869,8 +1869,9 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state) ...@@ -1869,8 +1869,9 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
} }
int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 data_size, u32 data_offset, const char *obj_name, u32 data_size, u32 data_offset,
u32 *data_written, u8 *addn_status) const char *obj_name, u32 *data_written,
u8 *change_status, u8 *addn_status)
{ {
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
struct lancer_cmd_req_write_object *req; struct lancer_cmd_req_write_object *req;
...@@ -1926,10 +1927,12 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, ...@@ -1926,10 +1927,12 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
status = adapter->flash_status; status = adapter->flash_status;
resp = embedded_payload(wrb); resp = embedded_payload(wrb);
if (!status) if (!status) {
*data_written = le32_to_cpu(resp->actual_write_len); *data_written = le32_to_cpu(resp->actual_write_len);
else *change_status = resp->change_status;
} else {
*addn_status = resp->additional_status; *addn_status = resp->additional_status;
}
return status; return status;
......
...@@ -1163,6 +1163,8 @@ struct lancer_cmd_req_write_object { ...@@ -1163,6 +1163,8 @@ struct lancer_cmd_req_write_object {
u32 addr_high; u32 addr_high;
}; };
#define LANCER_NO_RESET_NEEDED 0x00
#define LANCER_FW_RESET_NEEDED 0x02
struct lancer_cmd_resp_write_object { struct lancer_cmd_resp_write_object {
u8 opcode; u8 opcode;
u8 subsystem; u8 subsystem;
...@@ -1173,6 +1175,8 @@ struct lancer_cmd_resp_write_object { ...@@ -1173,6 +1175,8 @@ struct lancer_cmd_resp_write_object {
u32 resp_len; u32 resp_len;
u32 actual_resp_len; u32 actual_resp_len;
u32 actual_write_len; u32 actual_write_len;
u8 change_status;
u8 rsvd3[3];
}; };
/************************ Lancer Read FW info **************/ /************************ Lancer Read FW info **************/
...@@ -1721,7 +1725,8 @@ extern int lancer_cmd_write_object(struct be_adapter *adapter, ...@@ -1721,7 +1725,8 @@ extern int lancer_cmd_write_object(struct be_adapter *adapter,
struct be_dma_mem *cmd, struct be_dma_mem *cmd,
u32 data_size, u32 data_offset, u32 data_size, u32 data_offset,
const char *obj_name, const char *obj_name,
u32 *data_written, u8 *addn_status); u32 *data_written, u8 *change_status,
u8 *addn_status);
int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 data_size, u32 data_offset, const char *obj_name, u32 data_size, u32 data_offset, const char *obj_name,
u32 *data_read, u32 *eof, u8 *addn_status); u32 *data_read, u32 *eof, u8 *addn_status);
...@@ -1744,7 +1749,7 @@ extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, ...@@ -1744,7 +1749,7 @@ extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
u8 loopback_type, u8 enable); u8 loopback_type, u8 enable);
extern int be_cmd_get_phy_info(struct be_adapter *adapter); extern int be_cmd_get_phy_info(struct be_adapter *adapter);
extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain);
extern void be_detect_dump_ue(struct be_adapter *adapter); extern void be_detect_error(struct be_adapter *adapter);
extern int be_cmd_get_die_temperature(struct be_adapter *adapter); extern int be_cmd_get_die_temperature(struct be_adapter *adapter);
extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter);
extern int be_cmd_req_native_mode(struct be_adapter *adapter); extern int be_cmd_req_native_mode(struct be_adapter *adapter);
......
...@@ -45,18 +45,19 @@ ...@@ -45,18 +45,19 @@
#define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */ #define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */
/* Lancer SLIPORT_CONTROL SLIPORT_STATUS registers */ /* Lancer SLIPORT registers */
#define SLIPORT_STATUS_OFFSET 0x404 #define SLIPORT_STATUS_OFFSET 0x404
#define SLIPORT_CONTROL_OFFSET 0x408 #define SLIPORT_CONTROL_OFFSET 0x408
#define SLIPORT_ERROR1_OFFSET 0x40C #define SLIPORT_ERROR1_OFFSET 0x40C
#define SLIPORT_ERROR2_OFFSET 0x410 #define SLIPORT_ERROR2_OFFSET 0x410
#define PHYSDEV_CONTROL_OFFSET 0x414
#define SLIPORT_STATUS_ERR_MASK 0x80000000 #define SLIPORT_STATUS_ERR_MASK 0x80000000
#define SLIPORT_STATUS_RN_MASK 0x01000000 #define SLIPORT_STATUS_RN_MASK 0x01000000
#define SLIPORT_STATUS_RDY_MASK 0x00800000 #define SLIPORT_STATUS_RDY_MASK 0x00800000
#define SLI_PORT_CONTROL_IP_MASK 0x08000000 #define SLI_PORT_CONTROL_IP_MASK 0x08000000
#define PHYSDEV_CONTROL_FW_RESET_MASK 0x00000002
#define PHYSDEV_CONTROL_INP_MASK 0x40000000
/********* Memory BAR register ************/ /********* Memory BAR register ************/
#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
......
...@@ -155,7 +155,7 @@ static void be_intr_set(struct be_adapter *adapter, bool enable) ...@@ -155,7 +155,7 @@ static void be_intr_set(struct be_adapter *adapter, bool enable)
{ {
u32 reg, enabled; u32 reg, enabled;
if (adapter->eeh_err) if (adapter->eeh_error)
return; return;
pci_read_config_dword(adapter->pdev, PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET, pci_read_config_dword(adapter->pdev, PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET,
...@@ -201,7 +201,7 @@ static void be_eq_notify(struct be_adapter *adapter, u16 qid, ...@@ -201,7 +201,7 @@ static void be_eq_notify(struct be_adapter *adapter, u16 qid,
val |= ((qid & DB_EQ_RING_ID_EXT_MASK) << val |= ((qid & DB_EQ_RING_ID_EXT_MASK) <<
DB_EQ_RING_ID_EXT_MASK_SHIFT); DB_EQ_RING_ID_EXT_MASK_SHIFT);
if (adapter->eeh_err) if (adapter->eeh_error)
return; return;
if (arm) if (arm)
...@@ -220,7 +220,7 @@ void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped) ...@@ -220,7 +220,7 @@ void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped)
val |= ((qid & DB_CQ_RING_ID_EXT_MASK) << val |= ((qid & DB_CQ_RING_ID_EXT_MASK) <<
DB_CQ_RING_ID_EXT_MASK_SHIFT); DB_CQ_RING_ID_EXT_MASK_SHIFT);
if (adapter->eeh_err) if (adapter->eeh_error)
return; return;
if (arm) if (arm)
...@@ -2098,13 +2098,13 @@ int be_poll(struct napi_struct *napi, int budget) ...@@ -2098,13 +2098,13 @@ int be_poll(struct napi_struct *napi, int budget)
return max_work; return max_work;
} }
void be_detect_dump_ue(struct be_adapter *adapter) void be_detect_error(struct be_adapter *adapter)
{ {
u32 ue_lo = 0, ue_hi = 0, ue_lo_mask = 0, ue_hi_mask = 0; u32 ue_lo = 0, ue_hi = 0, ue_lo_mask = 0, ue_hi_mask = 0;
u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0; u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
u32 i; u32 i;
if (adapter->eeh_err || adapter->ue_detected) if (be_crit_error(adapter))
return; return;
if (lancer_chip(adapter)) { if (lancer_chip(adapter)) {
...@@ -2125,16 +2125,24 @@ void be_detect_dump_ue(struct be_adapter *adapter) ...@@ -2125,16 +2125,24 @@ void be_detect_dump_ue(struct be_adapter *adapter)
pci_read_config_dword(adapter->pdev, pci_read_config_dword(adapter->pdev,
PCICFG_UE_STATUS_HI_MASK, &ue_hi_mask); PCICFG_UE_STATUS_HI_MASK, &ue_hi_mask);
ue_lo = (ue_lo & (~ue_lo_mask)); ue_lo = (ue_lo & ~ue_lo_mask);
ue_hi = (ue_hi & (~ue_hi_mask)); ue_hi = (ue_hi & ~ue_hi_mask);
} }
if (ue_lo || ue_hi || if (ue_lo || ue_hi ||
sliport_status & SLIPORT_STATUS_ERR_MASK) { sliport_status & SLIPORT_STATUS_ERR_MASK) {
adapter->ue_detected = true; adapter->hw_error = true;
adapter->eeh_err = true;
dev_err(&adapter->pdev->dev, dev_err(&adapter->pdev->dev,
"Unrecoverable error in the card\n"); "Error detected in the card\n");
}
if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
dev_err(&adapter->pdev->dev,
"ERR: sliport status 0x%x\n", sliport_status);
dev_err(&adapter->pdev->dev,
"ERR: sliport error1 0x%x\n", sliport_err1);
dev_err(&adapter->pdev->dev,
"ERR: sliport error2 0x%x\n", sliport_err2);
} }
if (ue_lo) { if (ue_lo) {
...@@ -2144,6 +2152,7 @@ void be_detect_dump_ue(struct be_adapter *adapter) ...@@ -2144,6 +2152,7 @@ void be_detect_dump_ue(struct be_adapter *adapter)
"UE: %s bit set\n", ue_status_low_desc[i]); "UE: %s bit set\n", ue_status_low_desc[i]);
} }
} }
if (ue_hi) { if (ue_hi) {
for (i = 0; ue_hi; ue_hi >>= 1, i++) { for (i = 0; ue_hi; ue_hi >>= 1, i++) {
if (ue_hi & 1) if (ue_hi & 1)
...@@ -2152,14 +2161,6 @@ void be_detect_dump_ue(struct be_adapter *adapter) ...@@ -2152,14 +2161,6 @@ void be_detect_dump_ue(struct be_adapter *adapter)
} }
} }
if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
dev_err(&adapter->pdev->dev,
"sliport status 0x%x\n", sliport_status);
dev_err(&adapter->pdev->dev,
"sliport error1 0x%x\n", sliport_err1);
dev_err(&adapter->pdev->dev,
"sliport error2 0x%x\n", sliport_err2);
}
} }
static void be_msix_disable(struct be_adapter *adapter) static void be_msix_disable(struct be_adapter *adapter)
...@@ -3067,6 +3068,40 @@ static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr) ...@@ -3067,6 +3068,40 @@ static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr)
return 0; return 0;
} }
static int lancer_wait_idle(struct be_adapter *adapter)
{
#define SLIPORT_IDLE_TIMEOUT 30
u32 reg_val;
int status = 0, i;
for (i = 0; i < SLIPORT_IDLE_TIMEOUT; i++) {
reg_val = ioread32(adapter->db + PHYSDEV_CONTROL_OFFSET);
if ((reg_val & PHYSDEV_CONTROL_INP_MASK) == 0)
break;
ssleep(1);
}
if (i == SLIPORT_IDLE_TIMEOUT)
status = -1;
return status;
}
static int lancer_fw_reset(struct be_adapter *adapter)
{
int status = 0;
status = lancer_wait_idle(adapter);
if (status)
return status;
iowrite32(PHYSDEV_CONTROL_FW_RESET_MASK, adapter->db +
PHYSDEV_CONTROL_OFFSET);
return status;
}
static int lancer_fw_download(struct be_adapter *adapter, static int lancer_fw_download(struct be_adapter *adapter,
const struct firmware *fw) const struct firmware *fw)
{ {
...@@ -3081,6 +3116,7 @@ static int lancer_fw_download(struct be_adapter *adapter, ...@@ -3081,6 +3116,7 @@ static int lancer_fw_download(struct be_adapter *adapter,
u32 offset = 0; u32 offset = 0;
int status = 0; int status = 0;
u8 add_status = 0; u8 add_status = 0;
u8 change_status;
if (!IS_ALIGNED(fw->size, sizeof(u32))) { if (!IS_ALIGNED(fw->size, sizeof(u32))) {
dev_err(&adapter->pdev->dev, dev_err(&adapter->pdev->dev,
...@@ -3113,9 +3149,10 @@ static int lancer_fw_download(struct be_adapter *adapter, ...@@ -3113,9 +3149,10 @@ static int lancer_fw_download(struct be_adapter *adapter,
memcpy(dest_image_ptr, data_ptr, chunk_size); memcpy(dest_image_ptr, data_ptr, chunk_size);
status = lancer_cmd_write_object(adapter, &flash_cmd, status = lancer_cmd_write_object(adapter, &flash_cmd,
chunk_size, offset, LANCER_FW_DOWNLOAD_LOCATION, chunk_size, offset,
&data_written, &add_status); LANCER_FW_DOWNLOAD_LOCATION,
&data_written, &change_status,
&add_status);
if (status) if (status)
break; break;
...@@ -3127,8 +3164,10 @@ static int lancer_fw_download(struct be_adapter *adapter, ...@@ -3127,8 +3164,10 @@ static int lancer_fw_download(struct be_adapter *adapter,
if (!status) { if (!status) {
/* Commit the FW written */ /* Commit the FW written */
status = lancer_cmd_write_object(adapter, &flash_cmd, status = lancer_cmd_write_object(adapter, &flash_cmd,
0, offset, LANCER_FW_DOWNLOAD_LOCATION, 0, offset,
&data_written, &add_status); LANCER_FW_DOWNLOAD_LOCATION,
&data_written, &change_status,
&add_status);
} }
dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va, dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
...@@ -3141,6 +3180,20 @@ static int lancer_fw_download(struct be_adapter *adapter, ...@@ -3141,6 +3180,20 @@ static int lancer_fw_download(struct be_adapter *adapter,
goto lancer_fw_exit; goto lancer_fw_exit;
} }
if (change_status == LANCER_FW_RESET_NEEDED) {
status = lancer_fw_reset(adapter);
if (status) {
dev_err(&adapter->pdev->dev,
"Adapter busy for FW reset.\n"
"New FW will not be active.\n");
goto lancer_fw_exit;
}
} else if (change_status != LANCER_NO_RESET_NEEDED) {
dev_err(&adapter->pdev->dev,
"System reboot required for new FW"
" to be active\n");
}
dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
lancer_fw_exit: lancer_fw_exit:
return status; return status;
...@@ -3469,6 +3522,8 @@ static void __devexit be_remove(struct pci_dev *pdev) ...@@ -3469,6 +3522,8 @@ static void __devexit be_remove(struct pci_dev *pdev)
be_roce_dev_remove(adapter); be_roce_dev_remove(adapter);
cancel_delayed_work_sync(&adapter->func_recovery_work);
unregister_netdev(adapter->netdev); unregister_netdev(adapter->netdev);
be_clear(adapter); be_clear(adapter);
...@@ -3625,32 +3680,20 @@ static int be_dev_type_check(struct be_adapter *adapter) ...@@ -3625,32 +3680,20 @@ static int be_dev_type_check(struct be_adapter *adapter)
return 0; return 0;
} }
static void lancer_test_and_recover_fn_err(struct be_adapter *adapter) static int lancer_recover_func(struct be_adapter *adapter)
{ {
int status; int status;
u32 sliport_status;
if (adapter->eeh_err || adapter->ue_detected)
return;
sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
dev_err(&adapter->pdev->dev,
"Adapter in error state."
"Trying to recover.\n");
status = lancer_test_and_set_rdy_state(adapter); status = lancer_test_and_set_rdy_state(adapter);
if (status) if (status)
goto err; goto err;
netif_device_detach(adapter->netdev);
if (netif_running(adapter->netdev)) if (netif_running(adapter->netdev))
be_close(adapter->netdev); be_close(adapter->netdev);
be_clear(adapter); be_clear(adapter);
adapter->hw_error = false;
adapter->fw_timeout = false; adapter->fw_timeout = false;
status = be_setup(adapter); status = be_setup(adapter);
...@@ -3663,15 +3706,42 @@ static void lancer_test_and_recover_fn_err(struct be_adapter *adapter) ...@@ -3663,15 +3706,42 @@ static void lancer_test_and_recover_fn_err(struct be_adapter *adapter)
goto err; goto err;
} }
netif_device_attach(adapter->netdev);
dev_err(&adapter->pdev->dev, dev_err(&adapter->pdev->dev,
"Adapter error recovery succeeded\n"); "Adapter SLIPORT recovery succeeded\n");
} return 0;
return;
err: err:
dev_err(&adapter->pdev->dev, dev_err(&adapter->pdev->dev,
"Adapter error recovery failed\n"); "Adapter SLIPORT recovery failed\n");
return status;
}
static void be_func_recovery_task(struct work_struct *work)
{
struct be_adapter *adapter =
container_of(work, struct be_adapter, func_recovery_work.work);
int status;
be_detect_error(adapter);
if (adapter->hw_error && lancer_chip(adapter)) {
if (adapter->eeh_error)
goto out;
rtnl_lock();
netif_device_detach(adapter->netdev);
rtnl_unlock();
status = lancer_recover_func(adapter);
if (!status)
netif_device_attach(adapter->netdev);
}
out:
schedule_delayed_work(&adapter->func_recovery_work,
msecs_to_jiffies(1000));
} }
static void be_worker(struct work_struct *work) static void be_worker(struct work_struct *work)
...@@ -3682,11 +3752,6 @@ static void be_worker(struct work_struct *work) ...@@ -3682,11 +3752,6 @@ static void be_worker(struct work_struct *work)
struct be_eq_obj *eqo; struct be_eq_obj *eqo;
int i; int i;
if (lancer_chip(adapter))
lancer_test_and_recover_fn_err(adapter);
be_detect_dump_ue(adapter);
/* when interrupts are not yet enabled, just reap any pending /* when interrupts are not yet enabled, just reap any pending
* mcc completions */ * mcc completions */
if (!netif_running(adapter->netdev)) { if (!netif_running(adapter->netdev)) {
...@@ -3805,6 +3870,7 @@ static int __devinit be_probe(struct pci_dev *pdev, ...@@ -3805,6 +3870,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
goto stats_clean; goto stats_clean;
INIT_DELAYED_WORK(&adapter->work, be_worker); INIT_DELAYED_WORK(&adapter->work, be_worker);
INIT_DELAYED_WORK(&adapter->func_recovery_work, be_func_recovery_task);
adapter->rx_fc = adapter->tx_fc = true; adapter->rx_fc = adapter->tx_fc = true;
status = be_setup(adapter); status = be_setup(adapter);
...@@ -3818,6 +3884,8 @@ static int __devinit be_probe(struct pci_dev *pdev, ...@@ -3818,6 +3884,8 @@ static int __devinit be_probe(struct pci_dev *pdev,
be_roce_dev_add(adapter); be_roce_dev_add(adapter);
schedule_delayed_work(&adapter->func_recovery_work,
msecs_to_jiffies(1000));
dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev), dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev),
adapter->port_num); adapter->port_num);
...@@ -3851,6 +3919,8 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -3851,6 +3919,8 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
if (adapter->wol) if (adapter->wol)
be_setup_wol(adapter, true); be_setup_wol(adapter, true);
cancel_delayed_work_sync(&adapter->func_recovery_work);
netif_device_detach(netdev); netif_device_detach(netdev);
if (netif_running(netdev)) { if (netif_running(netdev)) {
rtnl_lock(); rtnl_lock();
...@@ -3891,6 +3961,9 @@ static int be_resume(struct pci_dev *pdev) ...@@ -3891,6 +3961,9 @@ static int be_resume(struct pci_dev *pdev)
be_open(netdev); be_open(netdev);
rtnl_unlock(); rtnl_unlock();
} }
schedule_delayed_work(&adapter->func_recovery_work,
msecs_to_jiffies(1000));
netif_device_attach(netdev); netif_device_attach(netdev);
if (adapter->wol) if (adapter->wol)
...@@ -3910,6 +3983,7 @@ static void be_shutdown(struct pci_dev *pdev) ...@@ -3910,6 +3983,7 @@ static void be_shutdown(struct pci_dev *pdev)
return; return;
cancel_delayed_work_sync(&adapter->work); cancel_delayed_work_sync(&adapter->work);
cancel_delayed_work_sync(&adapter->func_recovery_work);
netif_device_detach(adapter->netdev); netif_device_detach(adapter->netdev);
...@@ -3929,9 +4003,13 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev, ...@@ -3929,9 +4003,13 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev,
dev_err(&adapter->pdev->dev, "EEH error detected\n"); dev_err(&adapter->pdev->dev, "EEH error detected\n");
adapter->eeh_err = true; adapter->eeh_error = true;
cancel_delayed_work_sync(&adapter->func_recovery_work);
rtnl_lock();
netif_device_detach(netdev); netif_device_detach(netdev);
rtnl_unlock();
if (netif_running(netdev)) { if (netif_running(netdev)) {
rtnl_lock(); rtnl_lock();
...@@ -3959,9 +4037,7 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev) ...@@ -3959,9 +4037,7 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
int status; int status;
dev_info(&adapter->pdev->dev, "EEH reset\n"); dev_info(&adapter->pdev->dev, "EEH reset\n");
adapter->eeh_err = false; be_clear_all_error(adapter);
adapter->ue_detected = false;
adapter->fw_timeout = false;
status = pci_enable_device(pdev); status = pci_enable_device(pdev);
if (status) if (status)
...@@ -4007,6 +4083,9 @@ static void be_eeh_resume(struct pci_dev *pdev) ...@@ -4007,6 +4083,9 @@ static void be_eeh_resume(struct pci_dev *pdev)
if (status) if (status)
goto err; goto err;
} }
schedule_delayed_work(&adapter->func_recovery_work,
msecs_to_jiffies(1000));
netif_device_attach(netdev); netif_device_attach(netdev);
return; return;
err: err:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment