|
@@ -34,6 +34,7 @@
|
|
#include <wlan_utility.h>
|
|
#include <wlan_utility.h>
|
|
#endif
|
|
#endif
|
|
#include "wlan_psoc_mlme_api.h"
|
|
#include "wlan_psoc_mlme_api.h"
|
|
|
|
+#include "reg_services_public_struct.h"
|
|
|
|
|
|
#define MAX_IE_LEN 1024
|
|
#define MAX_IE_LEN 1024
|
|
#define SHORT_SSID_LEN 4
|
|
#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;
|
|
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
|
|
static QDF_STATUS
|
|
util_scan_get_chan_from_he_6g_params(struct wlan_objmgr_pdev *pdev,
|
|
util_scan_get_chan_from_he_6g_params(struct wlan_objmgr_pdev *pdev,
|
|
struct scan_cache_entry *scan_params,
|
|
struct scan_cache_entry *scan_params,
|
|
qdf_freq_t *chan_freq,
|
|
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;
|
|
struct he_oper_6g_param *he_6g_params;
|
|
uint8_t *he_ops;
|
|
uint8_t *he_ops;
|
|
struct wlan_scan_obj *scan_obj;
|
|
struct wlan_scan_obj *scan_obj;
|
|
struct wlan_objmgr_psoc *psoc;
|
|
struct wlan_objmgr_psoc *psoc;
|
|
|
|
+ bool is_out_of_band_leak = true;
|
|
|
|
|
|
psoc = wlan_pdev_get_psoc(pdev);
|
|
psoc = wlan_pdev_get_psoc(pdev);
|
|
if (!psoc) {
|
|
if (!psoc) {
|
|
@@ -362,7 +536,7 @@ util_scan_get_chan_from_he_6g_params(struct wlan_objmgr_pdev *pdev,
|
|
return QDF_STATUS_E_INVAL;
|
|
return QDF_STATUS_E_INVAL;
|
|
}
|
|
}
|
|
|
|
|
|
- *he_6g_dup_bcon = false;
|
|
|
|
|
|
+ *is_6g_dup_bcon = false;
|
|
|
|
|
|
he_ops = util_scan_entry_heop(scan_params);
|
|
he_ops = util_scan_entry_heop(scan_params);
|
|
if (!util_scan_entry_hecap(scan_params) || !he_ops)
|
|
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);
|
|
he_6g_params->primary_channel, *chan_freq);
|
|
return QDF_STATUS_E_INVAL;
|
|
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;
|
|
return QDF_STATUS_SUCCESS;
|
|
}
|
|
}
|
|
@@ -463,8 +657,9 @@ static QDF_STATUS
|
|
util_scan_get_chan_from_he_6g_params(struct wlan_objmgr_pdev *pdev,
|
|
util_scan_get_chan_from_he_6g_params(struct wlan_objmgr_pdev *pdev,
|
|
struct scan_cache_entry *scan_params,
|
|
struct scan_cache_entry *scan_params,
|
|
qdf_freq_t *chan_freq,
|
|
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;
|
|
return QDF_STATUS_SUCCESS;
|
|
}
|
|
}
|
|
@@ -2090,8 +2285,9 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev,
|
|
struct scan_cache_node *scan_node;
|
|
struct scan_cache_node *scan_node;
|
|
uint8_t i;
|
|
uint8_t i;
|
|
qdf_freq_t chan_freq = 0;
|
|
qdf_freq_t chan_freq = 0;
|
|
- bool he_6g_dup_bcon = false;
|
|
|
|
|
|
+ bool is_6g_dup_bcon = false;
|
|
uint8_t band_mask;
|
|
uint8_t band_mask;
|
|
|
|
+ qdf_freq_t recv_freq = 0;
|
|
|
|
|
|
scan_entry = qdf_mem_malloc_atomic(sizeof(*scan_entry));
|
|
scan_entry = qdf_mem_malloc_atomic(sizeof(*scan_entry));
|
|
if (!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->tsf_delta = rx_param->tsf_delta;
|
|
scan_entry->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
|
|
scan_entry->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
|
|
|
|
|
|
|
|
+ recv_freq = rx_param->chan_freq;
|
|
/* Copy per chain rssi to scan entry */
|
|
/* Copy per chain rssi to scan entry */
|
|
qdf_mem_copy(scan_entry->per_chain_rssi, rx_param->rssi_ctl,
|
|
qdf_mem_copy(scan_entry->per_chain_rssi, rx_param->rssi_ctl,
|
|
WLAN_MGMT_TXRX_HOST_MAX_ANTENNA);
|
|
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),
|
|
if (!wlan_psoc_nif_fw_ext_cap_get(wlan_pdev_get_psoc(pdev),
|
|
WLAN_SOC_CEXT_HW_DB2DBM)) {
|
|
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)) {
|
|
if (!chan_freq && util_scan_entry_hecap(scan_entry)) {
|
|
status = util_scan_get_chan_from_he_6g_params(pdev, scan_entry,
|
|
status = util_scan_get_chan_from_he_6g_params(pdev, scan_entry,
|
|
&chan_freq,
|
|
&chan_freq,
|
|
- &he_6g_dup_bcon,
|
|
|
|
- band_mask);
|
|
|
|
|
|
+ &is_6g_dup_bcon,
|
|
|
|
+ band_mask,
|
|
|
|
+ recv_freq);
|
|
if (QDF_IS_STATUS_ERROR(status)) {
|
|
if (QDF_IS_STATUS_ERROR(status)) {
|
|
qdf_mem_free(scan_entry->raw_frame.ptr);
|
|
qdf_mem_free(scan_entry->raw_frame.ptr);
|
|
qdf_mem_free(scan_entry);
|
|
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 no channel info is present in beacon use meta channel */
|
|
if (!scan_entry->channel.chan_freq) {
|
|
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) {
|
|
scan_entry->channel.chan_freq) {
|
|
if (!wlan_reg_is_49ghz_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;
|
|
scan_entry->channel_mismatch = true;
|
|
}
|
|
}
|
|
|
|
|