From 46df590464f2bc4fdf37dd069a9b62b4ac837da0 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Thu, 14 Oct 2021 14:23:31 +0530 Subject: [PATCH] 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 --- .../regulatory/core/src/reg_build_chan_list.c | 131 ++++++++++++++++-- 1 file changed, 122 insertions(+), 9 deletions(-) diff --git a/umac/regulatory/core/src/reg_build_chan_list.c b/umac/regulatory/core/src/reg_build_chan_list.c index d20271009038..f6e70bd26ead 100644 --- a/umac/regulatory/core/src/reg_build_chan_list.c +++ b/umac/regulatory/core/src/reg_build_chan_list.c @@ -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