Loading drivers/platform/msm/ipa/ipa_v2/ipa.c +113 −48 Original line number Diff line number Diff line Loading @@ -1329,14 +1329,24 @@ static void ipa_free_buffer(void *user1, int user2) kfree(user1); } static int ipa_q6_pipe_delay(void) static int ipa_q6_pipe_delay(bool zip_pipes) { u32 reg_val = 0; int client_idx; int ep_idx; /* For ZIP pipes, processing is done in AFTER_SHUTDOWN callback. */ for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) { if (IPA_CLIENT_IS_Q6_PROD(client_idx)) { /* Skip the processing for non Q6 pipes. */ if (!IPA_CLIENT_IS_Q6_PROD(client_idx)) continue; /* Skip the processing for NON-ZIP pipes. */ else if (zip_pipes && IPA_CLIENT_IS_Q6_NON_ZIP_PROD(client_idx)) continue; /* Skip the processing for ZIP pipes. */ else if (!zip_pipes && IPA_CLIENT_IS_Q6_ZIP_PROD(client_idx)) continue; ep_idx = ipa2_get_ep_mapping(client_idx); if (ep_idx == -1) continue; Loading @@ -1348,12 +1358,31 @@ static int ipa_q6_pipe_delay(void) ipa_write_reg(ipa_ctx->mmio, IPA_ENDP_INIT_CTRL_N_OFST(ep_idx), reg_val); } return 0; } int ipa_q6_monitor_holb_mitigation(bool enable) { int ep_idx; int client_idx; for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) { if (IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client_idx)) { ep_idx = ipa2_get_ep_mapping(client_idx); if (ep_idx == -1) continue; /* Send a command to Uc to enable/disable * holb monitoring. */ ipa_uc_monitor_holb(client_idx, enable); } } return 0; } static int ipa_q6_avoid_holb(void) static int ipa_q6_avoid_holb(bool zip_pipes) { u32 reg_val; int ep_idx; Loading @@ -1363,8 +1392,18 @@ static int ipa_q6_avoid_holb(void) memset(&avoid_holb, 0, sizeof(avoid_holb)); avoid_holb.ipa_ep_suspend = true; /* For ZIP pipes, processing is done in AFTER_SHUTDOWN callback. */ for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) { if (IPA_CLIENT_IS_Q6_CONS(client_idx)) { /* Skip the processing for non Q6 pipes. */ if (!IPA_CLIENT_IS_Q6_CONS(client_idx)) continue; /* Skip the processing for NON-ZIP pipes. */ else if (zip_pipes && IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client_idx)) continue; /* Skip the processing for ZIP pipes. */ else if (!zip_pipes && IPA_CLIENT_IS_Q6_ZIP_CONS(client_idx)) continue; ep_idx = ipa2_get_ep_mapping(client_idx); if (ep_idx == -1) continue; Loading Loading @@ -1395,7 +1434,6 @@ static int ipa_q6_avoid_holb(void) ipa2_cfg_ep_ctrl(ep_idx, &avoid_holb); } } return 0; } Loading Loading @@ -1615,7 +1653,8 @@ static int ipa_q6_set_ex_path_dis_agg(void) /* Disable AGGR on IPA->Q6 pipes */ for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) { if (IPA_CLIENT_IS_Q6_CONS(client_idx)) { if (IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client_idx) || IPA_CLIENT_IS_Q6_ZIP_CONS(client_idx)) { reg_write = kzalloc(sizeof(*reg_write), GFP_KERNEL); if (!reg_write) { Loading Loading @@ -1655,15 +1694,16 @@ static int ipa_q6_set_ex_path_dis_agg(void) } /** * ipa_q6_cleanup() - A cleanup for all Q6 related configuration * in IPA HW. This is performed in case of SSR. * ipa_q6_pre_shutdown_cleanup() - A cleanup for all Q6 related configuration * in IPA HW before modem shutdown. This is performed in * case of SSR. * * Return codes: * 0: success * This is a mandatory procedure, in case one of the steps fails, the * AP needs to restart. */ int ipa_q6_cleanup(void) int ipa_q6_pre_shutdown_cleanup(void) { /* If uC has notified the APPS upon a ZIP engine error, * APPS need to assert (This is a non recoverable error). Loading @@ -1672,12 +1712,21 @@ int ipa_q6_cleanup(void) BUG(); ipa_inc_client_enable_clks(); if (ipa_q6_pipe_delay()) { /* * pipe delay and holb discard for ZIP pipes are handled * in post shutdown callback. */ if (ipa_q6_pipe_delay(false)) { IPAERR("Failed to delay Q6 pipes\n"); BUG(); } if (ipa_q6_avoid_holb()) { if (ipa_q6_monitor_holb_mitigation(false)) { IPAERR("Failed to disable HOLB monitroing on Q6 pipes\n"); BUG(); } if (ipa_q6_avoid_holb(false)) { IPAERR("Failed to set HOLB on Q6 pipes\n"); BUG(); } Loading @@ -1695,27 +1744,43 @@ int ipa_q6_cleanup(void) } /** * ipa_q6_pipe_reset() - A cleanup for the Q6 pipes * in IPA HW. This is performed in case of SSR. * ipa_q6_post_shutdown_cleanup() - A cleanup for the Q6 pipes * in IPA HW after modem shutdown. This is performed * in case of SSR. * * Return codes: * 0: success * This is a mandatory procedure, in case one of the steps fails, the * AP needs to restart. */ int ipa_q6_pipe_reset(void) int ipa_q6_post_shutdown_cleanup(void) { int client_idx; int res; /* * pipe delay and holb discard for ZIP pipes are handled in * post shutdown. */ if (ipa_q6_pipe_delay(true)) { IPAERR("Failed to delay Q6 ZIP pipes\n"); BUG(); } if (ipa_q6_avoid_holb(true)) { IPAERR("Failed to set HOLB on Q6 ZIP pipes\n"); BUG(); } if (!ipa_ctx->uc_ctx.uc_loaded) { IPAERR("uC is not loaded, won't reset Q6 pipes\n"); return 0; } for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) if (IPA_CLIENT_IS_Q6_CONS(client_idx) || IPA_CLIENT_IS_Q6_PROD(client_idx)) { if (IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client_idx) || IPA_CLIENT_IS_Q6_ZIP_CONS(client_idx) || IPA_CLIENT_IS_Q6_NON_ZIP_PROD(client_idx) || IPA_CLIENT_IS_Q6_ZIP_PROD(client_idx)) { res = ipa_uc_reset_pipe(client_idx); if (res) BUG(); Loading drivers/platform/msm/ipa/ipa_v2/ipa_i.h +3 −2 Original line number Diff line number Diff line Loading @@ -1940,9 +1940,10 @@ int ipa_write_qmapid_wdi_pipe(u32 clnt_hdl, u8 qmap_id); int ipa_tag_process(struct ipa_desc *desc, int num_descs, unsigned long timeout); int ipa_q6_cleanup(void); int ipa_q6_pipe_reset(void); int ipa_q6_pre_shutdown_cleanup(void); int ipa_q6_post_shutdown_cleanup(void); int ipa_init_q6_smem(void); int ipa_q6_monitor_holb_mitigation(bool enable); int ipa_sps_connect_safe(struct sps_pipe *h, struct sps_connect *connect, enum ipa_client_type ipa_client); Loading drivers/platform/msm/ipa/ipa_v2/ipa_uc.c +1 −10 Original line number Diff line number Diff line Loading @@ -751,7 +751,6 @@ int ipa_uc_monitor_holb(enum ipa_client_type ipa_client, bool enable) union IpaHwmonitorHolbCmdData_t cmd; int ep_idx; int ret; struct ipa_ep_context *ep; /* HOLB monitoring is applicable only to 2.6L. */ if (ipa_ctx->ipa_hw_type != IPA_HW_v2_6L) { Loading @@ -765,14 +764,6 @@ int ipa_uc_monitor_holb(enum ipa_client_type ipa_client, bool enable) return 0; } ep = &ipa_ctx->ep[ep_idx]; if (!ep->valid) { IPAERR("EP not valid.\n"); return 0; } /* * If the uC interface has not been initialized yet, * continue with the sequence without resetting the Loading @@ -794,7 +785,7 @@ int ipa_uc_monitor_holb(enum ipa_client_type ipa_client, bool enable) cmd.params.monitorPipe = (u8)(enable ? 1 : 0); cmd.params.pipeNum = (u8)ep_idx; IPADBG("uC holb monitoring on IPA pipe %d\n, Enable: %d", IPADBG("uC holb monitoring on IPA pipe %d, Enable: %d\n", ep_idx, enable); ret = ipa_uc_send_cmd(cmd.raw32b, Loading drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c +5 −2 Original line number Diff line number Diff line Loading @@ -2179,7 +2179,7 @@ static int ssr_notifier_cb(struct notifier_block *this, if (SUBSYS_BEFORE_SHUTDOWN == code) { pr_info("IPA received MPSS BEFORE_SHUTDOWN\n"); atomic_set(&is_ssr, 1); ipa_q6_cleanup(); ipa_q6_pre_shutdown_cleanup(); if (ipa_netdevs[0]) netif_stop_queue(ipa_netdevs[0]); ipa_qmi_stop_workqueues(); Loading @@ -2193,7 +2193,7 @@ static int ssr_notifier_cb(struct notifier_block *this, if (SUBSYS_AFTER_SHUTDOWN == code) { pr_info("IPA received MPSS AFTER_SHUTDOWN\n"); if (atomic_read(&is_ssr)) ipa_q6_pipe_reset(); ipa_q6_post_shutdown_cleanup(); pr_info("IPA AFTER_SHUTDOWN handling is complete\n"); return NOTIFY_DONE; } Loading Loading @@ -2689,6 +2689,9 @@ void ipa_q6_handshake_complete(bool ssr_bootup) * SSR recovery */ rmnet_ipa_get_network_stats_and_update(); /* Enable holb monitoring on Q6 pipes. */ ipa_q6_monitor_holb_mitigation(true); } } Loading include/uapi/linux/msm_ipa.h +19 −0 Original line number Diff line number Diff line Loading @@ -239,6 +239,25 @@ enum ipa_client_type { (client) == IPA_CLIENT_Q6_DECOMP_PROD || \ (client) == IPA_CLIENT_Q6_DECOMP2_PROD) #define IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client) \ ((client) == IPA_CLIENT_Q6_LAN_CONS || \ (client) == IPA_CLIENT_Q6_WAN_CONS || \ (client) == IPA_CLIENT_Q6_DUN_CONS || \ (client) == IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS) #define IPA_CLIENT_IS_Q6_ZIP_CONS(client) \ ((client) == IPA_CLIENT_Q6_DECOMP_CONS || \ (client) == IPA_CLIENT_Q6_DECOMP2_CONS) #define IPA_CLIENT_IS_Q6_NON_ZIP_PROD(client) \ ((client) == IPA_CLIENT_Q6_LAN_PROD || \ (client) == IPA_CLIENT_Q6_WAN_PROD || \ (client) == IPA_CLIENT_Q6_CMD_PROD) #define IPA_CLIENT_IS_Q6_ZIP_PROD(client) \ ((client) == IPA_CLIENT_Q6_DECOMP_PROD || \ (client) == IPA_CLIENT_Q6_DECOMP2_PROD) #define IPA_CLIENT_IS_MEMCPY_DMA_CONS(client) \ ((client) == IPA_CLIENT_MEMCPY_DMA_SYNC_CONS || \ (client) == IPA_CLIENT_MEMCPY_DMA_ASYNC_CONS) Loading Loading
drivers/platform/msm/ipa/ipa_v2/ipa.c +113 −48 Original line number Diff line number Diff line Loading @@ -1329,14 +1329,24 @@ static void ipa_free_buffer(void *user1, int user2) kfree(user1); } static int ipa_q6_pipe_delay(void) static int ipa_q6_pipe_delay(bool zip_pipes) { u32 reg_val = 0; int client_idx; int ep_idx; /* For ZIP pipes, processing is done in AFTER_SHUTDOWN callback. */ for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) { if (IPA_CLIENT_IS_Q6_PROD(client_idx)) { /* Skip the processing for non Q6 pipes. */ if (!IPA_CLIENT_IS_Q6_PROD(client_idx)) continue; /* Skip the processing for NON-ZIP pipes. */ else if (zip_pipes && IPA_CLIENT_IS_Q6_NON_ZIP_PROD(client_idx)) continue; /* Skip the processing for ZIP pipes. */ else if (!zip_pipes && IPA_CLIENT_IS_Q6_ZIP_PROD(client_idx)) continue; ep_idx = ipa2_get_ep_mapping(client_idx); if (ep_idx == -1) continue; Loading @@ -1348,12 +1358,31 @@ static int ipa_q6_pipe_delay(void) ipa_write_reg(ipa_ctx->mmio, IPA_ENDP_INIT_CTRL_N_OFST(ep_idx), reg_val); } return 0; } int ipa_q6_monitor_holb_mitigation(bool enable) { int ep_idx; int client_idx; for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) { if (IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client_idx)) { ep_idx = ipa2_get_ep_mapping(client_idx); if (ep_idx == -1) continue; /* Send a command to Uc to enable/disable * holb monitoring. */ ipa_uc_monitor_holb(client_idx, enable); } } return 0; } static int ipa_q6_avoid_holb(void) static int ipa_q6_avoid_holb(bool zip_pipes) { u32 reg_val; int ep_idx; Loading @@ -1363,8 +1392,18 @@ static int ipa_q6_avoid_holb(void) memset(&avoid_holb, 0, sizeof(avoid_holb)); avoid_holb.ipa_ep_suspend = true; /* For ZIP pipes, processing is done in AFTER_SHUTDOWN callback. */ for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) { if (IPA_CLIENT_IS_Q6_CONS(client_idx)) { /* Skip the processing for non Q6 pipes. */ if (!IPA_CLIENT_IS_Q6_CONS(client_idx)) continue; /* Skip the processing for NON-ZIP pipes. */ else if (zip_pipes && IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client_idx)) continue; /* Skip the processing for ZIP pipes. */ else if (!zip_pipes && IPA_CLIENT_IS_Q6_ZIP_CONS(client_idx)) continue; ep_idx = ipa2_get_ep_mapping(client_idx); if (ep_idx == -1) continue; Loading Loading @@ -1395,7 +1434,6 @@ static int ipa_q6_avoid_holb(void) ipa2_cfg_ep_ctrl(ep_idx, &avoid_holb); } } return 0; } Loading Loading @@ -1615,7 +1653,8 @@ static int ipa_q6_set_ex_path_dis_agg(void) /* Disable AGGR on IPA->Q6 pipes */ for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) { if (IPA_CLIENT_IS_Q6_CONS(client_idx)) { if (IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client_idx) || IPA_CLIENT_IS_Q6_ZIP_CONS(client_idx)) { reg_write = kzalloc(sizeof(*reg_write), GFP_KERNEL); if (!reg_write) { Loading Loading @@ -1655,15 +1694,16 @@ static int ipa_q6_set_ex_path_dis_agg(void) } /** * ipa_q6_cleanup() - A cleanup for all Q6 related configuration * in IPA HW. This is performed in case of SSR. * ipa_q6_pre_shutdown_cleanup() - A cleanup for all Q6 related configuration * in IPA HW before modem shutdown. This is performed in * case of SSR. * * Return codes: * 0: success * This is a mandatory procedure, in case one of the steps fails, the * AP needs to restart. */ int ipa_q6_cleanup(void) int ipa_q6_pre_shutdown_cleanup(void) { /* If uC has notified the APPS upon a ZIP engine error, * APPS need to assert (This is a non recoverable error). Loading @@ -1672,12 +1712,21 @@ int ipa_q6_cleanup(void) BUG(); ipa_inc_client_enable_clks(); if (ipa_q6_pipe_delay()) { /* * pipe delay and holb discard for ZIP pipes are handled * in post shutdown callback. */ if (ipa_q6_pipe_delay(false)) { IPAERR("Failed to delay Q6 pipes\n"); BUG(); } if (ipa_q6_avoid_holb()) { if (ipa_q6_monitor_holb_mitigation(false)) { IPAERR("Failed to disable HOLB monitroing on Q6 pipes\n"); BUG(); } if (ipa_q6_avoid_holb(false)) { IPAERR("Failed to set HOLB on Q6 pipes\n"); BUG(); } Loading @@ -1695,27 +1744,43 @@ int ipa_q6_cleanup(void) } /** * ipa_q6_pipe_reset() - A cleanup for the Q6 pipes * in IPA HW. This is performed in case of SSR. * ipa_q6_post_shutdown_cleanup() - A cleanup for the Q6 pipes * in IPA HW after modem shutdown. This is performed * in case of SSR. * * Return codes: * 0: success * This is a mandatory procedure, in case one of the steps fails, the * AP needs to restart. */ int ipa_q6_pipe_reset(void) int ipa_q6_post_shutdown_cleanup(void) { int client_idx; int res; /* * pipe delay and holb discard for ZIP pipes are handled in * post shutdown. */ if (ipa_q6_pipe_delay(true)) { IPAERR("Failed to delay Q6 ZIP pipes\n"); BUG(); } if (ipa_q6_avoid_holb(true)) { IPAERR("Failed to set HOLB on Q6 ZIP pipes\n"); BUG(); } if (!ipa_ctx->uc_ctx.uc_loaded) { IPAERR("uC is not loaded, won't reset Q6 pipes\n"); return 0; } for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) if (IPA_CLIENT_IS_Q6_CONS(client_idx) || IPA_CLIENT_IS_Q6_PROD(client_idx)) { if (IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client_idx) || IPA_CLIENT_IS_Q6_ZIP_CONS(client_idx) || IPA_CLIENT_IS_Q6_NON_ZIP_PROD(client_idx) || IPA_CLIENT_IS_Q6_ZIP_PROD(client_idx)) { res = ipa_uc_reset_pipe(client_idx); if (res) BUG(); Loading
drivers/platform/msm/ipa/ipa_v2/ipa_i.h +3 −2 Original line number Diff line number Diff line Loading @@ -1940,9 +1940,10 @@ int ipa_write_qmapid_wdi_pipe(u32 clnt_hdl, u8 qmap_id); int ipa_tag_process(struct ipa_desc *desc, int num_descs, unsigned long timeout); int ipa_q6_cleanup(void); int ipa_q6_pipe_reset(void); int ipa_q6_pre_shutdown_cleanup(void); int ipa_q6_post_shutdown_cleanup(void); int ipa_init_q6_smem(void); int ipa_q6_monitor_holb_mitigation(bool enable); int ipa_sps_connect_safe(struct sps_pipe *h, struct sps_connect *connect, enum ipa_client_type ipa_client); Loading
drivers/platform/msm/ipa/ipa_v2/ipa_uc.c +1 −10 Original line number Diff line number Diff line Loading @@ -751,7 +751,6 @@ int ipa_uc_monitor_holb(enum ipa_client_type ipa_client, bool enable) union IpaHwmonitorHolbCmdData_t cmd; int ep_idx; int ret; struct ipa_ep_context *ep; /* HOLB monitoring is applicable only to 2.6L. */ if (ipa_ctx->ipa_hw_type != IPA_HW_v2_6L) { Loading @@ -765,14 +764,6 @@ int ipa_uc_monitor_holb(enum ipa_client_type ipa_client, bool enable) return 0; } ep = &ipa_ctx->ep[ep_idx]; if (!ep->valid) { IPAERR("EP not valid.\n"); return 0; } /* * If the uC interface has not been initialized yet, * continue with the sequence without resetting the Loading @@ -794,7 +785,7 @@ int ipa_uc_monitor_holb(enum ipa_client_type ipa_client, bool enable) cmd.params.monitorPipe = (u8)(enable ? 1 : 0); cmd.params.pipeNum = (u8)ep_idx; IPADBG("uC holb monitoring on IPA pipe %d\n, Enable: %d", IPADBG("uC holb monitoring on IPA pipe %d, Enable: %d\n", ep_idx, enable); ret = ipa_uc_send_cmd(cmd.raw32b, Loading
drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c +5 −2 Original line number Diff line number Diff line Loading @@ -2179,7 +2179,7 @@ static int ssr_notifier_cb(struct notifier_block *this, if (SUBSYS_BEFORE_SHUTDOWN == code) { pr_info("IPA received MPSS BEFORE_SHUTDOWN\n"); atomic_set(&is_ssr, 1); ipa_q6_cleanup(); ipa_q6_pre_shutdown_cleanup(); if (ipa_netdevs[0]) netif_stop_queue(ipa_netdevs[0]); ipa_qmi_stop_workqueues(); Loading @@ -2193,7 +2193,7 @@ static int ssr_notifier_cb(struct notifier_block *this, if (SUBSYS_AFTER_SHUTDOWN == code) { pr_info("IPA received MPSS AFTER_SHUTDOWN\n"); if (atomic_read(&is_ssr)) ipa_q6_pipe_reset(); ipa_q6_post_shutdown_cleanup(); pr_info("IPA AFTER_SHUTDOWN handling is complete\n"); return NOTIFY_DONE; } Loading Loading @@ -2689,6 +2689,9 @@ void ipa_q6_handshake_complete(bool ssr_bootup) * SSR recovery */ rmnet_ipa_get_network_stats_and_update(); /* Enable holb monitoring on Q6 pipes. */ ipa_q6_monitor_holb_mitigation(true); } } Loading
include/uapi/linux/msm_ipa.h +19 −0 Original line number Diff line number Diff line Loading @@ -239,6 +239,25 @@ enum ipa_client_type { (client) == IPA_CLIENT_Q6_DECOMP_PROD || \ (client) == IPA_CLIENT_Q6_DECOMP2_PROD) #define IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client) \ ((client) == IPA_CLIENT_Q6_LAN_CONS || \ (client) == IPA_CLIENT_Q6_WAN_CONS || \ (client) == IPA_CLIENT_Q6_DUN_CONS || \ (client) == IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS) #define IPA_CLIENT_IS_Q6_ZIP_CONS(client) \ ((client) == IPA_CLIENT_Q6_DECOMP_CONS || \ (client) == IPA_CLIENT_Q6_DECOMP2_CONS) #define IPA_CLIENT_IS_Q6_NON_ZIP_PROD(client) \ ((client) == IPA_CLIENT_Q6_LAN_PROD || \ (client) == IPA_CLIENT_Q6_WAN_PROD || \ (client) == IPA_CLIENT_Q6_CMD_PROD) #define IPA_CLIENT_IS_Q6_ZIP_PROD(client) \ ((client) == IPA_CLIENT_Q6_DECOMP_PROD || \ (client) == IPA_CLIENT_Q6_DECOMP2_PROD) #define IPA_CLIENT_IS_MEMCPY_DMA_CONS(client) \ ((client) == IPA_CLIENT_MEMCPY_DMA_SYNC_CONS || \ (client) == IPA_CLIENT_MEMCPY_DMA_ASYNC_CONS) Loading