aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/emulex/benet
diff options
context:
space:
mode:
authorPadmanabh Ratnakar <padmanabh.ratnakar@emulex.com>2012-07-11 23:57:09 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-12 11:16:46 -0400
commitf67ef7bae8dd025086fdf8186958865bceb44595 (patch)
tree9f2d253cf391438c016fba93e689c2f047ee7602 /drivers/net/ethernet/emulex/benet
parentbf99e50dc2ec49fc1256f9499987699a3f7f158b (diff)
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: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/emulex/benet')
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h20
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c13
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h15
-rw-r--r--drivers/net/ethernet/emulex/benet/be_hw.h7
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c203
5 files changed, 180 insertions, 78 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 748e870958af..e2dfe3114eb1 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -389,6 +389,7 @@ struct be_adapter {
389 struct delayed_work work; 389 struct delayed_work work;
390 u16 work_counter; 390 u16 work_counter;
391 391
392 struct delayed_work func_recovery_work;
392 u32 flags; 393 u32 flags;
393 /* Ethtool knobs and info */ 394 /* Ethtool knobs and info */
394 char fw_ver[FW_VER_LEN]; 395 char fw_ver[FW_VER_LEN];
@@ -396,9 +397,10 @@ struct be_adapter {
396 u32 *pmac_id; /* MAC addr handle used by BE card */ 397 u32 *pmac_id; /* MAC addr handle used by BE card */
397 u32 beacon_state; /* for set_phys_id */ 398 u32 beacon_state; /* for set_phys_id */
398 399
399 bool eeh_err; 400 bool eeh_error;
400 bool ue_detected;
401 bool fw_timeout; 401 bool fw_timeout;
402 bool hw_error;
403
402 u32 port_num; 404 u32 port_num;
403 bool promiscuous; 405 bool promiscuous;
404 u32 function_mode; 406 u32 function_mode;
@@ -599,7 +601,19 @@ static inline bool be_multi_rxq(const struct be_adapter *adapter)
599 601
600static inline bool be_error(struct be_adapter *adapter) 602static inline bool be_error(struct be_adapter *adapter)
601{ 603{
602 return adapter->eeh_err || adapter->ue_detected || adapter->fw_timeout; 604 return adapter->eeh_error || adapter->hw_error || adapter->fw_timeout;
605}
606
607static inline bool be_crit_error(struct be_adapter *adapter)
608{
609 return adapter->eeh_error || adapter->hw_error;
610}
611
612static inline void be_clear_all_error(struct be_adapter *adapter)
613{
614 adapter->eeh_error = false;
615 adapter->hw_error = false;
616 adapter->fw_timeout = false;
603} 617}
604 618
605static inline bool be_is_wol_excluded(struct be_adapter *adapter) 619static inline bool be_is_wol_excluded(struct be_adapter *adapter)
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 431f7749eea2..34dfc0c5c774 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -349,7 +349,7 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
349 if (msecs > 4000) { 349 if (msecs > 4000) {
350 dev_err(&adapter->pdev->dev, "FW not responding\n"); 350 dev_err(&adapter->pdev->dev, "FW not responding\n");
351 adapter->fw_timeout = true; 351 adapter->fw_timeout = true;
352 be_detect_dump_ue(adapter); 352 be_detect_error(adapter);
353 return -1; 353 return -1;
354 } 354 }
355 355
@@ -1869,8 +1869,9 @@ err:
1869} 1869}
1870 1870
1871int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, 1871int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
1872 u32 data_size, u32 data_offset, const char *obj_name, 1872 u32 data_size, u32 data_offset,
1873 u32 *data_written, u8 *addn_status) 1873 const char *obj_name, u32 *data_written,
1874 u8 *change_status, u8 *addn_status)
1874{ 1875{
1875 struct be_mcc_wrb *wrb; 1876 struct be_mcc_wrb *wrb;
1876 struct lancer_cmd_req_write_object *req; 1877 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 status = adapter->flash_status; 1927 status = adapter->flash_status;
1927 1928
1928 resp = embedded_payload(wrb); 1929 resp = embedded_payload(wrb);
1929 if (!status) 1930 if (!status) {
1930 *data_written = le32_to_cpu(resp->actual_write_len); 1931 *data_written = le32_to_cpu(resp->actual_write_len);
1931 else 1932 *change_status = resp->change_status;
1933 } else {
1932 *addn_status = resp->additional_status; 1934 *addn_status = resp->additional_status;
1935 }
1933 1936
1934 return status; 1937 return status;
1935 1938
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index cfc0620b747b..c1324e74ba19 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -1163,6 +1163,8 @@ struct lancer_cmd_req_write_object {
1163 u32 addr_high; 1163 u32 addr_high;
1164}; 1164};
1165 1165
1166#define LANCER_NO_RESET_NEEDED 0x00
1167#define LANCER_FW_RESET_NEEDED 0x02
1166struct lancer_cmd_resp_write_object { 1168struct lancer_cmd_resp_write_object {
1167 u8 opcode; 1169 u8 opcode;
1168 u8 subsystem; 1170 u8 subsystem;
@@ -1173,6 +1175,8 @@ struct lancer_cmd_resp_write_object {
1173 u32 resp_len; 1175 u32 resp_len;
1174 u32 actual_resp_len; 1176 u32 actual_resp_len;
1175 u32 actual_write_len; 1177 u32 actual_write_len;
1178 u8 change_status;
1179 u8 rsvd3[3];
1176}; 1180};
1177 1181
1178/************************ Lancer Read FW info **************/ 1182/************************ Lancer Read FW info **************/
@@ -1718,10 +1722,11 @@ extern int be_cmd_write_flashrom(struct be_adapter *adapter,
1718 struct be_dma_mem *cmd, u32 flash_oper, 1722 struct be_dma_mem *cmd, u32 flash_oper,
1719 u32 flash_opcode, u32 buf_size); 1723 u32 flash_opcode, u32 buf_size);
1720extern int lancer_cmd_write_object(struct be_adapter *adapter, 1724extern int lancer_cmd_write_object(struct be_adapter *adapter,
1721 struct be_dma_mem *cmd, 1725 struct be_dma_mem *cmd,
1722 u32 data_size, u32 data_offset, 1726 u32 data_size, u32 data_offset,
1723 const char *obj_name, 1727 const char *obj_name,
1724 u32 *data_written, u8 *addn_status); 1728 u32 *data_written, u8 *change_status,
1729 u8 *addn_status);
1725int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, 1730int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
1726 u32 data_size, u32 data_offset, const char *obj_name, 1731 u32 data_size, u32 data_offset, const char *obj_name,
1727 u32 *data_read, u32 *eof, u8 *addn_status); 1732 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 u8 loopback_type, u8 enable); 1749 u8 loopback_type, u8 enable);
1745extern int be_cmd_get_phy_info(struct be_adapter *adapter); 1750extern int be_cmd_get_phy_info(struct be_adapter *adapter);
1746extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); 1751extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain);
1747extern void be_detect_dump_ue(struct be_adapter *adapter); 1752extern void be_detect_error(struct be_adapter *adapter);
1748extern int be_cmd_get_die_temperature(struct be_adapter *adapter); 1753extern int be_cmd_get_die_temperature(struct be_adapter *adapter);
1749extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); 1754extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter);
1750extern int be_cmd_req_native_mode(struct be_adapter *adapter); 1755extern int be_cmd_req_native_mode(struct be_adapter *adapter);
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h
index 7c8a710eac2f..b755f7061dce 100644
--- a/drivers/net/ethernet/emulex/benet/be_hw.h
+++ b/drivers/net/ethernet/emulex/benet/be_hw.h
@@ -45,18 +45,19 @@
45#define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */ 45#define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */
46 46
47 47
48/* Lancer SLIPORT_CONTROL SLIPORT_STATUS registers */ 48/* Lancer SLIPORT registers */
49#define SLIPORT_STATUS_OFFSET 0x404 49#define SLIPORT_STATUS_OFFSET 0x404
50#define SLIPORT_CONTROL_OFFSET 0x408 50#define SLIPORT_CONTROL_OFFSET 0x408
51#define SLIPORT_ERROR1_OFFSET 0x40C 51#define SLIPORT_ERROR1_OFFSET 0x40C
52#define SLIPORT_ERROR2_OFFSET 0x410 52#define SLIPORT_ERROR2_OFFSET 0x410
53#define PHYSDEV_CONTROL_OFFSET 0x414
53 54
54#define SLIPORT_STATUS_ERR_MASK 0x80000000 55#define SLIPORT_STATUS_ERR_MASK 0x80000000
55#define SLIPORT_STATUS_RN_MASK 0x01000000 56#define SLIPORT_STATUS_RN_MASK 0x01000000
56#define SLIPORT_STATUS_RDY_MASK 0x00800000 57#define SLIPORT_STATUS_RDY_MASK 0x00800000
57
58
59#define SLI_PORT_CONTROL_IP_MASK 0x08000000 58#define SLI_PORT_CONTROL_IP_MASK 0x08000000
59#define PHYSDEV_CONTROL_FW_RESET_MASK 0x00000002
60#define PHYSDEV_CONTROL_INP_MASK 0x40000000
60 61
61/********* Memory BAR register ************/ 62/********* Memory BAR register ************/
62#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc 63#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index a3641baa8604..9e7dbd59b57e 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -155,7 +155,7 @@ static void be_intr_set(struct be_adapter *adapter, bool enable)
155{ 155{
156 u32 reg, enabled; 156 u32 reg, enabled;
157 157
158 if (adapter->eeh_err) 158 if (adapter->eeh_error)
159 return; 159 return;
160 160
161 pci_read_config_dword(adapter->pdev, PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET, 161 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 val |= ((qid & DB_EQ_RING_ID_EXT_MASK) << 201 val |= ((qid & DB_EQ_RING_ID_EXT_MASK) <<
202 DB_EQ_RING_ID_EXT_MASK_SHIFT); 202 DB_EQ_RING_ID_EXT_MASK_SHIFT);
203 203
204 if (adapter->eeh_err) 204 if (adapter->eeh_error)
205 return; 205 return;
206 206
207 if (arm) 207 if (arm)
@@ -220,7 +220,7 @@ void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped)
220 val |= ((qid & DB_CQ_RING_ID_EXT_MASK) << 220 val |= ((qid & DB_CQ_RING_ID_EXT_MASK) <<
221 DB_CQ_RING_ID_EXT_MASK_SHIFT); 221 DB_CQ_RING_ID_EXT_MASK_SHIFT);
222 222
223 if (adapter->eeh_err) 223 if (adapter->eeh_error)
224 return; 224 return;
225 225
226 if (arm) 226 if (arm)
@@ -2098,13 +2098,13 @@ int be_poll(struct napi_struct *napi, int budget)
2098 return max_work; 2098 return max_work;
2099} 2099}
2100 2100
2101void be_detect_dump_ue(struct be_adapter *adapter) 2101void be_detect_error(struct be_adapter *adapter)
2102{ 2102{
2103 u32 ue_lo = 0, ue_hi = 0, ue_lo_mask = 0, ue_hi_mask = 0; 2103 u32 ue_lo = 0, ue_hi = 0, ue_lo_mask = 0, ue_hi_mask = 0;
2104 u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0; 2104 u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
2105 u32 i; 2105 u32 i;
2106 2106
2107 if (adapter->eeh_err || adapter->ue_detected) 2107 if (be_crit_error(adapter))
2108 return; 2108 return;
2109 2109
2110 if (lancer_chip(adapter)) { 2110 if (lancer_chip(adapter)) {
@@ -2125,16 +2125,24 @@ void be_detect_dump_ue(struct be_adapter *adapter)
2125 pci_read_config_dword(adapter->pdev, 2125 pci_read_config_dword(adapter->pdev,
2126 PCICFG_UE_STATUS_HI_MASK, &ue_hi_mask); 2126 PCICFG_UE_STATUS_HI_MASK, &ue_hi_mask);
2127 2127
2128 ue_lo = (ue_lo & (~ue_lo_mask)); 2128 ue_lo = (ue_lo & ~ue_lo_mask);
2129 ue_hi = (ue_hi & (~ue_hi_mask)); 2129 ue_hi = (ue_hi & ~ue_hi_mask);
2130 } 2130 }
2131 2131
2132 if (ue_lo || ue_hi || 2132 if (ue_lo || ue_hi ||
2133 sliport_status & SLIPORT_STATUS_ERR_MASK) { 2133 sliport_status & SLIPORT_STATUS_ERR_MASK) {
2134 adapter->ue_detected = true; 2134 adapter->hw_error = true;
2135 adapter->eeh_err = true;
2136 dev_err(&adapter->pdev->dev, 2135 dev_err(&adapter->pdev->dev,
2137 "Unrecoverable error in the card\n"); 2136 "Error detected in the card\n");
2137 }
2138
2139 if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
2140 dev_err(&adapter->pdev->dev,
2141 "ERR: sliport status 0x%x\n", sliport_status);
2142 dev_err(&adapter->pdev->dev,
2143 "ERR: sliport error1 0x%x\n", sliport_err1);
2144 dev_err(&adapter->pdev->dev,
2145 "ERR: sliport error2 0x%x\n", sliport_err2);
2138 } 2146 }
2139 2147
2140 if (ue_lo) { 2148 if (ue_lo) {
@@ -2144,6 +2152,7 @@ void be_detect_dump_ue(struct be_adapter *adapter)
2144 "UE: %s bit set\n", ue_status_low_desc[i]); 2152 "UE: %s bit set\n", ue_status_low_desc[i]);
2145 } 2153 }
2146 } 2154 }
2155
2147 if (ue_hi) { 2156 if (ue_hi) {
2148 for (i = 0; ue_hi; ue_hi >>= 1, i++) { 2157 for (i = 0; ue_hi; ue_hi >>= 1, i++) {
2149 if (ue_hi & 1) 2158 if (ue_hi & 1)
@@ -2152,14 +2161,6 @@ void be_detect_dump_ue(struct be_adapter *adapter)
2152 } 2161 }
2153 } 2162 }
2154 2163
2155 if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
2156 dev_err(&adapter->pdev->dev,
2157 "sliport status 0x%x\n", sliport_status);
2158 dev_err(&adapter->pdev->dev,
2159 "sliport error1 0x%x\n", sliport_err1);
2160 dev_err(&adapter->pdev->dev,
2161 "sliport error2 0x%x\n", sliport_err2);
2162 }
2163} 2164}
2164 2165
2165static void be_msix_disable(struct be_adapter *adapter) 2166static void be_msix_disable(struct be_adapter *adapter)
@@ -3067,6 +3068,40 @@ static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr)
3067 return 0; 3068 return 0;
3068} 3069}
3069 3070
3071static int lancer_wait_idle(struct be_adapter *adapter)
3072{
3073#define SLIPORT_IDLE_TIMEOUT 30
3074 u32 reg_val;
3075 int status = 0, i;
3076
3077 for (i = 0; i < SLIPORT_IDLE_TIMEOUT; i++) {
3078 reg_val = ioread32(adapter->db + PHYSDEV_CONTROL_OFFSET);
3079 if ((reg_val & PHYSDEV_CONTROL_INP_MASK) == 0)
3080 break;
3081
3082 ssleep(1);
3083 }
3084
3085 if (i == SLIPORT_IDLE_TIMEOUT)
3086 status = -1;
3087
3088 return status;
3089}
3090
3091static int lancer_fw_reset(struct be_adapter *adapter)
3092{
3093 int status = 0;
3094
3095 status = lancer_wait_idle(adapter);
3096 if (status)
3097 return status;
3098
3099 iowrite32(PHYSDEV_CONTROL_FW_RESET_MASK, adapter->db +
3100 PHYSDEV_CONTROL_OFFSET);
3101
3102 return status;
3103}
3104
3070static int lancer_fw_download(struct be_adapter *adapter, 3105static int lancer_fw_download(struct be_adapter *adapter,
3071 const struct firmware *fw) 3106 const struct firmware *fw)
3072{ 3107{
@@ -3081,6 +3116,7 @@ static int lancer_fw_download(struct be_adapter *adapter,
3081 u32 offset = 0; 3116 u32 offset = 0;
3082 int status = 0; 3117 int status = 0;
3083 u8 add_status = 0; 3118 u8 add_status = 0;
3119 u8 change_status;
3084 3120
3085 if (!IS_ALIGNED(fw->size, sizeof(u32))) { 3121 if (!IS_ALIGNED(fw->size, sizeof(u32))) {
3086 dev_err(&adapter->pdev->dev, 3122 dev_err(&adapter->pdev->dev,
@@ -3113,9 +3149,10 @@ static int lancer_fw_download(struct be_adapter *adapter,
3113 memcpy(dest_image_ptr, data_ptr, chunk_size); 3149 memcpy(dest_image_ptr, data_ptr, chunk_size);
3114 3150
3115 status = lancer_cmd_write_object(adapter, &flash_cmd, 3151 status = lancer_cmd_write_object(adapter, &flash_cmd,
3116 chunk_size, offset, LANCER_FW_DOWNLOAD_LOCATION, 3152 chunk_size, offset,
3117 &data_written, &add_status); 3153 LANCER_FW_DOWNLOAD_LOCATION,
3118 3154 &data_written, &change_status,
3155 &add_status);
3119 if (status) 3156 if (status)
3120 break; 3157 break;
3121 3158
@@ -3127,8 +3164,10 @@ static int lancer_fw_download(struct be_adapter *adapter,
3127 if (!status) { 3164 if (!status) {
3128 /* Commit the FW written */ 3165 /* Commit the FW written */
3129 status = lancer_cmd_write_object(adapter, &flash_cmd, 3166 status = lancer_cmd_write_object(adapter, &flash_cmd,
3130 0, offset, LANCER_FW_DOWNLOAD_LOCATION, 3167 0, offset,
3131 &data_written, &add_status); 3168 LANCER_FW_DOWNLOAD_LOCATION,
3169 &data_written, &change_status,
3170 &add_status);
3132 } 3171 }
3133 3172
3134 dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va, 3173 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 goto lancer_fw_exit; 3180 goto lancer_fw_exit;
3142 } 3181 }
3143 3182
3183 if (change_status == LANCER_FW_RESET_NEEDED) {
3184 status = lancer_fw_reset(adapter);
3185 if (status) {
3186 dev_err(&adapter->pdev->dev,
3187 "Adapter busy for FW reset.\n"
3188 "New FW will not be active.\n");
3189 goto lancer_fw_exit;
3190 }
3191 } else if (change_status != LANCER_NO_RESET_NEEDED) {
3192 dev_err(&adapter->pdev->dev,
3193 "System reboot required for new FW"
3194 " to be active\n");
3195 }
3196
3144 dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); 3197 dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
3145lancer_fw_exit: 3198lancer_fw_exit:
3146 return status; 3199 return status;
@@ -3469,6 +3522,8 @@ static void __devexit be_remove(struct pci_dev *pdev)
3469 3522
3470 be_roce_dev_remove(adapter); 3523 be_roce_dev_remove(adapter);
3471 3524
3525 cancel_delayed_work_sync(&adapter->func_recovery_work);
3526
3472 unregister_netdev(adapter->netdev); 3527 unregister_netdev(adapter->netdev);
3473 3528
3474 be_clear(adapter); 3529 be_clear(adapter);
@@ -3625,53 +3680,68 @@ static int be_dev_type_check(struct be_adapter *adapter)
3625 return 0; 3680 return 0;
3626} 3681}
3627 3682
3628static void lancer_test_and_recover_fn_err(struct be_adapter *adapter) 3683static int lancer_recover_func(struct be_adapter *adapter)
3629{ 3684{
3630 int status; 3685 int status;
3631 u32 sliport_status;
3632 3686
3633 if (adapter->eeh_err || adapter->ue_detected) 3687 status = lancer_test_and_set_rdy_state(adapter);
3634 return; 3688 if (status)
3689 goto err;
3635 3690
3636 sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); 3691 if (netif_running(adapter->netdev))
3692 be_close(adapter->netdev);
3637 3693
3638 if (sliport_status & SLIPORT_STATUS_ERR_MASK) { 3694 be_clear(adapter);
3639 dev_err(&adapter->pdev->dev, 3695
3640 "Adapter in error state." 3696 adapter->hw_error = false;
3641 "Trying to recover.\n"); 3697 adapter->fw_timeout = false;
3698
3699 status = be_setup(adapter);
3700 if (status)
3701 goto err;
3642 3702
3643 status = lancer_test_and_set_rdy_state(adapter); 3703 if (netif_running(adapter->netdev)) {
3704 status = be_open(adapter->netdev);
3644 if (status) 3705 if (status)
3645 goto err; 3706 goto err;
3707 }
3646 3708
3647 netif_device_detach(adapter->netdev); 3709 dev_err(&adapter->pdev->dev,
3710 "Adapter SLIPORT recovery succeeded\n");
3711 return 0;
3712err:
3713 dev_err(&adapter->pdev->dev,
3714 "Adapter SLIPORT recovery failed\n");
3648 3715
3649 if (netif_running(adapter->netdev)) 3716 return status;
3650 be_close(adapter->netdev); 3717}
3718
3719static void be_func_recovery_task(struct work_struct *work)
3720{
3721 struct be_adapter *adapter =
3722 container_of(work, struct be_adapter, func_recovery_work.work);
3723 int status;
3651 3724
3652 be_clear(adapter); 3725 be_detect_error(adapter);
3653 3726
3654 adapter->fw_timeout = false; 3727 if (adapter->hw_error && lancer_chip(adapter)) {
3655 3728
3656 status = be_setup(adapter); 3729 if (adapter->eeh_error)
3657 if (status) 3730 goto out;
3658 goto err;
3659 3731
3660 if (netif_running(adapter->netdev)) { 3732 rtnl_lock();
3661 status = be_open(adapter->netdev); 3733 netif_device_detach(adapter->netdev);
3662 if (status) 3734 rtnl_unlock();
3663 goto err;
3664 }
3665 3735
3666 netif_device_attach(adapter->netdev); 3736 status = lancer_recover_func(adapter);
3667 3737
3668 dev_err(&adapter->pdev->dev, 3738 if (!status)
3669 "Adapter error recovery succeeded\n"); 3739 netif_device_attach(adapter->netdev);
3670 } 3740 }
3671 return; 3741
3672err: 3742out:
3673 dev_err(&adapter->pdev->dev, 3743 schedule_delayed_work(&adapter->func_recovery_work,
3674 "Adapter error recovery failed\n"); 3744 msecs_to_jiffies(1000));
3675} 3745}
3676 3746
3677static void be_worker(struct work_struct *work) 3747static void be_worker(struct work_struct *work)
@@ -3682,11 +3752,6 @@ static void be_worker(struct work_struct *work)
3682 struct be_eq_obj *eqo; 3752 struct be_eq_obj *eqo;
3683 int i; 3753 int i;
3684 3754
3685 if (lancer_chip(adapter))
3686 lancer_test_and_recover_fn_err(adapter);
3687
3688 be_detect_dump_ue(adapter);
3689
3690 /* when interrupts are not yet enabled, just reap any pending 3755 /* when interrupts are not yet enabled, just reap any pending
3691 * mcc completions */ 3756 * mcc completions */
3692 if (!netif_running(adapter->netdev)) { 3757 if (!netif_running(adapter->netdev)) {
@@ -3805,6 +3870,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
3805 goto stats_clean; 3870 goto stats_clean;
3806 3871
3807 INIT_DELAYED_WORK(&adapter->work, be_worker); 3872 INIT_DELAYED_WORK(&adapter->work, be_worker);
3873 INIT_DELAYED_WORK(&adapter->func_recovery_work, be_func_recovery_task);
3808 adapter->rx_fc = adapter->tx_fc = true; 3874 adapter->rx_fc = adapter->tx_fc = true;
3809 3875
3810 status = be_setup(adapter); 3876 status = be_setup(adapter);
@@ -3818,6 +3884,8 @@ static int __devinit be_probe(struct pci_dev *pdev,
3818 3884
3819 be_roce_dev_add(adapter); 3885 be_roce_dev_add(adapter);
3820 3886
3887 schedule_delayed_work(&adapter->func_recovery_work,
3888 msecs_to_jiffies(1000));
3821 dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev), 3889 dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev),
3822 adapter->port_num); 3890 adapter->port_num);
3823 3891
@@ -3851,6 +3919,8 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
3851 if (adapter->wol) 3919 if (adapter->wol)
3852 be_setup_wol(adapter, true); 3920 be_setup_wol(adapter, true);
3853 3921
3922 cancel_delayed_work_sync(&adapter->func_recovery_work);
3923
3854 netif_device_detach(netdev); 3924 netif_device_detach(netdev);
3855 if (netif_running(netdev)) { 3925 if (netif_running(netdev)) {
3856 rtnl_lock(); 3926 rtnl_lock();
@@ -3891,6 +3961,9 @@ static int be_resume(struct pci_dev *pdev)
3891 be_open(netdev); 3961 be_open(netdev);
3892 rtnl_unlock(); 3962 rtnl_unlock();
3893 } 3963 }
3964
3965 schedule_delayed_work(&adapter->func_recovery_work,
3966 msecs_to_jiffies(1000));
3894 netif_device_attach(netdev); 3967 netif_device_attach(netdev);
3895 3968
3896 if (adapter->wol) 3969 if (adapter->wol)
@@ -3910,6 +3983,7 @@ static void be_shutdown(struct pci_dev *pdev)
3910 return; 3983 return;
3911 3984
3912 cancel_delayed_work_sync(&adapter->work); 3985 cancel_delayed_work_sync(&adapter->work);
3986 cancel_delayed_work_sync(&adapter->func_recovery_work);
3913 3987
3914 netif_device_detach(adapter->netdev); 3988 netif_device_detach(adapter->netdev);
3915 3989
@@ -3929,9 +4003,13 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev,
3929 4003
3930 dev_err(&adapter->pdev->dev, "EEH error detected\n"); 4004 dev_err(&adapter->pdev->dev, "EEH error detected\n");
3931 4005
3932 adapter->eeh_err = true; 4006 adapter->eeh_error = true;
4007
4008 cancel_delayed_work_sync(&adapter->func_recovery_work);
3933 4009
4010 rtnl_lock();
3934 netif_device_detach(netdev); 4011 netif_device_detach(netdev);
4012 rtnl_unlock();
3935 4013
3936 if (netif_running(netdev)) { 4014 if (netif_running(netdev)) {
3937 rtnl_lock(); 4015 rtnl_lock();
@@ -3959,9 +4037,7 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
3959 int status; 4037 int status;
3960 4038
3961 dev_info(&adapter->pdev->dev, "EEH reset\n"); 4039 dev_info(&adapter->pdev->dev, "EEH reset\n");
3962 adapter->eeh_err = false; 4040 be_clear_all_error(adapter);
3963 adapter->ue_detected = false;
3964 adapter->fw_timeout = false;
3965 4041
3966 status = pci_enable_device(pdev); 4042 status = pci_enable_device(pdev);
3967 if (status) 4043 if (status)
@@ -4007,6 +4083,9 @@ static void be_eeh_resume(struct pci_dev *pdev)
4007 if (status) 4083 if (status)
4008 goto err; 4084 goto err;
4009 } 4085 }
4086
4087 schedule_delayed_work(&adapter->func_recovery_work,
4088 msecs_to_jiffies(1000));
4010 netif_device_attach(netdev); 4089 netif_device_attach(netdev);
4011 return; 4090 return;
4012err: 4091err: