diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c b/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c index 3783ebea11..4a2a94b271 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c @@ -59,10 +59,7 @@ * No. of filters reserving at wlan for IPA-XR usecase. */ #define NO_OF_FILTERS 2 - -static void ipa_xr_wdi_opt_dpath_rsrv_filter_wq_handler(struct work_struct *work); -static struct workqueue_struct *wlan_flt_rsrv_wq = NULL; -static DECLARE_DELAYED_WORK(wlan_flt_rsrv_handle, ipa_xr_wdi_opt_dpath_rsrv_filter_wq_handler); +#define IPA_WDI_FLT_RSRV_TIMEOUT_MS 200 struct ipa_wdi_intf_info { char netdev_name[IPA_RESOURCE_NAME_MAX]; @@ -107,7 +104,7 @@ struct ipa_wdi_opt_dpath_add_flt_handle { uint64_t filter_handle; }; -struct ipa_wdi_opt_dpath_add_flt_handle add_flt_hndl[4]; +struct ipa_wdi_opt_dpath_add_flt_handle add_flt_hndl[MAX_STREAMS]; /** * opt_dpath_info contains fn callbacks which are set by WLAN context and @@ -874,23 +871,6 @@ int ipa_wdi_enable_pipes_per_inst(ipa_wdi_hdl_t hdl) } } - if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR) { - if (wlan_flt_rsrv_wq == NULL) { - wlan_flt_rsrv_wq = create_singlethread_workqueue("wlan_flt_rsrv_wq"); - if (!wlan_flt_rsrv_wq) { - IPA_WDI_ERR("failed to create wq\n"); - return 0; - } - - ret = queue_delayed_work(wlan_flt_rsrv_wq, &wlan_flt_rsrv_handle, - msecs_to_jiffies(QUEUE_DELAY_TIME)); - if (!ret) { - IPA_WDI_ERR("failed to queue delayed wq\n"); - return 0; - } - } - } - return 0; } EXPORT_SYMBOL(ipa_wdi_enable_pipes_per_inst); @@ -1123,6 +1103,7 @@ int ipa_wdi_opt_dpath_notify_flt_rsvd_per_inst (ipa_wdi_hdl_t hdl, bool is_success) { int ret = 0; + int flt_rsv_status = 0; struct ipa_wlan_opt_dp_rsrv_filter_complt_ind_msg_v01 ind; if (hdl < 0 || hdl >= IPA_WDI_INST_MAX) { @@ -1144,7 +1125,10 @@ int ipa_wdi_opt_dpath_notify_flt_rsvd_per_inst } if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR) { - ipa3_ctx->ipa_xr_wdi_flt_rsv_status = is_success; + IPA_WDI_DBG("Received wlan flt rsv status %d\n", is_success); + flt_rsv_status = is_success ? 1 : 0; + atomic_set(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status, flt_rsv_status); + complete(&ipa3_ctx->ipa_xr_wdi_flt_rsrv_success); return ret; } @@ -1169,6 +1153,7 @@ int ipa_wdi_opt_dpath_notify_flt_rlsd_per_inst (ipa_wdi_hdl_t hdl, bool is_success) { int ret = 0; + int flt_rsv_status = 0; struct ipa_wlan_opt_dp_remove_all_filter_complt_ind_msg_v01 ind; if (hdl < 0 || hdl >= IPA_WDI_INST_MAX) { @@ -1182,8 +1167,13 @@ int ipa_wdi_opt_dpath_notify_flt_rlsd_per_inst } ret = ipa_pm_deferred_deactivate(ipa_wdi_ctx_list[0]->ipa_pm_hdl); - if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR) + + if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR) { + IPA_WDI_DBG("Received wlan flt rlsd status %d\n", is_success); + flt_rsv_status = is_success ? 0 : 1; + atomic_set(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status, flt_rsv_status); return ret; + } memset(&ind, 0, sizeof(ind)); ind.filter_removal_all_status.result = @@ -1476,6 +1466,7 @@ int ipa_xr_wdi_opt_dpath_rsrv_filter_req(void) { int ret = 0; struct ipa_wdi_opt_dpath_flt_rsrv_cb_params rsrv_filter_req; + int rsrv_completed; memset(&rsrv_filter_req, 0, sizeof(struct ipa_wdi_opt_dpath_flt_rsrv_cb_params)); if (!atomic_read(&opt_dpath_info[0].is_xr_opt_dp_cb_registered)) { @@ -1494,6 +1485,7 @@ int ipa_xr_wdi_opt_dpath_rsrv_filter_req(void) return -EFAULT; } + init_completion(&ipa3_ctx->ipa_xr_wdi_flt_rsrv_success); rsrv_filter_req.num_filters = NO_OF_FILTERS; ret = opt_dpath_info[0].flt_rsrv_cb( opt_dpath_info[0].priv, &rsrv_filter_req); @@ -1505,6 +1497,12 @@ int ipa_xr_wdi_opt_dpath_rsrv_filter_req(void) } IPA_WDI_DBG("reserved filter callbacks called.\n"); + rsrv_completed = wait_for_completion_timeout(&ipa3_ctx->ipa_xr_wdi_flt_rsrv_success, + msecs_to_jiffies(IPA_WDI_FLT_RSRV_TIMEOUT_MS)); + if (!rsrv_completed) { + IPADBG("Timed out waiting for filter reservation notification from WLAN\n"); + return -EPERM; + } return ret; } EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_rsrv_filter_req); @@ -1532,8 +1530,9 @@ int ipa_xr_wdi_opt_dpath_add_filter_req(struct ipa_wdi_opt_dpath_flt_add_cb_para ret = opt_dpath_info[0].flt_add_cb (opt_dpath_info[0].priv, req); - add_flt_hndl[stream_id].filter_handle = req->flt_info[0].out_hdl; - IPA_WDI_DBG("add filter callbacks called, stream id %d\n", stream_id); + IPA_WDI_DBG("Add filter callbacks called for stream id %d\n", stream_id); + if (!ret) + add_flt_hndl[stream_id].filter_handle = req->flt_info[0].out_hdl; return ret; } EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_add_filter_req); @@ -1563,7 +1562,9 @@ int ipa_xr_wdi_opt_dpath_remove_filter_req(u32 stream_id) ret = opt_dpath_info[0].flt_rem_cb (opt_dpath_info[0].priv, &flt_rem_req); - IPA_WDI_DBG("remove filter callbacks called, stream id %d\n", stream_id); + IPA_WDI_DBG("Remove filter callbacks called for stream id %d\n", stream_id); + if (!ret) + add_flt_hndl[stream_id].filter_handle = 0; return ret; } EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_remove_filter_req); @@ -1606,16 +1607,6 @@ int ipa_xr_wdi_opt_dpath_remove_all_filter_req(void) } EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_remove_all_filter_req); - -static void ipa_xr_wdi_opt_dpath_rsrv_filter_wq_handler(struct work_struct *work) -{ - int res = 0; - - res = ipa_xr_wdi_opt_dpath_rsrv_filter_req(); - if (res) - IPAERR("Failed to reserve the filters in wlan\n"); -} - /** * clean up WDI IPA offload data path * @@ -1773,11 +1764,6 @@ int ipa_wdi_disconn_pipes_per_inst(ipa_wdi_hdl_t hdl) return -EPERM; } - if (wlan_flt_rsrv_wq) { - destroy_workqueue(wlan_flt_rsrv_wq); - wlan_flt_rsrv_wq = NULL; - } - if (ipa_wdi_ctx_list[hdl]->wdi_version >= IPA_WDI_1 && ipa_wdi_ctx_list[hdl]->wdi_version < IPA_WDI_3 && hdl > 0) { @@ -1919,6 +1905,8 @@ int ipa_wdi_disable_pipes_per_inst(ipa_wdi_hdl_t hdl) return -EFAULT; } + if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR) + atomic_set(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status, 0); return 0; } EXPORT_SYMBOL(ipa_wdi_disable_pipes_per_inst); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 3cadbbdb83..7044e83cec 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -579,7 +579,7 @@ enum { /* XR-IPA uC no. of temp buffers */ #define NO_OF_BUFFS 0x04 /* Max number of RTP streams supported */ -#define MAX_STREAMS 4 +#define MAX_STREAMS 2 /* miscellaneous for rmnet_ipa and qmi_service */ enum ipa_type_mode { @@ -2439,7 +2439,8 @@ struct ipa3_context { bool ipa_wdi2_over_gsi; bool ipa_wdi3_over_gsi; bool ipa_wdi_opt_dpath; - bool ipa_xr_wdi_flt_rsv_status; + atomic_t ipa_xr_wdi_flt_rsv_status; + struct completion ipa_xr_wdi_flt_rsrv_success; u8 rtp_stream_id_cnt; u32 rtp_proc_hdls[MAX_STREAMS]; u32 rtp_rt4_tbl_hdls[MAX_STREAMS]; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rtp_genl.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rtp_genl.c index abf279701a..1a860f24bd 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_rtp_genl.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rtp_genl.c @@ -24,7 +24,7 @@ .flags = 0, \ } -static u8 si[MAX_STREAMS]; +static u8 ipa_rtp_active_streams[MAX_STREAMS]; static struct nla_policy ipa_rtp_genl_attr_policy[IPA_RTP_GENL_ATTR_MAX + 1] = { [IPA_RTP_GENL_ATTR_STR] = { .type = NLA_NUL_STRING, .len = IPA_RTP_GENL_MAX_STR_LEN }, @@ -119,7 +119,6 @@ static int ipa3_rtp_del_flt_rule(u32 stream_id) struct ipa3_ep_context *ep; struct ipa_ioc_del_flt_rule *rtp_del_flt_rule = NULL; - IPADBG("Deleting rtp filter rules of stream_id: %u\n", stream_id); rtp_del_flt_rule = kzalloc(sizeof(*rtp_del_flt_rule) + 1 * sizeof(struct ipa_flt_rule_del), GFP_KERNEL); if (!rtp_del_flt_rule) { @@ -130,7 +129,10 @@ static int ipa3_rtp_del_flt_rule(u32 stream_id) ipa_ep_idx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_PROD); ep = &ipa3_ctx->ep[ipa_ep_idx]; - if (ep->rtp_flt4_rule_hdls[stream_id]) { + + /* check whether filter rule hdl is deleted or not */ + if (ep->rtp_flt4_rule_hdls[stream_id] != -1) { + IPADBG("Deleting rtp filter rules of stream_id: %u\n", stream_id); rtp_del_flt_rule->commit = 1; rtp_del_flt_rule->ip = 0; rtp_del_flt_rule->num_hdls = 1; @@ -141,7 +143,7 @@ static int ipa3_rtp_del_flt_rule(u32 stream_id) rc = -EPERM; return rc; } - ep->rtp_flt4_rule_hdls[stream_id] = 0; + ep->rtp_flt4_rule_hdls[stream_id] = -1; } kfree(rtp_del_flt_rule); @@ -153,7 +155,6 @@ static int ipa3_rtp_del_rt_rule(u32 stream_id) int rc = 0; struct ipa_ioc_del_rt_rule *rtp_del_rt_rule = NULL; - IPADBG("Deleting rtp route rules of stream_id: %u\n", stream_id); rtp_del_rt_rule = kzalloc(sizeof(*rtp_del_rt_rule) + 1 * sizeof(struct ipa_rt_rule_del), GFP_KERNEL); if (!rtp_del_rt_rule) { @@ -162,7 +163,9 @@ static int ipa3_rtp_del_rt_rule(u32 stream_id) return rc; } - if (ipa3_ctx->rtp_rt4_rule_hdls[stream_id]) { + /* check whether route rule hdl is deleted or not */ + if (ipa3_ctx->rtp_rt4_rule_hdls[stream_id] != -1) { + IPADBG("Deleting rtp route rules of stream_id: %u\n", stream_id); rtp_del_rt_rule->commit = 1; rtp_del_rt_rule->ip = 0; rtp_del_rt_rule->num_hdls = 1; @@ -187,7 +190,6 @@ static int ipa3_rtp_del_hdr_proc_ctx(u32 stream_id) struct ipa_ioc_del_hdr_proc_ctx *rtp_del_proc_ctx = NULL; struct ipa_hdr_proc_ctx_del *rtp_del_proc_ctx_entry = NULL; - IPADBG("Deleting rtp hdr proc ctx of stream_id: %u\n", stream_id); buf_size = (sizeof(struct ipa_ioc_del_hdr_proc_ctx) + (sizeof(struct ipa_hdr_proc_ctx_del))); rtp_del_proc_ctx = kzalloc(buf_size, GFP_KERNEL); @@ -197,7 +199,9 @@ static int ipa3_rtp_del_hdr_proc_ctx(u32 stream_id) return rc; } - if (ipa3_ctx->rtp_proc_hdls[stream_id]) { + /* check whether hdr proc ctx hdl is deleted or not */ + if (ipa3_ctx->rtp_proc_hdls[stream_id] != -1) { + IPADBG("Deleting rtp hdr proc ctx of stream_id: %u\n", stream_id); rtp_del_proc_ctx_entry = &(rtp_del_proc_ctx->hdl[0]); rtp_del_proc_ctx->commit = 1; rtp_del_proc_ctx->num_hdls = 1; @@ -526,16 +530,15 @@ int ipa_rtp_tuple_info_req_hdlr(struct sk_buff *skb_2, memset(&tuple_info_resp, 0, sizeof(tuple_info_resp)); for (i = 0; i < MAX_STREAMS; i++) { - if (si[i] == 0) { + if (ipa_rtp_active_streams[i] == 0) { tuple_info_resp.stream_id = i; - si[i] = 1; stream_id_available = 1; break; } } if (!stream_id_available) { - IPAERR("max stream-ids supported are four only\n"); + IPAERR("max stream-ids supported are %u only\n", MAX_STREAMS); return rc; } @@ -543,17 +546,20 @@ int ipa_rtp_tuple_info_req_hdlr(struct sk_buff *skb_2, if (ipa3_install_rtp_hdr_proc_rt_flt_rules(&tuple_info_req, tuple_info_resp.stream_id) || ipa3_tuple_info_cmd_to_wlan_uc(&tuple_info_req, tuple_info_resp.stream_id)) { IPAERR("failed to install hdr proc and flt rules or filters at WLAN\n"); + ipa3_delete_rtp_hdr_proc_rt_flt_rules(tuple_info_resp.stream_id); return rc; } + ipa_rtp_active_streams[tuple_info_resp.stream_id] = 1; + if (is_req_valid && - ipa_rtp_send_tuple_info_resp(info, &tuple_info_resp)) { + ipa_rtp_send_tuple_info_resp(info, &tuple_info_resp)) { IPAERR("failed in sending stream_id response\n"); memset(&rmv_sid_req, 0, sizeof(rmv_sid_req)); rmv_sid_req.stream_id = tuple_info_resp.stream_id; ipa3_uc_send_remove_stream_cmd(&rmv_sid_req); ipa3_delete_rtp_hdr_proc_rt_flt_rules(rmv_sid_req.stream_id); - si[tuple_info_resp.stream_id] = 0; + ipa_rtp_active_streams[tuple_info_resp.stream_id] = 0; } else rc = 0; @@ -865,7 +871,7 @@ int ipa_rtp_rmv_stream_id_req_hdlr(struct sk_buff *skb_2, return rc; } - si[rmv_sid_req.stream_id] = 0; + ipa_rtp_active_streams[rmv_sid_req.stream_id] = 0; ipa3_ctx->rtp_stream_id_cnt--; IPADBG("Exit\n"); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rtp_genl.h b/drivers/platform/msm/ipa/ipa_v3/ipa_rtp_genl.h index e85c8b1fee..e14cc710ab 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_rtp_genl.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rtp_genl.h @@ -69,6 +69,24 @@ struct remove_bitstream_buffers { uint32_t stream_id; }; +struct bitstream_buffer_info_to_uc { + uint8_t stream_id; + uint16_t fence_id; + uint8_t reserved; + u64 buff_addr; + u32 buff_fd; + u32 buff_size; + u64 meta_buff_addr; + u32 meta_buff_fd; + u32 meta_buff_size; +} __packed; + +struct bitstream_buffers_to_uc { + uint16_t buff_cnt; + uint16_t cookie; + struct bitstream_buffer_info_to_uc bs_info[MAX_BUFF]; +} __packed; + /** * struct traffic_selector_info - traffic selector information. * @no_of_openframe: no. of openframes in a stream. diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c index 85e981d1b7..987f33a22d 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c @@ -60,24 +60,6 @@ enum ipa3_cpu_2_hw_rtp_commands { FEATURE_ENUM_VAL(IPA_HW_FEATURE_RTP, 11), }; -struct bitstream_buffer_info_to_uc { - uint8_t stream_id; - uint16_t fence_id; - uint8_t reserved; - u64 buff_addr; - u32 buff_fd; - u32 buff_size; - u64 meta_buff_addr; - u32 meta_buff_fd; - u32 meta_buff_size; -} __packed; - -struct bitstream_buffers_to_uc { - uint16_t buff_cnt; - uint16_t cookie; - struct bitstream_buffer_info_to_uc bs_info[MAX_BUFF]; -} __packed; - struct dma_address_map_table { struct dma_buf *dma_buf_list[2]; struct dma_buf_attachment *attachment[2]; @@ -222,9 +204,8 @@ int ipa3_tuple_info_cmd_to_wlan_uc(struct traffic_tuple_info *req, u32 stream_id return -EINVAL; } - if (!ipa3_ctx->ipa_xr_wdi_flt_rsv_status) { + if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) { result = ipa_xr_wdi_opt_dpath_rsrv_filter_req(); - ipa3_ctx->ipa_xr_wdi_flt_rsv_status = !result; if (result) { IPAERR("filter reservation failed at WLAN %d\n", result); return result; @@ -264,18 +245,20 @@ int ipa3_tuple_info_cmd_to_wlan_uc(struct traffic_tuple_info *req, u32 stream_id flt_add_req.flt_info[0].ipv6_addr.ipv6_daddr[3]); } + result = ipa3_uc_send_tuple_info_cmd(req); + if (result) { + IPAERR("Fail to send tuple info cmd to uc\n"); + return -EPERM; + } + else + IPADBG("send tuple info cmd to uc succeeded\n"); + result = ipa_xr_wdi_opt_dpath_add_filter_req(&flt_add_req, stream_id); if (result) { IPAERR("Fail to send tuple info cmd to wlan\n"); return -EPERM; } - result = ipa3_uc_send_tuple_info_cmd(req); - if (result) - IPAERR("Fail to send tuple info cmd to uc\n"); - else - IPADBG("send tuple info cmd to uc succeeded\n"); - return result; } @@ -291,8 +274,10 @@ int ipa3_uc_send_remove_stream_cmd(struct remove_bitstream_buffers *data) } result = ipa_xr_wdi_opt_dpath_remove_filter_req(data->stream_id); - if (result) + if (result) { IPAERR("Failed to remove wlan filter of stream ID %d\n", data->stream_id); + return result; + } cmd.size = sizeof(*cmd_data); cmd.base = dma_alloc_coherent(ipa3_ctx->uc_pdev, cmd.size,