ACS: Use frequency params in ACS (offload) completed event interface

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>
This commit is contained in:
Ankita Bajaj 2019-11-18 14:39:04 +05:30 committed by Jouni Malinen
parent 840532aea5
commit 41cac481a8
3 changed files with 63 additions and 19 deletions

View file

@ -17,6 +17,7 @@
#include "common/wpa_ctrl.h" #include "common/wpa_ctrl.h"
#include "common/dpp.h" #include "common/dpp.h"
#include "common/sae.h" #include "common/sae.h"
#include "common/hw_features_common.h"
#include "crypto/random.h" #include "crypto/random.h"
#include "p2p/p2p.h" #include "p2p/p2p.h"
#include "wps/wps.h" #include "wps/wps.h"
@ -935,6 +936,7 @@ void hostapd_acs_channel_selected(struct hostapd_data *hapd,
{ {
int ret, i; int ret, i;
int err = 0; int err = 0;
struct hostapd_channel_data *pri_chan;
if (hapd->iconf->channel) { if (hapd->iconf->channel) {
wpa_printf(MSG_INFO, "ACS: Channel was already set to %d", 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_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_WARNING, HOSTAPD_LEVEL_WARNING,
"driver switched to bad channel"); "driver switched to bad channel");
err = 1; err = 1;
goto out; 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; hapd->iconf->acs = 1;
if (acs_res->sec_channel == 0) if (acs_res->sec_freq == 0)
hapd->iconf->secondary_channel = 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; 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; hapd->iconf->secondary_channel = 1;
else { else {
wpa_printf(MSG_ERROR, "Invalid secondary channel!"); wpa_printf(MSG_ERROR, "Invalid secondary channel!");

View file

@ -5607,8 +5607,8 @@ union wpa_event_data {
/** /**
* struct acs_selected_channels - Data for EVENT_ACS_CHANNEL_SELECTED * struct acs_selected_channels - Data for EVENT_ACS_CHANNEL_SELECTED
* @pri_channel: Selected primary channel * @pri_freq: Selected primary frequency
* @sec_channel: Selected secondary channel * @sec_freq: Selected secondary frequency
* @vht_seg0_center_ch: VHT mode Segment0 center channel * @vht_seg0_center_ch: VHT mode Segment0 center channel
* @vht_seg1_center_ch: VHT mode Segment1 center channel * @vht_seg1_center_ch: VHT mode Segment1 center channel
* @ch_width: Selected Channel width by driver. Driver may choose to * @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) * hw_mode: Selected band (used with hw_mode=any)
*/ */
struct acs_selected_channels { struct acs_selected_channels {
u8 pri_channel; unsigned int pri_freq;
u8 sec_channel; unsigned int sec_freq;
u8 vht_seg0_center_ch; u8 vht_seg0_center_ch;
u8 vht_seg1_center_ch; u8 vht_seg1_center_ch;
u16 ch_width; u16 ch_width;

View 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, static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
const u8 *data, size_t len) const u8 *data, size_t len)
{ {
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1]; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
union wpa_event_data event; union wpa_event_data event;
u8 chan;
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"nl80211: ACS channel selection vendor event received"); "nl80211: ACS channel selection vendor event received");
if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX, if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX,
(struct nlattr *) data, len, NULL) || (struct nlattr *) data, len, NULL) ||
!tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL] || (!tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY] &&
!tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]) !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; return;
os_memset(&event, 0, sizeof(event)); os_memset(&event, 0, sizeof(event));
event.acs_selected_channels.pri_channel = if (tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]) {
nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]); event.acs_selected_channels.pri_freq = nla_get_u32(
event.acs_selected_channels.sec_channel = tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]);
nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]); } 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]) if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
event.acs_selected_channels.vht_seg0_center_ch = event.acs_selected_channels.vht_seg0_center_ch =
nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]); 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, wpa_printf(MSG_INFO,
"nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d", "nl80211: ACS Results: PFreq: %d SFreq: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
event.acs_selected_channels.pri_channel, event.acs_selected_channels.pri_freq,
event.acs_selected_channels.sec_channel, event.acs_selected_channels.sec_freq,
event.acs_selected_channels.ch_width, event.acs_selected_channels.ch_width,
event.acs_selected_channels.vht_seg0_center_ch, event.acs_selected_channels.vht_seg0_center_ch,
event.acs_selected_channels.vht_seg1_center_ch, event.acs_selected_channels.vht_seg1_center_ch,