qcacld-3.0: Enable dynamic puncture for DFS radar

Once the radar is found, identify the affected sub 20 MHz channels in the
current channel. From the  position(s) of the sub 20 MHz subchannels, find
the nearest valid puncturing pattern.
If a valid puncturing pattern is found, find the corresponding reduced
bandwidth new channel for the legacy ( <= 11AX) devices and send CSA. At
the end of CSA, do a vdev restart so that the 11BE devices see a new
puncturing pattern.
And If not found, then fallback to the default behavior of changing channel
using Random channel selection.

Change-Id: I41e6206f310722bc3dacc9ce8d024f679ff1af3e
CRs-Fixed: 3386022
This commit is contained in:
Jianmin Zhu
2023-01-16 00:30:18 +08:00
committed by Madan Koyyalamudi
parent 7af91cd9d6
commit 589a32f847
7 changed files with 132 additions and 10 deletions

1
Kbuild
View File

@@ -4205,6 +4205,7 @@ endif
cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DDFS_COMPONENT_ENABLE
cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DQCA_DFS_USE_POLICY_MANAGER
cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DQCA_DFS_NOL_PLATFORM_DRV_SUPPORT
cppflags-$(CONFIG_QCA_DFS_BW_PUNCTURE) += -DQCA_DFS_BW_PUNCTURE
cppflags-$(CONFIG_WLAN_DEBUGFS) += -DWLAN_DEBUGFS
cppflags-$(CONFIG_WLAN_STREAMFS) += -DWLAN_STREAMFS

View File

@@ -55,6 +55,8 @@ CONFIG_WLAN_FEATURE_COAP := y
#Enable TSF read using scratch register
CONFIG_QCA_GET_TSF_VIA_REG := y
CONFIG_QCA_DFS_BW_PUNCTURE := y
ifeq ($(CONFIG_ARCH_SDXPINN), y)
CONFIG_DP_FEATURE_HW_COOKIE_CONVERSION := n
CONFIG_DP_HW_COOKIE_CONVERT_EXCEPTION := n

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2023 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
@@ -5253,6 +5253,7 @@ struct sir_update_session_txq_edca_param {
* @sec_ch_offset: second channel offset
* @center_freq_seg0: channel center freq 0
* @center_freq_seg1: channel center freq 1
* @target_punc_bitmap: New channel puncturing bitmap
* @dot11mode: dot11 mode
* @nw_type: nw type
* @cac_duration_ms: cac duration in ms
@@ -5267,6 +5268,9 @@ struct channel_change_req {
enum phy_ch_width ch_width;
uint8_t center_freq_seg0;
uint8_t center_freq_seg1;
#ifdef WLAN_FEATURE_11BE
uint16_t target_punc_bitmap;
#endif
uint32_t dot11mode;
tSirNwType nw_type;
uint32_t cac_duration_ms;

View File

@@ -8556,6 +8556,27 @@ static void lim_change_channel(
session_entry);
}
#ifdef WLAN_FEATURE_11BE
static bool
lim_is_puncture_bitmap_changed(struct pe_session *session,
struct channel_change_req *ch_change_req)
{
uint16_t ori_puncture_bitmap;
ori_puncture_bitmap =
*(uint16_t *)session->eht_op.disabled_sub_chan_bitmap;
return ori_puncture_bitmap != ch_change_req->target_punc_bitmap;
}
#else
static inline bool
lim_is_puncture_bitmap_changed(struct pe_session *session,
struct channel_change_req *ch_change_req)
{
return false;
}
#endif
/**
* lim_process_sme_channel_change_request() - process sme ch change req
*
@@ -8600,8 +8621,10 @@ static void lim_process_sme_channel_change_request(struct mac_context *mac_ctx,
return;
}
if (session_entry->curr_op_freq == target_freq &&
session_entry->ch_width == ch_change_req->ch_width) {
if ((session_entry->curr_op_freq == target_freq &&
session_entry->ch_width == ch_change_req->ch_width) &&
(!IS_DOT11_MODE_EHT(session_entry->dot11mode) ||
!lim_is_puncture_bitmap_changed(session_entry, ch_change_req))) {
pe_err("Target channel and mode is same as current channel and mode channel freq %d and mode %d",
session_entry->curr_op_freq, session_entry->ch_width);
return;
@@ -9165,6 +9188,14 @@ static void lim_process_sme_dfs_csa_ie_request(struct mac_context *mac_ctx,
session_entry->dfsIncludeChanSwIe = true;
session_entry->gLimChannelSwitch.switchCount =
dfs_csa_ie_req->ch_switch_beacon_cnt;
wlan_reg_set_create_punc_bitmap(&dfs_csa_ie_req->ch_params, false);
wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
dfs_csa_ie_req->target_chan_freq,
0,
&dfs_csa_ie_req->ch_params,
REG_CURRENT_PWR_MODE);
ch_width = dfs_csa_ie_req->ch_params.ch_width;
if (ch_width >= CH_WIDTH_160MHZ &&
wma_get_vht_ch_width() < WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) {

View File

@@ -10802,7 +10802,8 @@ QDF_STATUS lim_pre_vdev_start(struct mac_context *mac,
if (ch_params.mhz_freq_seg0 == session->curr_op_freq - 10)
sec_chan_freq = session->curr_op_freq - 20;
}
if (LIM_IS_AP_ROLE(session))
if (LIM_IS_AP_ROLE(session) &&
!mlme_is_chan_switch_in_progress(mlme_obj->vdev))
lim_apply_puncture(mac, session, ch_params.mhz_freq_seg1);
if (IS_DOT11_MODE_EHT(session->dot11mode))

View File

@@ -169,13 +169,75 @@ static uint8_t *sap_hdd_event_to_string(eSapHddEvent event)
}
}
/*----------------------------------------------------------------------------
* Externalized Function Definitions
* -------------------------------------------------------------------------*/
#ifdef QCA_DFS_BW_PUNCTURE
/**
* sap_is_chan_change_needed() - Check if SAP channel change needed
* @sap_ctx: sap context.
*
* Even some 20 MHz sub channel disabled for nol, if puncture pattern is valid,
* SAP still can keep current channel width and primary channel, don't need
* change channel.
*
* Return: bool, true: channel change needed
*/
static bool
sap_is_chan_change_needed(struct sap_context *sap_ctx)
{
uint8_t ch_wd;
uint16_t pri_freq_puncture = 0;
struct ch_params *ch_params;
QDF_STATUS status;
struct mac_context *mac_ctx;
/*----------------------------------------------------------------------------
* Function Declarations and Documentation
* -------------------------------------------------------------------------*/
mac_ctx = sap_get_mac_context();
if (!mac_ctx) {
sap_err("Invalid MAC context");
return true;
}
ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) {
ch_wd = sap_ctx->ch_width_orig;
mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd;
} else {
ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth;
}
ch_params->ch_width = ch_wd;
if (sap_phymode_is_eht(sap_ctx->phyMode))
wlan_reg_set_create_punc_bitmap(ch_params, true);
wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
sap_ctx->chan_freq,
0,
ch_params,
REG_CURRENT_PWR_MODE);
if (ch_params->ch_width == sap_ctx->ch_params.ch_width) {
status = wlan_reg_extract_puncture_by_bw(ch_params->ch_width,
ch_params->reg_punc_bitmap,
sap_ctx->chan_freq,
ch_params->mhz_freq_seg1,
CH_WIDTH_20MHZ,
&pri_freq_puncture);
if (QDF_IS_STATUS_SUCCESS(status) && !pri_freq_puncture) {
sap_debug("Eht valid puncture : 0x%x, keep freq %d",
ch_params->reg_punc_bitmap,
sap_ctx->chan_freq);
mac_ctx->sap.SapDfsInfo.new_chanWidth =
ch_params->ch_width;
return false;
}
}
return true;
}
#else
static inline bool
sap_is_chan_change_needed(struct sap_context *sap_ctx)
{
return true;
}
#endif
#ifdef DFS_COMPONENT_ENABLE
/**
@@ -271,6 +333,7 @@ static qdf_freq_t sap_random_channel_sel(struct sap_context *sap_ctx)
(void *)eSAP_STATUS_SUCCESS);
return 0;
}
mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_params->ch_width;
sap_ctx->ch_params.ch_width = ch_params->ch_width;
sap_ctx->ch_params.sec_ch_offset = ch_params->sec_ch_offset;
@@ -4520,6 +4583,9 @@ qdf_freq_t sap_indicate_radar(struct sap_context *sap_ctx)
(void *) eSAP_STATUS_SUCCESS)))
return 0;
if (!sap_is_chan_change_needed(sap_ctx))
return sap_ctx->chan_freq;
chan_freq = sap_random_channel_sel(sap_ctx);
if (!chan_freq)
sap_signal_hdd_event(sap_ctx, NULL,

View File

@@ -1824,6 +1824,21 @@ void wlansap_get_sec_channel(uint8_t sec_ch_offset,
}
}
#ifdef WLAN_FEATURE_11BE
static void
wlansap_fill_channel_change_puncture(struct channel_change_req *req,
struct ch_params *ch_param)
{
req->target_punc_bitmap = ch_param->reg_punc_bitmap;
}
#else
static inline void
wlansap_fill_channel_change_puncture(struct channel_change_req *req,
struct ch_params *ch_param)
{
}
#endif
/**
* wlansap_fill_channel_change_request() - Fills the channel change request
* @sap_ctx: sap context
@@ -1868,6 +1883,8 @@ wlansap_fill_channel_change_request(struct sap_context *sap_ctx,
req->ch_width = sap_ctx->ch_params.ch_width;
req->center_freq_seg0 = sap_ctx->ch_params.center_freq_seg0;
req->center_freq_seg1 = sap_ctx->ch_params.center_freq_seg1;
wlansap_fill_channel_change_puncture(req, &sap_ctx->ch_params);
req->dot11mode = dot11_cfg.dot11_mode;
req->nw_type = dot11_cfg.nw_type;