From d1483b79d1da39bf4f4ea54a5d9b7a210d16a215 Mon Sep 17 00:00:00 2001 From: Prasad Arepalli Date: Thu, 27 Jun 2024 17:13:41 +0530 Subject: [PATCH 1/8] msm: ipa3: Initiate filter reservation during filter addition Trigger filter reservation only when the first request to add a filter with tuple info is received from C2 component. Change-Id: I90f105bcb9bde83d510367c92aa30fe334f75a08 Signed-off-by: Prasad Arepalli --- .../platform/msm/ipa/ipa_clients/ipa_wdi3.c | 72 ++++++++----------- drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 5 +- .../platform/msm/ipa/ipa_v3/ipa_rtp_genl.c | 34 +++++---- .../platform/msm/ipa/ipa_v3/ipa_rtp_genl.h | 18 +++++ drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c | 39 ++++------ 5 files changed, 83 insertions(+), 85 deletions(-) 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, From 90dd8e86859c147626ba52959054825e38922df5 Mon Sep 17 00:00:00 2001 From: Prasad Arepalli Date: Fri, 19 Jul 2024 18:50:57 +0530 Subject: [PATCH 2/8] msm: ipa: Add debugfs nodes to install/remove xr wlan filters Enable ipa debugfs nodes to install/remove filters at wlan fw from ipa driver and handle accordingly. Change-Id: I856a1f8cbae38432fdbb865090747295c03bc691 Signed-off-by: Prasad Arepalli --- drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c | 506 ++++++++++++++++++ drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 1 + 2 files changed, 507 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index 94c0447872..fc4861c28e 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -26,6 +26,7 @@ #define IPA_DBG_MAX_RULE_IN_TBL 128 #define IPA_DBG_ACTIVE_CLIENT_BUF_SIZE ((IPA3_ACTIVE_CLIENTS_LOG_LINE_LEN \ * IPA3_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES) + IPA_MAX_MSG_LEN) +#define MAX_UC_BUFF_SIZE (1 * 1024UL * 1024UL) #define IPA_DUMP_STATUS_FIELD(f) \ pr_err(#f "=0x%x\n", status->f) @@ -144,6 +145,8 @@ static char *active_clients_buf; static s8 ep_reg_idx; static void *ipa_ipc_low_buff; +static u8 active_streams[MAX_STREAMS]; +static u8 active_flt_cnt; static ssize_t ipa3_read_gen_reg(struct file *file, char __user *ubuf, @@ -3542,6 +3545,491 @@ free_rt: return 0; } +static inline u32 ip_to_int(u8 a, u8 b, u8 c, u8 d) +{ + // IP to int is first octet * 256^3 + second octet * 256^2 + third octet * 256 + fourth oct + // Bit shifting is quicker than multiplication + // 2^24 = 256^3, 2^16 = 256^2, 256 = 2^8 + return (a << 24) + (b << 16) + (c << 8) + d; +} + +static u32 string_ip_to_integer_ip(char *str_ip) +{ + u8 a = 0, b = 0, c = 0, d = 0; + char *found = NULL; + u32 ip = 0; + + if (!str_ip) + return ip; + + found = strsep(&str_ip, "."); + if (!found || kstrtou8(found, 0, &a)) + goto err; + + found = strsep(&str_ip, "."); + if (!found || kstrtou8(found, 0, &b)) + goto err; + + found = strsep(&str_ip, "."); + if (!found || kstrtou8(found, 0, &c)) + goto err; + + found = strsep(&str_ip, "."); + if (!found || kstrtou8(found, 0, &d)) + goto err; + + pr_info("IP ADDR -> %d.%d.%d.%d\n", a, b, c, d); + ip = ip_to_int(a, b, c, d); + +err: + return ip; +} + +static ssize_t ipa_xr_add_flt_to_wlan(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + u32 src_ip[MAX_STREAMS] = {0}; + u32 dst_ip[MAX_STREAMS] = {0}; + u16 src_port[MAX_STREAMS] = {0}; + u16 dst_port[MAX_STREAMS] = {0}; + u8 prot[MAX_STREAMS] = {0}; + u8 num_filters = 0; + ssize_t missing = 0; + char *sptr = NULL; + char *token = NULL; + struct ipa_wdi_opt_dpath_flt_add_cb_params flt_add_req; + int result = 0; + u8 i = 0, j = 0, stream_id = 0; + + if (count >= sizeof(dbg_buff)) + return -EFAULT; + + memset(dbg_buff, 0, sizeof(dbg_buff)); + missing = copy_from_user(dbg_buff, buf, count); + if (missing) + return -EFAULT; + + dbg_buff[count] = '\0'; + sptr = dbg_buff; + + /* Getting the number of filters configured by user */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou8(token, 0, &num_filters)) + return -EINVAL; + + IPADBG("Number of filters %d\n", num_filters); + + if (num_filters > MAX_STREAMS || num_filters == 0) { + IPAERR("Number of filters is zero or more than max_streams, so it is invalid\n"); + return -EINVAL; + } + + if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) { + memset(active_streams, 0, sizeof(active_streams)); + active_flt_cnt = 0; + } + + if (active_flt_cnt + num_filters > MAX_STREAMS) { + IPAERR("Active filter count of %u exceeded maximum streams of %u\n", + active_flt_cnt, MAX_STREAMS); + return -EFAULT; + } + + for (i = 0; i < num_filters; i++) { + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + src_ip[i] = string_ip_to_integer_ip(token); + if (!src_ip[i]) + return -EINVAL; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + dst_ip[i] = string_ip_to_integer_ip(token); + if (!dst_ip[i]) + return -EINVAL; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + /* Range detection will be done by this API */ + if (kstrtou16(token, 0, &src_port[i]) || src_port[i] == 0) + return -EINVAL; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + /* Range detection will be done by this API */ + if (kstrtou16(token, 0, &dst_port[i]) || dst_port[i] == 0) + return -EINVAL; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou8(token, 0, &prot[i]) || prot[i] != IPPROTO_UDP) + return -EINVAL; + } + + if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) { + result = ipa_xr_wdi_opt_dpath_rsrv_filter_req(); + if (result) { + IPAERR("Filter reservation failed at WLAN %d\n", result); + return result; + } + } + + for (i = 0; i < num_filters; i++) { + for (j = 0; j < MAX_STREAMS; j++) { + if (active_streams[j] == 0) { + stream_id = j; + break; + } + } + + IPADBG("Available stream id %u\n", stream_id); + memset(&flt_add_req, 0, sizeof(struct ipa_wdi_opt_dpath_flt_add_cb_params)); + flt_add_req.num_tuples = 1; + flt_add_req.flt_info[0].version = 0; + flt_add_req.flt_info[0].ipv4_addr.ipv4_saddr = src_ip[i]; + flt_add_req.flt_info[0].ipv4_addr.ipv4_daddr = dst_ip[i]; + flt_add_req.flt_info[0].sport = src_port[i]; + flt_add_req.flt_info[0].dport = dst_port[i]; + flt_add_req.flt_info[0].protocol = prot[i]; + + IPADBG("IPv4 saddr:%lu, daddr:%lu IPv4 sport:%u, dport:%u protocol:%u\n", + flt_add_req.flt_info[0].ipv4_addr.ipv4_saddr, + flt_add_req.flt_info[0].ipv4_addr.ipv4_daddr, + flt_add_req.flt_info[0].sport, + flt_add_req.flt_info[0].dport, + flt_add_req.flt_info[0].protocol); + + result = ipa_xr_wdi_opt_dpath_add_filter_req(&flt_add_req, stream_id); + if (result) { + IPAERR("Failed to add filters at wlan\n"); + return -EPERM; + } + active_streams[stream_id] = 1; + active_flt_cnt++; + } + + return count; +} + +static ssize_t ipa_xr_remove_flt_to_wlan(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + char *sptr = NULL, *token = NULL; + u8 flt_opt = 0; + int result = 0; + ssize_t missing = 0; + + if (active_flt_cnt == 0) { + IPAERR("No active filters to delete\n"); + return -EFAULT; + } + + if (count >= sizeof(dbg_buff)) + return -EFAULT; + + memset(dbg_buff, 0, sizeof(dbg_buff)); + missing = copy_from_user(dbg_buff, buf, count); + if (missing) + return -EFAULT; + + dbg_buff[count] = '\0'; + sptr = dbg_buff; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou8(token, 0, &flt_opt)) + return -EINVAL; + + if (flt_opt > MAX_STREAMS) { + IPAERR("Flt_opt is more than max_streams, so it is invalid\n"); + return -EINVAL; + } + + if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) { + IPAERR("No existing filters at wlan\n"); + memset(active_streams, 0, sizeof(active_streams)); + active_flt_cnt = 0; + return -EPERM; + } + + /* flt_opt == 0, will remove all streams filters from wlan */ + if (!flt_opt) { + result = ipa_xr_wdi_opt_dpath_remove_all_filter_req(); + if (result) { + IPAERR("Failed to remove all streams filters from wlan\n"); + return -EPERM; + } + active_flt_cnt = 0; + memset(active_streams, 0, sizeof(active_streams)); + IPADBG("Removed all streams existing filters\n"); + return count; + } + + if (active_streams[flt_opt-1] == 0) { + IPADBG("Stream_ID: %d filter is already deleted at WLAN\n", flt_opt); + return -EPERM; + } + + /* Based on stream ID removing filters from wlan */ + result = ipa_xr_wdi_opt_dpath_remove_filter_req(flt_opt - 1); + if (result) { + IPAERR("Failed to remove stream-id: %d filter from wlan\n", flt_opt); + return -EPERM; + } + IPADBG("Removed stream-id: %d filter from wlan\n", flt_opt); + active_flt_cnt--; + active_streams[flt_opt - 1] = 0; + return count; +} + +#ifdef CONFIG_IPA_RTP +static ssize_t ipa_xr_add_flt_to_ipa_wlan(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + struct traffic_tuple_info tuple_info; + u32 src_ip = 0; + u32 dst_ip = 0; + u16 src_port = 0; + u16 dst_port = 0; + u8 prot = 0; + ssize_t missing = 0; + char *sptr = NULL, *token = NULL; + int result = 0; + u32 bs_buff_size = 0; + u8 stream_id = 0; + + struct bitstream_buffers_to_uc data; + dma_addr_t bs_phys_base[MAX_BUFF], mb_phys_base[MAX_BUFF]; + void *bs_va[MAX_BUFF] = {NULL}, *mb_va[MAX_BUFF] = {NULL}; + int i = 0, j = 0; + + if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) { + memset(active_streams, 0, sizeof(active_streams)); + active_flt_cnt = 0; + } + + if (active_flt_cnt >= MAX_STREAMS) { + IPAERR("Maximum filters already installed: %u\n", active_flt_cnt); + return -EFAULT; + } + + if (count >= sizeof(dbg_buff)) + return -EFAULT; + + memset(dbg_buff, 0, sizeof(dbg_buff)); + missing = copy_from_user(dbg_buff, buf, count); + if (missing) + return -EFAULT; + + dbg_buff[count] = '\0'; + sptr = dbg_buff; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + src_ip = string_ip_to_integer_ip(token); + if (!src_ip) + return -EINVAL; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + dst_ip = string_ip_to_integer_ip(token); + if (!dst_ip) + return -EINVAL; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou16(token, 0, &src_port) || src_port == 0) + return -EINVAL; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou16(token, 0, &dst_port) || dst_port == 0) + return -EINVAL; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou8(token, 0, &prot) || prot != IPPROTO_UDP) + return -EINVAL; + + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou32(token, 0, &bs_buff_size) || bs_buff_size > MAX_UC_BUFF_SIZE) + return -EINVAL; + + for (j = 0; j < MAX_STREAMS; j++) { + if (active_streams[j] == 0) { + stream_id = j; + break; + } + } + + IPADBG("Available stream id %u\n", stream_id); + IPADBG("Framing bitstream & Metadata buffer of size :%lu\n", bs_buff_size); + + data.buff_cnt = MAX_BUFF; + data.cookie = 0x1234; + for (i = 0; i < data.buff_cnt; i++) { + data.bs_info[i].stream_id = stream_id; + data.bs_info[i].fence_id = i; + bs_va[i] = dma_alloc_coherent(ipa3_ctx->rtp_pdev, bs_buff_size, + &bs_phys_base[i], GFP_KERNEL); + if (!bs_va[i]) { + IPADBG("Failed to allocate bitstream buffers of size: %u\n", + bs_buff_size); + goto free_bs_mb_buff; + } + + IPADBG("Bit stream buffer va is 0x%x\n", bs_va[i]); + IPADBG("Bit stream buffer iova is 0x%x\n", bs_phys_base[i]); + data.bs_info[i].buff_addr = bs_phys_base[i]; + data.bs_info[i].buff_fd = 0; + data.bs_info[i].buff_size = bs_buff_size; + mb_va[i] = dma_alloc_coherent(ipa3_ctx->rtp_pdev, IPA_MAX_MSG_LEN, + &mb_phys_base[i], GFP_KERNEL); + if (!mb_va[i]) { + IPADBG("Failed to allocate metadata buffers of size: %u\n", + IPA_MAX_MSG_LEN); + dma_free_coherent(ipa3_ctx->rtp_pdev, bs_buff_size, + bs_va[i], bs_phys_base[i]); + goto free_bs_mb_buff; + } + + IPADBG("Metadata buffer va is 0x%x\n", mb_va[i]); + IPADBG("Metadata buffer iova is 0x%x\n", mb_phys_base[i]); + data.bs_info[i].meta_buff_addr = mb_phys_base[i]; + data.bs_info[i].meta_buff_fd = 0; + data.bs_info[i].meta_buff_size = IPA_MAX_MSG_LEN; + } + + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); + + result = ipa3_uc_send_add_bitstream_buffers_cmd(&data); + if (result) { + IPAERR("Failed to send bitstream buffers to uC\n"); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + goto free_bs_mb_buff; + } + + tuple_info.ts_info.no_of_openframe = 3; + tuple_info.ts_info.max_pkt_frame = 256; + tuple_info.ts_info.stream_type = 0; + tuple_info.ts_info.reorder_timeout = 100; + tuple_info.ts_info.num_slices_per_frame = 0; + + tuple_info.ip_type = 0; + tuple_info.ip_info.ipv4.src_port_number = src_port; + tuple_info.ip_info.ipv4.dst_port_number = dst_port; + tuple_info.ip_info.ipv4.src_ip = src_ip; + tuple_info.ip_info.ipv4.dst_ip = dst_ip; + tuple_info.ip_info.ipv4.protocol = prot; + + IPADBG("IPv4 saddr:0x%x, daddr:0x%x\n", + tuple_info.ip_info.ipv4.src_ip, + tuple_info.ip_info.ipv4.dst_ip); + IPADBG("IPv4 sport:%u, dport:%u\n", + tuple_info.ip_info.ipv4.src_port_number, + tuple_info.ip_info.ipv4.dst_port_number); + + if (ipa3_install_rtp_hdr_proc_rt_flt_rules(&tuple_info, stream_id) || + ipa3_tuple_info_cmd_to_wlan_uc(&tuple_info, stream_id)) { + IPAERR("Failed to install rtp hdr proc and flt rules or filters at WLAN\n"); + ipa3_delete_rtp_hdr_proc_rt_flt_rules(stream_id); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + goto free_bs_mb_buff; + } + active_flt_cnt++; + active_streams[stream_id] = 1; + IPADBG("Sent bitstream and metadata buffer, filter info to uC or WLAN\n"); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + + return count; + +free_bs_mb_buff: + /* ith bs_buff is already freed above */ + for (j = i-1; j >= 0; j--) { + if (bs_va[j]) + dma_free_coherent(ipa3_ctx->rtp_pdev, bs_buff_size, + bs_va[j], bs_phys_base[j]); + if (mb_va[j]) + dma_free_coherent(ipa3_ctx->rtp_pdev, IPA_MAX_MSG_LEN, + mb_va[j], mb_phys_base[j]); + } + return -ENOMEM; +} + +static ssize_t ipa_xr_remove_flt_to_ipa_wlan(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + char *sptr = NULL, *token = NULL; + u8 stream_id = 0; + ssize_t missing = 0; + struct remove_bitstream_buffers rmv_sid_req; + + if (active_flt_cnt == 0) { + IPAERR("No active filters to delete\n"); + return -EFAULT; + } + + if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) { + IPAERR("No existing filters at wlan\n"); + memset(active_streams, 0, sizeof(active_streams)); + active_flt_cnt = 0; + return -EPERM; + } + + if (count >= sizeof(dbg_buff)) + return -EFAULT; + + memset(dbg_buff, 0, sizeof(dbg_buff)); + missing = copy_from_user(dbg_buff, buf, count); + if (missing) + return -EFAULT; + + dbg_buff[count] = '\0'; + sptr = dbg_buff; + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou8(token, 0, &stream_id)) + return -EINVAL; + + if (stream_id > MAX_STREAMS || stream_id == 0) { + IPAERR("Stream_id is zero or more than %u. Exit\n", MAX_STREAMS); + return -EINVAL; + } + + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); + + rmv_sid_req.stream_id = stream_id; + if (ipa3_uc_send_remove_stream_cmd(&rmv_sid_req) || + ipa3_delete_rtp_hdr_proc_rt_flt_rules(stream_id - 1)) { + IPADBG("Failed to remove stream id: %d filters from IPA and WLAN\n", stream_id); + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + return -EPERM; + } + + active_streams[stream_id - 1] = 0; + active_flt_cnt--; + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + IPADBG("Removed stream id: %d filters from IPA and WLAN\n", stream_id); + return count; +} +#endif + static const struct ipa3_debugfs_file debugfs_files[] = { { "gen_reg", IPA_READ_ONLY_MODE, NULL, { @@ -3777,6 +4265,24 @@ static const struct ipa3_debugfs_file debugfs_files[] = { "ipa_loopback_on_ipa", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_perform_loopback, } + }, { + "xr_wlan_add_flt", IPA_WRITE_ONLY_MODE, NULL, { + .write = ipa_xr_add_flt_to_wlan + } + }, { + "xr_wlan_rmv_flt", IPA_WRITE_ONLY_MODE, NULL, { + .write = ipa_xr_remove_flt_to_wlan, + } +#if defined(CONFIG_IPA_RTP) + }, { + "xr_ipa_wlan_add_flt", IPA_WRITE_ONLY_MODE, NULL, { + .write = ipa_xr_add_flt_to_ipa_wlan, + } + }, { + "xr_ipa_wlan_rmv_flt", IPA_WRITE_ONLY_MODE, NULL, { + .write = ipa_xr_remove_flt_to_ipa_wlan, + } +#endif } }; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 7044e83cec..82cd0e99fb 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -3863,5 +3863,6 @@ int ipa3_create_hfi_send_uc(void); int ipa3_allocate_uc_pipes_er_tr_send_to_uc(void); void ipa3_free_uc_temp_buffs(unsigned int no_of_buffs); void ipa3_free_uc_pipes_er_tr(void); +int ipa3_uc_send_add_bitstream_buffers_cmd(struct bitstream_buffers_to_uc *data); #endif #endif /* _IPA3_I_H_ */ From 621ace510e207b050f7145f19f774cf765b9958c Mon Sep 17 00:00:00 2001 From: Chirag Rastogi Date: Wed, 26 Jun 2024 15:01:41 -0700 Subject: [PATCH 3/8] msm: ipa: Remove warnings when rate limited Removed WARN_ON from the IPA rate limit macro. Change-Id: Ifceeb4360bfd0141c95fb1c41855f09a349153f0 Signed-off-by: Chirag Rastogi --- drivers/platform/msm/ipa/ipa_common_i.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_common_i.h b/drivers/platform/msm/ipa/ipa_common_i.h index 1ed86d3ca9..6f4a215f22 100644 --- a/drivers/platform/msm/ipa/ipa_common_i.h +++ b/drivers/platform/msm/ipa/ipa_common_i.h @@ -131,6 +131,7 @@ ipa3_dec_client_disable_clks_no_block(&log_info); \ } while (0) +#ifdef IPA_DEBUG /* * Printing one warning message in 5 seconds if multiple warning messages * are coming back to back. @@ -146,6 +147,9 @@ if (unlikely(rtn && __ratelimit(&_rs))) \ WARN_ON(rtn); \ }) +#else +#define WARN_ON_RATELIMIT_IPA(condition) ((void)0) +#endif /* * Printing one error message in 5 seconds if multiple error messages From 4aca461895800a154fcec59dd149700fa56579d4 Mon Sep 17 00:00:00 2001 From: Prasad Arepalli Date: Tue, 6 Aug 2024 17:53:29 +0530 Subject: [PATCH 4/8] msm: ipa: Updating the con pipe TRE structure as per uc Updating the consumer pipe TRE structure as per uc. Also, saving the virtual addresses during allocation of uc producer transfer or event rings, and its consumer transfer rings separately to free them in failure scenarios. Change-Id: I928c97c8f65418628d1bc7c1662d9e6a03f9d610 Signed-off-by: Prasad Arepalli --- drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c | 92 +++++++++----------- 1 file changed, 41 insertions(+), 51 deletions(-) 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..97e247fe50 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c @@ -25,8 +25,6 @@ #define MAX_UC_PROD_PIPES_ER_INDEX (MAX_UC_PROD_PIPES_TR_INDEX + MAX_UC_PROD_PIPES) #define MAX_UC_CONS_PIPES_TR_INDEX (MAX_UC_PROD_PIPES_ER_INDEX + MAX_UC_CONS_PIPES) -#define ER_TR_UC_BUFFS (MAX_UC_PROD_PIPES + MAX_UC_PROD_PIPES + MAX_UC_CONS_PIPES) - #define MAX_SYNX_FENCE_SESSION_NAME 64 #define DMA_DIR DMA_BIDIRECTIONAL @@ -105,17 +103,15 @@ struct prod_pipe_tre { } __packed; struct con_pipe_tre { - uint64_t buffer_ptr; - uint16_t buf_len; - uint16_t resvd1; - uint16_t chain:1; - uint16_t resvd4:7; - uint16_t ieob:1; - uint16_t ieot:1; - uint16_t bei:1; - uint16_t resvd3:5; - uint8_t re_type; - uint8_t resvd2; + uint16_t bufferIndex; + uint16_t offset2Payload; + uint16_t payloadSize:16; + uint8_t valid:1; + uint8_t ieot:1; + uint8_t tre_type:2; + uint8_t reserved0:4; + uint8_t last_tre:1; + uint8_t reserved1:7; } __packed; struct temp_buff_info { @@ -147,9 +143,13 @@ struct uc_temp_buffer_info { } __packed; struct er_tr_to_free { - void *cpu_address[ER_TR_UC_BUFFS]; + void *cpu_address_prod_tr[MAX_UC_PROD_PIPES]; + void *cpu_address_prod_er[MAX_UC_PROD_PIPES]; + void *cpu_address_cons_tr[MAX_UC_CONS_PIPES]; struct rtp_pipe_setup_cmd_data rtp_tr_er; - uint16_t no_buffs; + uint8_t prod_tr_no_buffs; + uint8_t prod_er_no_buffs; + uint8_t cons_tr_no_buffs; } __packed; struct er_tr_to_free er_tr_cpu_addresses; @@ -513,8 +513,8 @@ static int ipa3_uc_setup_prod_pipe_transfer_ring( rtp_cmd_data->uc_prod_tr[idx].temp_buff_pa = ring.phys_base; rtp_cmd_data->uc_prod_tr[idx].temp_buff_size = ring.size; - er_tr_cpu_addresses.cpu_address[er_tr_cpu_addresses.no_buffs] = ring.base; - er_tr_cpu_addresses.no_buffs += 1; + er_tr_cpu_addresses.cpu_address_prod_tr[idx] = ring.base; + er_tr_cpu_addresses.prod_tr_no_buffs += 1; IPADBG("prod pipe transfer ring setup done\n"); return 0; } @@ -539,8 +539,8 @@ static int ipa3_uc_setup_prod_pipe_event_ring( rtp_cmd_data->uc_prod_er[index].temp_buff_pa = ring.phys_base; rtp_cmd_data->uc_prod_er[index].temp_buff_size = ring.size; - er_tr_cpu_addresses.cpu_address[er_tr_cpu_addresses.no_buffs] = ring.base; - er_tr_cpu_addresses.no_buffs += 1; + er_tr_cpu_addresses.cpu_address_prod_er[index] = ring.base; + er_tr_cpu_addresses.prod_er_no_buffs += 1; IPADBG("prod pipe event ring setup done\n"); return 0; } @@ -565,45 +565,35 @@ static int ipa3_uc_setup_con_pipe_transfer_ring( rtp_cmd_data->uc_cons_tr[index].temp_buff_pa = ring.phys_base; rtp_cmd_data->uc_cons_tr[index].temp_buff_size = ring.size; - er_tr_cpu_addresses.cpu_address[er_tr_cpu_addresses.no_buffs] = ring.base; - er_tr_cpu_addresses.no_buffs += 1; + er_tr_cpu_addresses.cpu_address_cons_tr[index] = ring.base; + er_tr_cpu_addresses.cons_tr_no_buffs += 1; IPADBG("con pipe transfer ring setup done\n"); return 0; } void ipa3_free_uc_pipes_er_tr(void) { - uint16_t index = 0; + uint8_t index = 0; - for (index = 0; index < er_tr_cpu_addresses.no_buffs; index++) { - if (index < MAX_UC_PROD_PIPES_TR_INDEX) { - dma_free_coherent(ipa3_ctx->uc_pdev, - er_tr_cpu_addresses.rtp_tr_er.uc_prod_tr[index].temp_buff_size, - er_tr_cpu_addresses.cpu_address[index], - er_tr_cpu_addresses.rtp_tr_er.uc_prod_tr[index].temp_buff_pa); - } else if (index >= MAX_UC_PROD_PIPES_TR_INDEX && - index < MAX_UC_PROD_PIPES_ER_INDEX) { - /* subtracting MAX_UC_PROD_TR_INDEX here because, - * uc_prod_er[] is of size MAX_UC_PROD_PIPES only - */ - dma_free_coherent(ipa3_ctx->uc_pdev, - er_tr_cpu_addresses.rtp_tr_er.uc_prod_er[index - -MAX_UC_PROD_PIPES_TR_INDEX].temp_buff_size, - er_tr_cpu_addresses.cpu_address[index], - er_tr_cpu_addresses.rtp_tr_er.uc_prod_er[index - -MAX_UC_PROD_PIPES_TR_INDEX].temp_buff_pa); - } else if (index >= MAX_UC_PROD_PIPES_ER_INDEX && - index < MAX_UC_CONS_PIPES_TR_INDEX) { - /* subtracting MAX_UC_PROD_TR_INDEX here because, - * uc_cons_tr[] is of size MAX_UC_CONS_PIPES only - */ - dma_free_coherent(ipa3_ctx->uc_pdev, - er_tr_cpu_addresses.rtp_tr_er.uc_cons_tr[index - -MAX_UC_PROD_PIPES_ER_INDEX].temp_buff_size, - er_tr_cpu_addresses.cpu_address[index], - er_tr_cpu_addresses.rtp_tr_er.uc_cons_tr[index - -MAX_UC_PROD_PIPES_ER_INDEX].temp_buff_pa); - } + for (index = 0; index < er_tr_cpu_addresses.prod_tr_no_buffs; index++) { + dma_free_coherent(ipa3_ctx->uc_pdev, + er_tr_cpu_addresses.rtp_tr_er.uc_prod_tr[index].temp_buff_size, + er_tr_cpu_addresses.cpu_address_prod_tr[index], + er_tr_cpu_addresses.rtp_tr_er.uc_prod_tr[index].temp_buff_pa); + } + + for (index = 0; index < er_tr_cpu_addresses.prod_er_no_buffs; index++) { + dma_free_coherent(ipa3_ctx->uc_pdev, + er_tr_cpu_addresses.rtp_tr_er.uc_prod_er[index].temp_buff_size, + er_tr_cpu_addresses.cpu_address_prod_er[index], + er_tr_cpu_addresses.rtp_tr_er.uc_prod_er[index].temp_buff_pa); + } + + for (index = 0; index < er_tr_cpu_addresses.cons_tr_no_buffs; index++) { + dma_free_coherent(ipa3_ctx->uc_pdev, + er_tr_cpu_addresses.rtp_tr_er.uc_cons_tr[index].temp_buff_size, + er_tr_cpu_addresses.cpu_address_cons_tr[index], + er_tr_cpu_addresses.rtp_tr_er.uc_cons_tr[index].temp_buff_pa); } IPADBG("freed uc pipes er and tr memory\n"); From d8e985cde29d02fd4e13422dbc8c0e30dc39be7a Mon Sep 17 00:00:00 2001 From: Jagadeesh Ponduru Date: Wed, 14 Aug 2024 11:57:50 +0530 Subject: [PATCH 5/8] msm: ipa: allow both tcp and udp for the debugfs wlan filters allow both tcp and udp protocols when we install wlan filters through ipa debugfs nodes. Change-Id: I543b7b914fe3f15f53ba3e6baca9bc93147f398c Signed-off-by: Jagadeesh Ponduru --- drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index fc4861c28e..fd58864851 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -3669,7 +3669,8 @@ static ssize_t ipa_xr_add_flt_to_wlan(struct file *file, token = strsep(&sptr, " "); if (!token) return -EINVAL; - if (kstrtou8(token, 0, &prot[i]) || prot[i] != IPPROTO_UDP) + if (kstrtou8(token, 0, &prot[i]) || + !(prot[i] == IPPROTO_UDP || prot[i] == IPPROTO_TCP)) return -EINVAL; } From 41c6b23c1d5eacbda446605cca8c1a12cdac548b Mon Sep 17 00:00:00 2001 From: Prasad Arepalli Date: Wed, 14 Aug 2024 21:33:02 +0530 Subject: [PATCH 6/8] msm: ipa: Update uC HFI cmd queue payload size param Retrieve the HFI queue payload size parameter directly from synX driver and update it to uC. Change-Id: I6ab34853f92740795fd0de6c2a144707facca7e7 Signed-off-by: Prasad Arepalli --- drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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 987f33a22d..494abd5e69 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c @@ -113,7 +113,7 @@ struct rtp_pipe_setup_cmd_data { struct hfi_queue_info { u64 hfi_queue_addr; - u32 hfi_queue_size; + u32 hfi_queue_payload_size; u64 queue_header_start_addr; u64 queue_payload_start_addr; } __packed; @@ -1038,6 +1038,7 @@ int ipa3_create_hfi_send_uc(void) struct hfi_queue_info data; dma_addr_t hfi_queue_addr = 0; struct ipa_smmu_cb_ctx *cb = NULL; + struct synx_hw_fence_hfi_queue_header *hfi_queue_payload_vptr = NULL; snprintf(synx_session_name, MAX_SYNX_FENCE_SESSION_NAME, "ipa synx fence"); queue_desc.vaddr = NULL; @@ -1071,11 +1072,15 @@ int ipa3_create_hfi_send_uc(void) hfi_queue_addr = queue_desc.dev_addr; data.hfi_queue_addr = hfi_queue_addr; - data.hfi_queue_size = queue_desc.size; data.queue_header_start_addr = hfi_queue_addr + sizeof(struct synx_hw_fence_hfi_queue_table_header); data.queue_payload_start_addr = data.queue_header_start_addr + sizeof(struct synx_hw_fence_hfi_queue_header); + hfi_queue_payload_vptr = (struct synx_hw_fence_hfi_queue_header *)(queue_desc.vaddr + + sizeof(struct synx_hw_fence_hfi_queue_table_header)); + data.hfi_queue_payload_size = hfi_queue_payload_vptr->queue_size; + IPADBG("hfi queue payload vptr is 0x%x\n", hfi_queue_payload_vptr); + IPADBG("hfi queue payload size is 0x%x\n", data.hfi_queue_payload_size); res = ipa3_uc_send_hfi_cmd(&data); return res; } From 528993cef4eb4bb291c1ee9dfd604ee52aa7cdf5 Mon Sep 17 00:00:00 2001 From: Jagadeesh Ponduru Date: Thu, 8 Aug 2024 13:17:22 +0530 Subject: [PATCH 7/8] msm: ipa: workaround to ignore gsi pending irq type for XR platform remove the gsi pending irq check for xr platform as we are observing discrete ieob irq set for wdi use case and in a way it is taken care by msi interrupts. Change-Id: I306cad1f63cd9cf156567fc6b0cb210f7bf0152c Signed-off-by: Jagadeesh Ponduru --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index aa8c73faa6..cce9bdf971 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -6789,7 +6789,7 @@ void ipa3_disable_clks(void) * issue on GSI FW side. We need to capture before * turn off the ipa clock. */ - if (!ipa3_ctx->ipa_config_is_mhi) { + if (!ipa3_ctx->ipa_config_is_mhi || (ipa3_ctx->platform_type != IPA_PLAT_TYPE_XR)) { type = gsi_pending_irq_type(); if (type != -EPERM && type) { IPAERR("unexpected gsi irq type: %d\n", type); From b23ae7f5e48a74b0dabe63f0b02d720f4ecd2c59 Mon Sep 17 00:00:00 2001 From: Pavan Kumar M Date: Wed, 28 Aug 2024 11:13:03 +0530 Subject: [PATCH 8/8] msm: ipa3: Cleanup unused deepsleep API's Deepsleep & hibernate entry/exit SSR API's are same as regular SSR usecases. Clean up the unused deepsleep API's. Change-Id: I82745f13b679c473184a31c561a12c56a54b08ca Signed-off-by: Pavan Kumar M --- drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c | 32 --------------------- 1 file changed, 32 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 6f98383c13..e2c9b894cb 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -3959,9 +3959,6 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, } switch (code) { -#if IS_ENABLED(CONFIG_DEEPSLEEP) - case SUBSYS_BEFORE_DS_ENTRY: -#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)) case QCOM_SSR_BEFORE_SHUTDOWN: #else @@ -3990,17 +3987,6 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, ipa3_odl_pipe_cleanup_from_ssr(); IPAWANINFO("IPA BEFORE_SHUTDOWN handling is complete\n"); break; -#if IS_ENABLED(CONFIG_DEEPSLEEP) - case SUBSYS_AFTER_DS_ENTRY: - IPAWANINFO("IPA Received AFTER DEEPSLEEP ENTRY\n"); - if (atomic_read(&rmnet_ipa3_ctx->is_ssr) && - ipa3_ctx_get_type(IPA_HW_TYPE) < IPA_HW_v4_0) - ipa3_q6_post_shutdown_cleanup(); - - IPAWANINFO("AFTER DEEPSLEEP ENTRY handling is complete\n"); - break; -#endif - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)) case QCOM_SSR_AFTER_SHUTDOWN: #else @@ -4027,21 +4013,6 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, ipa3_client_prod_post_shutdown_cleanup(); IPAWANINFO("IPA AFTER_SHUTDOWN handling is complete\n"); break; -#if IS_ENABLED(CONFIG_DEEPSLEEP) - case SUBSYS_BEFORE_DS_EXIT: - IPAWANINFO("IPA received BEFORE DEEPSLEEP EXIT\n"); - if (atomic_read(&rmnet_ipa3_ctx->is_ssr)) { - /* clean up cached QMI msg/handlers */ - ipa3_qmi_service_exit(); - ipa3_q6_pre_powerup_cleanup(); - } - /* hold a proxy vote for the modem. */ - ipa3_proxy_clk_vote(atomic_read(&rmnet_ipa3_ctx->is_ssr)); - ipa3_reset_freeze_vote(); - IPAWANINFO("BEFORE DEEPSLEEP EXIT handling is complete\n"); - break; -#endif - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)) case QCOM_SSR_BEFORE_POWERUP: #else @@ -4058,9 +4029,6 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, ipa3_reset_freeze_vote(); IPAWANINFO("IPA BEFORE_POWERUP handling is complete\n"); break; -#if IS_ENABLED(CONFIG_DEEPSLEEP) - case SUBSYS_AFTER_DS_EXIT: -#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)) case QCOM_SSR_AFTER_POWERUP: #else