qcacmn: Consider all power types to prepare client channel list

Currently driver prepares client channel list based on indoor ap
power type and this list is given to kernel. There are couple of
issues with this approach as mentioned below:
1. Based on this list kernel sends the scan requests because of
which there is a possibility that driver does not scan channels
which are not part of LPI channel list but are part of SP channel
list or VLP channel list.
2. Kernel sends start AP as well based on this channel list, since
all LPI channel are marked as NO_IR from driver and because of
which kernel dont send start AP on these chanels which leads to
SAP start failure even if there are VLP channels available.

Change-Id: I90174920df158c8b370e541034307a9a58448c29
CRs-Fixed: 3054543
This commit is contained in:
Ashish Kumar Dhanotiya 2021-10-14 14:23:31 +05:30 • committed by Gerrit - the friendly Code Review server
commit 46df590464

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -1019,12 +1020,118 @@ reg_modify_disable_chan_list_for_unii1_and_unii2a(
#ifdef CONFIG_BAND_6GHZ
#ifdef CONFIG_REG_CLIENT
#ifdef CONFIG_AFC_SUPPORT
/**
* reg_append_mas_chan_list_for_6g_sp() - Append SP channels to the master
* channel list
* @pdev_priv_obj: Pointer to pdev private object
*
* This function appends SP channels to the master channel list
*
* Return: void.
*/
static void
reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj
*pdev_priv_obj)
{
struct regulatory_channel *master_chan_list_6g_client_sp;
master_chan_list_6g_client_sp = pdev_priv_obj->afc_chan_list;
qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
master_chan_list_6g_client_sp,
NUM_6GHZ_CHANNELS *
sizeof(struct regulatory_channel));
}
#else
static inline void
reg_append_mas_chan_list_for_6g_sp(struct wlan_regulatory_pdev_priv_obj
*pdev_priv_obj)
{
}
#endif
/**
* reg_append_mas_chan_list_for_6g_lpi() - Append LPI channels to the master
* channel list
* @pdev_priv_obj: Pointer to pdev private object
*
* This function appends LPI channels to the master channel list
*
* Return: void.
*/
static void
reg_append_mas_chan_list_for_6g_lpi(struct wlan_regulatory_pdev_priv_obj
*pdev_priv_obj)
{
struct regulatory_channel *master_chan_list_6g_client_lpi;
uint8_t i, j;
if (!pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_INDOOR_AP]) {
reg_debug("No LPI reg rules");
return;
}
master_chan_list_6g_client_lpi =
pdev_priv_obj->mas_chan_list_6g_client[REG_INDOOR_AP]
[pdev_priv_obj->reg_cur_6g_client_mobility_type];
for (i = MIN_6GHZ_CHANNEL, j = 0;
i <= MAX_6GHZ_CHANNEL && j < NUM_6GHZ_CHANNELS; i++, j++) {
if ((pdev_priv_obj->mas_chan_list[i].state ==
CHANNEL_STATE_DISABLE) ||
(pdev_priv_obj->mas_chan_list[i].chan_flags &
REGULATORY_CHAN_DISABLED)) {
qdf_mem_copy(&pdev_priv_obj->mas_chan_list[i],
&master_chan_list_6g_client_lpi[j],
sizeof(struct regulatory_channel));
}
}
}
/**
* reg_append_mas_chan_list_for_6g_VLP() - Append VLP channels to the master
* channel list
* @pdev_priv_obj: Pointer to pdev private object
*
* This function appends VLP channels to the master channel list
*
* Return: void.
*/
static void
reg_append_mas_chan_list_for_6g_vlp(struct wlan_regulatory_pdev_priv_obj
*pdev_priv_obj)
{
struct regulatory_channel *master_chan_list_6g_client_vlp;
uint8_t i, j;
if (!pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_VERY_LOW_POWER_AP]) {
reg_debug("No VLP reg rules");
return;
}
master_chan_list_6g_client_vlp =
pdev_priv_obj->mas_chan_list_6g_client[REG_VERY_LOW_POWER_AP]
[pdev_priv_obj->reg_cur_6g_client_mobility_type];
for (i = MIN_6GHZ_CHANNEL, j = 0;
i <= MAX_6GHZ_CHANNEL && j < NUM_6GHZ_CHANNELS; i++, j++) {
if ((pdev_priv_obj->mas_chan_list[i].state ==
CHANNEL_STATE_DISABLE) ||
(pdev_priv_obj->mas_chan_list[i].chan_flags &
REGULATORY_CHAN_DISABLED)) {
qdf_mem_copy(&pdev_priv_obj->mas_chan_list[i],
&master_chan_list_6g_client_vlp[j],
sizeof(struct regulatory_channel));
}
}
}
static void
reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj
*pdev_priv_obj)
{
struct regulatory_channel *master_chan_list_6g_client;
if (pdev_priv_obj->reg_cur_6g_ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE ||
pdev_priv_obj->reg_cur_6g_client_mobility_type >=
REG_MAX_CLIENT_TYPE) {
@ -1032,14 +1139,20 @@ reg_append_mas_chan_list_for_6g(struct wlan_regulatory_pdev_priv_obj
return;
}
master_chan_list_6g_client =
pdev_priv_obj->mas_chan_list_6g_client[REG_INDOOR_AP]
[pdev_priv_obj->reg_cur_6g_client_mobility_type];
/* Client should be able to scan all types of APs, so prepare the
* client list which has all the enabled channels, first priority is
* given to AFC power type and then second priority is decided based on
* gindoor_channel_support ini value
*/
reg_append_mas_chan_list_for_6g_sp(pdev_priv_obj);
qdf_mem_copy(&pdev_priv_obj->mas_chan_list[MIN_6GHZ_CHANNEL],
master_chan_list_6g_client,
NUM_6GHZ_CHANNELS *
sizeof(struct regulatory_channel));
if (pdev_priv_obj->indoor_chan_enabled) {
reg_append_mas_chan_list_for_6g_lpi(pdev_priv_obj);
reg_append_mas_chan_list_for_6g_vlp(pdev_priv_obj);
} else {
reg_append_mas_chan_list_for_6g_vlp(pdev_priv_obj);
reg_append_mas_chan_list_for_6g_lpi(pdev_priv_obj);
}
}
static void