]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
ACS: Use frequency params in ACS (offload) completed event interface
authorAnkita Bajaj <bankita@codeaurora.org>
Mon, 18 Nov 2019 09:09:04 +0000 (14:39 +0530)
committerJouni Malinen <j@w1.fi>
Fri, 20 Dec 2019 10:31:01 +0000 (12:31 +0200)
Replace channel fields with frequency fields in ACS completed event
interface from the driver layer. Use
QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY and
QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY attributes if the driver
includes them in the QCA_NL80211_VENDOR_SUBCMD_DO_ACS event, otherwise
use QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL and
QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL attributes to maintain
backwards compatibility with old drivers.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/ap/drv_callbacks.c
src/drivers/driver.h
src/drivers/driver_nl80211_event.c

index e5ce76d1136851289767a23bfa1bc0d4b7b719d1..49f4a0e36cf7a56404e71a711ebd0224fe0bf4d3 100644 (file)
@@ -17,6 +17,7 @@
 #include "common/wpa_ctrl.h"
 #include "common/dpp.h"
 #include "common/sae.h"
+#include "common/hw_features_common.h"
 #include "crypto/random.h"
 #include "p2p/p2p.h"
 #include "wps/wps.h"
@@ -935,6 +936,7 @@ void hostapd_acs_channel_selected(struct hostapd_data *hapd,
 {
        int ret, i;
        int err = 0;
+       struct hostapd_channel_data *pri_chan;
 
        if (hapd->iconf->channel) {
                wpa_printf(MSG_INFO, "ACS: Channel was already set to %d",
@@ -961,24 +963,35 @@ void hostapd_acs_channel_selected(struct hostapd_data *hapd,
                }
        }
 
-       hapd->iface->freq = hostapd_hw_get_freq(hapd, acs_res->pri_channel);
+       hapd->iface->freq = acs_res->pri_freq;
 
-       if (!acs_res->pri_channel) {
+       if (!acs_res->pri_freq) {
                hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
                               HOSTAPD_LEVEL_WARNING,
                               "driver switched to bad channel");
                err = 1;
                goto out;
        }
+       pri_chan = hw_get_channel_freq(hapd->iface->current_mode->mode,
+                                      acs_res->pri_freq, NULL,
+                                      hapd->iface->hw_features,
+                                      hapd->iface->num_hw_features);
+       if (!pri_chan) {
+               wpa_printf(MSG_ERROR,
+                          "ACS: Could not determine primary channel number from pri_freq %u",
+                          acs_res->pri_freq);
+               err = 1;
+               goto out;
+       }
 
-       hapd->iconf->channel = acs_res->pri_channel;
+       hapd->iconf->channel = pri_chan->chan;
        hapd->iconf->acs = 1;
 
-       if (acs_res->sec_channel == 0)
+       if (acs_res->sec_freq == 0)
                hapd->iconf->secondary_channel = 0;
-       else if (acs_res->sec_channel < acs_res->pri_channel)
+       else if (acs_res->sec_freq < acs_res->pri_freq)
                hapd->iconf->secondary_channel = -1;
-       else if (acs_res->sec_channel > acs_res->pri_channel)
+       else if (acs_res->sec_freq > acs_res->pri_freq)
                hapd->iconf->secondary_channel = 1;
        else {
                wpa_printf(MSG_ERROR, "Invalid secondary channel!");
index c6b7db8c29329e004fddba8f3228ac2bfaf50629..f0e2a6f26e2abd6b8edbaea3423b66e9d09b8e04 100644 (file)
@@ -5607,8 +5607,8 @@ union wpa_event_data {
 
        /**
         * struct acs_selected_channels - Data for EVENT_ACS_CHANNEL_SELECTED
-        * @pri_channel: Selected primary channel
-        * @sec_channel: Selected secondary channel
+        * @pri_freq: Selected primary frequency
+        * @sec_freq: Selected secondary frequency
         * @vht_seg0_center_ch: VHT mode Segment0 center channel
         * @vht_seg1_center_ch: VHT mode Segment1 center channel
         * @ch_width: Selected Channel width by driver. Driver may choose to
@@ -5617,8 +5617,8 @@ union wpa_event_data {
         * hw_mode: Selected band (used with hw_mode=any)
         */
        struct acs_selected_channels {
-               u8 pri_channel;
-               u8 sec_channel;
+               unsigned int pri_freq;
+               unsigned int sec_freq;
                u8 vht_seg0_center_ch;
                u8 vht_seg1_center_ch;
                u16 ch_width;
index 809d8a8da020d6236bb8daa16af2293d90f8e86b..2aecc7492c85276cd4a1b8a724ac966bc5ba3fca 100644 (file)
@@ -1740,26 +1740,57 @@ static enum hostapd_hw_mode get_qca_hw_mode(u8 hw_mode)
 }
 
 
+static unsigned int chan_2ghz_or_5ghz_to_freq(u8 chan)
+{
+       if (chan >= 1 && chan <= 13)
+               return 2407 + 5 * chan;
+       if (chan == 14)
+               return 2484;
+       if (chan >= 36 && chan <= 169)
+               return 5000 + 5 * chan;
+
+       return 0;
+}
+
+
 static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
                                   const u8 *data, size_t len)
 {
        struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
        union wpa_event_data event;
+       u8 chan;
 
        wpa_printf(MSG_DEBUG,
                   "nl80211: ACS channel selection vendor event received");
 
        if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX,
                      (struct nlattr *) data, len, NULL) ||
-           !tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL] ||
-           !tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL])
+           (!tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY] &&
+            !tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]) ||
+           (!tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY] &&
+            !tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]))
                return;
 
        os_memset(&event, 0, sizeof(event));
-       event.acs_selected_channels.pri_channel =
-               nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]);
-       event.acs_selected_channels.sec_channel =
-               nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]);
+       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);
+       }
+
+       if (tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY]) {
+               event.acs_selected_channels.sec_freq = nla_get_u32(
+                       tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY]);
+       } else {
+               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);
+       }
+
        if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
                event.acs_selected_channels.vht_seg0_center_ch =
                        nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
@@ -1784,9 +1815,9 @@ static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
        }
 
        wpa_printf(MSG_INFO,
-                  "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
-                  event.acs_selected_channels.pri_channel,
-                  event.acs_selected_channels.sec_channel,
+                  "nl80211: ACS Results: PFreq: %d SFreq: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
+                  event.acs_selected_channels.pri_freq,
+                  event.acs_selected_channels.sec_freq,
                   event.acs_selected_channels.ch_width,
                   event.acs_selected_channels.vht_seg0_center_ch,
                   event.acs_selected_channels.vht_seg1_center_ch,