qcacmn: update unsafe channel list for SAP for freq extcmd

Currently unsafe channel list updated from firmware using
"wmi_wlan_freq_avoid_event_id".

This change is to update unsafe channel list for vendor
QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT which we receive from
userspace.

Change-Id: I57ff334e9cf47468c30bc6884a9ead0a65a92eab
CRs-Fixed: 3103275
Tento commit je obsažen v:
Balaji Pothunoori
2022-01-05 15:09:59 +05:30
odevzdal Madan Koyyalamudi
rodič 1a3cc5efc1
revize 7192d90810
8 změnil soubory, kde provedl 171 přidání a 14 odebrání

Zobrazit soubor

@@ -1659,6 +1659,9 @@ reg_modify_chan_list_for_avoid_chan_ext(struct wlan_regulatory_pdev_priv_obj
if (!psoc)
return;
if (reg_check_coex_unsafe_nb_user_prefer(psoc))
return;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj)
return;

Zobrazit soubor

@@ -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
@@ -92,6 +93,7 @@ static void reg_call_chan_change_cbks(struct wlan_objmgr_psoc *psoc,
qdf_mem_free(cur_chan_list);
}
#ifdef FEATURE_WLAN_CH_AVOID_EXT
/**
* reg_alloc_and_fill_payload() - Alloc and fill payload structure.
* @psoc: Pointer to global psoc structure.
@@ -110,6 +112,37 @@ static void reg_alloc_and_fill_payload(struct wlan_objmgr_psoc *psoc,
return;
}
*payload = qdf_mem_malloc(sizeof(**payload));
if (*payload) {
(*payload)->psoc = psoc;
(*payload)->pdev = pdev;
if (reg_check_coex_unsafe_nb_user_prefer(psoc)) {
(*payload)->ch_avoid_ind =
!!psoc_priv_obj->ch_avoid_ext_ind;
qdf_mem_copy(&(*payload)->avoid_info.freq_list,
&psoc_priv_obj->avoid_freq_ext_list,
sizeof(psoc_priv_obj->avoid_freq_ext_list));
psoc_priv_obj->ch_avoid_ext_ind = false;
}
qdf_mem_copy(&(*payload)->avoid_info.chan_list,
&psoc_priv_obj->unsafe_chan_list,
sizeof(psoc_priv_obj->unsafe_chan_list));
}
}
#else
static void reg_alloc_and_fill_payload(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
struct reg_sched_payload **payload)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
*payload = NULL;
return;
}
*payload = qdf_mem_malloc(sizeof(**payload));
if (*payload) {
(*payload)->psoc = psoc;
@@ -118,13 +151,13 @@ static void reg_alloc_and_fill_payload(struct wlan_objmgr_psoc *psoc,
qdf_mem_copy(&(*payload)->avoid_info.freq_list,
&psoc_priv_obj->avoid_freq_list,
sizeof(psoc_priv_obj->avoid_freq_list));
qdf_mem_copy(&(*payload)->avoid_info.chan_list,
&psoc_priv_obj->unsafe_chan_list,
sizeof(psoc_priv_obj->unsafe_chan_list));
psoc_priv_obj->ch_avoid_ind = false;
}
qdf_mem_copy(&(*payload)->avoid_info.chan_list,
&psoc_priv_obj->unsafe_chan_list,
sizeof(psoc_priv_obj->unsafe_chan_list));
}
#endif
/**
* reg_chan_change_flush_cbk_sb() - Flush south bound channel change callbacks.

Zobrazit soubor

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2014-2020 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
@@ -28,8 +28,8 @@
#include "reg_services_public_struct.h"
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include "reg_services_common.h"
#include "reg_priv_objs.h"
#include "reg_services_common.h"
#include "reg_build_chan_list.h"
#include "reg_callbacks.h"
#include "reg_lte.h"
@@ -185,6 +185,12 @@ QDF_STATUS reg_process_ch_avoid_event(struct wlan_objmgr_psoc *psoc,
reg_err("reg psoc private obj is NULL");
return QDF_STATUS_E_FAILURE;
}
if (reg_check_coex_unsafe_nb_user_prefer(psoc)) {
reg_err("skipping LTE Coex unsafe channel change");
return QDF_STATUS_E_FAILURE;
}
if (CH_AVOID_RULE_DO_NOT_RESTART ==
psoc_priv_obj->restart_beaconing) {
reg_debug("skipping all LTE Coex unsafe channel range");

Zobrazit soubor

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-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
@@ -178,6 +178,7 @@ struct wlan_regulatory_psoc_priv_obj {
#ifdef FEATURE_WLAN_CH_AVOID_EXT
bool ch_avoid_ext_ind;
struct ch_avoid_ind_type avoid_freq_ext_list;
bool coex_unsafe_chan_nb_user_prefer;
#endif
};

Zobrazit soubor

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-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
@@ -6070,11 +6070,16 @@ reg_process_ch_avoid_freq_ext(struct wlan_objmgr_psoc *psoc,
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
uint8_t start_channel;
uint8_t end_channel;
int32_t txpower;
bool is_valid_txpower;
struct ch_avoid_freq_type *range;
enum channel_enum ch_loop;
enum channel_enum start_ch_idx;
enum channel_enum end_ch_idx;
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
uint32_t len;
struct unsafe_ch_list *unsafe_ch_list;
bool coex_unsafe_nb_user_prefer;
pdev_priv_obj = reg_get_pdev_obj(pdev);
@@ -6088,15 +6093,23 @@ reg_process_ch_avoid_freq_ext(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_E_FAILURE;
}
if (pdev_priv_obj->avoid_chan_ext_list.chan_cnt > 0) {
uint32_t len;
unsafe_ch_list = &psoc_priv_obj->unsafe_chan_list;
coex_unsafe_nb_user_prefer =
psoc_priv_obj->coex_unsafe_chan_nb_user_prefer;
if (pdev_priv_obj->avoid_chan_ext_list.chan_cnt > 0) {
len = sizeof(pdev_priv_obj->avoid_chan_ext_list.chan_freq_list);
pdev_priv_obj->avoid_chan_ext_list.chan_cnt = 0;
qdf_mem_zero(&pdev_priv_obj->avoid_chan_ext_list.chan_freq_list,
len);
}
if (unsafe_ch_list->chan_cnt > 0) {
len = sizeof(unsafe_ch_list->chan_freq_list);
unsafe_ch_list->chan_cnt = 0;
qdf_mem_zero(unsafe_ch_list->chan_freq_list, len);
}
for (i = 0; i < psoc_priv_obj->avoid_freq_ext_list.ch_avoid_range_cnt;
i++) {
if (pdev_priv_obj->avoid_chan_ext_list.chan_cnt >=
@@ -6105,15 +6118,23 @@ reg_process_ch_avoid_freq_ext(struct wlan_objmgr_psoc *psoc,
break;
}
if (unsafe_ch_list->chan_cnt >= NUM_CHANNELS) {
reg_warn("LTE Coex unsafe channel list full");
break;
}
start_ch_idx = INVALID_CHANNEL;
end_ch_idx = INVALID_CHANNEL;
range = &psoc_priv_obj->avoid_freq_ext_list.avoid_freq_range[i];
start_channel = reg_freq_to_chan(pdev, range->start_freq);
end_channel = reg_freq_to_chan(pdev, range->end_freq);
reg_debug("start: freq %d, ch %d, end: freq %d, ch %d",
txpower = range->txpower;
is_valid_txpower = range->is_valid_txpower;
reg_debug("start: freq %d, ch %d, end: freq %d, ch %d txpower %d",
range->start_freq, start_channel, range->end_freq,
end_channel);
end_channel, txpower);
/* do not process frequency bands that are not mapped to
* predefined channels
@@ -6148,6 +6169,23 @@ reg_process_ch_avoid_freq_ext(struct wlan_objmgr_psoc *psoc,
[pdev_priv_obj->avoid_chan_ext_list.chan_cnt++] =
REG_CH_TO_FREQ(ch_loop);
if (coex_unsafe_nb_user_prefer) {
if (unsafe_ch_list->chan_cnt >=
NUM_CHANNELS) {
reg_warn("LTECoex unsafe ch list full");
break;
}
unsafe_ch_list->txpower[
unsafe_ch_list->chan_cnt] =
txpower;
unsafe_ch_list->is_valid_txpower[
unsafe_ch_list->chan_cnt] =
is_valid_txpower;
unsafe_ch_list->chan_freq_list[
unsafe_ch_list->chan_cnt++] =
REG_CH_TO_FREQ(ch_loop);
}
if (pdev_priv_obj->avoid_chan_ext_list.chan_cnt >=
NUM_CHANNELS) {
reg_debug("avoid freq ext list full");
@@ -6167,6 +6205,14 @@ reg_process_ch_avoid_freq_ext(struct wlan_objmgr_psoc *psoc,
range->start_freq = range->start_freq - HALF_20MHZ_BW;
range->end_freq = range->end_freq + HALF_20MHZ_BW;
}
for (ch_loop = 0; ch_loop <
unsafe_ch_list->chan_cnt; ch_loop++) {
if (ch_loop >= NUM_CHANNELS)
break;
reg_debug("Unsafe freq %d",
unsafe_ch_list->chan_freq_list[ch_loop]);
}
}
return QDF_STATUS_SUCCESS;
@@ -6242,7 +6288,14 @@ reg_process_ch_avoid_ext_event(struct wlan_objmgr_psoc *psoc,
ch_avoid_event->avoid_freq_range[i].start_freq;
range->end_freq =
ch_avoid_event->avoid_freq_range[i].end_freq;
range->txpower =
ch_avoid_event->avoid_freq_range[i].txpower;
range->is_valid_txpower =
ch_avoid_event->avoid_freq_range[i].is_valid_txpower;
}
psoc_priv_obj->avoid_freq_ext_list.restriction_mask =
ch_avoid_event->restriction_mask;
psoc_priv_obj->avoid_freq_ext_list.ch_avoid_range_cnt =
ch_avoid_event->ch_avoid_range_cnt;
@@ -6264,6 +6317,19 @@ reg_process_ch_avoid_ext_event(struct wlan_objmgr_psoc *psoc,
return status;
}
bool reg_check_coex_unsafe_nb_user_prefer(struct wlan_objmgr_psoc *psoc)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return false;
}
return psoc_priv_obj->coex_unsafe_chan_nb_user_prefer;
}
#endif
#if defined(CONFIG_AFC_SUPPORT) && defined(CONFIG_BAND_6GHZ)

Zobrazit soubor

@@ -1732,6 +1732,15 @@ bool reg_is_upper_6g_edge_ch_disabled(struct wlan_objmgr_psoc *psoc);
QDF_STATUS
reg_process_ch_avoid_ext_event(struct wlan_objmgr_psoc *psoc,
struct ch_avoid_ind_type *ch_avoid_event);
/**
* reg_check_coex_unsafe_nb_user_prefer() - get coex unsafe nb
* user prefer ini
* @psoc: pointer to psoc
*
* Return: bool
*/
bool reg_check_coex_unsafe_nb_user_prefer(struct wlan_objmgr_psoc *psoc);
#else
static inline QDF_STATUS
reg_process_ch_avoid_ext_event(struct wlan_objmgr_psoc *psoc,
@@ -1739,6 +1748,12 @@ reg_process_ch_avoid_ext_event(struct wlan_objmgr_psoc *psoc,
{
return QDF_STATUS_SUCCESS;
}
static inline
bool reg_check_coex_unsafe_nb_user_prefer(struct wlan_objmgr_psoc *psoc)
{
return false;
}
#endif
#if defined(CONFIG_AFC_SUPPORT) && defined(CONFIG_BAND_6GHZ)

Zobrazit soubor

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-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
@@ -375,6 +375,26 @@ reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc,
}
#endif
#ifdef FEATURE_WLAN_CH_AVOID_EXT
static inline
void reg_get_coex_unsafe_chan_nb_user_prefer(
struct wlan_regulatory_psoc_priv_obj
*psoc_priv_obj,
struct reg_config_vars config_vars)
{
psoc_priv_obj->coex_unsafe_chan_nb_user_prefer =
config_vars.coex_unsafe_chan_nb_user_prefer;
}
#else
static inline
void reg_get_coex_unsafe_chan_nb_user_prefer(
struct wlan_regulatory_psoc_priv_obj
*psoc_priv_obj,
struct reg_config_vars config_vars)
{
}
#endif
#ifdef CONFIG_CHAN_FREQ_API
bool reg_is_passive_or_disable_for_freq(struct wlan_objmgr_pdev *pdev,
qdf_freq_t freq)
@@ -793,6 +813,7 @@ QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc,
config_vars.enable_5dot9_ghz_chan_in_master_mode;
psoc_priv_obj->retain_nol_across_regdmn_update =
config_vars.retain_nol_across_regdmn_update;
reg_get_coex_unsafe_chan_nb_user_prefer(psoc_priv_obj, config_vars);
status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
if (QDF_IS_STATUS_ERROR(status)) {

Zobrazit soubor

@@ -48,7 +48,7 @@
#define MAX_STA_VDEV_CNT 4
#define INVALID_VDEV_ID 0xFF
#define INVALID_CHANNEL_NUM 0x0
#define CH_AVOID_MAX_RANGE 4
#define CH_AVOID_MAX_RANGE (NUM_5GHZ_CHANNELS + NUM_24GHZ_CHANNELS)
#define REG_ALPHA2_LEN 2
#define MAX_REG_RULES 10
#define MAX_6G_REG_RULES 5
@@ -1391,6 +1391,8 @@ enum restart_beaconing_on_ch_avoid_rule {
* @enable_5dot9_ghz_chan_in_master_mode: 5.9 GHz channel support in
* master mode
* @retain_nol_across_regdmn_update: Retain the NOL list across the regdomain.
* @coex_unsafe_chan_nb_user_prefer: Honor coex unsafe chan cmd from firmware or
* userspace
*/
struct reg_config_vars {
uint32_t enable_11d_support;
@@ -1405,6 +1407,9 @@ struct reg_config_vars {
bool enable_11d_in_world_mode;
bool enable_5dot9_ghz_chan_in_master_mode;
bool retain_nol_across_regdmn_update;
#ifdef FEATURE_WLAN_CH_AVOID_EXT
bool coex_unsafe_chan_nb_user_prefer;
#endif
};
/**
@@ -1534,20 +1539,25 @@ struct cur_regdmn_info {
* struct ch_avoid_freq_type
* @start_freq: start freq
* @end_freq: end freq
* @txpower: txpower
*/
struct ch_avoid_freq_type {
qdf_freq_t start_freq;
qdf_freq_t end_freq;
int32_t txpower;
bool is_valid_txpower;
};
/**
* struct ch_avoid_ind_type
* @ch_avoid_range_cnt: count
* @avoid_freq_range: avoid freq range array
* @restriction_mask: restriction mask to apply txpower
*/
struct ch_avoid_ind_type {
uint32_t ch_avoid_range_cnt;
struct ch_avoid_freq_type avoid_freq_range[CH_AVOID_MAX_RANGE];
uint8_t restriction_mask;
};
/**
@@ -1558,6 +1568,8 @@ struct ch_avoid_ind_type {
struct unsafe_ch_list {
uint16_t chan_cnt;
uint16_t chan_freq_list[NUM_CHANNELS];
int32_t txpower[NUM_CHANNELS];
bool is_valid_txpower[NUM_CHANNELS];
};
/**