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:
parent
840532aea5
commit
41cac481a8
3 changed files with 63 additions and 19 deletions
|
@ -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!");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue