aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-01-25 18:32:28 -0500
committerDavid S. Miller <davem@davemloft.net>2019-01-25 18:32:28 -0500
commitabfd04f738c2625f63e04c8fc7cadb3b7a70d580 (patch)
tree378a84845e9fc1b815c25dfb05680f42a7b96c68 /drivers
parent517952756ed3027a9b776e331985320a829b9f62 (diff)
qed: Revert error handling changes.
This is new code and not bug fixes. This reverts all changes added by merge commit 8fb18be93efd7292d6ee403b9f61af1008239639 Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed.h5
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_dev.c158
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_dev_api.h12
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_hsi.h2
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_hw.c11
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_int.c126
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_int.h3
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_main.c30
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.c115
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.h42
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_reg_addr.h2
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_spq.c22
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_sriov.c9
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede.h3
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_main.c300
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_rdma.c64
16 files changed, 198 insertions, 706 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index 3b0955d34716..24a90163775e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -554,6 +554,7 @@ struct qed_hwfn {
554 u8 dp_level; 554 u8 dp_level;
555 char name[NAME_SIZE]; 555 char name[NAME_SIZE];
556 556
557 bool first_on_engine;
557 bool hw_init_done; 558 bool hw_init_done;
558 559
559 u8 num_funcs_on_engine; 560 u8 num_funcs_on_engine;
@@ -804,9 +805,6 @@ struct qed_dev {
804 805
805 u32 mcp_nvm_resp; 806 u32 mcp_nvm_resp;
806 807
807 /* Recovery */
808 bool recov_in_prog;
809
810 /* Linux specific here */ 808 /* Linux specific here */
811 struct qede_dev *edev; 809 struct qede_dev *edev;
812 struct pci_dev *pdev; 810 struct pci_dev *pdev;
@@ -946,7 +944,6 @@ void qed_link_update(struct qed_hwfn *hwfn, struct qed_ptt *ptt);
946u32 qed_unzip_data(struct qed_hwfn *p_hwfn, 944u32 qed_unzip_data(struct qed_hwfn *p_hwfn,
947 u32 input_len, u8 *input_buf, 945 u32 input_len, u8 *input_buf,
948 u32 max_size, u8 *unzip_buf); 946 u32 max_size, u8 *unzip_buf);
949void qed_schedule_recovery_handler(struct qed_hwfn *p_hwfn);
950void qed_get_protocol_stats(struct qed_dev *cdev, 947void qed_get_protocol_stats(struct qed_dev *cdev,
951 enum qed_mcp_protocol_type type, 948 enum qed_mcp_protocol_type type,
952 union qed_mcp_protocol_stats *stats); 949 union qed_mcp_protocol_stats *stats);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index b17003d9066c..8f6551421945 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -1959,6 +1959,11 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn,
1959 (p_hwfn->hw_info.personality == QED_PCI_FCOE) ? 1 : 0); 1959 (p_hwfn->hw_info.personality == QED_PCI_FCOE) ? 1 : 0);
1960 STORE_RT_REG(p_hwfn, PRS_REG_SEARCH_ROCE_RT_OFFSET, 0); 1960 STORE_RT_REG(p_hwfn, PRS_REG_SEARCH_ROCE_RT_OFFSET, 0);
1961 1961
1962 /* Cleanup chip from previous driver if such remains exist */
1963 rc = qed_final_cleanup(p_hwfn, p_ptt, rel_pf_id, false);
1964 if (rc)
1965 return rc;
1966
1962 /* Sanity check before the PF init sequence that uses DMAE */ 1967 /* Sanity check before the PF init sequence that uses DMAE */
1963 rc = qed_dmae_sanity(p_hwfn, p_ptt, "pf_phase"); 1968 rc = qed_dmae_sanity(p_hwfn, p_ptt, "pf_phase");
1964 if (rc) 1969 if (rc)
@@ -2002,15 +2007,17 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn,
2002 return rc; 2007 return rc;
2003} 2008}
2004 2009
2005int qed_pglueb_set_pfid_enable(struct qed_hwfn *p_hwfn, 2010static int qed_change_pci_hwfn(struct qed_hwfn *p_hwfn,
2006 struct qed_ptt *p_ptt, bool b_enable) 2011 struct qed_ptt *p_ptt,
2012 u8 enable)
2007{ 2013{
2008 u32 delay_idx = 0, val, set_val = b_enable ? 1 : 0; 2014 u32 delay_idx = 0, val, set_val = enable ? 1 : 0;
2009 2015
2010 /* Configure the PF's internal FID_enable for master transactions */ 2016 /* Change PF in PXP */
2011 qed_wr(p_hwfn, p_ptt, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, set_val); 2017 qed_wr(p_hwfn, p_ptt,
2018 PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, set_val);
2012 2019
2013 /* Wait until value is set - try for 1 second every 50us */ 2020 /* wait until value is set - try for 1 second every 50us */
2014 for (delay_idx = 0; delay_idx < 20000; delay_idx++) { 2021 for (delay_idx = 0; delay_idx < 20000; delay_idx++) {
2015 val = qed_rd(p_hwfn, p_ptt, 2022 val = qed_rd(p_hwfn, p_ptt,
2016 PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER); 2023 PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER);
@@ -2064,19 +2071,13 @@ static int qed_vf_start(struct qed_hwfn *p_hwfn,
2064 return 0; 2071 return 0;
2065} 2072}
2066 2073
2067static void qed_pglueb_clear_err(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
2068{
2069 qed_wr(p_hwfn, p_ptt, PGLUE_B_REG_WAS_ERROR_PF_31_0_CLR,
2070 BIT(p_hwfn->abs_pf_id));
2071}
2072
2073int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params) 2074int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
2074{ 2075{
2075 struct qed_load_req_params load_req_params; 2076 struct qed_load_req_params load_req_params;
2076 u32 load_code, resp, param, drv_mb_param; 2077 u32 load_code, resp, param, drv_mb_param;
2077 bool b_default_mtu = true; 2078 bool b_default_mtu = true;
2078 struct qed_hwfn *p_hwfn; 2079 struct qed_hwfn *p_hwfn;
2079 int rc = 0, i; 2080 int rc = 0, mfw_rc, i;
2080 u16 ether_type; 2081 u16 ether_type;
2081 2082
2082 if ((p_params->int_mode == QED_INT_MODE_MSI) && (cdev->num_hwfns > 1)) { 2083 if ((p_params->int_mode == QED_INT_MODE_MSI) && (cdev->num_hwfns > 1)) {
@@ -2091,7 +2092,7 @@ int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
2091 } 2092 }
2092 2093
2093 for_each_hwfn(cdev, i) { 2094 for_each_hwfn(cdev, i) {
2094 p_hwfn = &cdev->hwfns[i]; 2095 struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
2095 2096
2096 /* If management didn't provide a default, set one of our own */ 2097 /* If management didn't provide a default, set one of our own */
2097 if (!p_hwfn->hw_info.mtu) { 2098 if (!p_hwfn->hw_info.mtu) {
@@ -2104,6 +2105,9 @@ int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
2104 continue; 2105 continue;
2105 } 2106 }
2106 2107
2108 /* Enable DMAE in PXP */
2109 rc = qed_change_pci_hwfn(p_hwfn, p_hwfn->p_main_ptt, true);
2110
2107 rc = qed_calc_hw_mode(p_hwfn); 2111 rc = qed_calc_hw_mode(p_hwfn);
2108 if (rc) 2112 if (rc)
2109 return rc; 2113 return rc;
@@ -2140,43 +2144,12 @@ int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
2140 "Load request was sent. Load code: 0x%x\n", 2144 "Load request was sent. Load code: 0x%x\n",
2141 load_code); 2145 load_code);
2142 2146
2143 /* Only relevant for recovery:
2144 * Clear the indication after LOAD_REQ is responded by the MFW.
2145 */
2146 cdev->recov_in_prog = false;
2147
2148 qed_mcp_set_capabilities(p_hwfn, p_hwfn->p_main_ptt); 2147 qed_mcp_set_capabilities(p_hwfn, p_hwfn->p_main_ptt);
2149 2148
2150 qed_reset_mb_shadow(p_hwfn, p_hwfn->p_main_ptt); 2149 qed_reset_mb_shadow(p_hwfn, p_hwfn->p_main_ptt);
2151 2150
2152 /* Clean up chip from previous driver if such remains exist. 2151 p_hwfn->first_on_engine = (load_code ==
2153 * This is not needed when the PF is the first one on the 2152 FW_MSG_CODE_DRV_LOAD_ENGINE);
2154 * engine, since afterwards we are going to init the FW.
2155 */
2156 if (load_code != FW_MSG_CODE_DRV_LOAD_ENGINE) {
2157 rc = qed_final_cleanup(p_hwfn, p_hwfn->p_main_ptt,
2158 p_hwfn->rel_pf_id, false);
2159 if (rc) {
2160 DP_NOTICE(p_hwfn, "Final cleanup failed\n");
2161 goto load_err;
2162 }
2163 }
2164
2165 /* Log and clear previous pglue_b errors if such exist */
2166 qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_main_ptt);
2167
2168 /* Enable the PF's internal FID_enable in the PXP */
2169 rc = qed_pglueb_set_pfid_enable(p_hwfn, p_hwfn->p_main_ptt,
2170 true);
2171 if (rc)
2172 goto load_err;
2173
2174 /* Clear the pglue_b was_error indication.
2175 * In E4 it must be done after the BME and the internal
2176 * FID_enable for the PF are set, since VDMs may cause the
2177 * indication to be set again.
2178 */
2179 qed_pglueb_clear_err(p_hwfn, p_hwfn->p_main_ptt);
2180 2153
2181 switch (load_code) { 2154 switch (load_code) {
2182 case FW_MSG_CODE_DRV_LOAD_ENGINE: 2155 case FW_MSG_CODE_DRV_LOAD_ENGINE:
@@ -2207,29 +2180,39 @@ int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
2207 break; 2180 break;
2208 } 2181 }
2209 2182
2210 if (rc) { 2183 if (rc)
2211 DP_NOTICE(p_hwfn, 2184 DP_NOTICE(p_hwfn,
2212 "init phase failed for loadcode 0x%x (rc %d)\n", 2185 "init phase failed for loadcode 0x%x (rc %d)\n",
2213 load_code, rc); 2186 load_code, rc);
2214 goto load_err;
2215 }
2216 2187
2217 rc = qed_mcp_load_done(p_hwfn, p_hwfn->p_main_ptt); 2188 /* ACK mfw regardless of success or failure of initialization */
2189 mfw_rc = qed_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt,
2190 DRV_MSG_CODE_LOAD_DONE,
2191 0, &load_code, &param);
2218 if (rc) 2192 if (rc)
2219 return rc; 2193 return rc;
2194 if (mfw_rc) {
2195 DP_NOTICE(p_hwfn, "Failed sending LOAD_DONE command\n");
2196 return mfw_rc;
2197 }
2198
2199 /* Check if there is a DID mismatch between nvm-cfg/efuse */
2200 if (param & FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR)
2201 DP_NOTICE(p_hwfn,
2202 "warning: device configuration is not supported on this board type. The device may not function as expected.\n");
2220 2203
2221 /* send DCBX attention request command */ 2204 /* send DCBX attention request command */
2222 DP_VERBOSE(p_hwfn, 2205 DP_VERBOSE(p_hwfn,
2223 QED_MSG_DCB, 2206 QED_MSG_DCB,
2224 "sending phony dcbx set command to trigger DCBx attention handling\n"); 2207 "sending phony dcbx set command to trigger DCBx attention handling\n");
2225 rc = qed_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt, 2208 mfw_rc = qed_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt,
2226 DRV_MSG_CODE_SET_DCBX, 2209 DRV_MSG_CODE_SET_DCBX,
2227 1 << DRV_MB_PARAM_DCBX_NOTIFY_SHIFT, 2210 1 << DRV_MB_PARAM_DCBX_NOTIFY_SHIFT,
2228 &resp, &param); 2211 &load_code, &param);
2229 if (rc) { 2212 if (mfw_rc) {
2230 DP_NOTICE(p_hwfn, 2213 DP_NOTICE(p_hwfn,
2231 "Failed to send DCBX attention request\n"); 2214 "Failed to send DCBX attention request\n");
2232 return rc; 2215 return mfw_rc;
2233 } 2216 }
2234 2217
2235 p_hwfn->hw_init_done = true; 2218 p_hwfn->hw_init_done = true;
@@ -2278,12 +2261,6 @@ int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
2278 } 2261 }
2279 2262
2280 return 0; 2263 return 0;
2281
2282load_err:
2283 /* The MFW load lock should be released also when initialization fails.
2284 */
2285 qed_mcp_load_done(p_hwfn, p_hwfn->p_main_ptt);
2286 return rc;
2287} 2264}
2288 2265
2289#define QED_HW_STOP_RETRY_LIMIT (10) 2266#define QED_HW_STOP_RETRY_LIMIT (10)
@@ -2296,9 +2273,6 @@ static void qed_hw_timers_stop(struct qed_dev *cdev,
2296 qed_wr(p_hwfn, p_ptt, TM_REG_PF_ENABLE_CONN, 0x0); 2273 qed_wr(p_hwfn, p_ptt, TM_REG_PF_ENABLE_CONN, 0x0);
2297 qed_wr(p_hwfn, p_ptt, TM_REG_PF_ENABLE_TASK, 0x0); 2274 qed_wr(p_hwfn, p_ptt, TM_REG_PF_ENABLE_TASK, 0x0);
2298 2275
2299 if (cdev->recov_in_prog)
2300 return;
2301
2302 for (i = 0; i < QED_HW_STOP_RETRY_LIMIT; i++) { 2276 for (i = 0; i < QED_HW_STOP_RETRY_LIMIT; i++) {
2303 if ((!qed_rd(p_hwfn, p_ptt, 2277 if ((!qed_rd(p_hwfn, p_ptt,
2304 TM_REG_PF_SCAN_ACTIVE_CONN)) && 2278 TM_REG_PF_SCAN_ACTIVE_CONN)) &&
@@ -2361,14 +2335,12 @@ int qed_hw_stop(struct qed_dev *cdev)
2361 p_hwfn->hw_init_done = false; 2335 p_hwfn->hw_init_done = false;
2362 2336
2363 /* Send unload command to MCP */ 2337 /* Send unload command to MCP */
2364 if (!cdev->recov_in_prog) { 2338 rc = qed_mcp_unload_req(p_hwfn, p_ptt);
2365 rc = qed_mcp_unload_req(p_hwfn, p_ptt); 2339 if (rc) {
2366 if (rc) { 2340 DP_NOTICE(p_hwfn,
2367 DP_NOTICE(p_hwfn, 2341 "Failed sending a UNLOAD_REQ command. rc = %d.\n",
2368 "Failed sending a UNLOAD_REQ command. rc = %d.\n", 2342 rc);
2369 rc); 2343 rc2 = -EINVAL;
2370 rc2 = -EINVAL;
2371 }
2372 } 2344 }
2373 2345
2374 qed_slowpath_irq_sync(p_hwfn); 2346 qed_slowpath_irq_sync(p_hwfn);
@@ -2410,31 +2382,27 @@ int qed_hw_stop(struct qed_dev *cdev)
2410 qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_DB_ENABLE, 0); 2382 qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_DB_ENABLE, 0);
2411 qed_wr(p_hwfn, p_ptt, QM_REG_PF_EN, 0); 2383 qed_wr(p_hwfn, p_ptt, QM_REG_PF_EN, 0);
2412 2384
2413 if (!cdev->recov_in_prog) { 2385 qed_mcp_unload_done(p_hwfn, p_ptt);
2414 rc = qed_mcp_unload_done(p_hwfn, p_ptt); 2386 if (rc) {
2415 if (rc) { 2387 DP_NOTICE(p_hwfn,
2416 DP_NOTICE(p_hwfn, 2388 "Failed sending a UNLOAD_DONE command. rc = %d.\n",
2417 "Failed sending a UNLOAD_DONE command. rc = %d.\n", 2389 rc);
2418 rc); 2390 rc2 = -EINVAL;
2419 rc2 = -EINVAL;
2420 }
2421 } 2391 }
2422 } 2392 }
2423 2393
2424 if (IS_PF(cdev) && !cdev->recov_in_prog) { 2394 if (IS_PF(cdev)) {
2425 p_hwfn = QED_LEADING_HWFN(cdev); 2395 p_hwfn = QED_LEADING_HWFN(cdev);
2426 p_ptt = QED_LEADING_HWFN(cdev)->p_main_ptt; 2396 p_ptt = QED_LEADING_HWFN(cdev)->p_main_ptt;
2427 2397
2428 /* Clear the PF's internal FID_enable in the PXP. 2398 /* Disable DMAE in PXP - in CMT, this should only be done for
2429 * In CMT this should only be done for first hw-function, and 2399 * first hw-function, and only after all transactions have
2430 * only after all transactions have stopped for all active 2400 * stopped for all active hw-functions.
2431 * hw-functions.
2432 */ 2401 */
2433 rc = qed_pglueb_set_pfid_enable(p_hwfn, p_ptt, false); 2402 rc = qed_change_pci_hwfn(p_hwfn, p_ptt, false);
2434 if (rc) { 2403 if (rc) {
2435 DP_NOTICE(p_hwfn, 2404 DP_NOTICE(p_hwfn,
2436 "qed_pglueb_set_pfid_enable() failed. rc = %d.\n", 2405 "qed_change_pci_hwfn failed. rc = %d.\n", rc);
2437 rc);
2438 rc2 = -EINVAL; 2406 rc2 = -EINVAL;
2439 } 2407 }
2440 } 2408 }
@@ -2534,8 +2502,9 @@ static void qed_hw_hwfn_prepare(struct qed_hwfn *p_hwfn)
2534 PGLUE_B_REG_PGL_ADDR_94_F0_BB, 0); 2502 PGLUE_B_REG_PGL_ADDR_94_F0_BB, 0);
2535 } 2503 }
2536 2504
2537 /* Clean previous pglue_b errors if such exist */ 2505 /* Clean Previous errors if such exist */
2538 qed_pglueb_clear_err(p_hwfn, p_hwfn->p_main_ptt); 2506 qed_wr(p_hwfn, p_hwfn->p_main_ptt,
2507 PGLUE_B_REG_WAS_ERROR_PF_31_0_CLR, 1 << p_hwfn->abs_pf_id);
2539 2508
2540 /* enable internal target-read */ 2509 /* enable internal target-read */
2541 qed_wr(p_hwfn, p_hwfn->p_main_ptt, 2510 qed_wr(p_hwfn, p_hwfn->p_main_ptt,
@@ -3471,7 +3440,6 @@ static int qed_hw_prepare_single(struct qed_hwfn *p_hwfn,
3471 void __iomem *p_doorbells, 3440 void __iomem *p_doorbells,
3472 enum qed_pci_personality personality) 3441 enum qed_pci_personality personality)
3473{ 3442{
3474 struct qed_dev *cdev = p_hwfn->cdev;
3475 int rc = 0; 3443 int rc = 0;
3476 3444
3477 /* Split PCI bars evenly between hwfns */ 3445 /* Split PCI bars evenly between hwfns */
@@ -3524,7 +3492,7 @@ static int qed_hw_prepare_single(struct qed_hwfn *p_hwfn,
3524 /* Sending a mailbox to the MFW should be done after qed_get_hw_info() 3492 /* Sending a mailbox to the MFW should be done after qed_get_hw_info()
3525 * is called as it sets the ports number in an engine. 3493 * is called as it sets the ports number in an engine.
3526 */ 3494 */
3527 if (IS_LEAD_HWFN(p_hwfn) && !cdev->recov_in_prog) { 3495 if (IS_LEAD_HWFN(p_hwfn)) {
3528 rc = qed_mcp_initiate_pf_flr(p_hwfn, p_hwfn->p_main_ptt); 3496 rc = qed_mcp_initiate_pf_flr(p_hwfn, p_hwfn->p_main_ptt);
3529 if (rc) 3497 if (rc)
3530 DP_NOTICE(p_hwfn, "Failed to initiate PF FLR\n"); 3498 DP_NOTICE(p_hwfn, "Failed to initiate PF FLR\n");
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
index e4b4e3b78e8a..acccd85170aa 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
@@ -473,18 +473,6 @@ int
473qed_set_queue_coalesce(u16 rx_coal, u16 tx_coal, void *p_handle); 473qed_set_queue_coalesce(u16 rx_coal, u16 tx_coal, void *p_handle);
474 474
475/** 475/**
476 * @brief qed_pglueb_set_pfid_enable - Enable or disable PCI BUS MASTER
477 *
478 * @param p_hwfn
479 * @param p_ptt
480 * @param b_enable - true/false
481 *
482 * @return int
483 */
484int qed_pglueb_set_pfid_enable(struct qed_hwfn *p_hwfn,
485 struct qed_ptt *p_ptt, bool b_enable);
486
487/**
488 * @brief db_recovery_add - add doorbell information to the doorbell 476 * @brief db_recovery_add - add doorbell information to the doorbell
489 * recovery mechanism. 477 * recovery mechanism.
490 * 478 *
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index 417121e74ee9..b13cfb449d8f 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -12827,7 +12827,7 @@ enum MFW_DRV_MSG_TYPE {
12827 MFW_DRV_MSG_LLDP_DATA_UPDATED, 12827 MFW_DRV_MSG_LLDP_DATA_UPDATED,
12828 MFW_DRV_MSG_DCBX_REMOTE_MIB_UPDATED, 12828 MFW_DRV_MSG_DCBX_REMOTE_MIB_UPDATED,
12829 MFW_DRV_MSG_DCBX_OPERATIONAL_MIB_UPDATED, 12829 MFW_DRV_MSG_DCBX_OPERATIONAL_MIB_UPDATED,
12830 MFW_DRV_MSG_ERROR_RECOVERY, 12830 MFW_DRV_MSG_RESERVED4,
12831 MFW_DRV_MSG_BW_UPDATE, 12831 MFW_DRV_MSG_BW_UPDATE,
12832 MFW_DRV_MSG_S_TAG_UPDATE, 12832 MFW_DRV_MSG_S_TAG_UPDATE,
12833 MFW_DRV_MSG_GET_LAN_STATS, 12833 MFW_DRV_MSG_GET_LAN_STATS,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hw.c b/drivers/net/ethernet/qlogic/qed/qed_hw.c
index 72ec1c6bdf70..70504dcf4087 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hw.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_hw.c
@@ -703,17 +703,6 @@ static int qed_dmae_execute_command(struct qed_hwfn *p_hwfn,
703 int qed_status = 0; 703 int qed_status = 0;
704 u32 offset = 0; 704 u32 offset = 0;
705 705
706 if (p_hwfn->cdev->recov_in_prog) {
707 DP_VERBOSE(p_hwfn,
708 NETIF_MSG_HW,
709 "Recovery is in progress. Avoid DMAE transaction [{src: addr 0x%llx, type %d}, {dst: addr 0x%llx, type %d}, size %d].\n",
710 src_addr, src_type, dst_addr, dst_type,
711 size_in_dwords);
712
713 /* Let the flow complete w/o any error handling */
714 return 0;
715 }
716
717 qed_dmae_opcode(p_hwfn, 706 qed_dmae_opcode(p_hwfn,
718 (src_type == QED_DMAE_ADDRESS_GRC), 707 (src_type == QED_DMAE_ADDRESS_GRC),
719 (dst_type == QED_DMAE_ADDRESS_GRC), 708 (dst_type == QED_DMAE_ADDRESS_GRC),
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c
index e23980e301b6..92340919d852 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -255,114 +255,112 @@ out:
255#define PGLUE_ATTENTION_ICPL_VALID (1 << 23) 255#define PGLUE_ATTENTION_ICPL_VALID (1 << 23)
256#define PGLUE_ATTENTION_ZLR_VALID (1 << 25) 256#define PGLUE_ATTENTION_ZLR_VALID (1 << 25)
257#define PGLUE_ATTENTION_ILT_VALID (1 << 23) 257#define PGLUE_ATTENTION_ILT_VALID (1 << 23)
258 258static int qed_pglub_rbc_attn_cb(struct qed_hwfn *p_hwfn)
259int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn,
260 struct qed_ptt *p_ptt)
261{ 259{
262 u32 tmp; 260 u32 tmp;
263 261
264 tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS2); 262 tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
263 PGLUE_B_REG_TX_ERR_WR_DETAILS2);
265 if (tmp & PGLUE_ATTENTION_VALID) { 264 if (tmp & PGLUE_ATTENTION_VALID) {
266 u32 addr_lo, addr_hi, details; 265 u32 addr_lo, addr_hi, details;
267 266
268 addr_lo = qed_rd(p_hwfn, p_ptt, 267 addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
269 PGLUE_B_REG_TX_ERR_WR_ADD_31_0); 268 PGLUE_B_REG_TX_ERR_WR_ADD_31_0);
270 addr_hi = qed_rd(p_hwfn, p_ptt, 269 addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
271 PGLUE_B_REG_TX_ERR_WR_ADD_63_32); 270 PGLUE_B_REG_TX_ERR_WR_ADD_63_32);
272 details = qed_rd(p_hwfn, p_ptt, 271 details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
273 PGLUE_B_REG_TX_ERR_WR_DETAILS); 272 PGLUE_B_REG_TX_ERR_WR_DETAILS);
274 273
275 DP_NOTICE(p_hwfn, 274 DP_INFO(p_hwfn,
276 "Illegal write by chip to [%08x:%08x] blocked.\n" 275 "Illegal write by chip to [%08x:%08x] blocked.\n"
277 "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n" 276 "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n"
278 "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n", 277 "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n",
279 addr_hi, addr_lo, details, 278 addr_hi, addr_lo, details,
280 (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID), 279 (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID),
281 (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID), 280 (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID),
282 GET_FIELD(details, 281 GET_FIELD(details,
283 PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0, 282 PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0,
284 tmp, 283 tmp,
285 GET_FIELD(tmp, 284 GET_FIELD(tmp,
286 PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1 : 0, 285 PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1 : 0,
287 GET_FIELD(tmp, 286 GET_FIELD(tmp,
288 PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0, 287 PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0,
289 GET_FIELD(tmp, 288 GET_FIELD(tmp,
290 PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1 : 0); 289 PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1 : 0);
291 } 290 }
292 291
293 tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_RD_DETAILS2); 292 tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
293 PGLUE_B_REG_TX_ERR_RD_DETAILS2);
294 if (tmp & PGLUE_ATTENTION_RD_VALID) { 294 if (tmp & PGLUE_ATTENTION_RD_VALID) {
295 u32 addr_lo, addr_hi, details; 295 u32 addr_lo, addr_hi, details;
296 296
297 addr_lo = qed_rd(p_hwfn, p_ptt, 297 addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
298 PGLUE_B_REG_TX_ERR_RD_ADD_31_0); 298 PGLUE_B_REG_TX_ERR_RD_ADD_31_0);
299 addr_hi = qed_rd(p_hwfn, p_ptt, 299 addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
300 PGLUE_B_REG_TX_ERR_RD_ADD_63_32); 300 PGLUE_B_REG_TX_ERR_RD_ADD_63_32);
301 details = qed_rd(p_hwfn, p_ptt, 301 details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
302 PGLUE_B_REG_TX_ERR_RD_DETAILS); 302 PGLUE_B_REG_TX_ERR_RD_DETAILS);
303 303
304 DP_NOTICE(p_hwfn, 304 DP_INFO(p_hwfn,
305 "Illegal read by chip from [%08x:%08x] blocked.\n" 305 "Illegal read by chip from [%08x:%08x] blocked.\n"
306 "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n" 306 " Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n"
307 "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n", 307 " Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n",
308 addr_hi, addr_lo, details, 308 addr_hi, addr_lo, details,
309 (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID), 309 (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID),
310 (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID), 310 (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID),
311 GET_FIELD(details, 311 GET_FIELD(details,
312 PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0, 312 PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0,
313 tmp, 313 tmp,
314 GET_FIELD(tmp, 314 GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1
315 PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1 : 0, 315 : 0,
316 GET_FIELD(tmp, 316 GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0,
317 PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0, 317 GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1
318 GET_FIELD(tmp, 318 : 0);
319 PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1 : 0);
320 } 319 }
321 320
322 tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS_ICPL); 321 tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
322 PGLUE_B_REG_TX_ERR_WR_DETAILS_ICPL);
323 if (tmp & PGLUE_ATTENTION_ICPL_VALID) 323 if (tmp & PGLUE_ATTENTION_ICPL_VALID)
324 DP_NOTICE(p_hwfn, "ICPL error - %08x\n", tmp); 324 DP_INFO(p_hwfn, "ICPL error - %08x\n", tmp);
325 325
326 tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_MASTER_ZLR_ERR_DETAILS); 326 tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
327 PGLUE_B_REG_MASTER_ZLR_ERR_DETAILS);
327 if (tmp & PGLUE_ATTENTION_ZLR_VALID) { 328 if (tmp & PGLUE_ATTENTION_ZLR_VALID) {
328 u32 addr_hi, addr_lo; 329 u32 addr_hi, addr_lo;
329 330
330 addr_lo = qed_rd(p_hwfn, p_ptt, 331 addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
331 PGLUE_B_REG_MASTER_ZLR_ERR_ADD_31_0); 332 PGLUE_B_REG_MASTER_ZLR_ERR_ADD_31_0);
332 addr_hi = qed_rd(p_hwfn, p_ptt, 333 addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
333 PGLUE_B_REG_MASTER_ZLR_ERR_ADD_63_32); 334 PGLUE_B_REG_MASTER_ZLR_ERR_ADD_63_32);
334 335
335 DP_NOTICE(p_hwfn, "ZLR error - %08x [Address %08x:%08x]\n", 336 DP_INFO(p_hwfn, "ZLR eror - %08x [Address %08x:%08x]\n",
336 tmp, addr_hi, addr_lo); 337 tmp, addr_hi, addr_lo);
337 } 338 }
338 339
339 tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_VF_ILT_ERR_DETAILS2); 340 tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
341 PGLUE_B_REG_VF_ILT_ERR_DETAILS2);
340 if (tmp & PGLUE_ATTENTION_ILT_VALID) { 342 if (tmp & PGLUE_ATTENTION_ILT_VALID) {
341 u32 addr_hi, addr_lo, details; 343 u32 addr_hi, addr_lo, details;
342 344
343 addr_lo = qed_rd(p_hwfn, p_ptt, 345 addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
344 PGLUE_B_REG_VF_ILT_ERR_ADD_31_0); 346 PGLUE_B_REG_VF_ILT_ERR_ADD_31_0);
345 addr_hi = qed_rd(p_hwfn, p_ptt, 347 addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
346 PGLUE_B_REG_VF_ILT_ERR_ADD_63_32); 348 PGLUE_B_REG_VF_ILT_ERR_ADD_63_32);
347 details = qed_rd(p_hwfn, p_ptt, 349 details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
348 PGLUE_B_REG_VF_ILT_ERR_DETAILS); 350 PGLUE_B_REG_VF_ILT_ERR_DETAILS);
349 351
350 DP_NOTICE(p_hwfn, 352 DP_INFO(p_hwfn,
351 "ILT error - Details %08x Details2 %08x [Address %08x:%08x]\n", 353 "ILT error - Details %08x Details2 %08x [Address %08x:%08x]\n",
352 details, tmp, addr_hi, addr_lo); 354 details, tmp, addr_hi, addr_lo);
353 } 355 }
354 356
355 /* Clear the indications */ 357 /* Clear the indications */
356 qed_wr(p_hwfn, p_ptt, PGLUE_B_REG_LATCHED_ERRORS_CLR, BIT(2)); 358 qed_wr(p_hwfn, p_hwfn->p_dpc_ptt,
359 PGLUE_B_REG_LATCHED_ERRORS_CLR, (1 << 2));
357 360
358 return 0; 361 return 0;
359} 362}
360 363
361static int qed_pglueb_rbc_attn_cb(struct qed_hwfn *p_hwfn)
362{
363 return qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_dpc_ptt);
364}
365
366#define QED_DORQ_ATTENTION_REASON_MASK (0xfffff) 364#define QED_DORQ_ATTENTION_REASON_MASK (0xfffff)
367#define QED_DORQ_ATTENTION_OPAQUE_MASK (0xffff) 365#define QED_DORQ_ATTENTION_OPAQUE_MASK (0xffff)
368#define QED_DORQ_ATTENTION_OPAQUE_SHIFT (0x0) 366#define QED_DORQ_ATTENTION_OPAQUE_SHIFT (0x0)
@@ -542,7 +540,7 @@ static struct aeu_invert_reg aeu_descs[NUM_ATTN_REGS] = {
542 {"PGLUE misc_flr", ATTENTION_SINGLE, 540 {"PGLUE misc_flr", ATTENTION_SINGLE,
543 NULL, MAX_BLOCK_ID}, 541 NULL, MAX_BLOCK_ID},
544 {"PGLUE B RBC", ATTENTION_PAR_INT, 542 {"PGLUE B RBC", ATTENTION_PAR_INT,
545 qed_pglueb_rbc_attn_cb, BLOCK_PGLUE_B}, 543 qed_pglub_rbc_attn_cb, BLOCK_PGLUE_B},
546 {"PGLUE misc_mctp", ATTENTION_SINGLE, 544 {"PGLUE misc_mctp", ATTENTION_SINGLE,
547 NULL, MAX_BLOCK_ID}, 545 NULL, MAX_BLOCK_ID},
548 {"Flash event", ATTENTION_SINGLE, NULL, MAX_BLOCK_ID}, 546 {"Flash event", ATTENTION_SINGLE, NULL, MAX_BLOCK_ID},
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.h b/drivers/net/ethernet/qlogic/qed/qed_int.h
index 1f356ed4f761..d81a62ebd524 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.h
@@ -431,7 +431,4 @@ int qed_int_set_timer_res(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
431 431
432#define QED_MAPPING_MEMORY_SIZE(dev) (NUM_OF_SBS(dev)) 432#define QED_MAPPING_MEMORY_SIZE(dev) (NUM_OF_SBS(dev))
433 433
434int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn,
435 struct qed_ptt *p_ptt);
436
437#endif 434#endif
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index b47352643fb5..6adf5bda9811 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -359,8 +359,6 @@ static struct qed_dev *qed_probe(struct pci_dev *pdev,
359 359
360 qed_init_dp(cdev, params->dp_module, params->dp_level); 360 qed_init_dp(cdev, params->dp_module, params->dp_level);
361 361
362 cdev->recov_in_prog = params->recov_in_prog;
363
364 rc = qed_init_pci(cdev, pdev); 362 rc = qed_init_pci(cdev, pdev);
365 if (rc) { 363 if (rc) {
366 DP_ERR(cdev, "init pci failed\n"); 364 DP_ERR(cdev, "init pci failed\n");
@@ -2205,15 +2203,6 @@ static int qed_nvm_get_image(struct qed_dev *cdev, enum qed_nvm_images type,
2205 return qed_mcp_get_nvm_image(hwfn, type, buf, len); 2203 return qed_mcp_get_nvm_image(hwfn, type, buf, len);
2206} 2204}
2207 2205
2208void qed_schedule_recovery_handler(struct qed_hwfn *p_hwfn)
2209{
2210 struct qed_common_cb_ops *ops = p_hwfn->cdev->protocol_ops.common;
2211 void *cookie = p_hwfn->cdev->ops_cookie;
2212
2213 if (ops && ops->schedule_recovery_handler)
2214 ops->schedule_recovery_handler(cookie);
2215}
2216
2217static int qed_set_coalesce(struct qed_dev *cdev, u16 rx_coal, u16 tx_coal, 2206static int qed_set_coalesce(struct qed_dev *cdev, u16 rx_coal, u16 tx_coal,
2218 void *handle) 2207 void *handle)
2219{ 2208{
@@ -2237,23 +2226,6 @@ static int qed_set_led(struct qed_dev *cdev, enum qed_led_mode mode)
2237 return status; 2226 return status;
2238} 2227}
2239 2228
2240static int qed_recovery_process(struct qed_dev *cdev)
2241{
2242 struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
2243 struct qed_ptt *p_ptt;
2244 int rc = 0;
2245
2246 p_ptt = qed_ptt_acquire(p_hwfn);
2247 if (!p_ptt)
2248 return -EAGAIN;
2249
2250 rc = qed_start_recovery_process(p_hwfn, p_ptt);
2251
2252 qed_ptt_release(p_hwfn, p_ptt);
2253
2254 return rc;
2255}
2256
2257static int qed_update_wol(struct qed_dev *cdev, bool enabled) 2229static int qed_update_wol(struct qed_dev *cdev, bool enabled)
2258{ 2230{
2259 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2231 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
@@ -2408,8 +2380,6 @@ const struct qed_common_ops qed_common_ops_pass = {
2408 .nvm_get_image = &qed_nvm_get_image, 2380 .nvm_get_image = &qed_nvm_get_image,
2409 .set_coalesce = &qed_set_coalesce, 2381 .set_coalesce = &qed_set_coalesce,
2410 .set_led = &qed_set_led, 2382 .set_led = &qed_set_led,
2411 .recovery_process = &qed_recovery_process,
2412 .recovery_prolog = &qed_recovery_prolog,
2413 .update_drv_state = &qed_update_drv_state, 2383 .update_drv_state = &qed_update_drv_state,
2414 .update_mac = &qed_update_mac, 2384 .update_mac = &qed_update_mac,
2415 .update_mtu = &qed_update_mtu, 2385 .update_mtu = &qed_update_mtu,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index bb8541847aa5..e7f18e34ff0d 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -1070,27 +1070,6 @@ int qed_mcp_load_req(struct qed_hwfn *p_hwfn,
1070 return 0; 1070 return 0;
1071} 1071}
1072 1072
1073int qed_mcp_load_done(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
1074{
1075 u32 resp = 0, param = 0;
1076 int rc;
1077
1078 rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_LOAD_DONE, 0, &resp,
1079 &param);
1080 if (rc) {
1081 DP_NOTICE(p_hwfn,
1082 "Failed to send a LOAD_DONE command, rc = %d\n", rc);
1083 return rc;
1084 }
1085
1086 /* Check if there is a DID mismatch between nvm-cfg/efuse */
1087 if (param & FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR)
1088 DP_NOTICE(p_hwfn,
1089 "warning: device configuration is not supported on this board type. The device may not function as expected.\n");
1090
1091 return 0;
1092}
1093
1094int qed_mcp_unload_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) 1073int qed_mcp_unload_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
1095{ 1074{
1096 struct qed_mcp_mb_params mb_params; 1075 struct qed_mcp_mb_params mb_params;
@@ -1549,60 +1528,6 @@ int qed_mcp_set_link(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, bool b_up)
1549 return 0; 1528 return 0;
1550} 1529}
1551 1530
1552u32 qed_get_process_kill_counter(struct qed_hwfn *p_hwfn,
1553 struct qed_ptt *p_ptt)
1554{
1555 u32 path_offsize_addr, path_offsize, path_addr, proc_kill_cnt;
1556
1557 if (IS_VF(p_hwfn->cdev))
1558 return -EINVAL;
1559
1560 path_offsize_addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base,
1561 PUBLIC_PATH);
1562 path_offsize = qed_rd(p_hwfn, p_ptt, path_offsize_addr);
1563 path_addr = SECTION_ADDR(path_offsize, QED_PATH_ID(p_hwfn));
1564
1565 proc_kill_cnt = qed_rd(p_hwfn, p_ptt,
1566 path_addr +
1567 offsetof(struct public_path, process_kill)) &
1568 PROCESS_KILL_COUNTER_MASK;
1569
1570 return proc_kill_cnt;
1571}
1572
1573static void qed_mcp_handle_process_kill(struct qed_hwfn *p_hwfn,
1574 struct qed_ptt *p_ptt)
1575{
1576 struct qed_dev *cdev = p_hwfn->cdev;
1577 u32 proc_kill_cnt;
1578
1579 /* Prevent possible attentions/interrupts during the recovery handling
1580 * and till its load phase, during which they will be re-enabled.
1581 */
1582 qed_int_igu_disable_int(p_hwfn, p_ptt);
1583
1584 DP_NOTICE(p_hwfn, "Received a process kill indication\n");
1585
1586 /* The following operations should be done once, and thus in CMT mode
1587 * are carried out by only the first HW function.
1588 */
1589 if (p_hwfn != QED_LEADING_HWFN(cdev))
1590 return;
1591
1592 if (cdev->recov_in_prog) {
1593 DP_NOTICE(p_hwfn,
1594 "Ignoring the indication since a recovery process is already in progress\n");
1595 return;
1596 }
1597
1598 cdev->recov_in_prog = true;
1599
1600 proc_kill_cnt = qed_get_process_kill_counter(p_hwfn, p_ptt);
1601 DP_NOTICE(p_hwfn, "Process kill counter: %d\n", proc_kill_cnt);
1602
1603 qed_schedule_recovery_handler(p_hwfn);
1604}
1605
1606static void qed_mcp_send_protocol_stats(struct qed_hwfn *p_hwfn, 1531static void qed_mcp_send_protocol_stats(struct qed_hwfn *p_hwfn,
1607 struct qed_ptt *p_ptt, 1532 struct qed_ptt *p_ptt,
1608 enum MFW_DRV_MSG_TYPE type) 1533 enum MFW_DRV_MSG_TYPE type)
@@ -1833,9 +1758,6 @@ int qed_mcp_handle_events(struct qed_hwfn *p_hwfn,
1833 case MFW_DRV_MSG_TRANSCEIVER_STATE_CHANGE: 1758 case MFW_DRV_MSG_TRANSCEIVER_STATE_CHANGE:
1834 qed_mcp_handle_transceiver_change(p_hwfn, p_ptt); 1759 qed_mcp_handle_transceiver_change(p_hwfn, p_ptt);
1835 break; 1760 break;
1836 case MFW_DRV_MSG_ERROR_RECOVERY:
1837 qed_mcp_handle_process_kill(p_hwfn, p_ptt);
1838 break;
1839 case MFW_DRV_MSG_GET_LAN_STATS: 1761 case MFW_DRV_MSG_GET_LAN_STATS:
1840 case MFW_DRV_MSG_GET_FCOE_STATS: 1762 case MFW_DRV_MSG_GET_FCOE_STATS:
1841 case MFW_DRV_MSG_GET_ISCSI_STATS: 1763 case MFW_DRV_MSG_GET_ISCSI_STATS:
@@ -2381,43 +2303,6 @@ int qed_mcp_get_flash_size(struct qed_hwfn *p_hwfn,
2381 return 0; 2303 return 0;
2382} 2304}
2383 2305
2384int qed_start_recovery_process(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
2385{
2386 struct qed_dev *cdev = p_hwfn->cdev;
2387
2388 if (cdev->recov_in_prog) {
2389 DP_NOTICE(p_hwfn,
2390 "Avoid triggering a recovery since such a process is already in progress\n");
2391 return -EAGAIN;
2392 }
2393
2394 DP_NOTICE(p_hwfn, "Triggering a recovery process\n");
2395 qed_wr(p_hwfn, p_ptt, MISC_REG_AEU_GENERAL_ATTN_35, 0x1);
2396
2397 return 0;
2398}
2399
2400#define QED_RECOVERY_PROLOG_SLEEP_MS 100
2401
2402int qed_recovery_prolog(struct qed_dev *cdev)
2403{
2404 struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
2405 struct qed_ptt *p_ptt = p_hwfn->p_main_ptt;
2406 int rc;
2407
2408 /* Allow ongoing PCIe transactions to complete */
2409 msleep(QED_RECOVERY_PROLOG_SLEEP_MS);
2410
2411 /* Clear the PF's internal FID_enable in the PXP */
2412 rc = qed_pglueb_set_pfid_enable(p_hwfn, p_ptt, false);
2413 if (rc)
2414 DP_NOTICE(p_hwfn,
2415 "qed_pglueb_set_pfid_enable() failed. rc = %d.\n",
2416 rc);
2417
2418 return rc;
2419}
2420
2421static int 2306static int
2422qed_mcp_config_vf_msix_bb(struct qed_hwfn *p_hwfn, 2307qed_mcp_config_vf_msix_bb(struct qed_hwfn *p_hwfn,
2423 struct qed_ptt *p_ptt, u8 vf_id, u8 num) 2308 struct qed_ptt *p_ptt, u8 vf_id, u8 num)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
index 6e1d72a669ae..eddf67798d6f 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
@@ -441,38 +441,6 @@ qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn,
441 struct qed_mcp_drv_version *p_ver); 441 struct qed_mcp_drv_version *p_ver);
442 442
443/** 443/**
444 * @brief Read the MFW process kill counter
445 *
446 * @param p_hwfn
447 * @param p_ptt
448 *
449 * @return u32
450 */
451u32 qed_get_process_kill_counter(struct qed_hwfn *p_hwfn,
452 struct qed_ptt *p_ptt);
453
454/**
455 * @brief Trigger a recovery process
456 *
457 * @param p_hwfn
458 * @param p_ptt
459 *
460 * @return int
461 */
462int qed_start_recovery_process(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
463
464/**
465 * @brief A recovery handler must call this function as its first step.
466 * It is assumed that the handler is not run from an interrupt context.
467 *
468 * @param cdev
469 * @param p_ptt
470 *
471 * @return int
472 */
473int qed_recovery_prolog(struct qed_dev *cdev);
474
475/**
476 * @brief Notify MFW about the change in base device properties 444 * @brief Notify MFW about the change in base device properties
477 * 445 *
478 * @param p_hwfn 446 * @param p_hwfn
@@ -833,16 +801,6 @@ int qed_mcp_load_req(struct qed_hwfn *p_hwfn,
833 struct qed_load_req_params *p_params); 801 struct qed_load_req_params *p_params);
834 802
835/** 803/**
836 * @brief Sends a LOAD_DONE message to the MFW
837 *
838 * @param p_hwfn
839 * @param p_ptt
840 *
841 * @return int - 0 - Operation was successful.
842 */
843int qed_mcp_load_done(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
844
845/**
846 * @brief Sends a UNLOAD_REQ message to the MFW 804 * @brief Sends a UNLOAD_REQ message to the MFW
847 * 805 *
848 * @param p_hwfn 806 * @param p_hwfn
diff --git a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
index 5ce825ca5f24..8939ed6e08b7 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
@@ -518,8 +518,6 @@
518 0x180824UL 518 0x180824UL
519#define MISC_REG_AEU_GENERAL_ATTN_0 \ 519#define MISC_REG_AEU_GENERAL_ATTN_0 \
520 0x008400UL 520 0x008400UL
521#define MISC_REG_AEU_GENERAL_ATTN_35 \
522 0x00848cUL
523#define CAU_REG_SB_ADDR_MEMORY \ 521#define CAU_REG_SB_ADDR_MEMORY \
524 0x1c8000UL 522 0x1c8000UL
525#define CAU_REG_SB_VAR_MEMORY \ 523#define CAU_REG_SB_VAR_MEMORY \
diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c
index 3e0f7c46bb1b..eb88bbc6b193 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_spq.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c
@@ -790,17 +790,6 @@ static int qed_spq_pend_post(struct qed_hwfn *p_hwfn)
790 SPQ_HIGH_PRI_RESERVE_DEFAULT); 790 SPQ_HIGH_PRI_RESERVE_DEFAULT);
791} 791}
792 792
793static void qed_spq_recov_set_ret_code(struct qed_spq_entry *p_ent,
794 u8 *fw_return_code)
795{
796 if (!fw_return_code)
797 return;
798
799 if (p_ent->elem.hdr.protocol_id == PROTOCOLID_ROCE ||
800 p_ent->elem.hdr.protocol_id == PROTOCOLID_IWARP)
801 *fw_return_code = RDMA_RETURN_OK;
802}
803
804/* Avoid overriding of SPQ entries when getting out-of-order completions, by 793/* Avoid overriding of SPQ entries when getting out-of-order completions, by
805 * marking the completions in a bitmap and increasing the chain consumer only 794 * marking the completions in a bitmap and increasing the chain consumer only
806 * for the first successive completed entries. 795 * for the first successive completed entries.
@@ -836,17 +825,6 @@ int qed_spq_post(struct qed_hwfn *p_hwfn,
836 return -EINVAL; 825 return -EINVAL;
837 } 826 }
838 827
839 if (p_hwfn->cdev->recov_in_prog) {
840 DP_VERBOSE(p_hwfn,
841 QED_MSG_SPQ,
842 "Recovery is in progress. Skip spq post [cmd %02x protocol %02x]\n",
843 p_ent->elem.hdr.cmd_id, p_ent->elem.hdr.protocol_id);
844
845 /* Let the flow complete w/o any error handling */
846 qed_spq_recov_set_ret_code(p_ent, fw_return_code);
847 return 0;
848 }
849
850 /* Complete the entry */ 828 /* Complete the entry */
851 rc = qed_spq_fill_entry(p_hwfn, p_ent); 829 rc = qed_spq_fill_entry(p_hwfn, p_ent);
852 830
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
index 71e28be58102..ca6290fa0f30 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
@@ -4447,13 +4447,6 @@ int qed_sriov_disable(struct qed_dev *cdev, bool pci_enabled)
4447 if (cdev->p_iov_info && cdev->p_iov_info->num_vfs && pci_enabled) 4447 if (cdev->p_iov_info && cdev->p_iov_info->num_vfs && pci_enabled)
4448 pci_disable_sriov(cdev->pdev); 4448 pci_disable_sriov(cdev->pdev);
4449 4449
4450 if (cdev->recov_in_prog) {
4451 DP_VERBOSE(cdev,
4452 QED_MSG_IOV,
4453 "Skip SRIOV disable operations in the device since a recovery is in progress\n");
4454 goto out;
4455 }
4456
4457 for_each_hwfn(cdev, i) { 4450 for_each_hwfn(cdev, i) {
4458 struct qed_hwfn *hwfn = &cdev->hwfns[i]; 4451 struct qed_hwfn *hwfn = &cdev->hwfns[i];
4459 struct qed_ptt *ptt = qed_ptt_acquire(hwfn); 4452 struct qed_ptt *ptt = qed_ptt_acquire(hwfn);
@@ -4493,7 +4486,7 @@ int qed_sriov_disable(struct qed_dev *cdev, bool pci_enabled)
4493 4486
4494 qed_ptt_release(hwfn, ptt); 4487 qed_ptt_release(hwfn, ptt);
4495 } 4488 }
4496out: 4489
4497 qed_iov_set_vfs_to_disable(cdev, false); 4490 qed_iov_set_vfs_to_disable(cdev, false);
4498 4491
4499 return 0; 4492 return 0;
diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index 843416404aeb..613249d1e967 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -162,7 +162,6 @@ struct qede_rdma_dev {
162 struct list_head entry; 162 struct list_head entry;
163 struct list_head rdma_event_list; 163 struct list_head rdma_event_list;
164 struct workqueue_struct *rdma_wq; 164 struct workqueue_struct *rdma_wq;
165 bool exp_recovery;
166}; 165};
167 166
168struct qede_ptp; 167struct qede_ptp;
@@ -265,7 +264,6 @@ struct qede_dev {
265enum QEDE_STATE { 264enum QEDE_STATE {
266 QEDE_STATE_CLOSED, 265 QEDE_STATE_CLOSED,
267 QEDE_STATE_OPEN, 266 QEDE_STATE_OPEN,
268 QEDE_STATE_RECOVERY,
269}; 267};
270 268
271#define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo)) 269#define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo))
@@ -464,7 +462,6 @@ struct qede_fastpath {
464#define QEDE_CSUM_UNNECESSARY BIT(1) 462#define QEDE_CSUM_UNNECESSARY BIT(1)
465#define QEDE_TUNN_CSUM_UNNECESSARY BIT(2) 463#define QEDE_TUNN_CSUM_UNNECESSARY BIT(2)
466 464
467#define QEDE_SP_RECOVERY 0
468#define QEDE_SP_RX_MODE 1 465#define QEDE_SP_RX_MODE 1
469 466
470#ifdef CONFIG_RFS_ACCEL 467#ifdef CONFIG_RFS_ACCEL
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index de955f2b2980..5a74fcbdbc2b 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -133,12 +133,23 @@ static int qede_probe(struct pci_dev *pdev, const struct pci_device_id *id);
133static void qede_remove(struct pci_dev *pdev); 133static void qede_remove(struct pci_dev *pdev);
134static void qede_shutdown(struct pci_dev *pdev); 134static void qede_shutdown(struct pci_dev *pdev);
135static void qede_link_update(void *dev, struct qed_link_output *link); 135static void qede_link_update(void *dev, struct qed_link_output *link);
136static void qede_schedule_recovery_handler(void *dev);
137static void qede_recovery_handler(struct qede_dev *edev);
138static void qede_get_eth_tlv_data(void *edev, void *data); 136static void qede_get_eth_tlv_data(void *edev, void *data);
139static void qede_get_generic_tlv_data(void *edev, 137static void qede_get_generic_tlv_data(void *edev,
140 struct qed_generic_tlvs *data); 138 struct qed_generic_tlvs *data);
141 139
140/* The qede lock is used to protect driver state change and driver flows that
141 * are not reentrant.
142 */
143void __qede_lock(struct qede_dev *edev)
144{
145 mutex_lock(&edev->qede_lock);
146}
147
148void __qede_unlock(struct qede_dev *edev)
149{
150 mutex_unlock(&edev->qede_lock);
151}
152
142#ifdef CONFIG_QED_SRIOV 153#ifdef CONFIG_QED_SRIOV
143static int qede_set_vf_vlan(struct net_device *ndev, int vf, u16 vlan, u8 qos, 154static int qede_set_vf_vlan(struct net_device *ndev, int vf, u16 vlan, u8 qos,
144 __be16 vlan_proto) 155 __be16 vlan_proto)
@@ -220,7 +231,6 @@ static struct qed_eth_cb_ops qede_ll_ops = {
220 .arfs_filter_op = qede_arfs_filter_op, 231 .arfs_filter_op = qede_arfs_filter_op,
221#endif 232#endif
222 .link_update = qede_link_update, 233 .link_update = qede_link_update,
223 .schedule_recovery_handler = qede_schedule_recovery_handler,
224 .get_generic_tlv_data = qede_get_generic_tlv_data, 234 .get_generic_tlv_data = qede_get_generic_tlv_data,
225 .get_protocol_tlv_data = qede_get_eth_tlv_data, 235 .get_protocol_tlv_data = qede_get_eth_tlv_data,
226 }, 236 },
@@ -940,57 +950,11 @@ err:
940 return -ENOMEM; 950 return -ENOMEM;
941} 951}
942 952
943/* The qede lock is used to protect driver state change and driver flows that
944 * are not reentrant.
945 */
946void __qede_lock(struct qede_dev *edev)
947{
948 mutex_lock(&edev->qede_lock);
949}
950
951void __qede_unlock(struct qede_dev *edev)
952{
953 mutex_unlock(&edev->qede_lock);
954}
955
956/* This version of the lock should be used when acquiring the RTNL lock is also
957 * needed in addition to the internal qede lock.
958 */
959void qede_lock(struct qede_dev *edev)
960{
961 rtnl_lock();
962 __qede_lock(edev);
963}
964
965void qede_unlock(struct qede_dev *edev)
966{
967 __qede_unlock(edev);
968 rtnl_unlock();
969}
970
971static void qede_sp_task(struct work_struct *work) 953static void qede_sp_task(struct work_struct *work)
972{ 954{
973 struct qede_dev *edev = container_of(work, struct qede_dev, 955 struct qede_dev *edev = container_of(work, struct qede_dev,
974 sp_task.work); 956 sp_task.work);
975 957
976 /* The locking scheme depends on the specific flag:
977 * In case of QEDE_SP_RECOVERY, acquiring the RTNL lock is required to
978 * ensure that ongoing flows are ended and new ones are not started.
979 * In other cases - only the internal qede lock should be acquired.
980 */
981
982 if (test_and_clear_bit(QEDE_SP_RECOVERY, &edev->sp_flags)) {
983#ifdef CONFIG_QED_SRIOV
984 /* SRIOV must be disabled outside the lock to avoid a deadlock.
985 * The recovery of the active VFs is currently not supported.
986 */
987 qede_sriov_configure(edev->pdev, 0);
988#endif
989 qede_lock(edev);
990 qede_recovery_handler(edev);
991 qede_unlock(edev);
992 }
993
994 __qede_lock(edev); 958 __qede_lock(edev);
995 959
996 if (test_and_clear_bit(QEDE_SP_RX_MODE, &edev->sp_flags)) 960 if (test_and_clear_bit(QEDE_SP_RX_MODE, &edev->sp_flags))
@@ -1067,13 +1031,8 @@ static void qede_log_probe(struct qede_dev *edev)
1067 1031
1068enum qede_probe_mode { 1032enum qede_probe_mode {
1069 QEDE_PROBE_NORMAL, 1033 QEDE_PROBE_NORMAL,
1070 QEDE_PROBE_RECOVERY,
1071}; 1034};
1072 1035
1073#define QEDE_RDMA_PROBE_MODE(mode) \
1074 ((mode) == QEDE_PROBE_NORMAL ? QEDE_RDMA_PROBE_NORMAL \
1075 : QEDE_RDMA_PROBE_RECOVERY)
1076
1077static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level, 1036static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
1078 bool is_vf, enum qede_probe_mode mode) 1037 bool is_vf, enum qede_probe_mode mode)
1079{ 1038{
@@ -1092,7 +1051,6 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
1092 probe_params.dp_module = dp_module; 1051 probe_params.dp_module = dp_module;
1093 probe_params.dp_level = dp_level; 1052 probe_params.dp_level = dp_level;
1094 probe_params.is_vf = is_vf; 1053 probe_params.is_vf = is_vf;
1095 probe_params.recov_in_prog = (mode == QEDE_PROBE_RECOVERY);
1096 cdev = qed_ops->common->probe(pdev, &probe_params); 1054 cdev = qed_ops->common->probe(pdev, &probe_params);
1097 if (!cdev) { 1055 if (!cdev) {
1098 rc = -ENODEV; 1056 rc = -ENODEV;
@@ -1120,20 +1078,11 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
1120 if (rc) 1078 if (rc)
1121 goto err2; 1079 goto err2;
1122 1080
1123 if (mode != QEDE_PROBE_RECOVERY) { 1081 edev = qede_alloc_etherdev(cdev, pdev, &dev_info, dp_module,
1124 edev = qede_alloc_etherdev(cdev, pdev, &dev_info, dp_module, 1082 dp_level);
1125 dp_level); 1083 if (!edev) {
1126 if (!edev) { 1084 rc = -ENOMEM;
1127 rc = -ENOMEM; 1085 goto err2;
1128 goto err2;
1129 }
1130 } else {
1131 struct net_device *ndev = pci_get_drvdata(pdev);
1132
1133 edev = netdev_priv(ndev);
1134 edev->cdev = cdev;
1135 memset(&edev->stats, 0, sizeof(edev->stats));
1136 memcpy(&edev->dev_info, &dev_info, sizeof(dev_info));
1137 } 1086 }
1138 1087
1139 if (is_vf) 1088 if (is_vf)
@@ -1141,31 +1090,28 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
1141 1090
1142 qede_init_ndev(edev); 1091 qede_init_ndev(edev);
1143 1092
1144 rc = qede_rdma_dev_add(edev, QEDE_RDMA_PROBE_MODE(mode)); 1093 rc = qede_rdma_dev_add(edev);
1145 if (rc) 1094 if (rc)
1146 goto err3; 1095 goto err3;
1147 1096
1148 if (mode != QEDE_PROBE_RECOVERY) { 1097 /* Prepare the lock prior to the registration of the netdev,
1149 /* Prepare the lock prior to the registration of the netdev, 1098 * as once it's registered we might reach flows requiring it
1150 * as once it's registered we might reach flows requiring it 1099 * [it's even possible to reach a flow needing it directly
1151 * [it's even possible to reach a flow needing it directly 1100 * from there, although it's unlikely].
1152 * from there, although it's unlikely]. 1101 */
1153 */ 1102 INIT_DELAYED_WORK(&edev->sp_task, qede_sp_task);
1154 INIT_DELAYED_WORK(&edev->sp_task, qede_sp_task); 1103 mutex_init(&edev->qede_lock);
1155 mutex_init(&edev->qede_lock); 1104 rc = register_netdev(edev->ndev);
1156 1105 if (rc) {
1157 rc = register_netdev(edev->ndev); 1106 DP_NOTICE(edev, "Cannot register net-device\n");
1158 if (rc) { 1107 goto err4;
1159 DP_NOTICE(edev, "Cannot register net-device\n");
1160 goto err4;
1161 }
1162 } 1108 }
1163 1109
1164 edev->ops->common->set_name(cdev, edev->ndev->name); 1110 edev->ops->common->set_name(cdev, edev->ndev->name);
1165 1111
1166 /* PTP not supported on VFs */ 1112 /* PTP not supported on VFs */
1167 if (!is_vf) 1113 if (!is_vf)
1168 qede_ptp_enable(edev, (mode == QEDE_PROBE_NORMAL)); 1114 qede_ptp_enable(edev, true);
1169 1115
1170 edev->ops->register_ops(cdev, &qede_ll_ops, edev); 1116 edev->ops->register_ops(cdev, &qede_ll_ops, edev);
1171 1117
@@ -1180,7 +1126,7 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
1180 return 0; 1126 return 0;
1181 1127
1182err4: 1128err4:
1183 qede_rdma_dev_remove(edev, QEDE_RDMA_PROBE_MODE(mode)); 1129 qede_rdma_dev_remove(edev);
1184err3: 1130err3:
1185 free_netdev(edev->ndev); 1131 free_netdev(edev->ndev);
1186err2: 1132err2:
@@ -1216,13 +1162,8 @@ static int qede_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1216 1162
1217enum qede_remove_mode { 1163enum qede_remove_mode {
1218 QEDE_REMOVE_NORMAL, 1164 QEDE_REMOVE_NORMAL,
1219 QEDE_REMOVE_RECOVERY,
1220}; 1165};
1221 1166
1222#define QEDE_RDMA_REMOVE_MODE(mode) \
1223 ((mode) == QEDE_REMOVE_NORMAL ? QEDE_RDMA_REMOVE_NORMAL \
1224 : QEDE_RDMA_REMOVE_RECOVERY)
1225
1226static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode) 1167static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
1227{ 1168{
1228 struct net_device *ndev = pci_get_drvdata(pdev); 1169 struct net_device *ndev = pci_get_drvdata(pdev);
@@ -1231,19 +1172,15 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
1231 1172
1232 DP_INFO(edev, "Starting qede_remove\n"); 1173 DP_INFO(edev, "Starting qede_remove\n");
1233 1174
1234 qede_rdma_dev_remove(edev, QEDE_RDMA_REMOVE_MODE(mode)); 1175 qede_rdma_dev_remove(edev);
1235 1176 unregister_netdev(ndev);
1236 if (mode != QEDE_REMOVE_RECOVERY) { 1177 cancel_delayed_work_sync(&edev->sp_task);
1237 unregister_netdev(ndev);
1238 1178
1239 cancel_delayed_work_sync(&edev->sp_task); 1179 qede_ptp_disable(edev);
1240 1180
1241 edev->ops->common->set_power_state(cdev, PCI_D0); 1181 edev->ops->common->set_power_state(cdev, PCI_D0);
1242 1182
1243 pci_set_drvdata(pdev, NULL); 1183 pci_set_drvdata(pdev, NULL);
1244 }
1245
1246 qede_ptp_disable(edev);
1247 1184
1248 /* Use global ops since we've freed edev */ 1185 /* Use global ops since we've freed edev */
1249 qed_ops->common->slowpath_stop(cdev); 1186 qed_ops->common->slowpath_stop(cdev);
@@ -1257,8 +1194,7 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
1257 * [e.g., QED register callbacks] won't break anything when 1194 * [e.g., QED register callbacks] won't break anything when
1258 * accessing the netdevice. 1195 * accessing the netdevice.
1259 */ 1196 */
1260 if (mode != QEDE_REMOVE_RECOVERY) 1197 free_netdev(ndev);
1261 free_netdev(ndev);
1262 1198
1263 dev_info(&pdev->dev, "Ending qede_remove successfully\n"); 1199 dev_info(&pdev->dev, "Ending qede_remove successfully\n");
1264} 1200}
@@ -1603,58 +1539,6 @@ static int qede_alloc_mem_load(struct qede_dev *edev)
1603 return 0; 1539 return 0;
1604} 1540}
1605 1541
1606static void qede_empty_tx_queue(struct qede_dev *edev,
1607 struct qede_tx_queue *txq)
1608{
1609 unsigned int pkts_compl = 0, bytes_compl = 0;
1610 struct netdev_queue *netdev_txq;
1611 int rc, len = 0;
1612
1613 netdev_txq = netdev_get_tx_queue(edev->ndev, txq->ndev_txq_id);
1614
1615 while (qed_chain_get_cons_idx(&txq->tx_pbl) !=
1616 qed_chain_get_prod_idx(&txq->tx_pbl)) {
1617 DP_VERBOSE(edev, NETIF_MSG_IFDOWN,
1618 "Freeing a packet on tx queue[%d]: chain_cons 0x%x, chain_prod 0x%x\n",
1619 txq->index, qed_chain_get_cons_idx(&txq->tx_pbl),
1620 qed_chain_get_prod_idx(&txq->tx_pbl));
1621
1622 rc = qede_free_tx_pkt(edev, txq, &len);
1623 if (rc) {
1624 DP_NOTICE(edev,
1625 "Failed to free a packet on tx queue[%d]: chain_cons 0x%x, chain_prod 0x%x\n",
1626 txq->index,
1627 qed_chain_get_cons_idx(&txq->tx_pbl),
1628 qed_chain_get_prod_idx(&txq->tx_pbl));
1629 break;
1630 }
1631
1632 bytes_compl += len;
1633 pkts_compl++;
1634 txq->sw_tx_cons++;
1635 }
1636
1637 netdev_tx_completed_queue(netdev_txq, pkts_compl, bytes_compl);
1638}
1639
1640static void qede_empty_tx_queues(struct qede_dev *edev)
1641{
1642 int i;
1643
1644 for_each_queue(i)
1645 if (edev->fp_array[i].type & QEDE_FASTPATH_TX) {
1646 int cos;
1647
1648 for_each_cos_in_txq(edev, cos) {
1649 struct qede_fastpath *fp;
1650
1651 fp = &edev->fp_array[i];
1652 qede_empty_tx_queue(edev,
1653 &fp->txq[cos]);
1654 }
1655 }
1656}
1657
1658/* This function inits fp content and resets the SB, RXQ and TXQ structures */ 1542/* This function inits fp content and resets the SB, RXQ and TXQ structures */
1659static void qede_init_fp(struct qede_dev *edev) 1543static void qede_init_fp(struct qede_dev *edev)
1660{ 1544{
@@ -2169,7 +2053,6 @@ out:
2169 2053
2170enum qede_unload_mode { 2054enum qede_unload_mode {
2171 QEDE_UNLOAD_NORMAL, 2055 QEDE_UNLOAD_NORMAL,
2172 QEDE_UNLOAD_RECOVERY,
2173}; 2056};
2174 2057
2175static void qede_unload(struct qede_dev *edev, enum qede_unload_mode mode, 2058static void qede_unload(struct qede_dev *edev, enum qede_unload_mode mode,
@@ -2185,8 +2068,7 @@ static void qede_unload(struct qede_dev *edev, enum qede_unload_mode mode,
2185 2068
2186 clear_bit(QEDE_FLAGS_LINK_REQUESTED, &edev->flags); 2069 clear_bit(QEDE_FLAGS_LINK_REQUESTED, &edev->flags);
2187 2070
2188 if (mode != QEDE_UNLOAD_RECOVERY) 2071 edev->state = QEDE_STATE_CLOSED;
2189 edev->state = QEDE_STATE_CLOSED;
2190 2072
2191 qede_rdma_dev_event_close(edev); 2073 qede_rdma_dev_event_close(edev);
2192 2074
@@ -2194,21 +2076,18 @@ static void qede_unload(struct qede_dev *edev, enum qede_unload_mode mode,
2194 netif_tx_disable(edev->ndev); 2076 netif_tx_disable(edev->ndev);
2195 netif_carrier_off(edev->ndev); 2077 netif_carrier_off(edev->ndev);
2196 2078
2197 if (mode != QEDE_UNLOAD_RECOVERY) { 2079 /* Reset the link */
2198 /* Reset the link */ 2080 memset(&link_params, 0, sizeof(link_params));
2199 memset(&link_params, 0, sizeof(link_params)); 2081 link_params.link_up = false;
2200 link_params.link_up = false; 2082 edev->ops->common->set_link(edev->cdev, &link_params);
2201 edev->ops->common->set_link(edev->cdev, &link_params); 2083 rc = qede_stop_queues(edev);
2202 2084 if (rc) {
2203 rc = qede_stop_queues(edev); 2085 qede_sync_free_irqs(edev);
2204 if (rc) { 2086 goto out;
2205 qede_sync_free_irqs(edev);
2206 goto out;
2207 }
2208
2209 DP_INFO(edev, "Stopped Queues\n");
2210 } 2087 }
2211 2088
2089 DP_INFO(edev, "Stopped Queues\n");
2090
2212 qede_vlan_mark_nonconfigured(edev); 2091 qede_vlan_mark_nonconfigured(edev);
2213 edev->ops->fastpath_stop(edev->cdev); 2092 edev->ops->fastpath_stop(edev->cdev);
2214 2093
@@ -2223,26 +2102,18 @@ static void qede_unload(struct qede_dev *edev, enum qede_unload_mode mode,
2223 2102
2224 qede_napi_disable_remove(edev); 2103 qede_napi_disable_remove(edev);
2225 2104
2226 if (mode == QEDE_UNLOAD_RECOVERY)
2227 qede_empty_tx_queues(edev);
2228
2229 qede_free_mem_load(edev); 2105 qede_free_mem_load(edev);
2230 qede_free_fp_array(edev); 2106 qede_free_fp_array(edev);
2231 2107
2232out: 2108out:
2233 if (!is_locked) 2109 if (!is_locked)
2234 __qede_unlock(edev); 2110 __qede_unlock(edev);
2235
2236 if (mode != QEDE_UNLOAD_RECOVERY)
2237 DP_NOTICE(edev, "Link is down\n");
2238
2239 DP_INFO(edev, "Ending qede unload\n"); 2111 DP_INFO(edev, "Ending qede unload\n");
2240} 2112}
2241 2113
2242enum qede_load_mode { 2114enum qede_load_mode {
2243 QEDE_LOAD_NORMAL, 2115 QEDE_LOAD_NORMAL,
2244 QEDE_LOAD_RELOAD, 2116 QEDE_LOAD_RELOAD,
2245 QEDE_LOAD_RECOVERY,
2246}; 2117};
2247 2118
2248static int qede_load(struct qede_dev *edev, enum qede_load_mode mode, 2119static int qede_load(struct qede_dev *edev, enum qede_load_mode mode,
@@ -2422,77 +2293,6 @@ static void qede_link_update(void *dev, struct qed_link_output *link)
2422 } 2293 }
2423} 2294}
2424 2295
2425static void qede_schedule_recovery_handler(void *dev)
2426{
2427 struct qede_dev *edev = dev;
2428
2429 if (edev->state == QEDE_STATE_RECOVERY) {
2430 DP_NOTICE(edev,
2431 "Avoid scheduling a recovery handling since already in recovery state\n");
2432 return;
2433 }
2434
2435 set_bit(QEDE_SP_RECOVERY, &edev->sp_flags);
2436 schedule_delayed_work(&edev->sp_task, 0);
2437
2438 DP_INFO(edev, "Scheduled a recovery handler\n");
2439}
2440
2441static void qede_recovery_failed(struct qede_dev *edev)
2442{
2443 netdev_err(edev->ndev, "Recovery handling has failed. Power cycle is needed.\n");
2444
2445 netif_device_detach(edev->ndev);
2446
2447 if (edev->cdev)
2448 edev->ops->common->set_power_state(edev->cdev, PCI_D3hot);
2449}
2450
2451static void qede_recovery_handler(struct qede_dev *edev)
2452{
2453 u32 curr_state = edev->state;
2454 int rc;
2455
2456 DP_NOTICE(edev, "Starting a recovery process\n");
2457
2458 /* No need to acquire first the qede_lock since is done by qede_sp_task
2459 * before calling this function.
2460 */
2461 edev->state = QEDE_STATE_RECOVERY;
2462
2463 edev->ops->common->recovery_prolog(edev->cdev);
2464
2465 if (curr_state == QEDE_STATE_OPEN)
2466 qede_unload(edev, QEDE_UNLOAD_RECOVERY, true);
2467
2468 __qede_remove(edev->pdev, QEDE_REMOVE_RECOVERY);
2469
2470 rc = __qede_probe(edev->pdev, edev->dp_module, edev->dp_level,
2471 IS_VF(edev), QEDE_PROBE_RECOVERY);
2472 if (rc) {
2473 edev->cdev = NULL;
2474 goto err;
2475 }
2476
2477 if (curr_state == QEDE_STATE_OPEN) {
2478 rc = qede_load(edev, QEDE_LOAD_RECOVERY, true);
2479 if (rc)
2480 goto err;
2481
2482 qede_config_rx_mode(edev->ndev);
2483 udp_tunnel_get_rx_info(edev->ndev);
2484 }
2485
2486 edev->state = curr_state;
2487
2488 DP_NOTICE(edev, "Recovery handling is done\n");
2489
2490 return;
2491
2492err:
2493 qede_recovery_failed(edev);
2494}
2495
2496static bool qede_is_txq_full(struct qede_dev *edev, struct qede_tx_queue *txq) 2296static bool qede_is_txq_full(struct qede_dev *edev, struct qede_tx_queue *txq)
2497{ 2297{
2498 struct netdev_queue *netdev_txq; 2298 struct netdev_queue *netdev_txq;
diff --git a/drivers/net/ethernet/qlogic/qede/qede_rdma.c b/drivers/net/ethernet/qlogic/qede/qede_rdma.c
index 9668e5e47d5f..1900bf7e67d1 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_rdma.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_rdma.c
@@ -50,8 +50,6 @@ static void _qede_rdma_dev_add(struct qede_dev *edev)
50 if (!qedr_drv) 50 if (!qedr_drv)
51 return; 51 return;
52 52
53 /* Leftovers from previous error recovery */
54 edev->rdma_info.exp_recovery = false;
55 edev->rdma_info.qedr_dev = qedr_drv->add(edev->cdev, edev->pdev, 53 edev->rdma_info.qedr_dev = qedr_drv->add(edev->cdev, edev->pdev,
56 edev->ndev); 54 edev->ndev);
57} 55}
@@ -89,26 +87,21 @@ static void qede_rdma_destroy_wq(struct qede_dev *edev)
89 destroy_workqueue(edev->rdma_info.rdma_wq); 87 destroy_workqueue(edev->rdma_info.rdma_wq);
90} 88}
91 89
92int qede_rdma_dev_add(struct qede_dev *edev, enum qede_rdma_probe_mode mode) 90int qede_rdma_dev_add(struct qede_dev *edev)
93{ 91{
94 int rc; 92 int rc = 0;
95 93
96 if (!qede_rdma_supported(edev)) 94 if (qede_rdma_supported(edev)) {
97 return 0; 95 rc = qede_rdma_create_wq(edev);
98 96 if (rc)
99 /* Cannot start qedr while recovering since it wasn't fully stopped */ 97 return rc;
100 if (mode == QEDE_RDMA_PROBE_RECOVERY)
101 return 0;
102
103 rc = qede_rdma_create_wq(edev);
104 if (rc)
105 return rc;
106 98
107 INIT_LIST_HEAD(&edev->rdma_info.entry); 99 INIT_LIST_HEAD(&edev->rdma_info.entry);
108 mutex_lock(&qedr_dev_list_lock); 100 mutex_lock(&qedr_dev_list_lock);
109 list_add_tail(&edev->rdma_info.entry, &qedr_dev_list); 101 list_add_tail(&edev->rdma_info.entry, &qedr_dev_list);
110 _qede_rdma_dev_add(edev); 102 _qede_rdma_dev_add(edev);
111 mutex_unlock(&qedr_dev_list_lock); 103 mutex_unlock(&qedr_dev_list_lock);
104 }
112 105
113 return rc; 106 return rc;
114} 107}
@@ -117,31 +110,19 @@ static void _qede_rdma_dev_remove(struct qede_dev *edev)
117{ 110{
118 if (qedr_drv && qedr_drv->remove && edev->rdma_info.qedr_dev) 111 if (qedr_drv && qedr_drv->remove && edev->rdma_info.qedr_dev)
119 qedr_drv->remove(edev->rdma_info.qedr_dev); 112 qedr_drv->remove(edev->rdma_info.qedr_dev);
113 edev->rdma_info.qedr_dev = NULL;
120} 114}
121 115
122void qede_rdma_dev_remove(struct qede_dev *edev, 116void qede_rdma_dev_remove(struct qede_dev *edev)
123 enum qede_rdma_remove_mode mode)
124{ 117{
125 if (!qede_rdma_supported(edev)) 118 if (!qede_rdma_supported(edev))
126 return; 119 return;
127 120
128 /* Cannot remove qedr while recovering since it wasn't fully stopped */ 121 qede_rdma_destroy_wq(edev);
129 if (mode == QEDE_RDMA_REMOVE_NORMAL) { 122 mutex_lock(&qedr_dev_list_lock);
130 qede_rdma_destroy_wq(edev); 123 _qede_rdma_dev_remove(edev);
131 mutex_lock(&qedr_dev_list_lock); 124 list_del(&edev->rdma_info.entry);
132 if (!edev->rdma_info.exp_recovery) 125 mutex_unlock(&qedr_dev_list_lock);
133 _qede_rdma_dev_remove(edev);
134 edev->rdma_info.qedr_dev = NULL;
135 list_del(&edev->rdma_info.entry);
136 mutex_unlock(&qedr_dev_list_lock);
137 } else {
138 if (!edev->rdma_info.exp_recovery) {
139 mutex_lock(&qedr_dev_list_lock);
140 _qede_rdma_dev_remove(edev);
141 mutex_unlock(&qedr_dev_list_lock);
142 }
143 edev->rdma_info.exp_recovery = true;
144 }
145} 126}
146 127
147static void _qede_rdma_dev_open(struct qede_dev *edev) 128static void _qede_rdma_dev_open(struct qede_dev *edev)
@@ -223,8 +204,7 @@ void qede_rdma_unregister_driver(struct qedr_driver *drv)
223 204
224 mutex_lock(&qedr_dev_list_lock); 205 mutex_lock(&qedr_dev_list_lock);
225 list_for_each_entry(edev, &qedr_dev_list, rdma_info.entry) { 206 list_for_each_entry(edev, &qedr_dev_list, rdma_info.entry) {
226 /* If device has experienced recovery it was already removed */ 207 if (edev->rdma_info.qedr_dev)
227 if (edev->rdma_info.qedr_dev && !edev->rdma_info.exp_recovery)
228 _qede_rdma_dev_remove(edev); 208 _qede_rdma_dev_remove(edev);
229 } 209 }
230 qedr_drv = NULL; 210 qedr_drv = NULL;
@@ -304,10 +284,6 @@ static void qede_rdma_add_event(struct qede_dev *edev,
304{ 284{
305 struct qede_rdma_event_work *event_node; 285 struct qede_rdma_event_work *event_node;
306 286
307 /* If a recovery was experienced avoid adding the event */
308 if (edev->rdma_info.exp_recovery)
309 return;
310
311 if (!edev->rdma_info.qedr_dev) 287 if (!edev->rdma_info.qedr_dev)
312 return; 288 return;
313 289