Merge "qcacmn: Drop 6 GHz beacon out of BSS operating BW"

此提交包含在:
Linux Build Service Account
2022-09-27 08:41:57 -07:00
提交者 Gerrit - the friendly Code Review server
當前提交 ab3b83ae82

查看文件

@@ -34,6 +34,7 @@
#include <wlan_utility.h>
#endif
#include "wlan_psoc_mlme_api.h"
#include "reg_services_public_struct.h"
#define MAX_IE_LEN 1024
#define SHORT_SSID_LEN 4
@@ -339,16 +340,189 @@ static struct he_oper_6g_param *util_scan_get_he_6g_params(uint8_t *he_ops)
return (struct he_oper_6g_param *)he_ops;
}
#ifdef WLAN_FEATURE_11BE
/*
* util_scan_is_out_of_band_leak_eht() - Check if eht beacon out of BSS BW
* @pdev: pointer to pdev.
* @scan_params: scan entry generated by beacon/probe rsp
* @band_mask: band mask of frequency beacon/probe rsp received
* @current_freq: frequency beacon/probe rsp received
*
* 1. If BSS BW <= 80MHz
* If Absolute value of (Current Channel Channel Center Frequency Segment 0) <=
* BSS BW/2 then eht beacon in BSS operating BW
* else eht beacon out of BSS operating BW
*
* 2. If BSS BW > 80MHz
* If Absolute value of (Current Channel Channel Center Frequency Segment 1) <=
* BSS BW/2 then eht beacon in BSS operating BW
* else eht beacon out of BSS operating BW
*
* Return: bool, whether eht beacon out of BSS operating BW
*/
static bool
util_scan_is_out_of_band_leak_eht(struct wlan_objmgr_pdev *pdev,
struct scan_cache_entry *scan_params,
uint8_t band_mask,
qdf_freq_t current_freq)
{
struct wlan_ie_ehtops *eht_ops;
uint8_t ch_width;
uint32_t bw;
uint32_t freq_diff;
qdf_freq_t freq_seg0;
qdf_freq_t freq_seg1;
eht_ops = (struct wlan_ie_ehtops *)util_scan_entry_ehtop(scan_params);
if (!util_scan_entry_ehtcap(scan_params) || !eht_ops)
return false;
if (!QDF_GET_BITS(eht_ops->ehtop_param,
EHTOP_INFO_PRESENT_IDX, EHTOP_INFO_PRESENT_BITS))
return false;
ch_width = QDF_GET_BITS(eht_ops->control,
EHTOP_INFO_CHAN_WIDTH_IDX,
EHTOP_INFO_CHAN_WIDTH_BITS);
freq_seg0 = wlan_reg_chan_band_to_freq(pdev, eht_ops->ccfs0,
band_mask);
freq_seg1 = wlan_reg_chan_band_to_freq(pdev, eht_ops->ccfs1,
band_mask);
if (ch_width == WLAN_EHT_CHWIDTH_320)
bw = BW_320_MHZ;
else if (ch_width == WLAN_EHT_CHWIDTH_160)
bw = BW_160_MHZ;
else if (ch_width == WLAN_EHT_CHWIDTH_80)
bw = BW_80_MHZ;
else if (ch_width == WLAN_EHT_CHWIDTH_40)
bw = BW_40_MHZ;
else if (ch_width == WLAN_EHT_CHWIDTH_20)
bw = BW_20_MHZ;
else
bw = BW_20_MHZ;
if (bw <= BW_80_MHZ)
freq_diff = abs(freq_seg0 - current_freq);
else
freq_diff = abs(freq_seg1 - current_freq);
if (freq_diff <= bw / 2)
return false;
scm_debug("Leaked freq:%u ch width:%u freq0:%u freq1:%u",
current_freq, bw, freq_seg0, freq_seg1);
return true;
}
#else
static bool
util_scan_is_out_of_band_leak_eht(struct wlan_objmgr_pdev *pdev,
struct scan_cache_entry *scan_params,
uint8_t band_mask,
qdf_freq_t current_freq)
{
return false;
}
#endif
/*
* util_scan_is_out_of_band_leak_he() - Check if HE beacon out of BSS BW
* @pdev: pointer to pdev.
* @he_6g_params: HE 6 GHz params
* @band_mask: band mask of frequency beacon/probe rsp received
* @current_freq: frequency beacon/probe rsp received
*
* 1. If BSS BW <= 80MHz
* If Absolute value of (Current Channel Channel Center Frequency Segment 0) <=
* BSS BW/2 then HE beacon in BSS operating BW
*
* 2. If BSS BW is 160MHz
* If Absolute value of (Current Channel Channel Center Frequency Segment 1) <=
* BSS BW/2 then HE beacon in BSS operating BW
*
* 3. If BSS BW is 80+80MHz
* If absolute value of (Current Channel - Channel Center Frequency Segment 0)
* <= 40 or absolute value of (Current Channel - Channel Center Frequency
* Segment 1) <= 40, then HE beacon in BSS operating BW
*
* Return: bool, whether HE beacon out of BSS operating BW
*/
static bool
util_scan_is_out_of_band_leak_he(struct wlan_objmgr_pdev *pdev,
struct he_oper_6g_param *he_6g_params,
uint8_t band_mask,
qdf_freq_t current_freq)
{
uint8_t ch_width;
uint32_t bw;
uint32_t freq_diff;
qdf_freq_t freq_seg0;
qdf_freq_t freq_seg1;
ch_width = he_6g_params->width;
freq_seg0 = wlan_reg_chan_band_to_freq(pdev,
he_6g_params->chan_freq_seg0,
band_mask);
freq_seg1 = wlan_reg_chan_band_to_freq(pdev,
he_6g_params->chan_freq_seg1,
band_mask);
if (ch_width == WLAN_HE_6GHZ_CHWIDTH_160_80_80)
bw = BW_160_MHZ;
else if (ch_width == WLAN_HE_6GHZ_CHWIDTH_80)
bw = BW_80_MHZ;
else if (ch_width == WLAN_HE_6GHZ_CHWIDTH_40)
bw = BW_40_MHZ;
else if (ch_width == WLAN_HE_6GHZ_CHWIDTH_20)
bw = BW_20_MHZ;
else
bw = BW_20_MHZ;
if (bw <= BW_80_MHZ) {
freq_diff = abs(freq_seg0 - current_freq);
if (freq_diff <= bw / 2)
return false;
} else if (WLAN_IS_HE160(he_6g_params)) {
freq_diff = abs(freq_seg1 - current_freq);
if (freq_diff <= bw / 2)
return false;
} else if (WLAN_IS_HE80_80(he_6g_params)) {
freq_diff = abs(freq_seg0 - current_freq);
if (freq_diff <= BW_40_MHZ)
return false;
freq_diff = abs(freq_seg1 - current_freq);
if (freq_diff <= BW_40_MHZ)
return false;
}
scm_debug("Leaked freq:%u ch width:%u freq0:%u freq1:%u",
current_freq, bw, freq_seg0, freq_seg1);
return true;
}
/*
* util_scan_get_chan_from_he_6g_params() - Get chan info from 6 GHz param
* @pdev: pointer to pdev.
* @scan_params: scan entry generated by beacon/probe rsp
* @chan_freq: output parmeter, primary freq from 6 GHz he params
* @is_6g_dup_bcon: output parmeter, bool, if false, invalid 6g duplicated
beacon out of BSS operating BW or not duplicated beacon, can drop if
channel mismatch
* @band_mask: band mask of frequency beacon/probe rsp received
* @current_freq: frequency beacon/probe rsp received
*
* Return: QDF_STATUS
*/
static QDF_STATUS
util_scan_get_chan_from_he_6g_params(struct wlan_objmgr_pdev *pdev,
struct scan_cache_entry *scan_params,
qdf_freq_t *chan_freq,
bool *he_6g_dup_bcon, uint8_t band_mask)
bool *is_6g_dup_bcon, uint8_t band_mask,
qdf_freq_t current_freq)
{
struct he_oper_6g_param *he_6g_params;
uint8_t *he_ops;
struct wlan_scan_obj *scan_obj;
struct wlan_objmgr_psoc *psoc;
bool is_out_of_band_leak = true;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
@@ -362,7 +536,7 @@ util_scan_get_chan_from_he_6g_params(struct wlan_objmgr_pdev *pdev,
return QDF_STATUS_E_INVAL;
}
*he_6g_dup_bcon = false;
*is_6g_dup_bcon = false;
he_ops = util_scan_entry_heop(scan_params);
if (!util_scan_entry_hecap(scan_params) || !he_ops)
@@ -383,7 +557,27 @@ util_scan_get_chan_from_he_6g_params(struct wlan_objmgr_pdev *pdev,
he_6g_params->primary_channel, *chan_freq);
return QDF_STATUS_E_INVAL;
}
*he_6g_dup_bcon = he_6g_params->duplicate_beacon ? true : false;
if (!he_6g_params->duplicate_beacon) {
*is_6g_dup_bcon = false;
return QDF_STATUS_SUCCESS;
}
is_out_of_band_leak =
util_scan_is_out_of_band_leak_eht(pdev, scan_params, band_mask,
current_freq);
if (is_out_of_band_leak) {
*is_6g_dup_bcon = false;
return QDF_STATUS_SUCCESS;
}
is_out_of_band_leak =
util_scan_is_out_of_band_leak_he(pdev, he_6g_params, band_mask,
current_freq);
if (is_out_of_band_leak) {
*is_6g_dup_bcon = false;
return QDF_STATUS_SUCCESS;
}
*is_6g_dup_bcon = true;
return QDF_STATUS_SUCCESS;
}
@@ -463,8 +657,9 @@ static QDF_STATUS
util_scan_get_chan_from_he_6g_params(struct wlan_objmgr_pdev *pdev,
struct scan_cache_entry *scan_params,
qdf_freq_t *chan_freq,
bool *he_6g_dup_bcon,
uint8_t band_mask)
bool *is_6g_dup_bcon,
uint8_t band_mask,
qdf_freq_t current_freq)
{
return QDF_STATUS_SUCCESS;
}
@@ -2090,8 +2285,9 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev,
struct scan_cache_node *scan_node;
uint8_t i;
qdf_freq_t chan_freq = 0;
bool he_6g_dup_bcon = false;
bool is_6g_dup_bcon = false;
uint8_t band_mask;
qdf_freq_t recv_freq = 0;
scan_entry = qdf_mem_malloc_atomic(sizeof(*scan_entry));
if (!scan_entry) {
@@ -2130,10 +2326,11 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev,
scan_entry->tsf_delta = rx_param->tsf_delta;
scan_entry->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
recv_freq = rx_param->chan_freq;
/* Copy per chain rssi to scan entry */
qdf_mem_copy(scan_entry->per_chain_rssi, rx_param->rssi_ctl,
WLAN_MGMT_TXRX_HOST_MAX_ANTENNA);
band_mask = BIT(wlan_reg_freq_to_band(rx_param->chan_freq));
band_mask = BIT(wlan_reg_freq_to_band(recv_freq));
if (!wlan_psoc_nif_fw_ext_cap_get(wlan_pdev_get_psoc(pdev),
WLAN_SOC_CEXT_HW_DB2DBM)) {
@@ -2195,8 +2392,9 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev,
if (!chan_freq && util_scan_entry_hecap(scan_entry)) {
status = util_scan_get_chan_from_he_6g_params(pdev, scan_entry,
&chan_freq,
&he_6g_dup_bcon,
band_mask);
&is_6g_dup_bcon,
band_mask,
recv_freq);
if (QDF_IS_STATUS_ERROR(status)) {
qdf_mem_free(scan_entry->raw_frame.ptr);
qdf_mem_free(scan_entry);
@@ -2209,11 +2407,11 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev,
/* If no channel info is present in beacon use meta channel */
if (!scan_entry->channel.chan_freq) {
scan_entry->channel.chan_freq = rx_param->chan_freq;
} else if (rx_param->chan_freq !=
scan_entry->channel.chan_freq = recv_freq;
} else if (recv_freq !=
scan_entry->channel.chan_freq) {
if (!wlan_reg_is_49ghz_freq(scan_entry->channel.chan_freq) &&
!he_6g_dup_bcon)
!is_6g_dup_bcon)
scan_entry->channel_mismatch = true;
}