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

Commit 3de98015 authored by Balaji Pothunoori's avatar Balaji Pothunoori Committed by Rahul Choudhary
Browse files

qcacld-3.0: Do not allow SAP SCC on non-PSC/non-VLP channels

SAP is allowed to come up on SCC with a STA operating
in 6 GHz only if the STA is on a PSC channel in VLP mode.
Therefore, filter out all 6 GHz channels from the PCL if
the STA operates on any non-VLP mode. Also, in case of
VLP mode, filter out non-PSC channels.

Change-Id: I37d9a510db3647fc07858af99eb614ebe824cc78
CRs-Fixed: 3206471
parent c5827e1f
Loading
Loading
Loading
Loading
+105 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include "wlan_mlme_ucfg_api.h"
#include "csr_neighbor_roam.h"
#include "wlan_scan_api.h"
#include <wlan_reg_ucfg_api.h>

/**
 * first_connection_pcl_table - table which provides PCL for the
@@ -733,6 +734,96 @@ policy_mgr_modify_pcl_based_on_indoor(struct wlan_objmgr_psoc *psoc,
	return QDF_STATUS_SUCCESS;
}

/**
 * policy_mgr_modify_sap_pcl_for_6G_channels() - filter out the
 * 6GHz channels where SCC is not supported.
 * @psoc: pointer to soc
 * @pcl_list_org: channel list to filter out
 * @weight_list_org: weight of channel list
 * @pcl_len_org: length of channel list
 *
 * Return: QDF_STATUS
 */
static QDF_STATUS
policy_mgr_modify_sap_pcl_for_6G_channels(struct wlan_objmgr_psoc *psoc,
					  uint32_t *pcl_list_org,
					  uint8_t *weight_list_org,
					  uint32_t *pcl_len_org)
{
	struct policy_mgr_psoc_priv_obj *pm_ctx;
	uint32_t pcl_list[NUM_CHANNELS];
	uint8_t weight_list[NUM_CHANNELS];
	uint32_t vdev_id = 0, pcl_len = 0, i;
	struct wlan_objmgr_vdev *vdev;
	qdf_freq_t sta_gc_freq = 0;
	uint32_t ap_pwr_type_6g = 0;

	pm_ctx = policy_mgr_get_context(psoc);
	if (!pm_ctx) {
		policy_mgr_err("Invalid Context");
		return QDF_STATUS_E_FAILURE;
	}

	if (*pcl_len_org > NUM_CHANNELS) {
		policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
		return QDF_STATUS_E_FAILURE;
	}

	if (policy_mgr_mode_specific_connection_count(psoc,
						      PM_STA_MODE, NULL)) {
		sta_gc_freq =
			policy_mgr_mode_specific_get_channel(psoc, PM_STA_MODE);
		vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_STA_MODE);
	} else if (policy_mgr_mode_specific_connection_count(psoc,
							     PM_P2P_CLIENT_MODE,
							     NULL)) {
		sta_gc_freq = policy_mgr_mode_specific_get_channel(
						psoc, PM_P2P_CLIENT_MODE);
		vdev_id = policy_mgr_mode_specific_vdev_id(psoc,
							   PM_P2P_CLIENT_MODE);
	}

	if (!sta_gc_freq || !WLAN_REG_IS_6GHZ_CHAN_FREQ(sta_gc_freq))
		return QDF_STATUS_SUCCESS;

	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
						    WLAN_POLICY_MGR_ID);
	if (!vdev) {
		policy_mgr_err("vdev %d is not present", vdev_id);
		return QDF_STATUS_E_FAILURE;
	}

	/* If STA is present in 6GHz, STA+SAP SCC is allowed
	 * only on PSC channels in VLP mode. Therefore, remove
	 * all other 6GHz channels from the PCL list.
	 *
	 * VLP STA in PSC + SAP     - Allowed
	 * VLP STA in non-PSC + SAP - Not allowed
	 * non-VLP STA + SAP        - Not allowed
	 */
	ucfg_reg_get_cur_6g_ap_pwr_type(pm_ctx->pdev, &ap_pwr_type_6g);
	policy_mgr_debug("STA power type : %d", ap_pwr_type_6g);
	for (i = 0; i < *pcl_len_org; i++) {
		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_list_org[i])) {
			if (ap_pwr_type_6g != REG_VERY_LOW_POWER_AP)
				continue;
			else if (!WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(pcl_list_org[i]))
				continue;
		}
		pcl_list[pcl_len] = pcl_list_org[i];
		weight_list[pcl_len++] = weight_list_org[i];
	}

	qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org));
	qdf_mem_zero(weight_list_org, *pcl_len_org * sizeof(*weight_list_org));
	qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org));
	qdf_mem_copy(weight_list_org, weight_list, pcl_len);
	*pcl_len_org = pcl_len;

	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
	return QDF_STATUS_SUCCESS;
}

static QDF_STATUS policy_mgr_pcl_modification_for_sap(
			struct wlan_objmgr_psoc *psoc,
			uint32_t *pcl_channels, uint8_t *pcl_weight,
@@ -793,6 +884,14 @@ static QDF_STATUS policy_mgr_pcl_modification_for_sap(
	}
	indoor_modified_pcl = true;

	status = policy_mgr_modify_sap_pcl_for_6G_channels(psoc,
							   pcl_channels,
							   pcl_weight, len);
	if (QDF_IS_STATUS_ERROR(status)) {
		policy_mgr_err("failed to modify pcl for 6G channels");
		return status;
	}

	modified_final_pcl = true;
	policy_mgr_debug(" %d %d %d %d %d",
			 mandatory_modified_pcl,
@@ -1031,6 +1130,8 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc,

	policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight);

	policy_mgr_debug("PCL before modification");
	policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight);
	policy_mgr_mode_specific_modification_on_pcl(
		psoc, pcl_channels, pcl_weight, len, mode);

@@ -1041,6 +1142,10 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc,
		policy_mgr_err("failed to get modified pcl based on DNBS");
		return status;
	}

	policy_mgr_debug("PCL after modification");
	policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight);

	return QDF_STATUS_SUCCESS;
}