nl80211: Add supported bandwidth parsing

Add NL80211_FREQUENCY_ATTR_NO_* channel attributes parsing. This is
needed for correct checking if channel is available in a particular
bandwidth.

Signed-off-by: Dmitry Lebed <dlebed@quantenna.com>
This commit is contained in:
Dmitry Lebed 2018-03-01 14:49:26 +03:00 committed by Jouni Malinen
parent 1185294944
commit 4299ad826d
3 changed files with 38 additions and 0 deletions

View file

@ -58,6 +58,16 @@
#define HOSTAPD_CHAN_VHT_130_30 0x04000000
#define HOSTAPD_CHAN_VHT_150_10 0x08000000
/* Allowed bandwidth mask */
enum hostapd_chan_width_attr {
HOSTAPD_CHAN_WIDTH_10 = BIT(0),
HOSTAPD_CHAN_WIDTH_20 = BIT(1),
HOSTAPD_CHAN_WIDTH_40P = BIT(2),
HOSTAPD_CHAN_WIDTH_40M = BIT(3),
HOSTAPD_CHAN_WIDTH_80 = BIT(4),
HOSTAPD_CHAN_WIDTH_160 = BIT(5),
};
/* Filter gratuitous ARP */
#define WPA_DATA_FRAME_FILTER_FLAG_ARP BIT(0)
/* Filter unsolicited Neighbor Advertisement */
@ -110,6 +120,13 @@ struct hostapd_channel_data {
*/
int flag;
/**
* allowed_bw - Allowed channel width bitmask
*
* See enum hostapd_chan_width_attr.
*/
u32 allowed_bw;
/**
* max_tx_power - Regulatory transmit power limit in dBm
*/

View file

@ -1131,6 +1131,7 @@ static struct hostapd_hw_modes * hostap_get_hw_feature_data(void *priv,
for (i = 0; i < 14; i++) {
mode->channels[i].chan = i + 1;
mode->channels[i].freq = chan2freq[i];
mode->channels[i].allowed_bw = HOSTAPD_CHAN_WIDTH_20;
/* TODO: Get allowed channel list from the driver */
if (i >= 11)
mode->channels[i].flag = HOSTAPD_CHAN_DISABLED;

View file

@ -1441,6 +1441,7 @@ static void phy_info_freq(struct hostapd_hw_modes *mode,
u8 channel;
chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
chan->flag = 0;
chan->allowed_bw = ~0;
chan->dfs_cac_ms = 0;
if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES)
chan->chan = channel;
@ -1456,6 +1457,19 @@ static void phy_info_freq(struct hostapd_hw_modes *mode,
if (tb_freq[NL80211_FREQUENCY_ATTR_GO_CONCURRENT])
chan->flag |= HOSTAPD_CHAN_GO_CONCURRENT;
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_10MHZ])
chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_10;
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_20MHZ])
chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_20;
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_PLUS])
chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40P;
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_MINUS])
chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40M;
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_80MHZ])
chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_80;
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_160MHZ])
chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_160;
if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
enum nl80211_dfs_state state =
nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]);
@ -1490,6 +1504,12 @@ static int phy_info_freqs(struct phy_info_arg *phy_info,
[NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
[NL80211_FREQUENCY_ATTR_DFS_STATE] = { .type = NLA_U32 },
[NL80211_FREQUENCY_ATTR_NO_10MHZ] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_NO_20MHZ] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_NO_HT40_PLUS] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_NO_HT40_MINUS] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_NO_80MHZ] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_NO_160MHZ] = { .type = NLA_FLAG },
};
int new_channels = 0;
struct hostapd_channel_data *channel;