#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"
{
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",
}
}
- 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!");
/**
* 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
* 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;
}
+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]);
}
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,