diff options
author | David S. Miller <davem@davemloft.net> | 2019-01-25 18:32:28 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-01-25 18:32:28 -0500 |
commit | abfd04f738c2625f63e04c8fc7cadb3b7a70d580 (patch) | |
tree | 378a84845e9fc1b815c25dfb05680f42a7b96c68 /drivers | |
parent | 517952756ed3027a9b776e331985320a829b9f62 (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.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_dev.c | 158 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_dev_api.h | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_hsi.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_hw.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_int.c | 126 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_int.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_main.c | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_mcp.c | 115 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_mcp.h | 42 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_reg_addr.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_spq.c | 22 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_sriov.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_main.c | 300 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_rdma.c | 64 |
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); | |||
946 | u32 qed_unzip_data(struct qed_hwfn *p_hwfn, | 944 | u32 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); |
949 | void qed_schedule_recovery_handler(struct qed_hwfn *p_hwfn); | ||
950 | void qed_get_protocol_stats(struct qed_dev *cdev, | 947 | void 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 | ||
2005 | int qed_pglueb_set_pfid_enable(struct qed_hwfn *p_hwfn, | 2010 | static 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 | ||
2067 | static 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 | |||
2073 | int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params) | 2074 | int 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, ¶m); | ||
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, ¶m); | 2211 | &load_code, ¶m); |
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 | |||
2282 | load_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 | |||
473 | qed_set_queue_coalesce(u16 rx_coal, u16 tx_coal, void *p_handle); | 473 | qed_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 | */ | ||
484 | int 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 | 258 | static int qed_pglub_rbc_attn_cb(struct qed_hwfn *p_hwfn) | |
259 | int 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 | ||
361 | static 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 | ||
434 | int 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 | ||
2208 | void 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 | |||
2217 | static int qed_set_coalesce(struct qed_dev *cdev, u16 rx_coal, u16 tx_coal, | 2206 | static 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 | ||
2240 | static 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 | |||
2257 | static int qed_update_wol(struct qed_dev *cdev, bool enabled) | 2229 | static 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 | ||
1073 | int 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 | ¶m); | ||
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 | |||
1094 | int qed_mcp_unload_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) | 1073 | int 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 | ||
1552 | u32 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 | |||
1573 | static 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 | |||
1606 | static void qed_mcp_send_protocol_stats(struct qed_hwfn *p_hwfn, | 1531 | static 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 | ||
2384 | int 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 | |||
2402 | int 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 | |||
2421 | static int | 2306 | static int |
2422 | qed_mcp_config_vf_msix_bb(struct qed_hwfn *p_hwfn, | 2307 | qed_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 | */ | ||
451 | u32 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 | */ | ||
462 | int 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 | */ | ||
473 | int 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 | */ | ||
843 | int 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 | ||
793 | static 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 | } |
4496 | out: | 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 | ||
168 | struct qede_ptp; | 167 | struct qede_ptp; |
@@ -265,7 +264,6 @@ struct qede_dev { | |||
265 | enum QEDE_STATE { | 264 | enum 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); | |||
133 | static void qede_remove(struct pci_dev *pdev); | 133 | static void qede_remove(struct pci_dev *pdev); |
134 | static void qede_shutdown(struct pci_dev *pdev); | 134 | static void qede_shutdown(struct pci_dev *pdev); |
135 | static void qede_link_update(void *dev, struct qed_link_output *link); | 135 | static void qede_link_update(void *dev, struct qed_link_output *link); |
136 | static void qede_schedule_recovery_handler(void *dev); | ||
137 | static void qede_recovery_handler(struct qede_dev *edev); | ||
138 | static void qede_get_eth_tlv_data(void *edev, void *data); | 136 | static void qede_get_eth_tlv_data(void *edev, void *data); |
139 | static void qede_get_generic_tlv_data(void *edev, | 137 | static 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 | */ | ||
143 | void __qede_lock(struct qede_dev *edev) | ||
144 | { | ||
145 | mutex_lock(&edev->qede_lock); | ||
146 | } | ||
147 | |||
148 | void __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 |
143 | static int qede_set_vf_vlan(struct net_device *ndev, int vf, u16 vlan, u8 qos, | 154 | static 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 | */ | ||
946 | void __qede_lock(struct qede_dev *edev) | ||
947 | { | ||
948 | mutex_lock(&edev->qede_lock); | ||
949 | } | ||
950 | |||
951 | void __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 | */ | ||
959 | void qede_lock(struct qede_dev *edev) | ||
960 | { | ||
961 | rtnl_lock(); | ||
962 | __qede_lock(edev); | ||
963 | } | ||
964 | |||
965 | void qede_unlock(struct qede_dev *edev) | ||
966 | { | ||
967 | __qede_unlock(edev); | ||
968 | rtnl_unlock(); | ||
969 | } | ||
970 | |||
971 | static void qede_sp_task(struct work_struct *work) | 953 | static 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 | ||
1068 | enum qede_probe_mode { | 1032 | enum 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 | |||
1077 | static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level, | 1036 | static 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 | ||
1182 | err4: | 1128 | err4: |
1183 | qede_rdma_dev_remove(edev, QEDE_RDMA_PROBE_MODE(mode)); | 1129 | qede_rdma_dev_remove(edev); |
1184 | err3: | 1130 | err3: |
1185 | free_netdev(edev->ndev); | 1131 | free_netdev(edev->ndev); |
1186 | err2: | 1132 | err2: |
@@ -1216,13 +1162,8 @@ static int qede_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1216 | 1162 | ||
1217 | enum qede_remove_mode { | 1163 | enum 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 | |||
1226 | static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode) | 1167 | static 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 | ||
1606 | static 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 | |||
1640 | static 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 */ |
1659 | static void qede_init_fp(struct qede_dev *edev) | 1543 | static void qede_init_fp(struct qede_dev *edev) |
1660 | { | 1544 | { |
@@ -2169,7 +2053,6 @@ out: | |||
2169 | 2053 | ||
2170 | enum qede_unload_mode { | 2054 | enum qede_unload_mode { |
2171 | QEDE_UNLOAD_NORMAL, | 2055 | QEDE_UNLOAD_NORMAL, |
2172 | QEDE_UNLOAD_RECOVERY, | ||
2173 | }; | 2056 | }; |
2174 | 2057 | ||
2175 | static void qede_unload(struct qede_dev *edev, enum qede_unload_mode mode, | 2058 | static 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 | ||
2232 | out: | 2108 | out: |
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 | ||
2242 | enum qede_load_mode { | 2114 | enum 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 | ||
2248 | static int qede_load(struct qede_dev *edev, enum qede_load_mode mode, | 2119 | static 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 | ||
2425 | static 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 | |||
2441 | static 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 | |||
2451 | static 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 | |||
2492 | err: | ||
2493 | qede_recovery_failed(edev); | ||
2494 | } | ||
2495 | |||
2496 | static bool qede_is_txq_full(struct qede_dev *edev, struct qede_tx_queue *txq) | 2296 | static 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 | ||
92 | int qede_rdma_dev_add(struct qede_dev *edev, enum qede_rdma_probe_mode mode) | 90 | int 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 | ||
122 | void qede_rdma_dev_remove(struct qede_dev *edev, | 116 | void 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 | ||
147 | static void _qede_rdma_dev_open(struct qede_dev *edev) | 128 | static 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 | ||