Loading drivers/platform/msm/ipa/ipa_v3/ipa.c +10 −1 Original line number Diff line number Diff line Loading @@ -6143,7 +6143,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, struct platform_device *ipa_pdev) { int result = 0; int i; int i, j; struct ipa3_rt_tbl_set *rset; struct ipa_active_client_logging_info log_info; struct cdev *cdev; Loading @@ -6165,6 +6165,15 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, for (i = 0; i < IPA_SMMU_CB_MAX; i++) ipa3_ctx->s1_bypass_arr[i] = true; /* initialize the gsi protocol info for uC debug stats */ 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++) ipa3_ctx->gsi_info[i].ch_id_info[j].ch_id = 0xFF; } ipa3_ctx->ipa_wrapper_base = resource_p->ipa_mem_base; ipa3_ctx->ipa_wrapper_size = resource_p->ipa_mem_size; ipa3_ctx->ipa_hw_type = resource_p->ipa_hw_type; Loading drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +146 −0 Original line number Diff line number Diff line Loading @@ -1956,6 +1956,136 @@ static ssize_t ipa3_read_ipahal_regs(struct file *file, char __user *ubuf, return 0; } 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; int nbytes; int cnt = 0; if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; goto done; } if (!ipa3_get_wdi_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 WDI GSI stats\n"); cnt += nbytes; } done: return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } 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; int nbytes; int cnt = 0; if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; goto done; } if (!ipa3_get_wdi3_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 WDI GSI stats\n"); cnt += nbytes; } done: return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } static ssize_t ipa3_read_11ad_gsi_stats(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { int nbytes; int cnt = 0; if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; goto done; } return 0; done: return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } static ssize_t ipa3_read_aqc_gsi_stats(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { int nbytes; int cnt = 0; if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; goto done; } return 0; done: return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } static void ipa_dump_status(struct ipahal_pkt_status *status) { IPA_DUMP_STATUS_FIELD(status_opcode); Loading Loading @@ -2230,6 +2360,22 @@ static const struct ipa3_debugfs_file debugfs_files[] = { "ipa_dump_regs", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_ipahal_regs, } }, { "wdi_gsi_stats", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_wdi_gsi_stats, } }, { "wdi3_gsi_stats", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_wdi3_gsi_stats, } }, { "11ad_gsi_stats", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_11ad_gsi_stats, } }, { "aqc_gsi_stats", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_aqc_gsi_stats, } } }; Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +49 −0 Original line number Diff line number Diff line Loading @@ -1296,6 +1296,36 @@ struct ipa3_stats { u32 tx_non_linear; }; /* offset for each stats */ #define IPA3_UC_DEBUG_STATS_RINGFULL_OFF (0) #define IPA3_UC_DEBUG_STATS_RINGEMPTY_OFF (4) #define IPA3_UC_DEBUG_STATS_RINGUSAGEHIGH_OFF (8) #define IPA3_UC_DEBUG_STATS_RINGUSAGELOW_OFF (12) #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 * @uc_dbg_stats_ofst: offset to SRAM base * @uc_dbg_stats_size: stats size for all channels * @uc_dbg_stats_mmio: mmio offset */ struct ipa3_uc_dbg_stats { u32 uc_dbg_stats_ofst; u16 uc_dbg_stats_size; void __iomem *uc_dbg_stats_mmio; }; struct ipa3_active_clients { struct mutex mutex; atomic_t cnt; Loading Loading @@ -1443,7 +1473,16 @@ struct ipa3_wdi2_ctx { u32 rdy_comp_ring_size; u32 *rdy_ring_rp_va; u32 *rdy_comp_ring_wp_va; struct ipa3_uc_dbg_stats dbg_stats; }; /** * struct ipa3_wdi3_ctx - IPA wdi3 context */ struct ipa3_wdi3_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. Loading Loading @@ -1684,6 +1723,8 @@ struct ipa3_pc_mbox_data { * @mhi_evid_limits: MHI event rings start and end ids * finished initializing. Example of use - IOCTLs to /dev/ipa * @flt_rt_counters: the counters usage info for flt rt stats * @wdi3_ctx: IPA wdi3 context * @gsi_info: channel/protocol info for GSI offloading uC stats * IPA context - holds all relevant info about IPA driver and its state */ struct ipa3_context { Loading Loading @@ -1839,6 +1880,7 @@ struct ipa3_context { void __iomem *reg_collection_base; struct ipa3_wdi2_ctx wdi2_ctx; struct ipa3_pc_mbox_data pc_mbox; struct ipa3_wdi3_ctx wdi3_ctx; atomic_t ipa_clk_vote; int gsi_chk_intset_value; int uc_mailbox17_chk; Loading @@ -1847,6 +1889,8 @@ struct ipa3_context { atomic_t is_ssr; bool (*get_teth_port_state[IPA_MAX_CLNT])(void); bool fw_loaded; struct IpaHwOffloadStatsAllocCmdData_t gsi_info[IPA_HW_PROTOCOL_MAX]; }; struct ipa3_plat_drv_res { Loading Loading @@ -2428,6 +2472,7 @@ 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_wdi_stats(struct IpaHwStatsWDIInfoData_t *stats); u16 ipa3_get_smem_restr_bytes(void); int ipa3_broadcast_wdi_quota_reach_ind(uint32_t fid, uint64_t num_bytes); Loading Loading @@ -2738,6 +2783,7 @@ int ipa3_write_qmapid_wdi_pipe(u32 clnt_hdl, u8 qmap_id); int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id); int ipa3_tag_process(struct ipa3_desc *desc, int num_descs, unsigned long timeout); int ipa3_get_wdi3_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats); void ipa3_q6_pre_shutdown_cleanup(void); void ipa3_q6_post_shutdown_cleanup(void); Loading Loading @@ -2783,6 +2829,9 @@ int ipa3_uc_mhi_stop_event_update_channel(int channelHandle); int ipa3_uc_mhi_print_stats(char *dbg_buff, int size); int ipa3_uc_memcpy(phys_addr_t dest, phys_addr_t src, int len); int ipa3_uc_send_remote_ipa_info(u32 remote_addr, uint32_t mbox_n); int ipa3_uc_debug_stats_alloc( struct IpaHwOffloadStatsAllocCmdData_t cmdinfo); int ipa3_uc_debug_stats_dealloc(uint32_t protocol); 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); Loading drivers/platform/msm/ipa/ipa_v3/ipa_uc.c +144 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ #define IPA_UC_POLL_SLEEP_USEC 100 #define IPA_UC_POLL_MAX_RETRY 10000 #define IPA_UC_DBG_STATS_GET_PROT_ID(x) (0xff & ((x) >> 24)) #define IPA_UC_DBG_STATS_GET_OFFSET(x) (0x00ffffff & (x)) /** * Mailbox register to Interrupt HWP for CPU cmd * Usage of IPA_UC_MAILBOX_m_n doorbell instead of IPA_IRQ_EE_UC_0 Loading Loading @@ -121,7 +124,7 @@ struct IpaHwRegWriteCmdData_t { * for IPA_HW_2_CPU_RESPONSE_CMD_COMPLETED response. * @originalCmdOp : The original command opcode * @status : 0 for success indication, otherwise failure * @reserved : Reserved * @responseData : 16b responseData * * Parameters are sent as 32b immediate parameters. */ Loading @@ -129,7 +132,7 @@ union IpaHwCpuCmdCompletedResponseData_t { struct IpaHwCpuCmdCompletedResponseParams_t { u32 originalCmdOp:8; u32 status:8; u32 reserved:16; u32 responseData:16; } __packed params; u32 raw32b; } __packed; Loading Loading @@ -220,6 +223,45 @@ const char *ipa_hw_error_str(enum ipa3_hw_errors err_type) return str; } static void ipa3_uc_save_dbg_stats(u32 size) { u8 protocol_id; u32 addr_offset; void __iomem *mmio; protocol_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); mmio = ioremap(ipa3_ctx->ipa_wrapper_base + addr_offset, sizeof(struct IpaHwRingStats_t) * MAX_CH_STATS_SUPPORTED); if (mmio == NULL) { IPAERR("unexpected NULL mmio\n"); return; } switch (protocol_id) { case IPA_HW_PROTOCOL_AQC: 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; 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; break; case IPA_HW_PROTOCOL_ETH: break; default: IPAERR("unknown protocols %d\n", protocol_id); } } static void ipa3_log_evt_hdlr(void) { int i; Loading Loading @@ -519,6 +561,10 @@ static void ipa3_uc_response_hdlr(enum ipa_irq_type interrupt, if (uc_rsp.params.originalCmdOp == ipa3_ctx->uc_ctx.pending_cmd) { ipa3_ctx->uc_ctx.uc_status = uc_rsp.params.status; if (uc_rsp.params.originalCmdOp == IPA_CPU_2_HW_CMD_OFFLOAD_STATS_ALLOC) ipa3_uc_save_dbg_stats( uc_rsp.params.responseData); complete_all(&ipa3_ctx->uc_ctx.uc_completion); } else { IPAERR("Expected cmd=%u rcvd cmd=%u\n", Loading Loading @@ -964,3 +1010,99 @@ int ipa3_uc_send_remote_ipa_info(u32 remote_addr, uint32_t mbox_n) dma_free_coherent(ipa3_ctx->uc_pdev, cmd.size, cmd.base, cmd.phys_base); return res; } int ipa3_uc_debug_stats_alloc( struct IpaHwOffloadStatsAllocCmdData_t cmdinfo) { int result; struct ipa_mem_buffer cmd; enum ipa_cpu_2_hw_offload_commands command; struct IpaHwOffloadStatsAllocCmdData_t *cmd_data; cmd.size = sizeof(*cmd_data); cmd.base = dma_alloc_coherent(ipa3_ctx->uc_pdev, cmd.size, &cmd.phys_base, GFP_KERNEL); if (cmd.base == NULL) { result = -ENOMEM; return result; } cmd_data = (struct IpaHwOffloadStatsAllocCmdData_t *)cmd.base; memcpy(cmd_data, &cmdinfo, sizeof(struct IpaHwOffloadStatsAllocCmdData_t)); command = IPA_CPU_2_HW_CMD_OFFLOAD_STATS_ALLOC; IPA_ACTIVE_CLIENTS_INC_SIMPLE(); result = ipa3_uc_send_cmd((u32)(cmd.phys_base), command, IPA_HW_2_CPU_OFFLOAD_CMD_STATUS_SUCCESS, false, 10 * HZ); if (result) { IPAERR("fail to alloc offload stats\n"); goto cleanup; } result = 0; cleanup: dma_free_coherent(ipa3_ctx->uc_pdev, cmd.size, cmd.base, cmd.phys_base); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPADBG("exit\n"); return result; } int ipa3_uc_debug_stats_dealloc(uint32_t protocol) { int result; struct ipa_mem_buffer cmd; enum ipa_cpu_2_hw_offload_commands command; struct IpaHwOffloadStatsDeAllocCmdData_t *cmd_data; cmd.size = sizeof(*cmd_data); cmd.base = dma_alloc_coherent(ipa3_ctx->uc_pdev, cmd.size, &cmd.phys_base, GFP_KERNEL); if (cmd.base == NULL) { result = -ENOMEM; return result; } cmd_data = (struct IpaHwOffloadStatsDeAllocCmdData_t *) cmd.base; cmd_data->protocol = protocol; command = IPA_CPU_2_HW_CMD_OFFLOAD_STATS_DEALLOC; IPA_ACTIVE_CLIENTS_INC_SIMPLE(); result = ipa3_uc_send_cmd((u32)(cmd.phys_base), command, IPA_HW_2_CPU_OFFLOAD_CMD_STATUS_SUCCESS, false, 10 * HZ); if (result) { IPAERR("fail to dealloc offload stats\n"); goto cleanup; } switch (protocol) { case IPA_HW_PROTOCOL_AQC: break; case IPA_HW_PROTOCOL_11ad: break; case IPA_HW_PROTOCOL_WDI: iounmap(ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_mmio); ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_mmio = NULL; break; case IPA_HW_PROTOCOL_WDI3: iounmap(ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_mmio); ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_mmio = NULL; break; case IPA_HW_PROTOCOL_ETH: break; default: IPAERR("unknown protocols %d\n", protocol); } result = 0; cleanup: dma_free_coherent(ipa3_ctx->uc_pdev, cmd.size, cmd.base, cmd.phys_base); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPADBG("exit\n"); return result; } drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h +55 −3 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, 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 Loading @@ -26,6 +26,11 @@ #define IPA_NTN_TX_DIR 1 #define IPA_NTN_RX_DIR 2 #define MAX_CH_STATS_SUPPORTED 5 #define DIR_CONSUMER 0 #define DIR_PRODUCER 1 /** * @brief Enum value determined based on the feature it * corresponds to Loading Loading @@ -71,6 +76,7 @@ enum ipa3_hw_features { * @IPA_HW_PROTOCOL_AQC : protocol related to AQC operation in IPA HW * @IPA_HW_PROTOCOL_11ad: protocol related to 11ad operation in IPA HW * @IPA_HW_PROTOCOL_WDI : protocol related to WDI operation in IPA HW * @IPA_HW_PROTOCOL_WDI3: protocol related to WDI3 operation in IPA HW * @IPA_HW_PROTOCOL_ETH : protocol related to ETH operation in IPA HW */ enum ipa4_hw_protocol { Loading @@ -78,6 +84,7 @@ enum ipa4_hw_protocol { IPA_HW_PROTOCOL_AQC = 0x1, IPA_HW_PROTOCOL_11ad = 0x2, IPA_HW_PROTOCOL_WDI = 0x3, IPA_HW_PROTOCOL_WDI3 = 0x4, IPA_HW_PROTOCOL_ETH = 0x5, IPA_HW_PROTOCOL_MAX }; Loading Loading @@ -158,6 +165,7 @@ enum ipa3_hw_errors { * @warningCounter : The warnings counter. The counter carries information * regarding non fatal errors in HW * @interfaceVersionCommon : The Common interface version as reported by HW * @responseParams_1: offset addr for uC stats * * The shared memory is used for communication between IPA HW and CPU. */ Loading @@ -181,6 +189,7 @@ struct IpaHwSharedMemCommonMapping_t { u16 reserved_23_22; u16 interfaceVersionCommon; u16 reserved_27_26; u32 responseParams_1; } __packed; /** Loading Loading @@ -431,6 +440,10 @@ struct Ipa3HwStatsNTNInfoData_t { * Offload protocol's Tx/ Rx Path * @IPA_CPU_2_HW_CMD_PERIPHERAL_INIT :Command to initialize peripheral * @IPA_CPU_2_HW_CMD_PERIPHERAL_DEINIT : Command to deinitialize peripheral * @IPA_CPU_2_HW_CMD_OFFLOAD_STATS_ALLOC: Command to start the * uC stats calculation for a particular protocol * @IPA_CPU_2_HW_CMD_OFFLOAD_STATS_DEALLOC: Command to stop the * uC stats calculation for a particular protocol */ enum ipa_cpu_2_hw_offload_commands { IPA_CPU_2_HW_CMD_OFFLOAD_CHANNEL_SET_UP = Loading @@ -441,8 +454,47 @@ enum ipa_cpu_2_hw_offload_commands { FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 3), IPA_CPU_2_HW_CMD_PERIPHERAL_DEINIT = FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 4), IPA_CPU_2_HW_CMD_OFFLOAD_STATS_ALLOC = FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 5), IPA_CPU_2_HW_CMD_OFFLOAD_STATS_DEALLOC = FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 6), }; /** * 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 * @protocol: Enum that indicates the protocol type */ struct IpaHwOffloadStatsDeAllocCmdData_t { uint32_t protocol; } __packed; /** * enum ipa3_hw_offload_channel_states - Values that represent Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa.c +10 −1 Original line number Diff line number Diff line Loading @@ -6143,7 +6143,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, struct platform_device *ipa_pdev) { int result = 0; int i; int i, j; struct ipa3_rt_tbl_set *rset; struct ipa_active_client_logging_info log_info; struct cdev *cdev; Loading @@ -6165,6 +6165,15 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, for (i = 0; i < IPA_SMMU_CB_MAX; i++) ipa3_ctx->s1_bypass_arr[i] = true; /* initialize the gsi protocol info for uC debug stats */ 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++) ipa3_ctx->gsi_info[i].ch_id_info[j].ch_id = 0xFF; } ipa3_ctx->ipa_wrapper_base = resource_p->ipa_mem_base; ipa3_ctx->ipa_wrapper_size = resource_p->ipa_mem_size; ipa3_ctx->ipa_hw_type = resource_p->ipa_hw_type; Loading
drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +146 −0 Original line number Diff line number Diff line Loading @@ -1956,6 +1956,136 @@ static ssize_t ipa3_read_ipahal_regs(struct file *file, char __user *ubuf, return 0; } 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; int nbytes; int cnt = 0; if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; goto done; } if (!ipa3_get_wdi_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 WDI GSI stats\n"); cnt += nbytes; } done: return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } 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; int nbytes; int cnt = 0; if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; goto done; } if (!ipa3_get_wdi3_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 WDI GSI stats\n"); cnt += nbytes; } done: return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } static ssize_t ipa3_read_11ad_gsi_stats(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { int nbytes; int cnt = 0; if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; goto done; } return 0; done: return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } static ssize_t ipa3_read_aqc_gsi_stats(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { int nbytes; int cnt = 0; if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) { nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN, "This feature only support on IPA4.5+\n"); cnt += nbytes; goto done; } return 0; done: return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } static void ipa_dump_status(struct ipahal_pkt_status *status) { IPA_DUMP_STATUS_FIELD(status_opcode); Loading Loading @@ -2230,6 +2360,22 @@ static const struct ipa3_debugfs_file debugfs_files[] = { "ipa_dump_regs", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_ipahal_regs, } }, { "wdi_gsi_stats", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_wdi_gsi_stats, } }, { "wdi3_gsi_stats", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_wdi3_gsi_stats, } }, { "11ad_gsi_stats", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_11ad_gsi_stats, } }, { "aqc_gsi_stats", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_aqc_gsi_stats, } } }; Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +49 −0 Original line number Diff line number Diff line Loading @@ -1296,6 +1296,36 @@ struct ipa3_stats { u32 tx_non_linear; }; /* offset for each stats */ #define IPA3_UC_DEBUG_STATS_RINGFULL_OFF (0) #define IPA3_UC_DEBUG_STATS_RINGEMPTY_OFF (4) #define IPA3_UC_DEBUG_STATS_RINGUSAGEHIGH_OFF (8) #define IPA3_UC_DEBUG_STATS_RINGUSAGELOW_OFF (12) #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 * @uc_dbg_stats_ofst: offset to SRAM base * @uc_dbg_stats_size: stats size for all channels * @uc_dbg_stats_mmio: mmio offset */ struct ipa3_uc_dbg_stats { u32 uc_dbg_stats_ofst; u16 uc_dbg_stats_size; void __iomem *uc_dbg_stats_mmio; }; struct ipa3_active_clients { struct mutex mutex; atomic_t cnt; Loading Loading @@ -1443,7 +1473,16 @@ struct ipa3_wdi2_ctx { u32 rdy_comp_ring_size; u32 *rdy_ring_rp_va; u32 *rdy_comp_ring_wp_va; struct ipa3_uc_dbg_stats dbg_stats; }; /** * struct ipa3_wdi3_ctx - IPA wdi3 context */ struct ipa3_wdi3_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. Loading Loading @@ -1684,6 +1723,8 @@ struct ipa3_pc_mbox_data { * @mhi_evid_limits: MHI event rings start and end ids * finished initializing. Example of use - IOCTLs to /dev/ipa * @flt_rt_counters: the counters usage info for flt rt stats * @wdi3_ctx: IPA wdi3 context * @gsi_info: channel/protocol info for GSI offloading uC stats * IPA context - holds all relevant info about IPA driver and its state */ struct ipa3_context { Loading Loading @@ -1839,6 +1880,7 @@ struct ipa3_context { void __iomem *reg_collection_base; struct ipa3_wdi2_ctx wdi2_ctx; struct ipa3_pc_mbox_data pc_mbox; struct ipa3_wdi3_ctx wdi3_ctx; atomic_t ipa_clk_vote; int gsi_chk_intset_value; int uc_mailbox17_chk; Loading @@ -1847,6 +1889,8 @@ struct ipa3_context { atomic_t is_ssr; bool (*get_teth_port_state[IPA_MAX_CLNT])(void); bool fw_loaded; struct IpaHwOffloadStatsAllocCmdData_t gsi_info[IPA_HW_PROTOCOL_MAX]; }; struct ipa3_plat_drv_res { Loading Loading @@ -2428,6 +2472,7 @@ 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_wdi_stats(struct IpaHwStatsWDIInfoData_t *stats); u16 ipa3_get_smem_restr_bytes(void); int ipa3_broadcast_wdi_quota_reach_ind(uint32_t fid, uint64_t num_bytes); Loading Loading @@ -2738,6 +2783,7 @@ int ipa3_write_qmapid_wdi_pipe(u32 clnt_hdl, u8 qmap_id); int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id); int ipa3_tag_process(struct ipa3_desc *desc, int num_descs, unsigned long timeout); int ipa3_get_wdi3_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats); void ipa3_q6_pre_shutdown_cleanup(void); void ipa3_q6_post_shutdown_cleanup(void); Loading Loading @@ -2783,6 +2829,9 @@ int ipa3_uc_mhi_stop_event_update_channel(int channelHandle); int ipa3_uc_mhi_print_stats(char *dbg_buff, int size); int ipa3_uc_memcpy(phys_addr_t dest, phys_addr_t src, int len); int ipa3_uc_send_remote_ipa_info(u32 remote_addr, uint32_t mbox_n); int ipa3_uc_debug_stats_alloc( struct IpaHwOffloadStatsAllocCmdData_t cmdinfo); int ipa3_uc_debug_stats_dealloc(uint32_t protocol); 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); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_uc.c +144 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ #define IPA_UC_POLL_SLEEP_USEC 100 #define IPA_UC_POLL_MAX_RETRY 10000 #define IPA_UC_DBG_STATS_GET_PROT_ID(x) (0xff & ((x) >> 24)) #define IPA_UC_DBG_STATS_GET_OFFSET(x) (0x00ffffff & (x)) /** * Mailbox register to Interrupt HWP for CPU cmd * Usage of IPA_UC_MAILBOX_m_n doorbell instead of IPA_IRQ_EE_UC_0 Loading Loading @@ -121,7 +124,7 @@ struct IpaHwRegWriteCmdData_t { * for IPA_HW_2_CPU_RESPONSE_CMD_COMPLETED response. * @originalCmdOp : The original command opcode * @status : 0 for success indication, otherwise failure * @reserved : Reserved * @responseData : 16b responseData * * Parameters are sent as 32b immediate parameters. */ Loading @@ -129,7 +132,7 @@ union IpaHwCpuCmdCompletedResponseData_t { struct IpaHwCpuCmdCompletedResponseParams_t { u32 originalCmdOp:8; u32 status:8; u32 reserved:16; u32 responseData:16; } __packed params; u32 raw32b; } __packed; Loading Loading @@ -220,6 +223,45 @@ const char *ipa_hw_error_str(enum ipa3_hw_errors err_type) return str; } static void ipa3_uc_save_dbg_stats(u32 size) { u8 protocol_id; u32 addr_offset; void __iomem *mmio; protocol_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); mmio = ioremap(ipa3_ctx->ipa_wrapper_base + addr_offset, sizeof(struct IpaHwRingStats_t) * MAX_CH_STATS_SUPPORTED); if (mmio == NULL) { IPAERR("unexpected NULL mmio\n"); return; } switch (protocol_id) { case IPA_HW_PROTOCOL_AQC: 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; 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; break; case IPA_HW_PROTOCOL_ETH: break; default: IPAERR("unknown protocols %d\n", protocol_id); } } static void ipa3_log_evt_hdlr(void) { int i; Loading Loading @@ -519,6 +561,10 @@ static void ipa3_uc_response_hdlr(enum ipa_irq_type interrupt, if (uc_rsp.params.originalCmdOp == ipa3_ctx->uc_ctx.pending_cmd) { ipa3_ctx->uc_ctx.uc_status = uc_rsp.params.status; if (uc_rsp.params.originalCmdOp == IPA_CPU_2_HW_CMD_OFFLOAD_STATS_ALLOC) ipa3_uc_save_dbg_stats( uc_rsp.params.responseData); complete_all(&ipa3_ctx->uc_ctx.uc_completion); } else { IPAERR("Expected cmd=%u rcvd cmd=%u\n", Loading Loading @@ -964,3 +1010,99 @@ int ipa3_uc_send_remote_ipa_info(u32 remote_addr, uint32_t mbox_n) dma_free_coherent(ipa3_ctx->uc_pdev, cmd.size, cmd.base, cmd.phys_base); return res; } int ipa3_uc_debug_stats_alloc( struct IpaHwOffloadStatsAllocCmdData_t cmdinfo) { int result; struct ipa_mem_buffer cmd; enum ipa_cpu_2_hw_offload_commands command; struct IpaHwOffloadStatsAllocCmdData_t *cmd_data; cmd.size = sizeof(*cmd_data); cmd.base = dma_alloc_coherent(ipa3_ctx->uc_pdev, cmd.size, &cmd.phys_base, GFP_KERNEL); if (cmd.base == NULL) { result = -ENOMEM; return result; } cmd_data = (struct IpaHwOffloadStatsAllocCmdData_t *)cmd.base; memcpy(cmd_data, &cmdinfo, sizeof(struct IpaHwOffloadStatsAllocCmdData_t)); command = IPA_CPU_2_HW_CMD_OFFLOAD_STATS_ALLOC; IPA_ACTIVE_CLIENTS_INC_SIMPLE(); result = ipa3_uc_send_cmd((u32)(cmd.phys_base), command, IPA_HW_2_CPU_OFFLOAD_CMD_STATUS_SUCCESS, false, 10 * HZ); if (result) { IPAERR("fail to alloc offload stats\n"); goto cleanup; } result = 0; cleanup: dma_free_coherent(ipa3_ctx->uc_pdev, cmd.size, cmd.base, cmd.phys_base); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPADBG("exit\n"); return result; } int ipa3_uc_debug_stats_dealloc(uint32_t protocol) { int result; struct ipa_mem_buffer cmd; enum ipa_cpu_2_hw_offload_commands command; struct IpaHwOffloadStatsDeAllocCmdData_t *cmd_data; cmd.size = sizeof(*cmd_data); cmd.base = dma_alloc_coherent(ipa3_ctx->uc_pdev, cmd.size, &cmd.phys_base, GFP_KERNEL); if (cmd.base == NULL) { result = -ENOMEM; return result; } cmd_data = (struct IpaHwOffloadStatsDeAllocCmdData_t *) cmd.base; cmd_data->protocol = protocol; command = IPA_CPU_2_HW_CMD_OFFLOAD_STATS_DEALLOC; IPA_ACTIVE_CLIENTS_INC_SIMPLE(); result = ipa3_uc_send_cmd((u32)(cmd.phys_base), command, IPA_HW_2_CPU_OFFLOAD_CMD_STATUS_SUCCESS, false, 10 * HZ); if (result) { IPAERR("fail to dealloc offload stats\n"); goto cleanup; } switch (protocol) { case IPA_HW_PROTOCOL_AQC: break; case IPA_HW_PROTOCOL_11ad: break; case IPA_HW_PROTOCOL_WDI: iounmap(ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_mmio); ipa3_ctx->wdi2_ctx.dbg_stats.uc_dbg_stats_mmio = NULL; break; case IPA_HW_PROTOCOL_WDI3: iounmap(ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_mmio); ipa3_ctx->wdi3_ctx.dbg_stats.uc_dbg_stats_mmio = NULL; break; case IPA_HW_PROTOCOL_ETH: break; default: IPAERR("unknown protocols %d\n", protocol); } result = 0; cleanup: dma_free_coherent(ipa3_ctx->uc_pdev, cmd.size, cmd.base, cmd.phys_base); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPADBG("exit\n"); return result; }
drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h +55 −3 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, 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 Loading @@ -26,6 +26,11 @@ #define IPA_NTN_TX_DIR 1 #define IPA_NTN_RX_DIR 2 #define MAX_CH_STATS_SUPPORTED 5 #define DIR_CONSUMER 0 #define DIR_PRODUCER 1 /** * @brief Enum value determined based on the feature it * corresponds to Loading Loading @@ -71,6 +76,7 @@ enum ipa3_hw_features { * @IPA_HW_PROTOCOL_AQC : protocol related to AQC operation in IPA HW * @IPA_HW_PROTOCOL_11ad: protocol related to 11ad operation in IPA HW * @IPA_HW_PROTOCOL_WDI : protocol related to WDI operation in IPA HW * @IPA_HW_PROTOCOL_WDI3: protocol related to WDI3 operation in IPA HW * @IPA_HW_PROTOCOL_ETH : protocol related to ETH operation in IPA HW */ enum ipa4_hw_protocol { Loading @@ -78,6 +84,7 @@ enum ipa4_hw_protocol { IPA_HW_PROTOCOL_AQC = 0x1, IPA_HW_PROTOCOL_11ad = 0x2, IPA_HW_PROTOCOL_WDI = 0x3, IPA_HW_PROTOCOL_WDI3 = 0x4, IPA_HW_PROTOCOL_ETH = 0x5, IPA_HW_PROTOCOL_MAX }; Loading Loading @@ -158,6 +165,7 @@ enum ipa3_hw_errors { * @warningCounter : The warnings counter. The counter carries information * regarding non fatal errors in HW * @interfaceVersionCommon : The Common interface version as reported by HW * @responseParams_1: offset addr for uC stats * * The shared memory is used for communication between IPA HW and CPU. */ Loading @@ -181,6 +189,7 @@ struct IpaHwSharedMemCommonMapping_t { u16 reserved_23_22; u16 interfaceVersionCommon; u16 reserved_27_26; u32 responseParams_1; } __packed; /** Loading Loading @@ -431,6 +440,10 @@ struct Ipa3HwStatsNTNInfoData_t { * Offload protocol's Tx/ Rx Path * @IPA_CPU_2_HW_CMD_PERIPHERAL_INIT :Command to initialize peripheral * @IPA_CPU_2_HW_CMD_PERIPHERAL_DEINIT : Command to deinitialize peripheral * @IPA_CPU_2_HW_CMD_OFFLOAD_STATS_ALLOC: Command to start the * uC stats calculation for a particular protocol * @IPA_CPU_2_HW_CMD_OFFLOAD_STATS_DEALLOC: Command to stop the * uC stats calculation for a particular protocol */ enum ipa_cpu_2_hw_offload_commands { IPA_CPU_2_HW_CMD_OFFLOAD_CHANNEL_SET_UP = Loading @@ -441,8 +454,47 @@ enum ipa_cpu_2_hw_offload_commands { FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 3), IPA_CPU_2_HW_CMD_PERIPHERAL_DEINIT = FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 4), IPA_CPU_2_HW_CMD_OFFLOAD_STATS_ALLOC = FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 5), IPA_CPU_2_HW_CMD_OFFLOAD_STATS_DEALLOC = FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 6), }; /** * 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 * @protocol: Enum that indicates the protocol type */ struct IpaHwOffloadStatsDeAllocCmdData_t { uint32_t protocol; } __packed; /** * enum ipa3_hw_offload_channel_states - Values that represent Loading