diff --git a/drivers/platform/msm/ipa/ipa_api.c b/drivers/platform/msm/ipa/ipa_api.c index 0c31e146ecd9..e2ace331fbf5 100644 --- a/drivers/platform/msm/ipa/ipa_api.c +++ b/drivers/platform/msm/ipa/ipa_api.c @@ -3706,6 +3706,45 @@ void ipa_deregister_client_callback(enum ipa_client_type client) } EXPORT_SYMBOL(ipa_deregister_client_callback); +int ipa_uc_debug_stats_alloc( + struct IpaHwOffloadStatsAllocCmdData_t cmdinfo) +{ + int ret; + + IPA_API_DISPATCH_RETURN(ipa_uc_debug_stats_alloc, cmdinfo); + + return ret; +} +EXPORT_SYMBOL(ipa_uc_debug_stats_alloc); + +int ipa_uc_debug_stats_dealloc(uint32_t prot_id) +{ + int ret; + + IPA_API_DISPATCH_RETURN(ipa_uc_debug_stats_dealloc, prot_id); + + return ret; +} +EXPORT_SYMBOL(ipa_uc_debug_stats_dealloc); + +void ipa_get_gsi_stats(int prot_id, + struct ipa_uc_dbg_ring_stats *stats) +{ + IPA_API_DISPATCH(ipa_get_gsi_stats, + prot_id, stats); +} +EXPORT_SYMBOL(ipa_get_gsi_stats); + +int ipa_get_prot_id(enum ipa_client_type client) +{ + int ret; + + IPA_API_DISPATCH_RETURN(ipa_get_prot_id, + client); + + return ret; +} +EXPORT_SYMBOL(ipa_get_prot_id); static const struct dev_pm_ops ipa_pm_ops = { .suspend_noirq = ipa_ap_suspend, diff --git a/drivers/platform/msm/ipa/ipa_api.h b/drivers/platform/msm/ipa/ipa_api.h index 6bd6bdd0f4e3..7140acb140bc 100644 --- a/drivers/platform/msm/ipa/ipa_api.h +++ b/drivers/platform/msm/ipa/ipa_api.h @@ -470,8 +470,18 @@ struct ipa_api_controller { bool (*teth_port_state)(void), enum ipa_client_type client); void (*ipa_deregister_client_callback)(enum ipa_client_type client); + bool (*ipa_get_lan_rx_napi)(void); + int (*ipa_uc_debug_stats_alloc)( + struct IpaHwOffloadStatsAllocCmdData_t cmdinfo); + + int (*ipa_uc_debug_stats_dealloc)(uint32_t prot_id); + + void (*ipa_get_gsi_stats)(int prot_id, + struct ipa_uc_dbg_ring_stats *stats); + + int (*ipa_get_prot_id)(enum ipa_client_type client); }; #if IS_ENABLED(CONFIG_IPA3) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 4cf1e5bf1020..66b304309670 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -6555,7 +6555,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, for (i = 0; i < IPA_HW_PROTOCOL_MAX; i++) { ipa3_ctx->gsi_info[i].protocol = i; /* initialize all to be not started */ - for (j = 0; j < MAX_CH_STATS_SUPPORTED; j++) + for (j = 0; j < IPA_MAX_CH_STATS_SUPPORTED; j++) ipa3_ctx->gsi_info[i].ch_id_info[j].ch_id = 0xFF; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 6d1b43e3dfd7..11d2d51abc96 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -739,7 +739,7 @@ EXPORT_SYMBOL(ipa3_set_usb_max_packet_size); * @note Cannot be called from atomic context * */ -int ipa3_get_usb_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) +int ipa3_get_usb_gsi_stats(struct ipa_uc_dbg_ring_stats *stats) { int i; @@ -1801,5 +1801,51 @@ int ipa3_clear_endpoint_delay(u32 clnt_hdl) IPADBG("client (ep: %d) removed ep delay\n", clnt_hdl); + return 0; +} + +/** + * ipa3_get_aqc_gsi_stats() - Query AQC gsi stats from uc + * @stats: [inout] stats blob from client populated by driver + * + * Returns: 0 on success, negative on failure + * + * @note Cannot be called from atomic context + * + */ +int ipa3_get_aqc_gsi_stats(struct ipa_uc_dbg_ring_stats *stats) +{ + int i; + + if (!ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_mmio) { + IPAERR("bad parms NULL aqc_gsi_stats_mmio\n"); + return -EINVAL; + } + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); + for (i = 0; i < MAX_AQC_CHANNELS; i++) { + stats->ring[i].ringFull = ioread32( + ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGFULL_OFF); + stats->ring[i].ringEmpty = ioread32( + ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGEMPTY_OFF); + stats->ring[i].ringUsageHigh = ioread32( + ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGUSAGEHIGH_OFF); + stats->ring[i].ringUsageLow = ioread32( + ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGUSAGELOW_OFF); + stats->ring[i].RingUtilCount = ioread32( + ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_mmio + + i * IPA3_UC_DEBUG_STATS_OFF + + IPA3_UC_DEBUG_STATS_RINGUTILCOUNT_OFF); + } + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + + return 0; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index 71b8d2d414d7..6fc1eba69641 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -2416,7 +2416,7 @@ static ssize_t ipa3_read_ipahal_regs(struct file *file, char __user *ubuf, static ssize_t ipa3_read_wdi_gsi_stats(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { - struct ipa3_uc_dbg_ring_stats stats; + struct ipa_uc_dbg_ring_stats stats; int nbytes; int cnt = 0; @@ -2464,7 +2464,7 @@ done: static ssize_t ipa3_read_wdi3_gsi_stats(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { - struct ipa3_uc_dbg_ring_stats stats; + struct ipa_uc_dbg_ring_stats stats; int nbytes; int cnt = 0; @@ -2529,6 +2529,7 @@ done: static ssize_t ipa3_read_aqc_gsi_stats(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { + struct ipa_uc_dbg_ring_stats stats; int nbytes; int cnt = 0; @@ -2538,7 +2539,36 @@ static ssize_t ipa3_read_aqc_gsi_stats(struct file *file, cnt += nbytes; goto done; } - return 0; + if (!ipa3_get_aqc_gsi_stats(&stats)) { + nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, + "TX ringFull=%u\n" + "TX ringEmpty=%u\n" + "TX ringUsageHigh=%u\n" + "TX ringUsageLow=%u\n" + "TX RingUtilCount=%u\n", + stats.ring[1].ringFull, + stats.ring[1].ringEmpty, + stats.ring[1].ringUsageHigh, + stats.ring[1].ringUsageLow, + stats.ring[1].RingUtilCount); + cnt += nbytes; + nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, + "RX ringFull=%u\n" + "RX ringEmpty=%u\n" + "RX ringUsageHigh=%u\n" + "RX ringUsageLow=%u\n" + "RX RingUtilCount=%u\n", + stats.ring[0].ringFull, + stats.ring[0].ringEmpty, + stats.ring[0].ringUsageHigh, + stats.ring[0].ringUsageLow, + stats.ring[0].RingUtilCount); + cnt += nbytes; + } else { + nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, + "Fail to read AQC GSI stats\n"); + cnt += nbytes; + } done: return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } @@ -2546,7 +2576,7 @@ done: static ssize_t ipa3_read_mhip_gsi_stats(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { - struct ipa3_uc_dbg_ring_stats stats; + struct ipa_uc_dbg_ring_stats stats; int nbytes; int cnt = 0; @@ -2618,7 +2648,7 @@ done: static ssize_t ipa3_read_usb_gsi_stats(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { - struct ipa3_uc_dbg_ring_stats stats; + struct ipa_uc_dbg_ring_stats stats; int nbytes; int cnt = 0; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 9211f15e08b7..603e4679cae8 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1403,15 +1403,6 @@ struct ipa3_stats { #define IPA3_UC_DEBUG_STATS_RINGUTILCOUNT_OFF (16) #define IPA3_UC_DEBUG_STATS_OFF (20) -/** - * struct ipa3_uc_dbg_gsi_stats - uC dbg stats info for each - * offloading protocol - * @ring: ring stats for each channel - */ -struct ipa3_uc_dbg_ring_stats { - struct IpaHwRingStats_t ring[MAX_CH_STATS_SUPPORTED]; -}; - /** * struct ipa3_uc_dbg_stats - uC dbg stats for offloading * protocols @@ -1602,6 +1593,14 @@ struct ipa3_mhip_ctx { struct ipa3_uc_dbg_stats dbg_stats; }; +/** + * struct ipa3_aqc_ctx - IPA aqc context + */ +struct ipa3_aqc_ctx { + struct ipa3_uc_dbg_stats dbg_stats; +}; + + /** * struct ipa3_transport_pm - transport power management related members * @transport_pm_mutex: Mutex to protect the transport_pm functionality. @@ -2040,6 +2039,7 @@ struct ipa3_context { struct ipa3_wdi3_ctx wdi3_ctx; struct ipa3_usb_ctx usb_ctx; struct ipa3_mhip_ctx mhip_ctx; + struct ipa3_aqc_ctx aqc_ctx; atomic_t ipa_clk_vote; int (*client_lock_unlock[IPA_MAX_CLNT])(bool is_lock); @@ -2642,10 +2642,14 @@ int ipa3_disconnect_gsi_wdi_pipe(u32 clnt_hdl); int ipa3_resume_wdi_pipe(u32 clnt_hdl); int ipa3_resume_gsi_wdi_pipe(u32 clnt_hdl); int ipa3_suspend_wdi_pipe(u32 clnt_hdl); -int ipa3_get_wdi_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats); -int ipa3_get_wdi3_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats); -int ipa3_get_usb_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats); +void ipa3_get_gsi_stats(int prot_id, + struct ipa_uc_dbg_ring_stats *stats); +int ipa3_get_wdi_gsi_stats(struct ipa_uc_dbg_ring_stats *stats); +int ipa3_get_wdi3_gsi_stats(struct ipa_uc_dbg_ring_stats *stats); +int ipa3_get_usb_gsi_stats(struct ipa_uc_dbg_ring_stats *stats); +int ipa3_get_aqc_gsi_stats(struct ipa_uc_dbg_ring_stats *stats); int ipa3_get_wdi_stats(struct IpaHwStatsWDIInfoData_t *stats); +int ipa3_get_prot_id(enum ipa_client_type client); u16 ipa3_get_smem_restr_bytes(void); int ipa3_broadcast_wdi_quota_reach_ind(uint32_t fid, uint64_t num_bytes); int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in, @@ -3019,6 +3023,7 @@ int ipa3_uc_quota_monitor(uint64_t quota); int ipa3_uc_bw_monitor(struct ipa_wdi_bw_info *info); int ipa3_uc_setup_event_ring(void); int ipa3_set_wlan_tx_info(struct ipa_wdi_tx_info *info); +int ipa3_uc_debug_stats_dealloc(uint32_t prot_id); void ipa3_tag_destroy_imm(void *user1, int user2); const struct ipa_gsi_ep_config *ipa3_get_gsi_ep_info (enum ipa_client_type client); @@ -3185,8 +3190,8 @@ int ipa3_is_mhip_offload_enabled(void); int ipa_mpm_reset_dma_mode(enum ipa_client_type src_pipe, enum ipa_client_type dst_pipe); int ipa_mpm_panic_handler(char *buf, int size); -int ipa3_get_mhip_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats); int ipa3_mpm_enable_adpl_over_odl(bool enable); +int ipa3_get_mhip_gsi_stats(struct ipa_uc_dbg_ring_stats *stats); #else /* IS_ENABLED(CONFIG_IPA3_MHI_PRIME_MANAGER) */ static inline int ipa_mpm_mhip_xdci_pipe_enable( enum ipa_usb_teth_prot prot) @@ -3217,7 +3222,7 @@ static inline int ipa_mpm_panic_handler(char *buf, int size) return 0; } -static inline int ipa3_get_mhip_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) +static inline int ipa3_get_mhip_gsi_stats(struct ipa_uc_dbg_ring_stats *stats) { return 0; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c index 1d2a38a98bb4..3a97943ebc84 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c @@ -3022,7 +3022,7 @@ int ipa_mpm_panic_handler(char *buf, int size) * @note Cannot be called from atomic context * */ -int ipa3_get_mhip_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) +int ipa3_get_mhip_gsi_stats(struct ipa_uc_dbg_ring_stats *stats) { int i; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c index 380ebaf61ff2..5d5a78d8da13 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c @@ -244,11 +244,11 @@ const char *ipa_hw_error_str(enum ipa3_hw_errors err_type) static void ipa3_uc_save_dbg_stats(u32 size) { - u8 protocol_id; + u8 prot_id; u32 addr_offset; void __iomem *mmio; - protocol_id = IPA_UC_DBG_STATS_GET_PROT_ID( + prot_id = IPA_UC_DBG_STATS_GET_PROT_ID( ipa3_ctx->uc_ctx.uc_sram_mmio->responseParams_1); addr_offset = IPA_UC_DBG_STATS_GET_OFFSET( ipa3_ctx->uc_ctx.uc_sram_mmio->responseParams_1); @@ -259,36 +259,72 @@ static void ipa3_uc_save_dbg_stats(u32 size) IPAERR("unexpected NULL mmio\n"); return; } - switch (protocol_id) { + switch (prot_id) { case IPA_HW_PROTOCOL_AQC: + if (!ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_mmio) { + ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_size = + size; + ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_ofst = + addr_offset; + ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_mmio = + mmio; + } else + goto unmap; break; case IPA_HW_PROTOCOL_11ad: break; case IPA_HW_PROTOCOL_WDI: - ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_size = size; - ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_ofst = addr_offset; - ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_mmio = mmio; + if (!ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_mmio) { + ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_size = + size; + ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_ofst = + addr_offset; + ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_mmio = + mmio; + } else + goto unmap; break; case IPA_HW_PROTOCOL_WDI3: - ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_size = size; - ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_ofst = addr_offset; - ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_mmio = mmio; + if (!ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_mmio) { + ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_size = + size; + ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_ofst = + addr_offset; + ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_mmio = + mmio; + } else + goto unmap; break; case IPA_HW_PROTOCOL_ETH: break; case IPA_HW_PROTOCOL_MHIP: - ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_size = size; - ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_ofst = addr_offset; - ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_mmio = mmio; + if (!ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_mmio) { + ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_size = + size; + ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_ofst = + addr_offset; + ipa3_ctx->mhip_ctx.dbg_stats.uc_dbg_stats_mmio = + mmio; + } else + goto unmap; break; case IPA_HW_PROTOCOL_USB: - ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_size = size; - ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_ofst = addr_offset; - ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_mmio = mmio; + if (!ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_mmio) { + ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_size = + size; + ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_ofst = + addr_offset; + ipa3_ctx->usb_ctx.dbg_stats.uc_dbg_stats_mmio = + mmio; + } else + goto unmap; break; default: - IPAERR("unknown protocols %d\n", protocol_id); + IPAERR("unknown protocols %d\n", prot_id); } + return; +unmap: + iounmap(mmio); } static void ipa3_log_evt_hdlr(void) @@ -1131,7 +1167,7 @@ cleanup: return result; } -int ipa3_uc_debug_stats_dealloc(uint32_t protocol) +int ipa3_uc_debug_stats_dealloc(uint32_t prot_id) { int result; struct ipa_mem_buffer cmd; @@ -1147,7 +1183,7 @@ int ipa3_uc_debug_stats_dealloc(uint32_t protocol) } cmd_data = (struct IpaHwOffloadStatsDeAllocCmdData_t *) cmd.base; - cmd_data->protocol = protocol; + cmd_data->protocol = prot_id; command = IPA_CPU_2_HW_CMD_OFFLOAD_STATS_DEALLOC; IPA_ACTIVE_CLIENTS_INC_SIMPLE(); @@ -1160,8 +1196,10 @@ int ipa3_uc_debug_stats_dealloc(uint32_t protocol) IPAERR("fail to dealloc offload stats\n"); goto cleanup; } - switch (protocol) { + switch (prot_id) { case IPA_HW_PROTOCOL_AQC: + iounmap(ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_mmio); + ipa3_ctx->aqc_ctx.dbg_stats.uc_dbg_stats_mmio = NULL; break; case IPA_HW_PROTOCOL_11ad: break; @@ -1176,7 +1214,7 @@ int ipa3_uc_debug_stats_dealloc(uint32_t protocol) case IPA_HW_PROTOCOL_ETH: break; default: - IPAERR("unknown protocols %d\n", protocol); + IPAERR("unknown protocols %d\n", prot_id); } result = 0; cleanup: diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h index 2b373277b8a1..2c891160f7a9 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h @@ -474,33 +474,6 @@ enum ipa_cpu_2_hw_offload_commands { FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 8), }; -/** - * struct IpaOffloadStatschannel_info - channel info for uC - * stats - * @dir: Director of the channel ID DIR_CONSUMER =0, - * DIR_PRODUCER = 1 - * @ch_id: Channel id of the IPA endpoint for which stats need - * to be calculated, 0xFF means invalid channel or disable stats - * on already stats enabled channel - */ -struct IpaOffloadStatschannel_info { - uint8_t dir; - uint8_t ch_id; -} __packed; - -/** - * struct IpaHwOffloadStatsAllocCmdData_t - protocol info for uC - * stats start - * @protocol: Enum that indicates the protocol type - * @ch_id_info: Channel id of the IPA endpoint for which stats - * need to be calculated - */ -struct IpaHwOffloadStatsAllocCmdData_t { - uint32_t protocol; - struct IpaOffloadStatschannel_info - ch_id_info[MAX_CH_STATS_SUPPORTED]; -} __packed; - /** * struct IpaHwOffloadStatsDeAllocCmdData_t - protocol info for * uC stats stop diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c index d6a057b6477c..c0f66ecb100a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c @@ -419,7 +419,7 @@ static void ipa3_uc_wdi_event_handler(struct IpaHwSharedMemCommonMapping_t * @note Cannot be called from atomic context * */ -int ipa3_get_wdi_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) +int ipa3_get_wdi_gsi_stats(struct ipa_uc_dbg_ring_stats *stats) { int i; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index fb5753ad24f9..c0dc4cddde75 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -7327,6 +7327,14 @@ int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type, api_ctrl->ipa_deregister_client_callback = ipa3_deregister_client_callback; api_ctrl->ipa_get_lan_rx_napi = ipa3_get_lan_rx_napi; + api_ctrl->ipa_uc_debug_stats_alloc = + ipa3_uc_debug_stats_alloc; + api_ctrl->ipa_uc_debug_stats_dealloc = + ipa3_uc_debug_stats_dealloc; + api_ctrl->ipa_get_gsi_stats = + ipa3_get_gsi_stats; + api_ctrl->ipa_get_prot_id = + ipa3_get_prot_id; return 0; } @@ -8914,6 +8922,47 @@ int ipa3_ctx_get_type(enum ipa_type_mode type) } } +/** + * ipa3_get_gsi_stats() - Query gsi stats from uc + * @prot_id: IPA_HW_FEATURE_OFFLOAD protocol id + * @stats: [inout] stats blob from client populated by driver + * + * @note Cannot be called from atomic context + * + */ +void ipa3_get_gsi_stats(int prot_id, + struct ipa_uc_dbg_ring_stats *stats) +{ + switch (prot_id) { + case IPA_HW_PROTOCOL_AQC: + stats->num_ch = MAX_AQC_CHANNELS; + ipa3_get_aqc_gsi_stats(stats); + break; + case IPA_HW_PROTOCOL_11ad: + break; + case IPA_HW_PROTOCOL_WDI: + stats->num_ch = MAX_WDI2_CHANNELS; + ipa3_get_wdi_gsi_stats(stats); + break; + case IPA_HW_PROTOCOL_WDI3: + stats->num_ch = MAX_WDI3_CHANNELS; + ipa3_get_wdi3_gsi_stats(stats); + break; + case IPA_HW_PROTOCOL_ETH: + break; + case IPA_HW_PROTOCOL_MHIP: + stats->num_ch = MAX_MHIP_CHANNELS; + ipa3_get_mhip_gsi_stats(stats); + break; + case IPA_HW_PROTOCOL_USB: + stats->num_ch = MAX_USB_CHANNELS; + ipa3_get_usb_gsi_stats(stats); + break; + default: + IPAERR("unsupported HW feature %d\n", prot_id); + } +} + /** * ipa3_ctx_get_flag() - to read some ipa3_ctx_flags * @@ -8947,3 +8996,57 @@ u32 ipa3_ctx_get_num_pipes(void) { return ipa3_ctx->ipa_num_pipes; } + +/* + * ipa3_get_prot_id() - Query gsi protocol id + * @client: ipa_client_type + * + * return the prot_id based on the client type, + * return -EINVAL when no such mapping exists. + */ +int ipa3_get_prot_id(enum ipa_client_type client) +{ + int prot_id = -EINVAL; + + switch (client) { + case IPA_CLIENT_AQC_ETHERNET_CONS: + case IPA_CLIENT_AQC_ETHERNET_PROD: + prot_id = IPA_HW_PROTOCOL_AQC; + break; + case IPA_CLIENT_MHI_PRIME_TETH_PROD: + case IPA_CLIENT_MHI_PRIME_TETH_CONS: + case IPA_CLIENT_MHI_PRIME_RMNET_PROD: + case IPA_CLIENT_MHI_PRIME_RMNET_CONS: + prot_id = IPA_HW_PROTOCOL_MHIP; + break; + case IPA_CLIENT_WLAN1_PROD: + case IPA_CLIENT_WLAN1_CONS: + prot_id = IPA_HW_PROTOCOL_WDI; + break; + case IPA_CLIENT_WLAN2_PROD: + case IPA_CLIENT_WLAN2_CONS: + prot_id = IPA_HW_PROTOCOL_WDI3; + break; + case IPA_CLIENT_USB_PROD: + case IPA_CLIENT_USB_CONS: + prot_id = IPA_HW_PROTOCOL_USB; + break; + case IPA_CLIENT_ETHERNET_PROD: + case IPA_CLIENT_ETHERNET_CONS: + prot_id = IPA_HW_PROTOCOL_ETH; + break; + case IPA_CLIENT_WIGIG_PROD: + case IPA_CLIENT_WIGIG1_CONS: + case IPA_CLIENT_WIGIG2_CONS: + case IPA_CLIENT_WIGIG3_CONS: + case IPA_CLIENT_WIGIG4_CONS: + prot_id = IPA_HW_PROTOCOL_11ad; + break; + default: + IPAERR("unknown prot_id for client %d\n", + client); + } + + return prot_id; +} + diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c index 281558599e0f..99b031dd2059 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c @@ -948,7 +948,7 @@ exit: * @note Cannot be called from atomic context * */ -int ipa3_get_wdi3_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) +int ipa3_get_wdi3_gsi_stats(struct ipa_uc_dbg_ring_stats *stats) { int i; diff --git a/include/linux/ipa.h b/include/linux/ipa.h index b9881ee28e27..9cc0a34447fb 100644 --- a/include/linux/ipa.h +++ b/include/linux/ipa.h @@ -15,6 +15,7 @@ #define IPA_APPS_MAX_BW_IN_MBPS 700 #define IPA_BW_THRESHOLD_MAX 3 +#define IPA_MAX_CH_STATS_SUPPORTED 5 /** * enum ipa_transport_type * transport type: either GSI or SPS @@ -913,6 +914,33 @@ struct IpaHwBamStats_t { u32 bamUtilCount; } __packed; +/** + * struct IpaOffloadStatschannel_info - channel info for uC + * stats + * @dir: Direction of the channel ID DIR_CONSUMER =0, + * DIR_PRODUCER = 1 + * @ch_id: GSI ch_id of the IPA endpoint for which stats need + * to be calculated, 0xFF means invalid channel or disable stats + * on already stats enabled channel + */ +struct IpaOffloadStatschannel_info { + u8 dir; + u8 ch_id; +} __packed; + +/** + * struct IpaHwOffloadStatsAllocCmdData_t - protocol info for uC + * stats start + * @protocol: Enum that indicates the protocol type + * @ch_id_info: GSI ch_id and dir of the IPA endpoint for which stats + * need to be calculated + */ +struct IpaHwOffloadStatsAllocCmdData_t { + u32 protocol; + struct IpaOffloadStatschannel_info + ch_id_info[IPA_MAX_CH_STATS_SUPPORTED]; +} __packed; + /** * struct IpaHwRingStats_t - Structure holding the Ring statistics * @@ -933,6 +961,17 @@ struct IpaHwRingStats_t { u32 RingUtilCount; } __packed; +/** + * struct ipa_uc_dbg_ring_stats - uC dbg stats info for each + * offloading protocol + * @ring: ring stats for each channel + * @ch_num: number of ch supported for given protocol + */ +struct ipa_uc_dbg_ring_stats { + struct IpaHwRingStats_t ring[IPA_MAX_CH_STATS_SUPPORTED]; + u8 num_ch; +}; + /** * struct IpaHwStatsWDIRxInfoData_t - Structure holding the WDI Rx channel * structures @@ -1617,6 +1656,13 @@ enum ipa_transport_type ipa_get_transport_type(void); struct device *ipa_get_dma_dev(void); struct iommu_domain *ipa_get_smmu_domain(void); +int ipa_uc_debug_stats_alloc( + struct IpaHwOffloadStatsAllocCmdData_t cmdinfo); +int ipa_uc_debug_stats_dealloc(uint32_t protocol); +void ipa_get_gsi_stats(int prot_id, + struct ipa_uc_dbg_ring_stats *stats); +int ipa_get_prot_id(enum ipa_client_type client); + int ipa_disable_apps_wan_cons_deaggr(uint32_t agg_size, uint32_t agg_count); const struct ipa_gsi_ep_config *ipa_get_gsi_ep_info @@ -2539,6 +2585,27 @@ static inline bool ipa_get_lan_rx_napi(void) return false; } +static inline int ipa_uc_debug_stats_alloc( + struct IpaHwOffloadStatsAllocCmdData_t cmdinfo) +{ + return -EPERM; +} + +static inline int ipa_uc_debug_stats_dealloc(uint32_t protocol) +{ + return -EPERM; +} + +static inline void ipa_get_gsi_stats(int prot_id, + struct ipa_uc_dbg_ring_stats *stats) +{ +} + +static inline int ipa_get_prot_id(enum ipa_client_type client) +{ + return -EPERM; +} + #endif /* IS_ENABLED(CONFIG_IPA3) */ #endif /* _IPA_H_ */