Procházet zdrojové kódy

Merge "msm: ipa3: Initiate filter reservation during filter addition"

QCTECMDR Service před 6 měsíci
rodič
revize
f9b1b2eeb0

+ 30 - 42
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);

+ 3 - 2
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];

+ 20 - 14
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");

+ 18 - 0
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.

+ 12 - 27
drivers/platform/msm/ipa/ipa_v3/ipa_uc_rtp.c

@@ -58,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];
@@ -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 = ipa_xr_wdi_opt_dpath_add_filter_req(&flt_add_req, stream_id);
+	result = ipa3_uc_send_tuple_info_cmd(req);
 	if (result) {
-		IPAERR("Fail to send tuple info cmd to wlan\n");
+		IPAERR("Fail to send tuple info cmd to uc\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");
 
+	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;
+	}
+
 	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,