Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +6 −0 Original line number Diff line number Diff line Loading @@ -3260,4 +3260,10 @@ static inline void *alloc_and_init(u32 size, u32 init_val) bool ipa3_is_apq(void); /* check if odl is connected */ bool ipa3_is_odl_connected(void); int ipa3_uc_send_enable_flow_control(uint16_t gsi_chid, uint16_t redMarkerThreshold); int ipa3_uc_send_disable_flow_control(void); int ipa3_uc_send_update_flow_control(uint32_t bitmask, uint8_t add_delete); #endif /* _IPA3_I_H_ */ drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +79 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,8 @@ #define IPA_CHANNEL_STOP_IN_PROC_TO_MSEC 5 #define IPA_CHANNEL_STOP_IN_PROC_SLEEP_USEC 200 #define IPA_MHIP_HOLB_TMO 31 /* value to match granularity on ipa HW 4.5 */ #define IPA_MPM_FLOW_CTRL_ADD 1 #define IPA_MPM_FLOW_CTRL_DELETE 0 enum mhip_re_type { MHIP_RE_XFER = 0x2, Loading Loading @@ -393,6 +395,7 @@ struct ipa_mpm_context { atomic_t probe_cnt; atomic_t pcie_clk_total_cnt; atomic_t ipa_clk_total_cnt; atomic_t flow_ctrl_mask; atomic_t adpl_over_usb_available; struct device *parent_pdev; struct ipa_smmu_cb_ctx carved_smmu_cb; Loading Loading @@ -1719,6 +1722,8 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) int ret = 0; enum ipa_mpm_mhip_client_type mhip_client = IPA_MPM_MHIP_TETH; bool is_acted = true; const struct ipa_gsi_ep_config *ep_cfg; uint32_t flow_ctrl_mask = 0; if (!state) return -EPERM; Loading Loading @@ -1775,6 +1780,35 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) } IPA_MPM_DBG("MHIP remote channels are started\n"); /* * Update flow control monitoring end point info. * This info will be used to set delay on the end points upon * hitting RED water mark. */ ep_cfg = ipa3_get_gsi_ep_info(IPA_CLIENT_WLAN2_PROD); if (!ep_cfg) IPA_MPM_ERR("ep = %d not allocated yet\n", IPA_CLIENT_WLAN2_PROD); else flow_ctrl_mask |= 1 << (ep_cfg->ipa_gsi_chan_num); ep_cfg = ipa3_get_gsi_ep_info(IPA_CLIENT_USB_PROD); if (!ep_cfg) IPA_MPM_ERR("ep = %d not allocated yet\n", IPA_CLIENT_USB_PROD); else flow_ctrl_mask |= 1 << (ep_cfg->ipa_gsi_chan_num); atomic_set(&ipa_mpm_ctx->flow_ctrl_mask, flow_ctrl_mask); ret = ipa3_uc_send_update_flow_control(flow_ctrl_mask, IPA_MPM_FLOW_CTRL_ADD); if (ret) IPA_MPM_ERR("Err = %d setting uc flow control\n", ret); status = ipa_mpm_start_stop_mhip_chan( IPA_MPM_MHIP_CHAN_UL, probe_id, MPM_MHIP_START); switch (status) { Loading Loading @@ -1812,6 +1846,23 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) } ipa_mpm_ctx->md[probe_id].mhip_client = mhip_client; } else { /* * Update flow control monitoring end point info. * This info will be used to reset delay on the end points. */ flow_ctrl_mask = atomic_read(&ipa_mpm_ctx->flow_ctrl_mask); ret = ipa3_uc_send_update_flow_control(flow_ctrl_mask, IPA_MPM_FLOW_CTRL_DELETE); flow_ctrl_mask = 0; atomic_set(&ipa_mpm_ctx->flow_ctrl_mask, 0); if (ret) { IPA_MPM_ERR("Err = %d resetting uc flow control\n", ret); ipa_assert(); } /* * Make sure to stop Device side channels before * stopping Host side UL channels. This is to make Loading Loading @@ -1968,6 +2019,8 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, u32 wp_addr; int pipe_idx; bool is_acted = true; uint64_t flow_ctrl_mask = 0; bool add_delete = false; IPA_MPM_FUNC_ENTRY(); Loading Loading @@ -2348,6 +2401,27 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); ipa_mpm_ctx->md[probe_id].init_complete = true; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); /* Update Flow control Monitoring, only for the teth UL Prod pipes */ if (probe_id == IPA_MPM_MHIP_CH_ID_0) { ipa_ep_idx = ipa3_get_ep_mapping(ul_prod); ep = &ipa3_ctx->ep[ipa_ep_idx]; ret = ipa3_uc_send_enable_flow_control(ep->gsi_chan_hdl, IPA_MPM_RING_LEN / 4); if (ret) { IPA_MPM_ERR("Err %d flow control enable\n", ret); goto fail_flow_control; } IPA_MPM_DBG("Flow Control enabled for %d", probe_id); flow_ctrl_mask = atomic_read(&ipa_mpm_ctx->flow_ctrl_mask); add_delete = flow_ctrl_mask > 0 ? 1 : 0; ret = ipa3_uc_send_update_flow_control(flow_ctrl_mask, add_delete); if (ret) { IPA_MPM_ERR("Err %d flow control update\n", ret); goto fail_flow_control; } IPA_MPM_DBG("Flow Control updated for %d", probe_id); } IPA_MPM_FUNC_EXIT(); return 0; Loading @@ -2355,6 +2429,7 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, fail_start_channel: fail_stop_channel: fail_smmu: fail_flow_control: if (ipa_mpm_ctx->dev_info.ipa_smmu_enabled) IPA_MPM_DBG("SMMU failed\n"); if (is_acted) Loading Loading @@ -2424,6 +2499,9 @@ static void ipa_mpm_mhi_remove_cb(struct mhi_device *mhi_dev) ipa_mpm_ctx->md[mhip_idx].init_complete = false; mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); if (mhip_idx == IPA_MPM_MHIP_CH_ID_0) ipa3_uc_send_disable_flow_control(); ipa_mpm_mhip_shutdown(mhip_idx); atomic_dec(&ipa_mpm_ctx->probe_cnt); Loading Loading @@ -2909,6 +2987,7 @@ static int ipa_mpm_probe(struct platform_device *pdev) atomic_set(&ipa_mpm_ctx->ipa_clk_total_cnt, 0); atomic_set(&ipa_mpm_ctx->pcie_clk_total_cnt, 0); atomic_set(&ipa_mpm_ctx->flow_ctrl_mask, 0); for (idx = 0; idx < IPA_MPM_MHIP_CH_ID_MAX; idx++) { ipa_mpm_ctx->md[idx].ul_prod.gsi_state = GSI_INIT; Loading drivers/platform/msm/ipa/ipa_v3/ipa_uc.c +103 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,10 @@ * IPA_CPU_2_HW_CMD_GSI_CH_EMPTY : Command to check for GSI channel emptiness. * IPA_CPU_2_HW_CMD_REMOTE_IPA_INFO: Command to store remote IPA Info * IPA_CPU_2_HW_CMD_SETUP_EVENT_RING: Command to setup the event ring * IPA_CPU_2_HW_CMD_ENABLE_FLOW_CTL_MONITOR: Command to enable pipe monitoring. * IPA_CPU_2_HW_CMD_UPDATE_FLOW_CTL_MONITOR: Command to update pipes to monitor. * IPA_CPU_2_HW_CMD_DISABLE_FLOW_CTL_MONITOR: Command to disable pipe monitoring, no parameter required. */ enum ipa3_cpu_2_hw_commands { IPA_CPU_2_HW_CMD_NO_OP = Loading Loading @@ -73,6 +77,13 @@ enum ipa3_cpu_2_hw_commands { FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 11), IPA_CPU_2_HW_CMD_SETUP_EVENT_RING = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 12), IPA_CPU_2_HW_CMD_ENABLE_FLOW_CTL_MONITOR = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 13), IPA_CPU_2_HW_CMD_UPDATE_FLOW_CTL_MONITOR = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 14), IPA_CPU_2_HW_CMD_DISABLE_FLOW_CTL_MONITOR = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 15), }; /** Loading Loading @@ -198,6 +209,36 @@ struct IpaHwDbAddrInfo_t { uint32_t mboxN; } __packed; /** * Structure holding the parameters for IPA_CPU_2_HW_CMD_ENABLE_PIPE_MONITOR * command. * @ipaProdGsiChid IPA prod GSI chid to monitor * @redMarkerThreshold red marker threshold in elements for the GSI channel */ union IpaEnablePipeMonitorCmdData_t { struct IpaEnablePipeMonitorCmdParams_t { u32 ipaProdGsiChid:16; u32 redMarkerThreshold:16; } __packed params; u32 raw32b; } __packed; /** * Structure holding the parameters for IPA_CPU_2_HW_CMD_UPDATE_PIPE_MONITOR * command. * * @bitmask The parameter of bitmask to add/delete channels/pipes from * global monitoring pipemask * IPA pipe# bitmask or GSI chid bitmask * add_delete 1: add pipes to monitor * 0: delete pipes to monitor */ struct IpaUpdateFlowCtlMonitorData_t { u32 bitmask; u8 add_delete; }; static DEFINE_MUTEX(uc_loaded_nb_lock); static BLOCKING_NOTIFIER_HEAD(uc_loaded_notifier); Loading Loading @@ -1484,3 +1525,65 @@ int ipa3_set_wlan_tx_info(struct ipa_wdi_tx_info *info) return 0; } int ipa3_uc_send_enable_flow_control(uint16_t gsi_chid, uint16_t redMarkerThreshold) { int res; union IpaEnablePipeMonitorCmdData_t cmd; cmd.params.ipaProdGsiChid = gsi_chid; cmd.params.redMarkerThreshold = redMarkerThreshold; IPA_ACTIVE_CLIENTS_INC_SIMPLE(); res = ipa3_uc_send_cmd((cmd.raw32b), IPA_CPU_2_HW_CMD_ENABLE_FLOW_CTL_MONITOR, 0, false, 10 * HZ); if (res) IPAERR("fail to enable flow ctrl for 0x%x\n", cmd.params.ipaProdGsiChid); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return res; } int ipa3_uc_send_disable_flow_control(void) { int res; IPA_ACTIVE_CLIENTS_INC_SIMPLE(); res = ipa3_uc_send_cmd(0, IPA_CPU_2_HW_CMD_DISABLE_FLOW_CTL_MONITOR, 0, false, 10 * HZ); if (res) IPAERR("fail to disable flow control\n"); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return res; } int ipa3_uc_send_update_flow_control(uint32_t bitmask, uint8_t add_delete) { int res; if (bitmask == 0) { IPAERR("Err update flow control, mask = 0\n"); return 0; } IPA_ACTIVE_CLIENTS_INC_SIMPLE(); res = ipa3_uc_send_cmd_64b_param(bitmask, add_delete, IPA_CPU_2_HW_CMD_UPDATE_FLOW_CTL_MONITOR, 0, false, 10 * HZ); if (res) IPAERR("fail flowCtrl update mask = 0x%x add_del = 0x%x\n", bitmask, add_delete); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return res; } Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +6 −0 Original line number Diff line number Diff line Loading @@ -3260,4 +3260,10 @@ static inline void *alloc_and_init(u32 size, u32 init_val) bool ipa3_is_apq(void); /* check if odl is connected */ bool ipa3_is_odl_connected(void); int ipa3_uc_send_enable_flow_control(uint16_t gsi_chid, uint16_t redMarkerThreshold); int ipa3_uc_send_disable_flow_control(void); int ipa3_uc_send_update_flow_control(uint32_t bitmask, uint8_t add_delete); #endif /* _IPA3_I_H_ */
drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +79 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,8 @@ #define IPA_CHANNEL_STOP_IN_PROC_TO_MSEC 5 #define IPA_CHANNEL_STOP_IN_PROC_SLEEP_USEC 200 #define IPA_MHIP_HOLB_TMO 31 /* value to match granularity on ipa HW 4.5 */ #define IPA_MPM_FLOW_CTRL_ADD 1 #define IPA_MPM_FLOW_CTRL_DELETE 0 enum mhip_re_type { MHIP_RE_XFER = 0x2, Loading Loading @@ -393,6 +395,7 @@ struct ipa_mpm_context { atomic_t probe_cnt; atomic_t pcie_clk_total_cnt; atomic_t ipa_clk_total_cnt; atomic_t flow_ctrl_mask; atomic_t adpl_over_usb_available; struct device *parent_pdev; struct ipa_smmu_cb_ctx carved_smmu_cb; Loading Loading @@ -1719,6 +1722,8 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) int ret = 0; enum ipa_mpm_mhip_client_type mhip_client = IPA_MPM_MHIP_TETH; bool is_acted = true; const struct ipa_gsi_ep_config *ep_cfg; uint32_t flow_ctrl_mask = 0; if (!state) return -EPERM; Loading Loading @@ -1775,6 +1780,35 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) } IPA_MPM_DBG("MHIP remote channels are started\n"); /* * Update flow control monitoring end point info. * This info will be used to set delay on the end points upon * hitting RED water mark. */ ep_cfg = ipa3_get_gsi_ep_info(IPA_CLIENT_WLAN2_PROD); if (!ep_cfg) IPA_MPM_ERR("ep = %d not allocated yet\n", IPA_CLIENT_WLAN2_PROD); else flow_ctrl_mask |= 1 << (ep_cfg->ipa_gsi_chan_num); ep_cfg = ipa3_get_gsi_ep_info(IPA_CLIENT_USB_PROD); if (!ep_cfg) IPA_MPM_ERR("ep = %d not allocated yet\n", IPA_CLIENT_USB_PROD); else flow_ctrl_mask |= 1 << (ep_cfg->ipa_gsi_chan_num); atomic_set(&ipa_mpm_ctx->flow_ctrl_mask, flow_ctrl_mask); ret = ipa3_uc_send_update_flow_control(flow_ctrl_mask, IPA_MPM_FLOW_CTRL_ADD); if (ret) IPA_MPM_ERR("Err = %d setting uc flow control\n", ret); status = ipa_mpm_start_stop_mhip_chan( IPA_MPM_MHIP_CHAN_UL, probe_id, MPM_MHIP_START); switch (status) { Loading Loading @@ -1812,6 +1846,23 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) } ipa_mpm_ctx->md[probe_id].mhip_client = mhip_client; } else { /* * Update flow control monitoring end point info. * This info will be used to reset delay on the end points. */ flow_ctrl_mask = atomic_read(&ipa_mpm_ctx->flow_ctrl_mask); ret = ipa3_uc_send_update_flow_control(flow_ctrl_mask, IPA_MPM_FLOW_CTRL_DELETE); flow_ctrl_mask = 0; atomic_set(&ipa_mpm_ctx->flow_ctrl_mask, 0); if (ret) { IPA_MPM_ERR("Err = %d resetting uc flow control\n", ret); ipa_assert(); } /* * Make sure to stop Device side channels before * stopping Host side UL channels. This is to make Loading Loading @@ -1968,6 +2019,8 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, u32 wp_addr; int pipe_idx; bool is_acted = true; uint64_t flow_ctrl_mask = 0; bool add_delete = false; IPA_MPM_FUNC_ENTRY(); Loading Loading @@ -2348,6 +2401,27 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); ipa_mpm_ctx->md[probe_id].init_complete = true; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); /* Update Flow control Monitoring, only for the teth UL Prod pipes */ if (probe_id == IPA_MPM_MHIP_CH_ID_0) { ipa_ep_idx = ipa3_get_ep_mapping(ul_prod); ep = &ipa3_ctx->ep[ipa_ep_idx]; ret = ipa3_uc_send_enable_flow_control(ep->gsi_chan_hdl, IPA_MPM_RING_LEN / 4); if (ret) { IPA_MPM_ERR("Err %d flow control enable\n", ret); goto fail_flow_control; } IPA_MPM_DBG("Flow Control enabled for %d", probe_id); flow_ctrl_mask = atomic_read(&ipa_mpm_ctx->flow_ctrl_mask); add_delete = flow_ctrl_mask > 0 ? 1 : 0; ret = ipa3_uc_send_update_flow_control(flow_ctrl_mask, add_delete); if (ret) { IPA_MPM_ERR("Err %d flow control update\n", ret); goto fail_flow_control; } IPA_MPM_DBG("Flow Control updated for %d", probe_id); } IPA_MPM_FUNC_EXIT(); return 0; Loading @@ -2355,6 +2429,7 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, fail_start_channel: fail_stop_channel: fail_smmu: fail_flow_control: if (ipa_mpm_ctx->dev_info.ipa_smmu_enabled) IPA_MPM_DBG("SMMU failed\n"); if (is_acted) Loading Loading @@ -2424,6 +2499,9 @@ static void ipa_mpm_mhi_remove_cb(struct mhi_device *mhi_dev) ipa_mpm_ctx->md[mhip_idx].init_complete = false; mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); if (mhip_idx == IPA_MPM_MHIP_CH_ID_0) ipa3_uc_send_disable_flow_control(); ipa_mpm_mhip_shutdown(mhip_idx); atomic_dec(&ipa_mpm_ctx->probe_cnt); Loading Loading @@ -2909,6 +2987,7 @@ static int ipa_mpm_probe(struct platform_device *pdev) atomic_set(&ipa_mpm_ctx->ipa_clk_total_cnt, 0); atomic_set(&ipa_mpm_ctx->pcie_clk_total_cnt, 0); atomic_set(&ipa_mpm_ctx->flow_ctrl_mask, 0); for (idx = 0; idx < IPA_MPM_MHIP_CH_ID_MAX; idx++) { ipa_mpm_ctx->md[idx].ul_prod.gsi_state = GSI_INIT; Loading
drivers/platform/msm/ipa/ipa_v3/ipa_uc.c +103 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,10 @@ * IPA_CPU_2_HW_CMD_GSI_CH_EMPTY : Command to check for GSI channel emptiness. * IPA_CPU_2_HW_CMD_REMOTE_IPA_INFO: Command to store remote IPA Info * IPA_CPU_2_HW_CMD_SETUP_EVENT_RING: Command to setup the event ring * IPA_CPU_2_HW_CMD_ENABLE_FLOW_CTL_MONITOR: Command to enable pipe monitoring. * IPA_CPU_2_HW_CMD_UPDATE_FLOW_CTL_MONITOR: Command to update pipes to monitor. * IPA_CPU_2_HW_CMD_DISABLE_FLOW_CTL_MONITOR: Command to disable pipe monitoring, no parameter required. */ enum ipa3_cpu_2_hw_commands { IPA_CPU_2_HW_CMD_NO_OP = Loading Loading @@ -73,6 +77,13 @@ enum ipa3_cpu_2_hw_commands { FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 11), IPA_CPU_2_HW_CMD_SETUP_EVENT_RING = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 12), IPA_CPU_2_HW_CMD_ENABLE_FLOW_CTL_MONITOR = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 13), IPA_CPU_2_HW_CMD_UPDATE_FLOW_CTL_MONITOR = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 14), IPA_CPU_2_HW_CMD_DISABLE_FLOW_CTL_MONITOR = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 15), }; /** Loading Loading @@ -198,6 +209,36 @@ struct IpaHwDbAddrInfo_t { uint32_t mboxN; } __packed; /** * Structure holding the parameters for IPA_CPU_2_HW_CMD_ENABLE_PIPE_MONITOR * command. * @ipaProdGsiChid IPA prod GSI chid to monitor * @redMarkerThreshold red marker threshold in elements for the GSI channel */ union IpaEnablePipeMonitorCmdData_t { struct IpaEnablePipeMonitorCmdParams_t { u32 ipaProdGsiChid:16; u32 redMarkerThreshold:16; } __packed params; u32 raw32b; } __packed; /** * Structure holding the parameters for IPA_CPU_2_HW_CMD_UPDATE_PIPE_MONITOR * command. * * @bitmask The parameter of bitmask to add/delete channels/pipes from * global monitoring pipemask * IPA pipe# bitmask or GSI chid bitmask * add_delete 1: add pipes to monitor * 0: delete pipes to monitor */ struct IpaUpdateFlowCtlMonitorData_t { u32 bitmask; u8 add_delete; }; static DEFINE_MUTEX(uc_loaded_nb_lock); static BLOCKING_NOTIFIER_HEAD(uc_loaded_notifier); Loading Loading @@ -1484,3 +1525,65 @@ int ipa3_set_wlan_tx_info(struct ipa_wdi_tx_info *info) return 0; } int ipa3_uc_send_enable_flow_control(uint16_t gsi_chid, uint16_t redMarkerThreshold) { int res; union IpaEnablePipeMonitorCmdData_t cmd; cmd.params.ipaProdGsiChid = gsi_chid; cmd.params.redMarkerThreshold = redMarkerThreshold; IPA_ACTIVE_CLIENTS_INC_SIMPLE(); res = ipa3_uc_send_cmd((cmd.raw32b), IPA_CPU_2_HW_CMD_ENABLE_FLOW_CTL_MONITOR, 0, false, 10 * HZ); if (res) IPAERR("fail to enable flow ctrl for 0x%x\n", cmd.params.ipaProdGsiChid); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return res; } int ipa3_uc_send_disable_flow_control(void) { int res; IPA_ACTIVE_CLIENTS_INC_SIMPLE(); res = ipa3_uc_send_cmd(0, IPA_CPU_2_HW_CMD_DISABLE_FLOW_CTL_MONITOR, 0, false, 10 * HZ); if (res) IPAERR("fail to disable flow control\n"); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return res; } int ipa3_uc_send_update_flow_control(uint32_t bitmask, uint8_t add_delete) { int res; if (bitmask == 0) { IPAERR("Err update flow control, mask = 0\n"); return 0; } IPA_ACTIVE_CLIENTS_INC_SIMPLE(); res = ipa3_uc_send_cmd_64b_param(bitmask, add_delete, IPA_CPU_2_HW_CMD_UPDATE_FLOW_CTL_MONITOR, 0, false, 10 * HZ); if (res) IPAERR("fail flowCtrl update mask = 0x%x add_del = 0x%x\n", bitmask, add_delete); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return res; }