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_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 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); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index 94c0447872..fd58864851 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,492 @@ 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 || prot[i] == IPPROTO_TCP)) + 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 +4266,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 3cadbbdb83..82cd0e99fb 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]; @@ -3862,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_ */ 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..8618431f3b 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 @@ -60,24 +58,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]; @@ -105,17 +85,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 { @@ -131,7 +109,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; @@ -147,9 +125,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; @@ -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, @@ -513,8 +498,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 +524,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 +550,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"); @@ -1053,6 +1028,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; @@ -1086,11 +1062,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; } 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