Loading drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c +77 −16 Original line number Diff line number Diff line Loading @@ -130,6 +130,10 @@ static int ipa_uc_offload_ntn_register_pm_client( struct ipa_pm_register_params params; memset(¶ms, 0, sizeof(params)); if (ntn_ctx->proto == IPA_UC_NTN_V2X) params.name = "ETH_v2x"; else params.name = "ETH"; params.callback = ipa_uc_offload_ntn_pm_cb; params.user_data = ntn_ctx; Loading @@ -139,11 +143,16 @@ static int ipa_uc_offload_ntn_register_pm_client( IPA_UC_OFFLOAD_ERR("fail to register with PM %d\n", res); return res; } if (ntn_ctx->proto == IPA_UC_NTN_V2X) res = ipa_pm_associate_ipa_cons_to_client(ntn_ctx->pm_hdl, IPA_CLIENT_ETHERNET2_CONS); else res = ipa_pm_associate_ipa_cons_to_client(ntn_ctx->pm_hdl, IPA_CLIENT_ETHERNET_CONS); if (res) { IPA_UC_OFFLOAD_ERR("fail to associate cons with PM %d\n", res); IPA_UC_OFFLOAD_ERR("fail to assoc. PM (%d) Prot:%d\n", res, ntn_ctx->proto); ipa_pm_deregister(ntn_ctx->pm_hdl); ntn_ctx->pm_hdl = ~0; return res; Loading Loading @@ -369,21 +378,43 @@ int ipa_uc_offload_reg_intf( return -EINVAL; } /* only register IPA properties for uc_ntn */ if (ctx->proto == IPA_UC_NTN) { ret = ipa_uc_offload_ntn_reg_intf(inp, outp, ctx); if (!ret) outp->clnt_hndl = IPA_UC_NTN; } /* only register IPA-pm for uc_ntn_v2x */ if (ctx->proto == IPA_UC_NTN_V2X) { /* always in vlan mode */ IPA_UC_OFFLOAD_INFO("v2x hdr_len %d\n", inp->hdr_info[0].hdr_len); ctx->hdr_len = inp->hdr_info[0].hdr_len; if (ipa_pm_is_used()) ret = ipa_uc_offload_ntn_register_pm_client(ctx); else IPA_UC_OFFLOAD_ERR("Not support uc_ntn_v2x ipa_rm\n"); if (!ret) outp->clnt_hndl = IPA_UC_NTN_V2X; else IPA_UC_OFFLOAD_ERR("fail to create rm resource\n"); /* set to initialized state */ ctx->state = IPA_UC_OFFLOAD_STATE_INITIALIZED; } return ret; } EXPORT_SYMBOL(ipa_uc_offload_reg_intf); /* only IPA_UC_NTN might use for ipa_rm */ static int ipa_uc_ntn_cons_release(void) { return 0; } /* only IPA_UC_NTN might use for ipa_rm */ static int ipa_uc_ntn_cons_request(void) { int ret = 0; Loading Loading @@ -506,6 +537,12 @@ int ipa_uc_ntn_conn_pipes(struct ipa_ntn_conn_in_params *inp, return result; } } else { /* not support v2x*/ if (ntn_ctx->proto == IPA_UC_NTN_V2X) { IPA_UC_OFFLOAD_ERR("Not support uc_ntn_v2x ipa_rm\n"); return -EINVAL; } result = ipa_rm_add_dependency(IPA_RM_RESOURCE_ETHERNET_PROD, IPA_RM_RESOURCE_APPS_CONS); if (result) { Loading Loading @@ -579,7 +616,7 @@ int ipa_uc_offload_conn_pipes(struct ipa_uc_offload_conn_in_params *inp, offload_ctx = ipa_uc_offload_ctx[inp->clnt_hndl]; if (!offload_ctx) { IPA_UC_OFFLOAD_ERR("Invalid Handle\n"); IPA_UC_OFFLOAD_ERR("Invalid ctx %d\n", inp->clnt_hndl); return -EINVAL; } Loading @@ -593,6 +630,7 @@ int ipa_uc_offload_conn_pipes(struct ipa_uc_offload_conn_in_params *inp, sizeof(struct ipa_ntn_conn_in_params)); switch (offload_ctx->proto) { case IPA_UC_NTN_V2X: case IPA_UC_NTN: ret = ipa_uc_ntn_conn_pipes(&inp->u.ntn, &outp->u.ntn, offload_ctx); Loading @@ -618,6 +656,17 @@ int ipa_set_perf_profile(struct ipa_perf_profile *profile) return -EINVAL; } if (ipa_pm_is_used()) { return ipa_pm_set_throughput( ipa_uc_offload_ctx[profile->proto]->pm_hdl, profile->max_supported_bw_mbps); } else { if (profile->proto == IPA_UC_NTN_V2X) { IPA_UC_OFFLOAD_ERR("not support NTN_v2x for ipa_rm\n"); return -EFAULT; } } rm_profile.max_supported_bandwidth_mbps = profile->max_supported_bw_mbps; Loading @@ -629,17 +678,10 @@ int ipa_set_perf_profile(struct ipa_perf_profile *profile) IPA_UC_OFFLOAD_ERR("not supported\n"); return -EINVAL; } if (ipa_pm_is_used()) return ipa_pm_set_throughput( ipa_uc_offload_ctx[IPA_UC_NTN]->pm_hdl, profile->max_supported_bw_mbps); if (ipa_rm_set_perf_profile(resource_name, &rm_profile)) { IPA_UC_OFFLOAD_ERR("fail to setup rm perf profile\n"); return -EFAULT; } return 0; } EXPORT_SYMBOL(ipa_set_perf_profile); Loading @@ -664,6 +706,12 @@ static int ipa_uc_ntn_disconn_pipes(struct ipa_uc_offload_ctx *ntn_ctx) return -EFAULT; } } else { /* not support ntn_v2x to use rm */ if (ntn_ctx->proto == IPA_UC_NTN_V2X) { IPA_UC_OFFLOAD_ERR("not support NTN_v2x for ipa_rm\n"); return -EFAULT; } ret = ipa_rm_release_resource(IPA_RM_RESOURCE_ETHERNET_PROD); if (ret) { IPA_UC_OFFLOAD_ERR("fail release ETHERNET_PROD: %d\n", Loading @@ -679,8 +727,13 @@ static int ipa_uc_ntn_disconn_pipes(struct ipa_uc_offload_ctx *ntn_ctx) } } if (ntn_ctx->proto == IPA_UC_NTN_V2X) { ipa_ep_idx_ul = ipa_get_ep_mapping(IPA_CLIENT_ETHERNET2_PROD); ipa_ep_idx_dl = ipa_get_ep_mapping(IPA_CLIENT_ETHERNET2_CONS); } else { ipa_ep_idx_ul = ipa_get_ep_mapping(IPA_CLIENT_ETHERNET_PROD); ipa_ep_idx_dl = ipa_get_ep_mapping(IPA_CLIENT_ETHERNET_CONS); } ret = ipa_tear_down_uc_offload_pipes(ipa_ep_idx_ul, ipa_ep_idx_dl, &ntn_ctx->conn); if (ret) { Loading Loading @@ -719,6 +772,7 @@ int ipa_uc_offload_disconn_pipes(u32 clnt_hdl) } switch (offload_ctx->proto) { case IPA_UC_NTN_V2X: case IPA_UC_NTN: ret = ipa_uc_ntn_disconn_pipes(offload_ctx); break; Loading Loading @@ -805,6 +859,13 @@ int ipa_uc_offload_cleanup(u32 clnt_hdl) case IPA_UC_NTN: ret = ipa_uc_ntn_cleanup(offload_ctx); break; case IPA_UC_NTN_V2X: /* only clean-up pm_handle */ if (ipa_pm_is_used()) ipa_uc_offload_ntn_deregister_pm_client(offload_ctx); else IPA_UC_OFFLOAD_ERR("Not support uc_ntn_v2x ipa_rm\n"); break; default: IPA_UC_OFFLOAD_ERR("Invalid Proto :%d\n", clnt_hdl); Loading Loading @@ -840,7 +901,7 @@ int ipa_uc_offload_reg_rdyCB(struct ipa_uc_ready_params *inp) return -EINVAL; } if (inp->proto == IPA_UC_NTN) if (inp->proto == IPA_UC_NTN || inp->proto == IPA_UC_NTN_V2X) ret = ipa_ntn_uc_reg_rdyCB(inp->notify, inp->priv); if (ret == -EEXIST) { Loading @@ -855,7 +916,7 @@ EXPORT_SYMBOL(ipa_uc_offload_reg_rdyCB); void ipa_uc_offload_dereg_rdyCB(enum ipa_uc_offload_proto proto) { if (proto == IPA_UC_NTN) if (proto == IPA_UC_NTN || proto == IPA_UC_NTN_V2X) ipa_ntn_uc_dereg_rdyCB(); } EXPORT_SYMBOL(ipa_uc_offload_dereg_rdyCB); drivers/platform/msm/ipa/ipa_v3/ipa.c +1 −1 Original line number Diff line number Diff line Loading @@ -7152,7 +7152,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, } IPADBG( "base(0x%x)+offset(0x%x)=(0x%x) mapped to (%pK) with len (0x%x)\n", "base(0x%x)+offset(0x%x)=(0x%x) mapped to (0x%x) with len (0x%x)\n", resource_p->ipa_mem_base, ipa3_ctx->ctrl->ipa_reg_base_ofst, resource_p->ipa_mem_base + ipa3_ctx->ctrl->ipa_reg_base_ofst, Loading drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +72 −65 Original line number Diff line number Diff line Loading @@ -1397,76 +1397,83 @@ static ssize_t ipa3_read_wstats(struct file *file, char __user *ubuf, static ssize_t ipa3_read_ntn(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { #define TX_STATS(y) \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->tx_ch_stats[0].y #define RX_STATS(y) \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->rx_ch_stats[0].y #define TX_STATS(x, y) \ stats.tx_ch_stats[x].y #define RX_STATS(x, y) \ stats.rx_ch_stats[x].y struct Ipa3HwStatsNTNInfoData_t stats; int nbytes; int cnt = 0; int cnt = 0, i = 0; if (!ipa3_get_ntn_stats(&stats)) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "TX num_pkts_processed=%u\n" "TX ringFull=%u\n" "TX ringEmpty=%u\n" "TX ringUsageHigh=%u\n" "TX ringUsageLow=%u\n" "TX RingUtilCount=%u\n" "TX bamFifoFull=%u\n" "TX bamFifoEmpty=%u\n" "TX bamFifoUsageHigh=%u\n" "TX bamFifoUsageLow=%u\n" "TX bamUtilCount=%u\n" "TX num_db=%u\n" "TX num_qmb_int_handled=%u\n" "TX ipa_pipe_number=%u\n", TX_STATS(num_pkts_processed), TX_STATS(ring_stats.ringFull), TX_STATS(ring_stats.ringEmpty), TX_STATS(ring_stats.ringUsageHigh), TX_STATS(ring_stats.ringUsageLow), TX_STATS(ring_stats.RingUtilCount), TX_STATS(gsi_stats.bamFifoFull), TX_STATS(gsi_stats.bamFifoEmpty), TX_STATS(gsi_stats.bamFifoUsageHigh), TX_STATS(gsi_stats.bamFifoUsageLow), TX_STATS(gsi_stats.bamUtilCount), TX_STATS(num_db), TX_STATS(num_qmb_int_handled), TX_STATS(ipa_pipe_number)); cnt += nbytes; nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, "RX num_pkts_processed=%u\n" "RX ringFull=%u\n" "RX ringEmpty=%u\n" "RX ringUsageHigh=%u\n" "RX ringUsageLow=%u\n" "RX RingUtilCount=%u\n" "RX bamFifoFull=%u\n" "RX bamFifoEmpty=%u\n" "RX bamFifoUsageHigh=%u\n" "RX bamFifoUsageLow=%u\n" "RX bamUtilCount=%u\n" "RX num_db=%u\n" "RX num_qmb_int_handled=%u\n" "RX ipa_pipe_number=%u\n", RX_STATS(num_pkts_processed), RX_STATS(ring_stats.ringFull), RX_STATS(ring_stats.ringEmpty), RX_STATS(ring_stats.ringUsageHigh), RX_STATS(ring_stats.ringUsageLow), RX_STATS(ring_stats.RingUtilCount), RX_STATS(gsi_stats.bamFifoFull), RX_STATS(gsi_stats.bamFifoEmpty), RX_STATS(gsi_stats.bamFifoUsageHigh), RX_STATS(gsi_stats.bamFifoUsageLow), RX_STATS(gsi_stats.bamUtilCount), RX_STATS(num_db), RX_STATS(num_qmb_int_handled), RX_STATS(ipa_pipe_number)); for (i = 0; i < IPA_UC_MAX_NTN_TX_CHANNELS; i++) { nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, "TX%d num_pkts_psr=%u\n" "TX%d ringFull=%u\n" "TX%d ringEmpty=%u\n" "TX%d ringUsageHigh=%u\n" "TX%d ringUsageLow=%u\n" "TX%d RingUtilCount=%u\n" "TX%d bamFifoFull=%u\n" "TX%d bamFifoEmpty=%u\n" "TX%d bamFifoUsageHigh=%u\n" "TX%d bamFifoUsageLow=%u\n" "TX%d bamUtilCount=%u\n" "TX%d num_db=%u\n" "TX%d num_qmb_int_handled=%u\n" "TX%d ipa_pipe_number=%u\n", i, TX_STATS(i, num_pkts_processed), i, TX_STATS(i, ring_stats.ringFull), i, TX_STATS(i, ring_stats.ringEmpty), i, TX_STATS(i, ring_stats.ringUsageHigh), i, TX_STATS(i, ring_stats.ringUsageLow), i, TX_STATS(i, ring_stats.RingUtilCount), i, TX_STATS(i, gsi_stats.bamFifoFull), i, TX_STATS(i, gsi_stats.bamFifoEmpty), i, TX_STATS(i, gsi_stats.bamFifoUsageHigh), i, TX_STATS(i, gsi_stats.bamFifoUsageLow), i, TX_STATS(i, gsi_stats.bamUtilCount), i, TX_STATS(i, num_db), i, TX_STATS(i, num_qmb_int_handled), i, TX_STATS(i, ipa_pipe_number)); cnt += nbytes; } for (i = 0; i < IPA_UC_MAX_NTN_RX_CHANNELS; i++) { nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, "RX%d num_pkts_psr=%u\n" "RX%d ringFull=%u\n" "RX%d ringEmpty=%u\n" "RX%d ringUsageHigh=%u\n" "RX%d ringUsageLow=%u\n" "RX%d RingUtilCount=%u\n" "RX%d bamFifoFull=%u\n" "RX%d bamFifoEmpty=%u\n" "RX%d bamFifoUsageHigh=%u\n" "RX%d bamFifoUsageLow=%u\n" "RX%d bamUtilCount=%u\n" "RX%d num_db=%u\n" "RX%d num_qmb_int_handled=%u\n" "RX%d ipa_pipe_number=%u\n", i, RX_STATS(i, num_pkts_processed), i, RX_STATS(i, ring_stats.ringFull), i, RX_STATS(i, ring_stats.ringEmpty), i, RX_STATS(i, ring_stats.ringUsageHigh), i, RX_STATS(i, ring_stats.ringUsageLow), i, RX_STATS(i, ring_stats.RingUtilCount), i, RX_STATS(i, gsi_stats.bamFifoFull), i, RX_STATS(i, gsi_stats.bamFifoEmpty), i, RX_STATS(i, gsi_stats.bamFifoUsageHigh), i, RX_STATS(i, gsi_stats.bamFifoUsageLow), i, RX_STATS(i, gsi_stats.bamUtilCount), i, RX_STATS(i, num_db), i, RX_STATS(i, num_qmb_int_handled), i, RX_STATS(i, ipa_pipe_number)); cnt += nbytes; } } else { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "Fail to read NTN stats\n"); Loading drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c +110 −45 Original line number Diff line number Diff line Loading @@ -69,10 +69,12 @@ struct IpaHwEventLogInfoData_t *uc_event_top_mmio) */ int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats) { #define TX_STATS(y) stats->tx_ch_stats[0].y = \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->tx_ch_stats[0].y #define RX_STATS(y) stats->rx_ch_stats[0].y = \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->rx_ch_stats[0].y #define TX_STATS(x, y) stats->tx_ch_stats[x].y = \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->tx_ch_stats[x].y #define RX_STATS(x, y) stats->rx_ch_stats[x].y = \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->rx_ch_stats[x].y int i = 0; if (unlikely(!ipa3_ctx)) { IPAERR("IPA driver was not initialized\n"); Loading @@ -87,36 +89,39 @@ int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats) } IPA_ACTIVE_CLIENTS_INC_SIMPLE(); TX_STATS(num_pkts_processed); TX_STATS(ring_stats.ringFull); TX_STATS(ring_stats.ringEmpty); TX_STATS(ring_stats.ringUsageHigh); TX_STATS(ring_stats.ringUsageLow); TX_STATS(ring_stats.RingUtilCount); TX_STATS(gsi_stats.bamFifoFull); TX_STATS(gsi_stats.bamFifoEmpty); TX_STATS(gsi_stats.bamFifoUsageHigh); TX_STATS(gsi_stats.bamFifoUsageLow); TX_STATS(gsi_stats.bamUtilCount); TX_STATS(num_db); TX_STATS(num_qmb_int_handled); TX_STATS(ipa_pipe_number); RX_STATS(num_pkts_processed); RX_STATS(ring_stats.ringFull); RX_STATS(ring_stats.ringEmpty); RX_STATS(ring_stats.ringUsageHigh); RX_STATS(ring_stats.ringUsageLow); RX_STATS(ring_stats.RingUtilCount); RX_STATS(gsi_stats.bamFifoFull); RX_STATS(gsi_stats.bamFifoEmpty); RX_STATS(gsi_stats.bamFifoUsageHigh); RX_STATS(gsi_stats.bamFifoUsageLow); RX_STATS(gsi_stats.bamUtilCount); RX_STATS(num_db); RX_STATS(num_qmb_int_handled); RX_STATS(ipa_pipe_number); for (i = 0; i < IPA_UC_MAX_NTN_TX_CHANNELS; i++) { TX_STATS(i, num_pkts_processed); TX_STATS(i, ring_stats.ringFull); TX_STATS(i, ring_stats.ringEmpty); TX_STATS(i, ring_stats.ringUsageHigh); TX_STATS(i, ring_stats.ringUsageLow); TX_STATS(i, ring_stats.RingUtilCount); TX_STATS(i, gsi_stats.bamFifoFull); TX_STATS(i, gsi_stats.bamFifoEmpty); TX_STATS(i, gsi_stats.bamFifoUsageHigh); TX_STATS(i, gsi_stats.bamFifoUsageLow); TX_STATS(i, gsi_stats.bamUtilCount); TX_STATS(i, num_db); TX_STATS(i, num_qmb_int_handled); TX_STATS(i, ipa_pipe_number); } for (i = 0; i < IPA_UC_MAX_NTN_RX_CHANNELS; i++) { RX_STATS(i, num_pkts_processed); RX_STATS(i, ring_stats.ringFull); RX_STATS(i, ring_stats.ringEmpty); RX_STATS(i, ring_stats.ringUsageHigh); RX_STATS(i, ring_stats.ringUsageLow); RX_STATS(i, ring_stats.RingUtilCount); RX_STATS(i, gsi_stats.bamFifoFull); RX_STATS(i, gsi_stats.bamFifoEmpty); RX_STATS(i, gsi_stats.bamFifoUsageHigh); RX_STATS(i, gsi_stats.bamFifoUsageLow); RX_STATS(i, gsi_stats.bamUtilCount); RX_STATS(i, num_db); RX_STATS(i, num_qmb_int_handled); RX_STATS(i, ipa_pipe_number); } IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); Loading Loading @@ -177,6 +182,12 @@ int ipa3_ntn_init(void) ipa3_uc_register_handlers(IPA_HW_FEATURE_NTN, &uc_ntn_cbs); /* ntn_init */ ipa3_ctx->uc_ntn_ctx.uc_ready_cb = NULL; ipa3_ctx->uc_ntn_ctx.priv = NULL; ipa3_ctx->uc_ntn_ctx.ntn_reg_base_ptr_pa_rd = 0x0; ipa3_ctx->uc_ntn_ctx.smmu_mapped = 0; return 0; } Loading Loading @@ -213,6 +224,7 @@ static int ipa3_uc_send_ntn_setup_pipe_cmd( IPADBG("num_buffers = %d\n", ntn_info->num_buffers); IPADBG("data_buff_size = %d\n", ntn_info->data_buff_size); IPADBG("tail_ptr_base_pa = 0x%pa\n", &ntn_info->ntn_reg_base_ptr_pa); IPADBG("db_mode = %d\n", ntn_info->db_mode); if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) cmd.size = sizeof(*cmd_data_v4_0); else Loading Loading @@ -248,6 +260,7 @@ static int ipa3_uc_send_ntn_setup_pipe_cmd( Ntn_params->num_buffers = ntn_info->num_buffers; Ntn_params->ntn_reg_base_ptr_pa = ntn_info->ntn_reg_base_ptr_pa; Ntn_params->data_buff_size = ntn_info->data_buff_size; Ntn_params->db_mode = ntn_info->db_mode; Ntn_params->ipa_pipe_number = ipa_ep_idx; Ntn_params->dir = dir; Loading @@ -263,7 +276,7 @@ static int ipa3_uc_send_ntn_setup_pipe_cmd( } static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params, bool map, bool map_unmap_once) bool map) { struct iommu_domain *smmu_domain; int result; Loading @@ -273,12 +286,20 @@ static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params, u64 iova_p; phys_addr_t pa_p; u32 size_p; bool map_unmap_once; if (params->data_buff_size > PAGE_SIZE) { IPAERR("invalid data buff size\n"); return -EINVAL; } /* only map/unmap once the ntn_reg_base_ptr_pa */ map_unmap_once = (map && ipa3_ctx->uc_ntn_ctx.smmu_mapped == 0) || (!map && ipa3_ctx->uc_ntn_ctx.smmu_mapped == 1); IPADBG(" %s uC regs, smmu_mapped %d\n", map ? "map" : "unmap", ipa3_ctx->uc_ntn_ctx.smmu_mapped); if (map_unmap_once) { result = ipa3_smmu_map_peer_reg(rounddown( params->ntn_reg_base_ptr_pa, PAGE_SIZE), Loading @@ -288,7 +309,33 @@ static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params, map ? "map" : "unmap", result); goto fail; } /* backup the ntn_reg_base_ptr_pa_r */ ipa3_ctx->uc_ntn_ctx.ntn_reg_base_ptr_pa_rd = rounddown(params->ntn_reg_base_ptr_pa, PAGE_SIZE); IPADBG(" %s ntn_reg_base_ptr_pa regs 0X%0x smmu_mapped %d\n", map ? "map" : "unmap", (unsigned long long) ipa3_ctx->uc_ntn_ctx.ntn_reg_base_ptr_pa_rd, ipa3_ctx->uc_ntn_ctx.smmu_mapped); } /* update smmu_mapped reference count */ if (map) { ipa3_ctx->uc_ntn_ctx.smmu_mapped++; IPADBG("uc_ntn_ctx.smmu_mapped %d\n", ipa3_ctx->uc_ntn_ctx.smmu_mapped); } else { if (ipa3_ctx->uc_ntn_ctx.smmu_mapped == 0) { IPAERR("Invalid smmu_mapped %d\n", ipa3_ctx->uc_ntn_ctx.smmu_mapped); goto fail; } else { ipa3_ctx->uc_ntn_ctx.smmu_mapped--; IPADBG("uc_ntn_ctx.smmu_mapped %d\n", ipa3_ctx->uc_ntn_ctx.smmu_mapped); } } if (params->smmu_enabled) { IPADBG("smmu is enabled on EMAC\n"); result = ipa3_smmu_map_peer_buff((u64)params->ring_base_iova, Loading Loading @@ -397,7 +444,6 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, int ipa_ep_idx_ul; int ipa_ep_idx_dl; int result = 0; bool unmapped = false; if (in == NULL) { IPAERR("invalid input\n"); Loading Loading @@ -451,7 +497,7 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, goto fail; } result = ipa3_smmu_map_uc_ntn_pipes(&in->ul, true, true); result = ipa3_smmu_map_uc_ntn_pipes(&in->ul, true); if (result) { IPAERR("failed to map SMMU for UL %d\n", result); goto fail; Loading @@ -471,7 +517,10 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, goto fail_disable_dp_ul; } ipa3_install_dflt_flt_rules(ipa_ep_idx_ul); outp->ul_uc_db_pa = IPA_UC_NTN_DB_PA_RX; /* Rx: IPA_UC_MAILBOX_m_n m = 1, n =3 mmio*/ outp->ul_uc_db_iomem = ipa3_ctx->mmio + ipahal_get_reg_mn_ofst(IPA_UC_MAILBOX_m_n, 1, 3); ep_ul->uc_offload_state |= IPA_UC_OFFLOAD_CONNECTED; IPADBG("client %d (ep: %d) connected\n", in->ul.client, ipa_ep_idx_ul); Loading @@ -490,7 +539,7 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, goto fail_disable_dp_ul; } result = ipa3_smmu_map_uc_ntn_pipes(&in->dl, true, false); result = ipa3_smmu_map_uc_ntn_pipes(&in->dl, true); if (result) { IPAERR("failed to map SMMU for DL %d\n", result); goto fail_disable_dp_ul; Loading @@ -509,7 +558,10 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, result = -EFAULT; goto fail_disable_dp_dl; } outp->dl_uc_db_pa = IPA_UC_NTN_DB_PA_TX; /* Tx: IPA_UC_MAILBOX_m_n m = 1, n =4 mmio */ outp->dl_uc_db_iomem = ipa3_ctx->mmio + ipahal_get_reg_mn_ofst(IPA_UC_MAILBOX_m_n, 1, 4); ep_dl->uc_offload_state |= IPA_UC_OFFLOAD_CONNECTED; IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); Loading @@ -521,12 +573,11 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, fail_disable_dp_dl: ipa3_disable_data_path(ipa_ep_idx_dl); fail_smmu_unmap_dl: ipa3_smmu_map_uc_ntn_pipes(&in->dl, false, true); unmapped = true; ipa3_smmu_map_uc_ntn_pipes(&in->dl, false); fail_disable_dp_ul: ipa3_disable_data_path(ipa_ep_idx_ul); fail_smmu_unmap_ul: ipa3_smmu_map_uc_ntn_pipes(&in->ul, false, !unmapped); ipa3_smmu_map_uc_ntn_pipes(&in->ul, false); fail: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return result; Loading @@ -549,6 +600,20 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, IPADBG("ep_ul = %d\n", ipa_ep_idx_ul); IPADBG("ep_dl = %d\n", ipa_ep_idx_dl); if (ipa_ep_idx_ul == IPA_EP_NOT_ALLOCATED || ipa_ep_idx_ul >= IPA3_MAX_NUM_PIPES) { IPAERR("ipa_ep_idx_ul %d invalid\n", ipa_ep_idx_ul); return -EFAULT; } if (ipa_ep_idx_dl == IPA_EP_NOT_ALLOCATED || ipa_ep_idx_dl >= IPA3_MAX_NUM_PIPES) { IPAERR("ep ipa_ep_idx_dl %d invalid\n", ipa_ep_idx_dl); return -EFAULT; } ep_ul = &ipa3_ctx->ep[ipa_ep_idx_ul]; ep_dl = &ipa3_ctx->ep[ipa_ep_idx_dl]; Loading Loading @@ -606,7 +671,7 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, } /* unmap the DL pipe */ result = ipa3_smmu_map_uc_ntn_pipes(¶ms->dl, false, false); result = ipa3_smmu_map_uc_ntn_pipes(¶ms->dl, false); if (result) { IPAERR("failed to unmap SMMU for DL %d\n", result); goto fail; Loading @@ -627,7 +692,7 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, } /* unmap the UL pipe */ result = ipa3_smmu_map_uc_ntn_pipes(¶ms->ul, false, true); result = ipa3_smmu_map_uc_ntn_pipes(¶ms->ul, false); if (result) { IPAERR("failed to unmap SMMU for UL %d\n", result); goto fail; Loading drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h +8 −4 Original line number Diff line number Diff line /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -20,8 +20,8 @@ * Neutrino protocol related data structures */ #define IPA_UC_MAX_NTN_TX_CHANNELS 1 #define IPA_UC_MAX_NTN_RX_CHANNELS 1 #define IPA_UC_MAX_NTN_TX_CHANNELS 2 #define IPA_UC_MAX_NTN_RX_CHANNELS 2 #define IPA_NTN_TX_DIR 1 #define IPA_NTN_RX_DIR 2 Loading Loading @@ -283,6 +283,8 @@ struct ipa3_uc_ntn_ctx { struct Ipa3HwStatsNTNInfoData_t *ntn_uc_stats_mmio; void *priv; ipa_uc_ready_cb uc_ready_cb; phys_addr_t ntn_reg_base_ptr_pa_rd; u32 smmu_mapped; }; /** Loading Loading @@ -361,7 +363,9 @@ struct Ipa3HwNtnSetUpCmdData_t { u8 ipa_pipe_number; u8 dir; u16 data_buff_size; u8 db_mode; u8 reserved1; u16 reserved2; } __packed; /** Loading Loading
drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c +77 −16 Original line number Diff line number Diff line Loading @@ -130,6 +130,10 @@ static int ipa_uc_offload_ntn_register_pm_client( struct ipa_pm_register_params params; memset(¶ms, 0, sizeof(params)); if (ntn_ctx->proto == IPA_UC_NTN_V2X) params.name = "ETH_v2x"; else params.name = "ETH"; params.callback = ipa_uc_offload_ntn_pm_cb; params.user_data = ntn_ctx; Loading @@ -139,11 +143,16 @@ static int ipa_uc_offload_ntn_register_pm_client( IPA_UC_OFFLOAD_ERR("fail to register with PM %d\n", res); return res; } if (ntn_ctx->proto == IPA_UC_NTN_V2X) res = ipa_pm_associate_ipa_cons_to_client(ntn_ctx->pm_hdl, IPA_CLIENT_ETHERNET2_CONS); else res = ipa_pm_associate_ipa_cons_to_client(ntn_ctx->pm_hdl, IPA_CLIENT_ETHERNET_CONS); if (res) { IPA_UC_OFFLOAD_ERR("fail to associate cons with PM %d\n", res); IPA_UC_OFFLOAD_ERR("fail to assoc. PM (%d) Prot:%d\n", res, ntn_ctx->proto); ipa_pm_deregister(ntn_ctx->pm_hdl); ntn_ctx->pm_hdl = ~0; return res; Loading Loading @@ -369,21 +378,43 @@ int ipa_uc_offload_reg_intf( return -EINVAL; } /* only register IPA properties for uc_ntn */ if (ctx->proto == IPA_UC_NTN) { ret = ipa_uc_offload_ntn_reg_intf(inp, outp, ctx); if (!ret) outp->clnt_hndl = IPA_UC_NTN; } /* only register IPA-pm for uc_ntn_v2x */ if (ctx->proto == IPA_UC_NTN_V2X) { /* always in vlan mode */ IPA_UC_OFFLOAD_INFO("v2x hdr_len %d\n", inp->hdr_info[0].hdr_len); ctx->hdr_len = inp->hdr_info[0].hdr_len; if (ipa_pm_is_used()) ret = ipa_uc_offload_ntn_register_pm_client(ctx); else IPA_UC_OFFLOAD_ERR("Not support uc_ntn_v2x ipa_rm\n"); if (!ret) outp->clnt_hndl = IPA_UC_NTN_V2X; else IPA_UC_OFFLOAD_ERR("fail to create rm resource\n"); /* set to initialized state */ ctx->state = IPA_UC_OFFLOAD_STATE_INITIALIZED; } return ret; } EXPORT_SYMBOL(ipa_uc_offload_reg_intf); /* only IPA_UC_NTN might use for ipa_rm */ static int ipa_uc_ntn_cons_release(void) { return 0; } /* only IPA_UC_NTN might use for ipa_rm */ static int ipa_uc_ntn_cons_request(void) { int ret = 0; Loading Loading @@ -506,6 +537,12 @@ int ipa_uc_ntn_conn_pipes(struct ipa_ntn_conn_in_params *inp, return result; } } else { /* not support v2x*/ if (ntn_ctx->proto == IPA_UC_NTN_V2X) { IPA_UC_OFFLOAD_ERR("Not support uc_ntn_v2x ipa_rm\n"); return -EINVAL; } result = ipa_rm_add_dependency(IPA_RM_RESOURCE_ETHERNET_PROD, IPA_RM_RESOURCE_APPS_CONS); if (result) { Loading Loading @@ -579,7 +616,7 @@ int ipa_uc_offload_conn_pipes(struct ipa_uc_offload_conn_in_params *inp, offload_ctx = ipa_uc_offload_ctx[inp->clnt_hndl]; if (!offload_ctx) { IPA_UC_OFFLOAD_ERR("Invalid Handle\n"); IPA_UC_OFFLOAD_ERR("Invalid ctx %d\n", inp->clnt_hndl); return -EINVAL; } Loading @@ -593,6 +630,7 @@ int ipa_uc_offload_conn_pipes(struct ipa_uc_offload_conn_in_params *inp, sizeof(struct ipa_ntn_conn_in_params)); switch (offload_ctx->proto) { case IPA_UC_NTN_V2X: case IPA_UC_NTN: ret = ipa_uc_ntn_conn_pipes(&inp->u.ntn, &outp->u.ntn, offload_ctx); Loading @@ -618,6 +656,17 @@ int ipa_set_perf_profile(struct ipa_perf_profile *profile) return -EINVAL; } if (ipa_pm_is_used()) { return ipa_pm_set_throughput( ipa_uc_offload_ctx[profile->proto]->pm_hdl, profile->max_supported_bw_mbps); } else { if (profile->proto == IPA_UC_NTN_V2X) { IPA_UC_OFFLOAD_ERR("not support NTN_v2x for ipa_rm\n"); return -EFAULT; } } rm_profile.max_supported_bandwidth_mbps = profile->max_supported_bw_mbps; Loading @@ -629,17 +678,10 @@ int ipa_set_perf_profile(struct ipa_perf_profile *profile) IPA_UC_OFFLOAD_ERR("not supported\n"); return -EINVAL; } if (ipa_pm_is_used()) return ipa_pm_set_throughput( ipa_uc_offload_ctx[IPA_UC_NTN]->pm_hdl, profile->max_supported_bw_mbps); if (ipa_rm_set_perf_profile(resource_name, &rm_profile)) { IPA_UC_OFFLOAD_ERR("fail to setup rm perf profile\n"); return -EFAULT; } return 0; } EXPORT_SYMBOL(ipa_set_perf_profile); Loading @@ -664,6 +706,12 @@ static int ipa_uc_ntn_disconn_pipes(struct ipa_uc_offload_ctx *ntn_ctx) return -EFAULT; } } else { /* not support ntn_v2x to use rm */ if (ntn_ctx->proto == IPA_UC_NTN_V2X) { IPA_UC_OFFLOAD_ERR("not support NTN_v2x for ipa_rm\n"); return -EFAULT; } ret = ipa_rm_release_resource(IPA_RM_RESOURCE_ETHERNET_PROD); if (ret) { IPA_UC_OFFLOAD_ERR("fail release ETHERNET_PROD: %d\n", Loading @@ -679,8 +727,13 @@ static int ipa_uc_ntn_disconn_pipes(struct ipa_uc_offload_ctx *ntn_ctx) } } if (ntn_ctx->proto == IPA_UC_NTN_V2X) { ipa_ep_idx_ul = ipa_get_ep_mapping(IPA_CLIENT_ETHERNET2_PROD); ipa_ep_idx_dl = ipa_get_ep_mapping(IPA_CLIENT_ETHERNET2_CONS); } else { ipa_ep_idx_ul = ipa_get_ep_mapping(IPA_CLIENT_ETHERNET_PROD); ipa_ep_idx_dl = ipa_get_ep_mapping(IPA_CLIENT_ETHERNET_CONS); } ret = ipa_tear_down_uc_offload_pipes(ipa_ep_idx_ul, ipa_ep_idx_dl, &ntn_ctx->conn); if (ret) { Loading Loading @@ -719,6 +772,7 @@ int ipa_uc_offload_disconn_pipes(u32 clnt_hdl) } switch (offload_ctx->proto) { case IPA_UC_NTN_V2X: case IPA_UC_NTN: ret = ipa_uc_ntn_disconn_pipes(offload_ctx); break; Loading Loading @@ -805,6 +859,13 @@ int ipa_uc_offload_cleanup(u32 clnt_hdl) case IPA_UC_NTN: ret = ipa_uc_ntn_cleanup(offload_ctx); break; case IPA_UC_NTN_V2X: /* only clean-up pm_handle */ if (ipa_pm_is_used()) ipa_uc_offload_ntn_deregister_pm_client(offload_ctx); else IPA_UC_OFFLOAD_ERR("Not support uc_ntn_v2x ipa_rm\n"); break; default: IPA_UC_OFFLOAD_ERR("Invalid Proto :%d\n", clnt_hdl); Loading Loading @@ -840,7 +901,7 @@ int ipa_uc_offload_reg_rdyCB(struct ipa_uc_ready_params *inp) return -EINVAL; } if (inp->proto == IPA_UC_NTN) if (inp->proto == IPA_UC_NTN || inp->proto == IPA_UC_NTN_V2X) ret = ipa_ntn_uc_reg_rdyCB(inp->notify, inp->priv); if (ret == -EEXIST) { Loading @@ -855,7 +916,7 @@ EXPORT_SYMBOL(ipa_uc_offload_reg_rdyCB); void ipa_uc_offload_dereg_rdyCB(enum ipa_uc_offload_proto proto) { if (proto == IPA_UC_NTN) if (proto == IPA_UC_NTN || proto == IPA_UC_NTN_V2X) ipa_ntn_uc_dereg_rdyCB(); } EXPORT_SYMBOL(ipa_uc_offload_dereg_rdyCB);
drivers/platform/msm/ipa/ipa_v3/ipa.c +1 −1 Original line number Diff line number Diff line Loading @@ -7152,7 +7152,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, } IPADBG( "base(0x%x)+offset(0x%x)=(0x%x) mapped to (%pK) with len (0x%x)\n", "base(0x%x)+offset(0x%x)=(0x%x) mapped to (0x%x) with len (0x%x)\n", resource_p->ipa_mem_base, ipa3_ctx->ctrl->ipa_reg_base_ofst, resource_p->ipa_mem_base + ipa3_ctx->ctrl->ipa_reg_base_ofst, Loading
drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +72 −65 Original line number Diff line number Diff line Loading @@ -1397,76 +1397,83 @@ static ssize_t ipa3_read_wstats(struct file *file, char __user *ubuf, static ssize_t ipa3_read_ntn(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { #define TX_STATS(y) \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->tx_ch_stats[0].y #define RX_STATS(y) \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->rx_ch_stats[0].y #define TX_STATS(x, y) \ stats.tx_ch_stats[x].y #define RX_STATS(x, y) \ stats.rx_ch_stats[x].y struct Ipa3HwStatsNTNInfoData_t stats; int nbytes; int cnt = 0; int cnt = 0, i = 0; if (!ipa3_get_ntn_stats(&stats)) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "TX num_pkts_processed=%u\n" "TX ringFull=%u\n" "TX ringEmpty=%u\n" "TX ringUsageHigh=%u\n" "TX ringUsageLow=%u\n" "TX RingUtilCount=%u\n" "TX bamFifoFull=%u\n" "TX bamFifoEmpty=%u\n" "TX bamFifoUsageHigh=%u\n" "TX bamFifoUsageLow=%u\n" "TX bamUtilCount=%u\n" "TX num_db=%u\n" "TX num_qmb_int_handled=%u\n" "TX ipa_pipe_number=%u\n", TX_STATS(num_pkts_processed), TX_STATS(ring_stats.ringFull), TX_STATS(ring_stats.ringEmpty), TX_STATS(ring_stats.ringUsageHigh), TX_STATS(ring_stats.ringUsageLow), TX_STATS(ring_stats.RingUtilCount), TX_STATS(gsi_stats.bamFifoFull), TX_STATS(gsi_stats.bamFifoEmpty), TX_STATS(gsi_stats.bamFifoUsageHigh), TX_STATS(gsi_stats.bamFifoUsageLow), TX_STATS(gsi_stats.bamUtilCount), TX_STATS(num_db), TX_STATS(num_qmb_int_handled), TX_STATS(ipa_pipe_number)); cnt += nbytes; nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, "RX num_pkts_processed=%u\n" "RX ringFull=%u\n" "RX ringEmpty=%u\n" "RX ringUsageHigh=%u\n" "RX ringUsageLow=%u\n" "RX RingUtilCount=%u\n" "RX bamFifoFull=%u\n" "RX bamFifoEmpty=%u\n" "RX bamFifoUsageHigh=%u\n" "RX bamFifoUsageLow=%u\n" "RX bamUtilCount=%u\n" "RX num_db=%u\n" "RX num_qmb_int_handled=%u\n" "RX ipa_pipe_number=%u\n", RX_STATS(num_pkts_processed), RX_STATS(ring_stats.ringFull), RX_STATS(ring_stats.ringEmpty), RX_STATS(ring_stats.ringUsageHigh), RX_STATS(ring_stats.ringUsageLow), RX_STATS(ring_stats.RingUtilCount), RX_STATS(gsi_stats.bamFifoFull), RX_STATS(gsi_stats.bamFifoEmpty), RX_STATS(gsi_stats.bamFifoUsageHigh), RX_STATS(gsi_stats.bamFifoUsageLow), RX_STATS(gsi_stats.bamUtilCount), RX_STATS(num_db), RX_STATS(num_qmb_int_handled), RX_STATS(ipa_pipe_number)); for (i = 0; i < IPA_UC_MAX_NTN_TX_CHANNELS; i++) { nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, "TX%d num_pkts_psr=%u\n" "TX%d ringFull=%u\n" "TX%d ringEmpty=%u\n" "TX%d ringUsageHigh=%u\n" "TX%d ringUsageLow=%u\n" "TX%d RingUtilCount=%u\n" "TX%d bamFifoFull=%u\n" "TX%d bamFifoEmpty=%u\n" "TX%d bamFifoUsageHigh=%u\n" "TX%d bamFifoUsageLow=%u\n" "TX%d bamUtilCount=%u\n" "TX%d num_db=%u\n" "TX%d num_qmb_int_handled=%u\n" "TX%d ipa_pipe_number=%u\n", i, TX_STATS(i, num_pkts_processed), i, TX_STATS(i, ring_stats.ringFull), i, TX_STATS(i, ring_stats.ringEmpty), i, TX_STATS(i, ring_stats.ringUsageHigh), i, TX_STATS(i, ring_stats.ringUsageLow), i, TX_STATS(i, ring_stats.RingUtilCount), i, TX_STATS(i, gsi_stats.bamFifoFull), i, TX_STATS(i, gsi_stats.bamFifoEmpty), i, TX_STATS(i, gsi_stats.bamFifoUsageHigh), i, TX_STATS(i, gsi_stats.bamFifoUsageLow), i, TX_STATS(i, gsi_stats.bamUtilCount), i, TX_STATS(i, num_db), i, TX_STATS(i, num_qmb_int_handled), i, TX_STATS(i, ipa_pipe_number)); cnt += nbytes; } for (i = 0; i < IPA_UC_MAX_NTN_RX_CHANNELS; i++) { nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, "RX%d num_pkts_psr=%u\n" "RX%d ringFull=%u\n" "RX%d ringEmpty=%u\n" "RX%d ringUsageHigh=%u\n" "RX%d ringUsageLow=%u\n" "RX%d RingUtilCount=%u\n" "RX%d bamFifoFull=%u\n" "RX%d bamFifoEmpty=%u\n" "RX%d bamFifoUsageHigh=%u\n" "RX%d bamFifoUsageLow=%u\n" "RX%d bamUtilCount=%u\n" "RX%d num_db=%u\n" "RX%d num_qmb_int_handled=%u\n" "RX%d ipa_pipe_number=%u\n", i, RX_STATS(i, num_pkts_processed), i, RX_STATS(i, ring_stats.ringFull), i, RX_STATS(i, ring_stats.ringEmpty), i, RX_STATS(i, ring_stats.ringUsageHigh), i, RX_STATS(i, ring_stats.ringUsageLow), i, RX_STATS(i, ring_stats.RingUtilCount), i, RX_STATS(i, gsi_stats.bamFifoFull), i, RX_STATS(i, gsi_stats.bamFifoEmpty), i, RX_STATS(i, gsi_stats.bamFifoUsageHigh), i, RX_STATS(i, gsi_stats.bamFifoUsageLow), i, RX_STATS(i, gsi_stats.bamUtilCount), i, RX_STATS(i, num_db), i, RX_STATS(i, num_qmb_int_handled), i, RX_STATS(i, ipa_pipe_number)); cnt += nbytes; } } else { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "Fail to read NTN stats\n"); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_uc_ntn.c +110 −45 Original line number Diff line number Diff line Loading @@ -69,10 +69,12 @@ struct IpaHwEventLogInfoData_t *uc_event_top_mmio) */ int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats) { #define TX_STATS(y) stats->tx_ch_stats[0].y = \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->tx_ch_stats[0].y #define RX_STATS(y) stats->rx_ch_stats[0].y = \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->rx_ch_stats[0].y #define TX_STATS(x, y) stats->tx_ch_stats[x].y = \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->tx_ch_stats[x].y #define RX_STATS(x, y) stats->rx_ch_stats[x].y = \ ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_mmio->rx_ch_stats[x].y int i = 0; if (unlikely(!ipa3_ctx)) { IPAERR("IPA driver was not initialized\n"); Loading @@ -87,36 +89,39 @@ int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats) } IPA_ACTIVE_CLIENTS_INC_SIMPLE(); TX_STATS(num_pkts_processed); TX_STATS(ring_stats.ringFull); TX_STATS(ring_stats.ringEmpty); TX_STATS(ring_stats.ringUsageHigh); TX_STATS(ring_stats.ringUsageLow); TX_STATS(ring_stats.RingUtilCount); TX_STATS(gsi_stats.bamFifoFull); TX_STATS(gsi_stats.bamFifoEmpty); TX_STATS(gsi_stats.bamFifoUsageHigh); TX_STATS(gsi_stats.bamFifoUsageLow); TX_STATS(gsi_stats.bamUtilCount); TX_STATS(num_db); TX_STATS(num_qmb_int_handled); TX_STATS(ipa_pipe_number); RX_STATS(num_pkts_processed); RX_STATS(ring_stats.ringFull); RX_STATS(ring_stats.ringEmpty); RX_STATS(ring_stats.ringUsageHigh); RX_STATS(ring_stats.ringUsageLow); RX_STATS(ring_stats.RingUtilCount); RX_STATS(gsi_stats.bamFifoFull); RX_STATS(gsi_stats.bamFifoEmpty); RX_STATS(gsi_stats.bamFifoUsageHigh); RX_STATS(gsi_stats.bamFifoUsageLow); RX_STATS(gsi_stats.bamUtilCount); RX_STATS(num_db); RX_STATS(num_qmb_int_handled); RX_STATS(ipa_pipe_number); for (i = 0; i < IPA_UC_MAX_NTN_TX_CHANNELS; i++) { TX_STATS(i, num_pkts_processed); TX_STATS(i, ring_stats.ringFull); TX_STATS(i, ring_stats.ringEmpty); TX_STATS(i, ring_stats.ringUsageHigh); TX_STATS(i, ring_stats.ringUsageLow); TX_STATS(i, ring_stats.RingUtilCount); TX_STATS(i, gsi_stats.bamFifoFull); TX_STATS(i, gsi_stats.bamFifoEmpty); TX_STATS(i, gsi_stats.bamFifoUsageHigh); TX_STATS(i, gsi_stats.bamFifoUsageLow); TX_STATS(i, gsi_stats.bamUtilCount); TX_STATS(i, num_db); TX_STATS(i, num_qmb_int_handled); TX_STATS(i, ipa_pipe_number); } for (i = 0; i < IPA_UC_MAX_NTN_RX_CHANNELS; i++) { RX_STATS(i, num_pkts_processed); RX_STATS(i, ring_stats.ringFull); RX_STATS(i, ring_stats.ringEmpty); RX_STATS(i, ring_stats.ringUsageHigh); RX_STATS(i, ring_stats.ringUsageLow); RX_STATS(i, ring_stats.RingUtilCount); RX_STATS(i, gsi_stats.bamFifoFull); RX_STATS(i, gsi_stats.bamFifoEmpty); RX_STATS(i, gsi_stats.bamFifoUsageHigh); RX_STATS(i, gsi_stats.bamFifoUsageLow); RX_STATS(i, gsi_stats.bamUtilCount); RX_STATS(i, num_db); RX_STATS(i, num_qmb_int_handled); RX_STATS(i, ipa_pipe_number); } IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); Loading Loading @@ -177,6 +182,12 @@ int ipa3_ntn_init(void) ipa3_uc_register_handlers(IPA_HW_FEATURE_NTN, &uc_ntn_cbs); /* ntn_init */ ipa3_ctx->uc_ntn_ctx.uc_ready_cb = NULL; ipa3_ctx->uc_ntn_ctx.priv = NULL; ipa3_ctx->uc_ntn_ctx.ntn_reg_base_ptr_pa_rd = 0x0; ipa3_ctx->uc_ntn_ctx.smmu_mapped = 0; return 0; } Loading Loading @@ -213,6 +224,7 @@ static int ipa3_uc_send_ntn_setup_pipe_cmd( IPADBG("num_buffers = %d\n", ntn_info->num_buffers); IPADBG("data_buff_size = %d\n", ntn_info->data_buff_size); IPADBG("tail_ptr_base_pa = 0x%pa\n", &ntn_info->ntn_reg_base_ptr_pa); IPADBG("db_mode = %d\n", ntn_info->db_mode); if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) cmd.size = sizeof(*cmd_data_v4_0); else Loading Loading @@ -248,6 +260,7 @@ static int ipa3_uc_send_ntn_setup_pipe_cmd( Ntn_params->num_buffers = ntn_info->num_buffers; Ntn_params->ntn_reg_base_ptr_pa = ntn_info->ntn_reg_base_ptr_pa; Ntn_params->data_buff_size = ntn_info->data_buff_size; Ntn_params->db_mode = ntn_info->db_mode; Ntn_params->ipa_pipe_number = ipa_ep_idx; Ntn_params->dir = dir; Loading @@ -263,7 +276,7 @@ static int ipa3_uc_send_ntn_setup_pipe_cmd( } static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params, bool map, bool map_unmap_once) bool map) { struct iommu_domain *smmu_domain; int result; Loading @@ -273,12 +286,20 @@ static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params, u64 iova_p; phys_addr_t pa_p; u32 size_p; bool map_unmap_once; if (params->data_buff_size > PAGE_SIZE) { IPAERR("invalid data buff size\n"); return -EINVAL; } /* only map/unmap once the ntn_reg_base_ptr_pa */ map_unmap_once = (map && ipa3_ctx->uc_ntn_ctx.smmu_mapped == 0) || (!map && ipa3_ctx->uc_ntn_ctx.smmu_mapped == 1); IPADBG(" %s uC regs, smmu_mapped %d\n", map ? "map" : "unmap", ipa3_ctx->uc_ntn_ctx.smmu_mapped); if (map_unmap_once) { result = ipa3_smmu_map_peer_reg(rounddown( params->ntn_reg_base_ptr_pa, PAGE_SIZE), Loading @@ -288,7 +309,33 @@ static int ipa3_smmu_map_uc_ntn_pipes(struct ipa_ntn_setup_info *params, map ? "map" : "unmap", result); goto fail; } /* backup the ntn_reg_base_ptr_pa_r */ ipa3_ctx->uc_ntn_ctx.ntn_reg_base_ptr_pa_rd = rounddown(params->ntn_reg_base_ptr_pa, PAGE_SIZE); IPADBG(" %s ntn_reg_base_ptr_pa regs 0X%0x smmu_mapped %d\n", map ? "map" : "unmap", (unsigned long long) ipa3_ctx->uc_ntn_ctx.ntn_reg_base_ptr_pa_rd, ipa3_ctx->uc_ntn_ctx.smmu_mapped); } /* update smmu_mapped reference count */ if (map) { ipa3_ctx->uc_ntn_ctx.smmu_mapped++; IPADBG("uc_ntn_ctx.smmu_mapped %d\n", ipa3_ctx->uc_ntn_ctx.smmu_mapped); } else { if (ipa3_ctx->uc_ntn_ctx.smmu_mapped == 0) { IPAERR("Invalid smmu_mapped %d\n", ipa3_ctx->uc_ntn_ctx.smmu_mapped); goto fail; } else { ipa3_ctx->uc_ntn_ctx.smmu_mapped--; IPADBG("uc_ntn_ctx.smmu_mapped %d\n", ipa3_ctx->uc_ntn_ctx.smmu_mapped); } } if (params->smmu_enabled) { IPADBG("smmu is enabled on EMAC\n"); result = ipa3_smmu_map_peer_buff((u64)params->ring_base_iova, Loading Loading @@ -397,7 +444,6 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, int ipa_ep_idx_ul; int ipa_ep_idx_dl; int result = 0; bool unmapped = false; if (in == NULL) { IPAERR("invalid input\n"); Loading Loading @@ -451,7 +497,7 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, goto fail; } result = ipa3_smmu_map_uc_ntn_pipes(&in->ul, true, true); result = ipa3_smmu_map_uc_ntn_pipes(&in->ul, true); if (result) { IPAERR("failed to map SMMU for UL %d\n", result); goto fail; Loading @@ -471,7 +517,10 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, goto fail_disable_dp_ul; } ipa3_install_dflt_flt_rules(ipa_ep_idx_ul); outp->ul_uc_db_pa = IPA_UC_NTN_DB_PA_RX; /* Rx: IPA_UC_MAILBOX_m_n m = 1, n =3 mmio*/ outp->ul_uc_db_iomem = ipa3_ctx->mmio + ipahal_get_reg_mn_ofst(IPA_UC_MAILBOX_m_n, 1, 3); ep_ul->uc_offload_state |= IPA_UC_OFFLOAD_CONNECTED; IPADBG("client %d (ep: %d) connected\n", in->ul.client, ipa_ep_idx_ul); Loading @@ -490,7 +539,7 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, goto fail_disable_dp_ul; } result = ipa3_smmu_map_uc_ntn_pipes(&in->dl, true, false); result = ipa3_smmu_map_uc_ntn_pipes(&in->dl, true); if (result) { IPAERR("failed to map SMMU for DL %d\n", result); goto fail_disable_dp_ul; Loading @@ -509,7 +558,10 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, result = -EFAULT; goto fail_disable_dp_dl; } outp->dl_uc_db_pa = IPA_UC_NTN_DB_PA_TX; /* Tx: IPA_UC_MAILBOX_m_n m = 1, n =4 mmio */ outp->dl_uc_db_iomem = ipa3_ctx->mmio + ipahal_get_reg_mn_ofst(IPA_UC_MAILBOX_m_n, 1, 4); ep_dl->uc_offload_state |= IPA_UC_OFFLOAD_CONNECTED; IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); Loading @@ -521,12 +573,11 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, fail_disable_dp_dl: ipa3_disable_data_path(ipa_ep_idx_dl); fail_smmu_unmap_dl: ipa3_smmu_map_uc_ntn_pipes(&in->dl, false, true); unmapped = true; ipa3_smmu_map_uc_ntn_pipes(&in->dl, false); fail_disable_dp_ul: ipa3_disable_data_path(ipa_ep_idx_ul); fail_smmu_unmap_ul: ipa3_smmu_map_uc_ntn_pipes(&in->ul, false, !unmapped); ipa3_smmu_map_uc_ntn_pipes(&in->ul, false); fail: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return result; Loading @@ -549,6 +600,20 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, IPADBG("ep_ul = %d\n", ipa_ep_idx_ul); IPADBG("ep_dl = %d\n", ipa_ep_idx_dl); if (ipa_ep_idx_ul == IPA_EP_NOT_ALLOCATED || ipa_ep_idx_ul >= IPA3_MAX_NUM_PIPES) { IPAERR("ipa_ep_idx_ul %d invalid\n", ipa_ep_idx_ul); return -EFAULT; } if (ipa_ep_idx_dl == IPA_EP_NOT_ALLOCATED || ipa_ep_idx_dl >= IPA3_MAX_NUM_PIPES) { IPAERR("ep ipa_ep_idx_dl %d invalid\n", ipa_ep_idx_dl); return -EFAULT; } ep_ul = &ipa3_ctx->ep[ipa_ep_idx_ul]; ep_dl = &ipa3_ctx->ep[ipa_ep_idx_dl]; Loading Loading @@ -606,7 +671,7 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, } /* unmap the DL pipe */ result = ipa3_smmu_map_uc_ntn_pipes(¶ms->dl, false, false); result = ipa3_smmu_map_uc_ntn_pipes(¶ms->dl, false); if (result) { IPAERR("failed to unmap SMMU for DL %d\n", result); goto fail; Loading @@ -627,7 +692,7 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, } /* unmap the UL pipe */ result = ipa3_smmu_map_uc_ntn_pipes(¶ms->ul, false, true); result = ipa3_smmu_map_uc_ntn_pipes(¶ms->ul, false); if (result) { IPAERR("failed to unmap SMMU for UL %d\n", result); goto fail; Loading
drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h +8 −4 Original line number Diff line number Diff line /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -20,8 +20,8 @@ * Neutrino protocol related data structures */ #define IPA_UC_MAX_NTN_TX_CHANNELS 1 #define IPA_UC_MAX_NTN_RX_CHANNELS 1 #define IPA_UC_MAX_NTN_TX_CHANNELS 2 #define IPA_UC_MAX_NTN_RX_CHANNELS 2 #define IPA_NTN_TX_DIR 1 #define IPA_NTN_RX_DIR 2 Loading Loading @@ -283,6 +283,8 @@ struct ipa3_uc_ntn_ctx { struct Ipa3HwStatsNTNInfoData_t *ntn_uc_stats_mmio; void *priv; ipa_uc_ready_cb uc_ready_cb; phys_addr_t ntn_reg_base_ptr_pa_rd; u32 smmu_mapped; }; /** Loading Loading @@ -361,7 +363,9 @@ struct Ipa3HwNtnSetUpCmdData_t { u8 ipa_pipe_number; u8 dir; u16 data_buff_size; u8 db_mode; u8 reserved1; u16 reserved2; } __packed; /** Loading