Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +2 −0 Original line number Diff line number Diff line Loading @@ -2485,6 +2485,8 @@ int ipa_create_gsi_smmu_mapping(int res_idx, bool wlan_smmu_en, phys_addr_t pa, struct sg_table *sgt, size_t len, bool device, unsigned long *iova); void ipa3_release_wdi3_gsi_smmu_mappings(u8 dir); /* * Tethering bridge (Rmnet / MBIM) */ Loading drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c +30 −0 Original line number Diff line number Diff line Loading @@ -869,6 +869,36 @@ int ipa_create_uc_smmu_mapping(int res_idx, bool wlan_smmu_en, return 0; } void ipa3_release_wdi3_gsi_smmu_mappings(u8 dir) { struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP); int i, j, start, end; if (dir == IPA_WDI3_TX_DIR) { start = IPA_WDI_TX_RING_RES; end = IPA_WDI_TX_DB_RES; } else { start = IPA_WDI_RX_RING_RES; end = IPA_WDI_RX_COMP_RING_WP_RES; } for (i = start; i <= end; i++) { if (wdi_res[i].valid) { for (j = 0; j < wdi_res[i].nents; j++) { iommu_unmap(cb->mapping->domain, wdi_res[i].res[j].iova, wdi_res[i].res[j].size); ipa3_ctx->wdi_map_cnt--; } kfree(wdi_res[i].res); wdi_res[i].valid = false; } } if (ipa3_ctx->wdi_map_cnt == 0) cb->next_addr = cb->va_end; } int ipa_create_gsi_smmu_mapping(int res_idx, bool wlan_smmu_en, phys_addr_t pa, struct sg_table *sgt, size_t len, bool device, unsigned long *iova) Loading drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c +30 −28 Original line number Diff line number Diff line Loading @@ -12,9 +12,6 @@ #include "ipa_i.h" #include <linux/ipa_wdi3.h> #define IPA_WDI3_TX_DIR 1 #define IPA_WDI3_RX_DIR 2 #define UPDATE_RP_MODERATION_CONFIG 1 #define UPDATE_RP_MODERATION_THRESHOLD 8 Loading Loading @@ -135,8 +132,8 @@ static int ipa3_setup_wdi3_gsi_channel(u8 is_smmu_enabled, &ep->gsi_evt_ring_hdl); if (result != GSI_STATUS_SUCCESS) { IPAERR("fail to alloc RX event ring\n"); /* TODO: release the gsi_smmu_mapping here if smmu enabled */ return -EFAULT; result = -EFAULT; goto fail_smmu_mapping; } ep->gsi_mem_info.evt_ring_len = gsi_evt_ring_props.ring_len; Loading Loading @@ -204,7 +201,6 @@ static int ipa3_setup_wdi3_gsi_channel(u8 is_smmu_enabled, result = gsi_alloc_channel(&gsi_channel_props, ipa3_ctx->gsi_dev_hdl, &ep->gsi_chan_hdl); if (result != GSI_STATUS_SUCCESS) { /* TODO: release the gsi_smmu_mapping here if smmu enabled */ goto fail_get_gsi_ep_info; } Loading Loading @@ -371,10 +367,6 @@ static int ipa3_setup_wdi3_gsi_channel(u8 is_smmu_enabled, result = -EFAULT; goto fail_write_scratch; } /* * TODO: for all access over PCIe for MDM, * there is no SMMU */ ch_scratch.wdi3.wifi_rp_address_low = (u32)va; ch_scratch.wdi3.wifi_rp_address_high = (u32)((u64)va >> 32); Loading Loading @@ -436,6 +428,8 @@ static int ipa3_setup_wdi3_gsi_channel(u8 is_smmu_enabled, fail_get_gsi_ep_info: gsi_dealloc_evt_ring(ep->gsi_evt_ring_hdl); ep->gsi_evt_ring_hdl = ~0; fail_smmu_mapping: ipa3_release_wdi3_gsi_smmu_mappings(dir); return result; } Loading Loading @@ -666,21 +660,22 @@ int ipa3_disconn_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) ep_tx = &ipa3_ctx->ep[ipa_ep_idx_tx]; ep_rx = &ipa3_ctx->ep[ipa_ep_idx_rx]; IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(ipa_ep_idx_tx)); /* tear down tx pipe */ result = ipa3_reset_gsi_channel(ipa_ep_idx_tx); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to reset gsi channel: %d.\n", result); return result; goto exit; } result = gsi_reset_evt_ring(ep_tx->gsi_evt_ring_hdl); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to reset evt ring: %d.\n", result); return result; goto exit; } result = ipa3_release_gsi_channel(ipa_ep_idx_tx); if (result) { IPAERR("failed to release gsi channel: %d\n", result); return result; goto exit; } memset(ep_tx, 0, sizeof(struct ipa3_ep_context)); Loading @@ -690,23 +685,25 @@ int ipa3_disconn_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) result = ipa3_reset_gsi_channel(ipa_ep_idx_rx); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to reset gsi channel: %d.\n", result); return result; goto exit; } result = gsi_reset_evt_ring(ep_rx->gsi_evt_ring_hdl); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to reset evt ring: %d.\n", result); return result; goto exit; } result = ipa3_release_gsi_channel(ipa_ep_idx_rx); if (result) { IPAERR("failed to release gsi channel: %d\n", result); return result; goto exit; } ipa3_delete_dflt_flt_rules(ipa_ep_idx_rx); memset(ep_rx, 0, sizeof(struct ipa3_ep_context)); IPADBG("rx client (ep: %d) disconnected\n", ipa_ep_idx_rx); exit: IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_by_pipe(ipa_ep_idx_tx)); return result; } Loading @@ -728,20 +725,23 @@ int ipa3_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) ep_tx = &ipa3_ctx->ep[ipa_ep_idx_tx]; ep_rx = &ipa3_ctx->ep[ipa_ep_idx_rx]; IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(ipa_ep_idx_tx)); /* start gsi tx channel */ result = gsi_start_channel(ep_tx->gsi_chan_hdl); if (result) { IPAERR("failed to start gsi tx channel\n"); return -EFAULT; result = -EFAULT; goto exit; } /* start gsi rx channel */ result = gsi_start_channel(ep_rx->gsi_chan_hdl); if (result) { IPAERR("failed to start gsi rx channel\n"); return -EFAULT; result = -EFAULT; goto exit; } IPA_ACTIVE_CLIENTS_INC_SIMPLE(); /* enable data path */ result = ipa3_enable_data_path(ipa_ep_idx_rx); Loading @@ -749,7 +749,7 @@ int ipa3_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) IPAERR("enable data path failed res=%d clnt=%d.\n", result, ipa_ep_idx_rx); result = -EFAULT; goto fail; goto exit; } result = ipa3_enable_data_path(ipa_ep_idx_tx); Loading @@ -757,11 +757,11 @@ int ipa3_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) IPAERR("enable data path failed res=%d clnt=%d.\n", result, ipa_ep_idx_tx); result = -EFAULT; goto fail; goto exit; } fail: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); exit: IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(ipa_ep_idx_tx)); return result; } Loading Loading @@ -865,13 +865,13 @@ int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id) if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to read channel scratch %d\n", result); return result; goto exit; } result = gsi_stop_channel(ep->gsi_chan_hdl); if (result != GSI_STATUS_SUCCESS && result != -GSI_STATUS_AGAIN && result != -GSI_STATUS_TIMED_OUT) { IPAERR("failed to stop gsi channel %d\n", result); return result; goto exit; } ch_scratch.wdi3.qmap_id = qmap_id; Loading @@ -879,14 +879,16 @@ int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id) ch_scratch); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to write channel scratch %d\n", result); return result; goto exit; } result = gsi_start_channel(ep->gsi_chan_hdl); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to start gsi channel %d\n", result); return result; goto exit; } return 0; exit: IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl)); return result; } include/linux/ipa_wdi3.h +3 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ enum ipa_wdi_version { IPA_WDI_3 }; #define IPA_WDI3_TX_DIR 1 #define IPA_WDI3_RX_DIR 2 /** * struct ipa_wdi_init_in_params - wdi init input parameters * Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +2 −0 Original line number Diff line number Diff line Loading @@ -2485,6 +2485,8 @@ int ipa_create_gsi_smmu_mapping(int res_idx, bool wlan_smmu_en, phys_addr_t pa, struct sg_table *sgt, size_t len, bool device, unsigned long *iova); void ipa3_release_wdi3_gsi_smmu_mappings(u8 dir); /* * Tethering bridge (Rmnet / MBIM) */ Loading
drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c +30 −0 Original line number Diff line number Diff line Loading @@ -869,6 +869,36 @@ int ipa_create_uc_smmu_mapping(int res_idx, bool wlan_smmu_en, return 0; } void ipa3_release_wdi3_gsi_smmu_mappings(u8 dir) { struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP); int i, j, start, end; if (dir == IPA_WDI3_TX_DIR) { start = IPA_WDI_TX_RING_RES; end = IPA_WDI_TX_DB_RES; } else { start = IPA_WDI_RX_RING_RES; end = IPA_WDI_RX_COMP_RING_WP_RES; } for (i = start; i <= end; i++) { if (wdi_res[i].valid) { for (j = 0; j < wdi_res[i].nents; j++) { iommu_unmap(cb->mapping->domain, wdi_res[i].res[j].iova, wdi_res[i].res[j].size); ipa3_ctx->wdi_map_cnt--; } kfree(wdi_res[i].res); wdi_res[i].valid = false; } } if (ipa3_ctx->wdi_map_cnt == 0) cb->next_addr = cb->va_end; } int ipa_create_gsi_smmu_mapping(int res_idx, bool wlan_smmu_en, phys_addr_t pa, struct sg_table *sgt, size_t len, bool device, unsigned long *iova) Loading
drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c +30 −28 Original line number Diff line number Diff line Loading @@ -12,9 +12,6 @@ #include "ipa_i.h" #include <linux/ipa_wdi3.h> #define IPA_WDI3_TX_DIR 1 #define IPA_WDI3_RX_DIR 2 #define UPDATE_RP_MODERATION_CONFIG 1 #define UPDATE_RP_MODERATION_THRESHOLD 8 Loading Loading @@ -135,8 +132,8 @@ static int ipa3_setup_wdi3_gsi_channel(u8 is_smmu_enabled, &ep->gsi_evt_ring_hdl); if (result != GSI_STATUS_SUCCESS) { IPAERR("fail to alloc RX event ring\n"); /* TODO: release the gsi_smmu_mapping here if smmu enabled */ return -EFAULT; result = -EFAULT; goto fail_smmu_mapping; } ep->gsi_mem_info.evt_ring_len = gsi_evt_ring_props.ring_len; Loading Loading @@ -204,7 +201,6 @@ static int ipa3_setup_wdi3_gsi_channel(u8 is_smmu_enabled, result = gsi_alloc_channel(&gsi_channel_props, ipa3_ctx->gsi_dev_hdl, &ep->gsi_chan_hdl); if (result != GSI_STATUS_SUCCESS) { /* TODO: release the gsi_smmu_mapping here if smmu enabled */ goto fail_get_gsi_ep_info; } Loading Loading @@ -371,10 +367,6 @@ static int ipa3_setup_wdi3_gsi_channel(u8 is_smmu_enabled, result = -EFAULT; goto fail_write_scratch; } /* * TODO: for all access over PCIe for MDM, * there is no SMMU */ ch_scratch.wdi3.wifi_rp_address_low = (u32)va; ch_scratch.wdi3.wifi_rp_address_high = (u32)((u64)va >> 32); Loading Loading @@ -436,6 +428,8 @@ static int ipa3_setup_wdi3_gsi_channel(u8 is_smmu_enabled, fail_get_gsi_ep_info: gsi_dealloc_evt_ring(ep->gsi_evt_ring_hdl); ep->gsi_evt_ring_hdl = ~0; fail_smmu_mapping: ipa3_release_wdi3_gsi_smmu_mappings(dir); return result; } Loading Loading @@ -666,21 +660,22 @@ int ipa3_disconn_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) ep_tx = &ipa3_ctx->ep[ipa_ep_idx_tx]; ep_rx = &ipa3_ctx->ep[ipa_ep_idx_rx]; IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(ipa_ep_idx_tx)); /* tear down tx pipe */ result = ipa3_reset_gsi_channel(ipa_ep_idx_tx); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to reset gsi channel: %d.\n", result); return result; goto exit; } result = gsi_reset_evt_ring(ep_tx->gsi_evt_ring_hdl); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to reset evt ring: %d.\n", result); return result; goto exit; } result = ipa3_release_gsi_channel(ipa_ep_idx_tx); if (result) { IPAERR("failed to release gsi channel: %d\n", result); return result; goto exit; } memset(ep_tx, 0, sizeof(struct ipa3_ep_context)); Loading @@ -690,23 +685,25 @@ int ipa3_disconn_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) result = ipa3_reset_gsi_channel(ipa_ep_idx_rx); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to reset gsi channel: %d.\n", result); return result; goto exit; } result = gsi_reset_evt_ring(ep_rx->gsi_evt_ring_hdl); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to reset evt ring: %d.\n", result); return result; goto exit; } result = ipa3_release_gsi_channel(ipa_ep_idx_rx); if (result) { IPAERR("failed to release gsi channel: %d\n", result); return result; goto exit; } ipa3_delete_dflt_flt_rules(ipa_ep_idx_rx); memset(ep_rx, 0, sizeof(struct ipa3_ep_context)); IPADBG("rx client (ep: %d) disconnected\n", ipa_ep_idx_rx); exit: IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_by_pipe(ipa_ep_idx_tx)); return result; } Loading @@ -728,20 +725,23 @@ int ipa3_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) ep_tx = &ipa3_ctx->ep[ipa_ep_idx_tx]; ep_rx = &ipa3_ctx->ep[ipa_ep_idx_rx]; IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(ipa_ep_idx_tx)); /* start gsi tx channel */ result = gsi_start_channel(ep_tx->gsi_chan_hdl); if (result) { IPAERR("failed to start gsi tx channel\n"); return -EFAULT; result = -EFAULT; goto exit; } /* start gsi rx channel */ result = gsi_start_channel(ep_rx->gsi_chan_hdl); if (result) { IPAERR("failed to start gsi rx channel\n"); return -EFAULT; result = -EFAULT; goto exit; } IPA_ACTIVE_CLIENTS_INC_SIMPLE(); /* enable data path */ result = ipa3_enable_data_path(ipa_ep_idx_rx); Loading @@ -749,7 +749,7 @@ int ipa3_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) IPAERR("enable data path failed res=%d clnt=%d.\n", result, ipa_ep_idx_rx); result = -EFAULT; goto fail; goto exit; } result = ipa3_enable_data_path(ipa_ep_idx_tx); Loading @@ -757,11 +757,11 @@ int ipa3_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx) IPAERR("enable data path failed res=%d clnt=%d.\n", result, ipa_ep_idx_tx); result = -EFAULT; goto fail; goto exit; } fail: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); exit: IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(ipa_ep_idx_tx)); return result; } Loading Loading @@ -865,13 +865,13 @@ int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id) if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to read channel scratch %d\n", result); return result; goto exit; } result = gsi_stop_channel(ep->gsi_chan_hdl); if (result != GSI_STATUS_SUCCESS && result != -GSI_STATUS_AGAIN && result != -GSI_STATUS_TIMED_OUT) { IPAERR("failed to stop gsi channel %d\n", result); return result; goto exit; } ch_scratch.wdi3.qmap_id = qmap_id; Loading @@ -879,14 +879,16 @@ int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id) ch_scratch); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to write channel scratch %d\n", result); return result; goto exit; } result = gsi_start_channel(ep->gsi_chan_hdl); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to start gsi channel %d\n", result); return result; goto exit; } return 0; exit: IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl)); return result; }
include/linux/ipa_wdi3.h +3 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ enum ipa_wdi_version { IPA_WDI_3 }; #define IPA_WDI3_TX_DIR 1 #define IPA_WDI3_RX_DIR 2 /** * struct ipa_wdi_init_in_params - wdi init input parameters * Loading