mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-21 03:13:17 +00:00
302 lines
9.8 KiB
Diff
302 lines
9.8 KiB
Diff
From b858abf06439625ce97dade46f599956d170e6e3 Mon Sep 17 00:00:00 2001
|
|
From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
|
Date: Thu, 18 Jun 2020 21:51:13 -0700
|
|
Subject: [PATCH] ath11k: fix for accepting bcast presp in GHz scan
|
|
|
|
A 6GHZ AP may respond to Probe Request frame with having Address 1
|
|
field of the Probe Response frame set to the broadcast address when
|
|
AP is not indicating its actual SSID in the SSID element of its
|
|
Beacon frames. So, without accepting broadcast probe responses in
|
|
scan, APs will not be discoverable.
|
|
|
|
Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
|
---
|
|
drivers/net/wireless/ath/ath11k/core.h | 2 +-
|
|
drivers/net/wireless/ath/ath11k/dp_rx.c | 5 ++++-
|
|
drivers/net/wireless/ath/ath11k/mac.c | 1 +
|
|
drivers/net/wireless/ath/ath11k/wmi.c | 7 ++++++-
|
|
net/mac80211/scan.c | 23 ++++++++++++-----------
|
|
5 files changed, 24 insertions(+), 14 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -409,9 +409,9 @@ struct ath11k_sta {
|
|
};
|
|
|
|
#define ATH11K_MIN_5G_FREQ 4150
|
|
-#define ATH11K_MIN_6G_FREQ 5945
|
|
-#define ATH11K_MAX_6G_FREQ 7115
|
|
-#define ATH11K_NUM_CHANS 100
|
|
+#define ATH11K_MIN_6G_FREQ 5925
|
|
+#define ATH11K_MAX_6G_FREQ 7125
|
|
+#define ATH11K_NUM_CHANS 101
|
|
#define ATH11K_MAX_5G_CHAN 173
|
|
|
|
enum ath11k_state {
|
|
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
@@ -2518,7 +2518,7 @@ static void ath11k_dp_rx_h_ppdu(struct a
|
|
channel_num = meta_data;
|
|
center_freq = meta_data >> 16;
|
|
|
|
- if (center_freq >= 5935 && center_freq <= 7105) {
|
|
+ if (center_freq >= ATH11K_MIN_6G_FREQ && center_freq <= ATH11K_MAX_6G_FREQ) {
|
|
rx_status->band = NL80211_BAND_6GHZ;
|
|
} else if (channel_num >= 1 && channel_num <= 14) {
|
|
rx_status->band = NL80211_BAND_2GHZ;
|
|
@@ -2540,6 +2540,9 @@ static void ath11k_dp_rx_h_ppdu(struct a
|
|
rx_status->freq = ieee80211_channel_to_frequency(channel_num,
|
|
rx_status->band);
|
|
|
|
+ if (rx_status->band == NL80211_BAND_6GHZ)
|
|
+ rx_status->freq = center_freq;
|
|
+
|
|
ath11k_dp_rx_h_rate(ar, rx_desc, rx_status);
|
|
}
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
|
@@ -96,6 +96,7 @@ static const struct ieee80211_channel at
|
|
|
|
static const struct ieee80211_channel ath11k_6ghz_channels[] = {
|
|
CHAN6G(1, 5955, 0),
|
|
+ CHAN6G(2, 5935, 0), /* op_class = 136 */
|
|
CHAN6G(5, 5975, 0),
|
|
CHAN6G(9, 5995, 0),
|
|
CHAN6G(13, 6015, 0),
|
|
@@ -7087,7 +7088,13 @@ static int ath11k_mac_op_get_survey(stru
|
|
|
|
if (!sband)
|
|
sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
|
|
+ if (sband && idx >= sband->n_channels) {
|
|
+ idx -= sband->n_channels;
|
|
+ sband = NULL;
|
|
+ }
|
|
|
|
+ if (!sband)
|
|
+ sband = hw->wiphy->bands[NL80211_BAND_6GHZ];
|
|
if (!sband || idx >= sband->n_channels) {
|
|
ret = -ENOENT;
|
|
goto exit;
|
|
@@ -7340,7 +7347,8 @@ static int ath11k_mac_setup_channels_rat
|
|
}
|
|
|
|
if (supported_bands & WMI_HOST_WLAN_5G_CAP) {
|
|
- if (reg_cap->high_5ghz_chan >= ATH11K_MAX_6G_FREQ) {
|
|
+ if (reg_cap->high_5ghz_chan > ATH11K_MIN_6G_FREQ &&
|
|
+ reg_cap->high_5ghz_chan <= ATH11K_MAX_6G_FREQ) {
|
|
channels = kmemdup(ath11k_6ghz_channels,
|
|
sizeof(ath11k_6ghz_channels), GFP_KERNEL);
|
|
if (!channels) {
|
|
@@ -7361,7 +7369,8 @@ static int ath11k_mac_setup_channels_rat
|
|
reg_cap->high_5ghz_chan);
|
|
}
|
|
|
|
- if (reg_cap->low_5ghz_chan < ATH11K_MIN_6G_FREQ) {
|
|
+ if (reg_cap->low_5ghz_chan < ATH11K_MIN_6G_FREQ &&
|
|
+ reg_cap->low_5ghz_chan >= ATH11K_MIN_5G_FREQ) {
|
|
channels = kmemdup(ath11k_5ghz_channels,
|
|
sizeof(ath11k_5ghz_channels),
|
|
GFP_KERNEL);
|
|
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
|
@@ -2307,25 +2307,23 @@ int ath11k_wmi_send_scan_start_cmd(struc
|
|
|
|
if (params->num_hint_bssid)
|
|
len += TLV_HDR_SIZE +
|
|
- params->num_hint_bssid * sizeof(struct hint_bssid);
|
|
+ params->num_hint_bssid * sizeof(struct hint_bssid);
|
|
|
|
if (params->num_hint_s_ssid)
|
|
len += TLV_HDR_SIZE +
|
|
- params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
|
|
+ params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
|
|
|
|
len += TLV_HDR_SIZE;
|
|
if (params->scan_f_en_ie_whitelist_in_probe)
|
|
len += params->ie_whitelist.num_vendor_oui *
|
|
- sizeof(struct wmi_vendor_oui);
|
|
-
|
|
+ sizeof(struct wmi_vendor_oui);
|
|
len += TLV_HDR_SIZE;
|
|
if (params->scan_f_wide_band)
|
|
phymode_roundup =
|
|
roundup(params->chan_list.num_chan * sizeof(u8),
|
|
- sizeof(u32));
|
|
+ sizeof(u32));
|
|
|
|
len += phymode_roundup;
|
|
-
|
|
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
|
if (!skb)
|
|
return -ENOMEM;
|
|
@@ -2362,6 +2360,7 @@ int ath11k_wmi_send_scan_start_cmd(struc
|
|
cmd->num_ssids = params->num_ssids;
|
|
cmd->ie_len = params->extraie.len;
|
|
cmd->n_probes = params->n_probes;
|
|
+ cmd->scan_ctrl_flags_ext = params->scan_ctrl_flags_ext;
|
|
|
|
ptr += sizeof(*cmd);
|
|
|
|
@@ -2427,39 +2426,6 @@ int ath11k_wmi_send_scan_start_cmd(struc
|
|
|
|
ptr += extraie_len_with_pad;
|
|
|
|
- if (params->num_hint_s_ssid) {
|
|
- len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
|
|
- tlv = ptr;
|
|
- tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
|
|
- FIELD_PREP(WMI_TLV_LEN, len);
|
|
- ptr += TLV_HDR_SIZE;
|
|
- s_ssid = ptr;
|
|
- for (i = 0; i < params->num_hint_s_ssid; ++i) {
|
|
- s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags;
|
|
- s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid;
|
|
- s_ssid++;
|
|
- }
|
|
- ptr += len;
|
|
- }
|
|
-
|
|
- if (params->num_hint_bssid) {
|
|
- len = params->num_hint_bssid * sizeof(struct hint_bssid);
|
|
- tlv = ptr;
|
|
- tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
|
|
- FIELD_PREP(WMI_TLV_LEN, len);
|
|
- ptr += TLV_HDR_SIZE;
|
|
- hint_bssid = ptr;
|
|
- for (i = 0; i < params->num_hint_bssid; ++i) {
|
|
- hint_bssid->freq_flags =
|
|
- params->hint_bssid[i].freq_flags;
|
|
- ether_addr_copy(¶ms->hint_bssid[i].bssid.addr[0],
|
|
- &hint_bssid->bssid.addr[0]);
|
|
- hint_bssid++;
|
|
- }
|
|
- }
|
|
-
|
|
- ptr += extraie_len_with_pad;
|
|
-
|
|
len = params->ie_whitelist.num_vendor_oui * sizeof(struct wmi_vendor_oui);
|
|
tlv = ptr;
|
|
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
|
|
@@ -2490,6 +2456,36 @@ int ath11k_wmi_send_scan_start_cmd(struc
|
|
}
|
|
ptr += phymode_roundup;
|
|
|
|
+ if (params->num_hint_s_ssid) {
|
|
+ len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
|
|
+ tlv = ptr;
|
|
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, len);
|
|
+ ptr += TLV_HDR_SIZE;
|
|
+ s_ssid = ptr;
|
|
+ for (i = 0; i < params->num_hint_s_ssid; ++i) {
|
|
+ s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags;
|
|
+ s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid;
|
|
+ s_ssid++;
|
|
+ }
|
|
+ ptr += len;
|
|
+ }
|
|
+
|
|
+ if (params->num_hint_bssid) {
|
|
+ len = params->num_hint_bssid * sizeof(struct hint_bssid);
|
|
+ tlv = ptr;
|
|
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, len);
|
|
+ ptr += TLV_HDR_SIZE;
|
|
+ hint_bssid = ptr;
|
|
+ for (i = 0; i < params->num_hint_bssid; ++i) {
|
|
+ hint_bssid->freq_flags =
|
|
+ params->hint_bssid[i].freq_flags;
|
|
+ ether_addr_copy(¶ms->hint_bssid[i].bssid.addr[0],
|
|
+ &hint_bssid->bssid.addr[0]);
|
|
+ hint_bssid++;
|
|
+ }
|
|
+ }
|
|
ret = ath11k_wmi_cmd_send(wmi, skb,
|
|
WMI_START_SCAN_CMDID);
|
|
if (ret) {
|
|
@@ -5160,7 +5156,7 @@ static int ath11k_pull_mgmt_rx_params_tl
|
|
}
|
|
|
|
hdr->pdev_id = ev->pdev_id;
|
|
- hdr->chan_freq = ev->chan_freq;
|
|
+ hdr->chan_freq = ev->chan_freq?ev->chan_freq:0;;
|
|
hdr->channel = ev->channel;
|
|
hdr->snr = ev->snr;
|
|
hdr->rate = ev->rate;
|
|
@@ -6653,7 +6649,8 @@ static void ath11k_mgmt_rx_event(struct
|
|
if (rx_ev.status & WMI_RX_STATUS_ERR_MIC)
|
|
status->flag |= RX_FLAG_MMIC_ERROR;
|
|
|
|
- if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ) {
|
|
+ if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ &&
|
|
+ rx_ev.chan_freq <= ATH11K_MAX_6G_FREQ) {
|
|
status->band = NL80211_BAND_6GHZ;
|
|
} else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) {
|
|
status->band = NL80211_BAND_2GHZ;
|
|
@@ -6677,6 +6674,10 @@ static void ath11k_mgmt_rx_event(struct
|
|
|
|
status->freq = ieee80211_channel_to_frequency(rx_ev.channel,
|
|
status->band);
|
|
+
|
|
+ if (status->band == NL80211_BAND_6GHZ)
|
|
+ status->freq = rx_ev.chan_freq;
|
|
+
|
|
status->signal = rx_ev.snr + ATH11K_DEFAULT_NOISE_FLOOR;
|
|
status->rate_idx = ath11k_mac_bitrate_to_idx(sband, rx_ev.rate / 100);
|
|
|
|
--- a/net/mac80211/scan.c
|
|
+++ b/net/mac80211/scan.c
|
|
@@ -231,13 +231,14 @@ ieee80211_bss_info_update(struct ieee802
|
|
}
|
|
|
|
static bool ieee80211_scan_accept_presp(struct ieee80211_sub_if_data *sdata,
|
|
- u32 scan_flags, const u8 *da)
|
|
+ u32 scan_flags, const u8 *da,
|
|
+ struct ieee80211_channel *channel)
|
|
{
|
|
if (!sdata)
|
|
return false;
|
|
/* accept broadcast for OCE */
|
|
- if (scan_flags & NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP &&
|
|
- is_broadcast_ether_addr(da))
|
|
+ if ((scan_flags & NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP ||
|
|
+ channel->band == NL80211_BAND_6GHZ) && is_broadcast_ether_addr(da))
|
|
return true;
|
|
if (scan_flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
|
|
return true;
|
|
@@ -266,6 +267,12 @@ void ieee80211_scan_rx(struct ieee80211_
|
|
if (likely(!sdata1 && !sdata2))
|
|
return;
|
|
|
|
+ channel = ieee80211_get_channel_khz(local->hw.wiphy,
|
|
+ ieee80211_rx_status_to_khz(rx_status));
|
|
+
|
|
+ if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
|
|
+ return;
|
|
+
|
|
if (ieee80211_is_probe_resp(mgmt->frame_control)) {
|
|
struct cfg80211_scan_request *scan_req;
|
|
struct cfg80211_sched_scan_request *sched_scan_req;
|
|
@@ -284,18 +291,12 @@ void ieee80211_scan_rx(struct ieee80211_
|
|
* unless scanning with randomised address
|
|
*/
|
|
if (!ieee80211_scan_accept_presp(sdata1, scan_req_flags,
|
|
- mgmt->da) &&
|
|
+ mgmt->da, channel) &&
|
|
!ieee80211_scan_accept_presp(sdata2, sched_scan_req_flags,
|
|
- mgmt->da))
|
|
+ mgmt->da, channel))
|
|
return;
|
|
}
|
|
|
|
- channel = ieee80211_get_channel_khz(local->hw.wiphy,
|
|
- ieee80211_rx_status_to_khz(rx_status));
|
|
-
|
|
- if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
|
|
- return;
|
|
-
|
|
bss = ieee80211_bss_info_update(local, rx_status,
|
|
mgmt, skb->len,
|
|
channel);
|