Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b5ff6187 authored by Pooja Kumari's avatar Pooja Kumari
Browse files

msm: ipa3: Enable dynamic switch between WDI2 and WDI3



Currently only WDI3 is supported in SDx55 target.
Enable WDI2 and dynamic switching between WDI3 
and WDI2 based on wlan input.

Change-Id: I063ef6cd6dc80a237f9f30946abb243dd1a81b67
Signed-off-by: default avatarPooja Kumari <kumarip@codeaurora.org>
parent 3db6f4c3
Loading
Loading
Loading
Loading
+39 −26
Original line number Diff line number Diff line
/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
/* Copyright (c) 2017, 2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -121,7 +121,7 @@ int ipa_wdi_init(struct ipa_wdi_init_in_params *in,

	ipa_wdi_ctx->is_smmu_enabled = out->is_smmu_enabled;

	if (ipa3_ctx->ipa_wdi3_over_gsi)
	if (IPA_WDI2_OVER_GSI() && (in->wdi_version == IPA_WDI_3))
		out->is_over_gsi = true;
	else
		out->is_over_gsi = false;
@@ -129,6 +129,15 @@ int ipa_wdi_init(struct ipa_wdi_init_in_params *in,
}
EXPORT_SYMBOL(ipa_wdi_init);

int ipa3_get_wdi_version(void)
{
	if (ipa_wdi_ctx)
		return ipa_wdi_ctx->wdi_version;
	/* default version is IPA_WDI_3 */
	return IPA_WDI_3;
}
EXPORT_SYMBOL(ipa3_get_wdi_version);

int ipa_wdi_cleanup(void)
{
	struct ipa_wdi_intf_info *entry;
@@ -255,20 +264,22 @@ int ipa_wdi_reg_intf(struct ipa_wdi_reg_intf_in_params *in)

	memset(tx_prop, 0, sizeof(tx_prop));
	tx_prop[0].ip = IPA_IP_v4;
	if (!ipa3_ctx->ipa_wdi3_over_gsi)
		tx_prop[0].dst_pipe = IPA_CLIENT_WLAN1_CONS;
	else
	if (ipa_wdi_ctx->wdi_version == IPA_WDI_3)
		tx_prop[0].dst_pipe = IPA_CLIENT_WLAN2_CONS;
	else
		tx_prop[0].dst_pipe = IPA_CLIENT_WLAN1_CONS;

	tx_prop[0].alt_dst_pipe = in->alt_dst_pipe;
	tx_prop[0].hdr_l2_type = in->hdr_info[0].hdr_type;
	strlcpy(tx_prop[0].hdr_name, hdr->hdr[IPA_IP_v4].name,
		sizeof(tx_prop[0].hdr_name));

	tx_prop[1].ip = IPA_IP_v6;
	if (!ipa3_ctx->ipa_wdi3_over_gsi)
		tx_prop[1].dst_pipe = IPA_CLIENT_WLAN1_CONS;
	else
	if (ipa_wdi_ctx->wdi_version == IPA_WDI_3)
		tx_prop[1].dst_pipe = IPA_CLIENT_WLAN2_CONS;
	else
		tx_prop[1].dst_pipe = IPA_CLIENT_WLAN1_CONS;

	tx_prop[1].alt_dst_pipe = in->alt_dst_pipe;
	tx_prop[1].hdr_l2_type = in->hdr_info[1].hdr_type;
	strlcpy(tx_prop[1].hdr_name, hdr->hdr[IPA_IP_v6].name,
@@ -279,10 +290,11 @@ int ipa_wdi_reg_intf(struct ipa_wdi_reg_intf_in_params *in)
	rx.prop = rx_prop;
	memset(rx_prop, 0, sizeof(rx_prop));
	rx_prop[0].ip = IPA_IP_v4;
	if (!ipa3_ctx->ipa_wdi3_over_gsi)
		rx_prop[0].src_pipe = IPA_CLIENT_WLAN1_PROD;
	else
	if (ipa_wdi_ctx->wdi_version == IPA_WDI_3)
		rx_prop[0].src_pipe = IPA_CLIENT_WLAN2_PROD;
	else
		rx_prop[0].src_pipe = IPA_CLIENT_WLAN1_PROD;

	rx_prop[0].hdr_l2_type = in->hdr_info[0].hdr_type;
	if (in->is_meta_data_valid) {
		rx_prop[0].attrib.attrib_mask |= IPA_FLT_META_DATA;
@@ -291,10 +303,11 @@ int ipa_wdi_reg_intf(struct ipa_wdi_reg_intf_in_params *in)
	}

	rx_prop[1].ip = IPA_IP_v6;
	if (!ipa3_ctx->ipa_wdi3_over_gsi)
		rx_prop[1].src_pipe = IPA_CLIENT_WLAN1_PROD;
	else
	if (ipa_wdi_ctx->wdi_version == IPA_WDI_3)
		rx_prop[1].src_pipe = IPA_CLIENT_WLAN2_PROD;
	else
		rx_prop[1].src_pipe = IPA_CLIENT_WLAN1_PROD;

	rx_prop[1].hdr_l2_type = in->hdr_info[1].hdr_type;
	if (in->is_meta_data_valid) {
		rx_prop[1].attrib.attrib_mask |= IPA_FLT_META_DATA;
@@ -673,12 +686,12 @@ int ipa_wdi_disconn_pipes(void)
		}
	}

	if (!ipa3_ctx->ipa_wdi3_over_gsi) {
		ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_PROD);
		ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_CONS);
	} else {
	if (ipa_wdi_ctx->wdi_version == IPA_WDI_3) {
		ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_PROD);
		ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_CONS);
	} else {
		ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_PROD);
		ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_CONS);
	}

	if (ipa_wdi_ctx->wdi_version == IPA_WDI_3) {
@@ -734,12 +747,12 @@ int ipa_wdi_enable_pipes(void)
		return -EPERM;
	}

	if (!ipa3_ctx->ipa_wdi3_over_gsi) {
		ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_PROD);
		ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_CONS);
	} else {
	if (ipa_wdi_ctx->wdi_version == IPA_WDI_3) {
		ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_PROD);
		ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_CONS);
	} else {
		ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_PROD);
		ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_CONS);
	}

	if (ipa_wdi_ctx->wdi_version == IPA_WDI_3) {
@@ -800,12 +813,12 @@ int ipa_wdi_disable_pipes(void)
		return -EPERM;
	}

	if (!ipa3_ctx->ipa_wdi3_over_gsi) {
		ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_PROD);
		ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_CONS);
	} else {
	if (ipa_wdi_ctx->wdi_version == IPA_WDI_3) {
		ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_PROD);
		ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_CONS);
	} else {
		ipa_ep_idx_rx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_PROD);
		ipa_ep_idx_tx = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_CONS);
	}

	if (ipa_wdi_ctx->wdi_version == IPA_WDI_3) {
+2 −2
Original line number Diff line number Diff line
@@ -8699,8 +8699,8 @@ int ipa3_get_smmu_params(struct ipa_smmu_in_params *in,

	switch (in->smmu_client) {
	case IPA_SMMU_WLAN_CLIENT:
		if (ipa3_ctx->ipa_wdi3_over_gsi ||
			ipa3_ctx->ipa_wdi2_over_gsi)
		if (ipa3_get_wdi_version() == IPA_WDI_3 ||
			IPA_WDI2_OVER_GSI())
			is_smmu_enable =
				!(ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_AP] |
				ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_WLAN]);
+4 −0
Original line number Diff line number Diff line
@@ -91,6 +91,9 @@
/*Bit pattern for SW to identify PC restoration completed */
#define PC_RESTORE_CONTEXT_STATUS_SUCCESS       0xCAFECAFE

#define IPA_WDI2_OVER_GSI() (ipa3_ctx->ipa_wdi2_over_gsi \
		&& (ipa3_get_wdi_version() == IPA_WDI_2))

#define IPADBG(fmt, args...) \
	do { \
		pr_debug(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args);\
@@ -2904,6 +2907,7 @@ int ipa3_tag_aggr_force_close(int pipe_num);

void ipa3_active_clients_unlock(void);
int ipa3_wdi_init(void);
int ipa3_get_wdi_version(void);
int ipa3_write_qmapid_gsi_wdi_pipe(u32 clnt_hdl, u8 qmap_id);
int ipa3_write_qmapid_wdi_pipe(u32 clnt_hdl, u8 qmap_id);
int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id);
+26 −24
Original line number Diff line number Diff line
@@ -728,14 +728,14 @@ static void ipa_release_ap_smmu_mappings(enum ipa_client_type client)

	if (IPA_CLIENT_IS_CONS(client)) {
		start = IPA_WDI_TX_RING_RES;
		if (ipa3_ctx->ipa_wdi3_over_gsi)
		if (ipa3_get_wdi_version() == IPA_WDI_3)
			end = IPA_WDI_TX_DB_RES;
		else
			end = IPA_WDI_CE_DB_RES;
	} else {
		start = IPA_WDI_RX_RING_RES;
		if (ipa3_ctx->ipa_wdi2 ||
			ipa3_ctx->ipa_wdi3_over_gsi)
			(ipa3_get_wdi_version() == IPA_WDI_3))
			end = IPA_WDI_RX_COMP_RING_WP_RES;
		else
			end = IPA_WDI_RX_RING_RP_RES;
@@ -1351,19 +1351,6 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,
		gsi_channel_props.ring_base_addr = va;
		gsi_channel_props.ring_base_vaddr =  NULL;
		gsi_channel_props.ring_len = len;
		pa = in->smmu_enabled ? in->u.ul_smmu.rdy_ring_rp_pa :
			in->u.ul.rdy_ring_rp_pa;
		if (ipa_create_gsi_smmu_mapping(IPA_WDI_RX_RING_RP_RES,
					in->smmu_enabled,
					pa,
					NULL,
					4,
					false,
					&wifi_rx_ri_addr)) {
			IPAERR("fail to create gsi RX rng RP\n");
			result = -ENOMEM;
			goto gsi_timeout;
		}
		len = in->smmu_enabled ?
			in->u.ul_smmu.rdy_comp_ring_size :
			in->u.ul.rdy_comp_ring_size;
@@ -1384,6 +1371,19 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,
			goto gsi_timeout;
		}
		gsi_evt_ring_props.ring_base_addr = va;
		pa = in->smmu_enabled ? in->u.ul_smmu.rdy_ring_rp_pa :
			in->u.ul.rdy_ring_rp_pa;
		if (ipa_create_gsi_smmu_mapping(IPA_WDI_RX_RING_RP_RES,
					in->smmu_enabled,
					pa,
					NULL,
					4,
					false,
					&wifi_rx_ri_addr)) {
			IPAERR("fail to create gsi RX rng RP\n");
			result = -ENOMEM;
			goto gsi_timeout;
		}
		gsi_evt_ring_props.ring_base_vaddr = NULL;
		gsi_evt_ring_props.ring_len = len;
		pa = in->smmu_enabled ?
@@ -1600,7 +1600,7 @@ int ipa3_connect_wdi_pipe(struct ipa_wdi_in_params *in,
		}
	}

	if (ipa3_ctx->ipa_wdi2_over_gsi)
	if (IPA_WDI2_OVER_GSI())
		return ipa3_connect_gsi_wdi_pipe(in, out);

	result = ipa3_uc_state_check();
@@ -2119,10 +2119,11 @@ int ipa3_disconnect_gsi_wdi_pipe(u32 clnt_hdl)
		ipa3_ctx->uc_wdi_ctx.stats_notify = NULL;
	else
		IPADBG("uc_wdi_ctx.stats_notify already null\n");
	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 ||
	if (ipa3_ctx->ipa_hw_type > IPA_HW_v4_5 ||
		(ipa3_ctx->ipa_hw_type == IPA_HW_v4_1 &&
		ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ))
		ipa3_uc_debug_stats_dealloc(IPA_HW_PROTOCOL_WDI);

	IPADBG("client (ep: %d) disconnected\n", clnt_hdl);

fail_dealloc_channel:
@@ -2149,7 +2150,7 @@ int ipa3_disconnect_wdi_pipe(u32 clnt_hdl)
		return -EINVAL;
	}

	if (ipa3_ctx->ipa_wdi2_over_gsi)
	if (IPA_WDI2_OVER_GSI())
		return ipa3_disconnect_gsi_wdi_pipe(clnt_hdl);

	result = ipa3_uc_state_check();
@@ -2320,7 +2321,7 @@ int ipa3_enable_wdi_pipe(u32 clnt_hdl)
		return -EINVAL;
	}

	if (ipa3_ctx->ipa_wdi2_over_gsi)
	if (IPA_WDI2_OVER_GSI())
		return ipa3_enable_gsi_wdi_pipe(clnt_hdl);

	result = ipa3_uc_state_check();
@@ -2385,7 +2386,7 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl)
		return -EINVAL;
	}

	if (ipa3_ctx->ipa_wdi2_over_gsi)
	if (IPA_WDI2_OVER_GSI())
		return ipa3_disable_gsi_wdi_pipe(clnt_hdl);

	result = ipa3_uc_state_check();
@@ -2423,6 +2424,7 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl)
		ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl);

		cons_hdl = ipa3_get_ep_mapping(IPA_CLIENT_WLAN1_CONS);

		if (cons_hdl == IPA_EP_NOT_ALLOCATED) {
			IPAERR("Client %u is not mapped\n",
				IPA_CLIENT_WLAN1_CONS);
@@ -2502,7 +2504,7 @@ int ipa3_resume_gsi_wdi_pipe(u32 clnt_hdl)
	}
	pcmd_t = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_WDI];
	/* start uC gsi dbg stats monitor */
	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 ||
	if (ipa3_ctx->ipa_hw_type > IPA_HW_v4_5 ||
		(ipa3_ctx->ipa_hw_type == IPA_HW_v4_1 &&
		ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ)) {
		if (IPA_CLIENT_IS_PROD(ep->client)) {
@@ -2558,7 +2560,7 @@ int ipa3_resume_wdi_pipe(u32 clnt_hdl)
		return -EINVAL;
	}

	if (ipa3_ctx->ipa_wdi2_over_gsi)
	if (IPA_WDI2_OVER_GSI())
		return ipa3_resume_gsi_wdi_pipe(clnt_hdl);

	result = ipa3_uc_state_check();
@@ -2680,7 +2682,7 @@ int ipa3_suspend_gsi_wdi_pipe(u32 clnt_hdl)
	}
	pcmd_t = &ipa3_ctx->gsi_info[IPA_HW_PROTOCOL_WDI];
	/* stop uC gsi dbg stats monitor */
	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 ||
	if (ipa3_ctx->ipa_hw_type > IPA_HW_v4_5 ||
		(ipa3_ctx->ipa_hw_type == IPA_HW_v4_1 &&
		ipa3_ctx->platform_type == IPA_PLAT_TYPE_APQ)) {
		if (IPA_CLIENT_IS_PROD(ep->client)) {
@@ -2731,7 +2733,7 @@ int ipa3_suspend_wdi_pipe(u32 clnt_hdl)
		return -EINVAL;
	}

	if (ipa3_ctx->ipa_wdi2_over_gsi)
	if (IPA_WDI2_OVER_GSI())
		return ipa3_suspend_gsi_wdi_pipe(clnt_hdl);

	result = ipa3_uc_state_check();
+30 −2
Original line number Diff line number Diff line
@@ -2299,6 +2299,13 @@ static const struct ipa_ep_configuration ipa3_ep_mapping
			IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP,
			QMB_MASTER_SELECT_DDR,
			{ 9, 12, 8, 16, IPA_EE_AP, GSI_FREE_PRE_FETCH, 2 } },
	/* config wlan1_prod same as wlan2_prod */
	[IPA_4_5][IPA_CLIENT_WLAN1_PROD]          = {
			true, IPA_v4_5_GROUP_UL_DL,
			true,
			IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP,
			QMB_MASTER_SELECT_DDR,
			{ 9, 12, 8, 16, IPA_EE_AP, GSI_FREE_PRE_FETCH, 2 } },
	[IPA_4_5][IPA_CLIENT_USB_PROD]            = {
			true, IPA_v4_5_GROUP_UL_DL,
			true,
@@ -2397,6 +2404,13 @@ static const struct ipa_ep_configuration ipa3_ep_mapping
			IPA_DPS_HPS_SEQ_TYPE_INVALID,
			QMB_MASTER_SELECT_DDR,
			{ 24, 3, 8, 14, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 } },
	/* config wlan1_cons same as wlan2_cons */
	[IPA_4_5][IPA_CLIENT_WLAN1_CONS]          = {
			true, IPA_v4_5_GROUP_UL_DL,
			false,
			IPA_DPS_HPS_SEQ_TYPE_INVALID,
			QMB_MASTER_SELECT_DDR,
			{ 24, 3, 8, 14, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 } },
	[IPA_4_5][IPA_CLIENT_USB_CONS]            = {
			true, IPA_v4_5_GROUP_UL_DL,
			false,
@@ -2673,7 +2687,14 @@ static const struct ipa_ep_configuration ipa3_ep_mapping

	/* IPA_4_5_AUTO */
	[IPA_4_5_AUTO][IPA_CLIENT_WLAN2_PROD]          = {
			false, IPA_v4_5_GROUP_UL_DL,
			true, IPA_v4_5_GROUP_UL_DL,
			true,
			IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP,
			QMB_MASTER_SELECT_DDR,
			{ 9, 12, 8, 16, IPA_EE_AP, GSI_FREE_PRE_FETCH, 2 } },
	/* config wlan1_prod same as wlan2_prod */
	[IPA_4_5_AUTO][IPA_CLIENT_WLAN1_PROD]          = {
			true, IPA_v4_5_GROUP_UL_DL,
			true,
			IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP,
			QMB_MASTER_SELECT_DDR,
@@ -2777,7 +2798,14 @@ static const struct ipa_ep_configuration ipa3_ep_mapping
			{ 11, 14, 8, 16, IPA_EE_AP } },

	[IPA_4_5_AUTO][IPA_CLIENT_WLAN2_CONS]          = {
			false, IPA_v4_5_GROUP_UL_DL,
			true, IPA_v4_5_GROUP_UL_DL,
			false,
			IPA_DPS_HPS_SEQ_TYPE_INVALID,
			QMB_MASTER_SELECT_DDR,
			{ 24, 18, 8, 14, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3 } },
	/* config wlan1_cons same as wlan2_cons */
	[IPA_4_5_AUTO][IPA_CLIENT_WLAN1_CONS]          = {
			true, IPA_v4_5_GROUP_UL_DL,
			false,
			IPA_DPS_HPS_SEQ_TYPE_INVALID,
			QMB_MASTER_SELECT_DDR,
Loading