aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoam Shaked <nshaked@codeaurora.org>2020-03-10 01:16:02 (GMT)
committerJouni Malinen <j@w1.fi>2020-03-23 20:29:04 (GMT)
commit00f6a27628ac571519bf83f44987816510532dd7 (patch)
tree90cd3abfa074355cdd5c73b0fb8e5b699afb1ea6
parent1e8ea0833dcb0dec7e02a407fb15abd5bcd08c5a (diff)
downloadhostap-00f6a27628ac571519bf83f44987816510532dd7.zip
hostap-00f6a27628ac571519bf83f44987816510532dd7.tar.gz
hostap-00f6a27628ac571519bf83f44987816510532dd7.tar.bz2
nl80211: Fix offloaded ACS regression for the 60 GHz band
Addition of chan_2ghz_or_5ghz_to_freq() broke 60 GHz ACS, because it assumes reported ACS channel is on either 2.4 or 5 GHz band. Fix this by converting chan_2ghz_or_5ghz_to_freq() to a more generic chan_to_freq(). The new function uses hw_mode to support 60 GHz. Fixes: 41cac481a889 ("ACS: Use frequency params in ACS (offload) completed event interface") Signed-off-by: Noam Shaked <nshaked@codeaurora.org>
-rw-r--r--src/drivers/driver_nl80211_event.c71
1 files changed, 54 insertions, 17 deletions
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index b634a2d..49d81d7 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -1753,8 +1753,41 @@ static enum hostapd_hw_mode get_qca_hw_mode(u8 hw_mode)
}
-static unsigned int chan_2ghz_or_5ghz_to_freq(u8 chan)
+static unsigned int chan_to_freq(struct wpa_driver_nl80211_data *drv,
+ u8 chan, enum hostapd_hw_mode hw_mode)
{
+ if (hw_mode == NUM_HOSTAPD_MODES) {
+ /* For drivers that do not report ACS_HW_MODE */
+ u16 num_modes, flags;
+ struct hostapd_hw_modes *modes;
+ u8 dfs_domain;
+ int i;
+
+ modes = nl80211_get_hw_feature_data(drv->first_bss, &num_modes,
+ &flags, &dfs_domain);
+ if (!modes) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Fetching hardware mode failed");
+ goto try_2_4_or_5;
+ }
+ if (num_modes == 1)
+ hw_mode = modes[0].mode;
+
+ for (i = 0; i < num_modes; i++) {
+ os_free(modes[i].channels);
+ os_free(modes[i].rates);
+ }
+
+ os_free(modes);
+ }
+
+ if (hw_mode == HOSTAPD_MODE_IEEE80211AD) {
+ if (chan >= 1 && chan <= 6)
+ return 56160 + (2160 * chan);
+ return 0;
+ }
+
+try_2_4_or_5:
if (chan >= 1 && chan <= 13)
return 2407 + 5 * chan;
if (chan == 14)
@@ -1785,13 +1818,30 @@ static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
return;
os_memset(&event, 0, sizeof(event));
+ event.acs_selected_channels.hw_mode = NUM_HOSTAPD_MODES;
+
+ if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
+ u8 hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
+
+ event.acs_selected_channels.hw_mode = get_qca_hw_mode(hw_mode);
+ if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
+ event.acs_selected_channels.hw_mode ==
+ HOSTAPD_MODE_IEEE80211ANY) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Invalid hw_mode %d in ACS selection event",
+ hw_mode);
+ return;
+ }
+ }
+
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]) {
event.acs_selected_channels.pri_freq = nla_get_u32(
tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]);
} else {
chan = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]);
event.acs_selected_channels.pri_freq =
- chan_2ghz_or_5ghz_to_freq(chan);
+ chan_to_freq(drv, chan,
+ event.acs_selected_channels.hw_mode);
}
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY]) {
@@ -1801,7 +1851,8 @@ static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
chan = nla_get_u8(
tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]);
event.acs_selected_channels.sec_freq =
- chan_2ghz_or_5ghz_to_freq(chan);
+ chan_to_freq(drv, chan,
+ event.acs_selected_channels.hw_mode);
}
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
@@ -1813,20 +1864,6 @@ static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH])
event.acs_selected_channels.ch_width =
nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]);
- if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
- u8 hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
-
- event.acs_selected_channels.hw_mode = get_qca_hw_mode(hw_mode);
- if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
- event.acs_selected_channels.hw_mode ==
- HOSTAPD_MODE_IEEE80211ANY) {
- wpa_printf(MSG_DEBUG,
- "nl80211: Invalid hw_mode %d in ACS selection event",
- hw_mode);
- return;
- }
- }
-
wpa_printf(MSG_INFO,
"nl80211: ACS Results: PFreq: %d SFreq: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
event.acs_selected_channels.pri_freq,