Merge tag 'mac80211-next-for-net-next-2020-02-14' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says: ==================== A few big new things: * 802.11 frame encapsulation offload support * more HE (802.11ax) support, including some for 6 GHz band * powersave in hwsim, for better testing Of course as usual there are various cleanups and small fixes. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -164,7 +164,9 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
||||
chandef->center_freq1 = channel->center_freq;
|
||||
|
||||
if (!ht_oper || !sta_ht_cap.ht_supported) {
|
||||
ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
|
||||
ret = IEEE80211_STA_DISABLE_HT |
|
||||
IEEE80211_STA_DISABLE_VHT |
|
||||
IEEE80211_STA_DISABLE_HE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -185,7 +187,9 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
||||
"Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
|
||||
channel->center_freq, ht_cfreq,
|
||||
ht_oper->primary_chan, channel->band);
|
||||
ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
|
||||
ret = IEEE80211_STA_DISABLE_HT |
|
||||
IEEE80211_STA_DISABLE_VHT |
|
||||
IEEE80211_STA_DISABLE_HE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -301,13 +305,18 @@ out:
|
||||
IEEE80211_CHAN_DISABLED)) {
|
||||
if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
|
||||
ret = IEEE80211_STA_DISABLE_HT |
|
||||
IEEE80211_STA_DISABLE_VHT;
|
||||
IEEE80211_STA_DISABLE_VHT |
|
||||
IEEE80211_STA_DISABLE_HE;
|
||||
break;
|
||||
}
|
||||
|
||||
ret |= ieee80211_chandef_downgrade(chandef);
|
||||
}
|
||||
|
||||
if (!he_oper || !cfg80211_chandef_usable(sdata->wdev.wiphy, chandef,
|
||||
IEEE80211_CHAN_NO_HE))
|
||||
ret |= IEEE80211_STA_DISABLE_HE;
|
||||
|
||||
if (chandef->width != vht_chandef.width && !tracking)
|
||||
sdata_info(sdata,
|
||||
"capabilities/regulatory prevented using AP HT/VHT configuration, downgraded\n");
|
||||
@@ -393,6 +402,7 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
if (flags != (ifmgd->flags & (IEEE80211_STA_DISABLE_HT |
|
||||
IEEE80211_STA_DISABLE_VHT |
|
||||
IEEE80211_STA_DISABLE_HE |
|
||||
IEEE80211_STA_DISABLE_40MHZ |
|
||||
IEEE80211_STA_DISABLE_80P80MHZ |
|
||||
IEEE80211_STA_DISABLE_160MHZ)) ||
|
||||
@@ -616,10 +626,21 @@ static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata,
|
||||
{
|
||||
u8 *pos;
|
||||
const struct ieee80211_sta_he_cap *he_cap = NULL;
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
u8 he_cap_size;
|
||||
bool reg_cap = false;
|
||||
|
||||
rcu_read_lock();
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (!WARN_ON_ONCE(!chanctx_conf))
|
||||
reg_cap = cfg80211_chandef_usable(sdata->wdev.wiphy,
|
||||
&chanctx_conf->def,
|
||||
IEEE80211_CHAN_NO_HE);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
he_cap = ieee80211_get_he_sta_cap(sband);
|
||||
if (!he_cap)
|
||||
if (!he_cap || !reg_cap)
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -650,6 +671,13 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
struct ieee80211_channel *chan;
|
||||
u32 rates = 0;
|
||||
struct element *ext_capa = NULL;
|
||||
|
||||
/* we know it's writable, cast away the const */
|
||||
if (assoc_data->ie_len)
|
||||
ext_capa = (void *)cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY,
|
||||
assoc_data->ie,
|
||||
assoc_data->ie_len);
|
||||
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
@@ -800,7 +828,15 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
||||
*pos++ = ieee80211_chandef_max_power(&chanctx_conf->def);
|
||||
}
|
||||
|
||||
if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
|
||||
/*
|
||||
* Per spec, we shouldn't include the list of channels if we advertise
|
||||
* support for extended channel switching, but we've always done that;
|
||||
* (for now?) apply this restriction only on the (new) 6 GHz band.
|
||||
*/
|
||||
if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT &&
|
||||
(sband->band != NL80211_BAND_6GHZ ||
|
||||
!ext_capa || ext_capa->datalen < 1 ||
|
||||
!(ext_capa->data[0] & WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING))) {
|
||||
/* TODO: get this in reg domain format */
|
||||
pos = skb_put(skb, 2 * sband->n_channels + 2);
|
||||
*pos++ = WLAN_EID_SUPPORTED_CHANNELS;
|
||||
@@ -814,18 +850,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
||||
|
||||
/* Set MBSSID support for HE AP if needed */
|
||||
if (ieee80211_hw_check(&local->hw, SUPPORTS_ONLY_HE_MULTI_BSSID) &&
|
||||
!(ifmgd->flags & IEEE80211_STA_DISABLE_HE) && assoc_data->ie_len) {
|
||||
struct element *elem;
|
||||
|
||||
/* we know it's writable, cast away the const */
|
||||
elem = (void *)cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY,
|
||||
assoc_data->ie,
|
||||
assoc_data->ie_len);
|
||||
|
||||
/* We can probably assume both always true */
|
||||
if (elem && elem->datalen >= 3)
|
||||
elem->data[2] |= WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT;
|
||||
}
|
||||
!(ifmgd->flags & IEEE80211_STA_DISABLE_HE) && assoc_data->ie_len &&
|
||||
ext_capa && ext_capa->datalen >= 3)
|
||||
ext_capa->data[2] |= WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT;
|
||||
|
||||
/* if present, add any custom IEs that go before HT */
|
||||
if (assoc_data->ie_len) {
|
||||
@@ -2460,7 +2487,7 @@ void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
|
||||
if (!ieee80211_is_data(hdr->frame_control))
|
||||
return;
|
||||
|
||||
if (ieee80211_is_nullfunc(hdr->frame_control) &&
|
||||
if (ieee80211_is_any_nullfunc(hdr->frame_control) &&
|
||||
sdata->u.mgd.probe_send_count > 0) {
|
||||
if (ack)
|
||||
ieee80211_sta_reset_conn_monitor(sdata);
|
||||
@@ -3368,9 +3395,16 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
if (bss_conf->he_support) {
|
||||
bss_conf->bss_color =
|
||||
bss_conf->he_bss_color.color =
|
||||
le32_get_bits(elems->he_operation->he_oper_params,
|
||||
IEEE80211_HE_OPERATION_BSS_COLOR_MASK);
|
||||
bss_conf->he_bss_color.partial =
|
||||
le32_get_bits(elems->he_operation->he_oper_params,
|
||||
IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR);
|
||||
bss_conf->he_bss_color.disabled =
|
||||
le32_get_bits(elems->he_operation->he_oper_params,
|
||||
IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
|
||||
changed |= BSS_CHANGED_HE_BSS_COLOR;
|
||||
|
||||
bss_conf->htc_trig_based_pkt_ext =
|
||||
le32_get_bits(elems->he_operation->he_oper_params,
|
||||
@@ -3649,13 +3683,28 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
||||
struct ieee80211_if_managed *ifmgd;
|
||||
struct ieee80211_rx_status *rx_status = (void *) skb->cb;
|
||||
struct ieee80211_channel *channel;
|
||||
size_t baselen, len = skb->len;
|
||||
|
||||
ifmgd = &sdata->u.mgd;
|
||||
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (!ether_addr_equal(mgmt->da, sdata->vif.addr))
|
||||
/*
|
||||
* According to Draft P802.11ax D6.0 clause 26.17.2.3.2:
|
||||
* "If a 6 GHz AP receives a Probe Request frame and responds with
|
||||
* a Probe Response frame [..], the Address 1 field of the Probe
|
||||
* Response frame shall be set to the broadcast address [..]"
|
||||
* So, on 6GHz band we should also accept broadcast responses.
|
||||
*/
|
||||
channel = ieee80211_get_channel(sdata->local->hw.wiphy,
|
||||
rx_status->freq);
|
||||
if (!channel)
|
||||
return;
|
||||
|
||||
if (!ether_addr_equal(mgmt->da, sdata->vif.addr) &&
|
||||
(channel->band != NL80211_BAND_6GHZ ||
|
||||
!is_broadcast_ether_addr(mgmt->da)))
|
||||
return; /* ignore ProbeResp to foreign address */
|
||||
|
||||
baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
|
||||
@@ -4753,10 +4802,22 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
IEEE80211_STA_DISABLE_80P80MHZ |
|
||||
IEEE80211_STA_DISABLE_160MHZ);
|
||||
|
||||
/* disable HT/VHT/HE if we don't support them */
|
||||
if (!sband->ht_cap.ht_supported) {
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
}
|
||||
|
||||
if (!sband->vht_cap.vht_supported)
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
|
||||
if (!ieee80211_get_he_sta_cap(sband))
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
|
||||
sband->ht_cap.ht_supported) {
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
|
||||
const u8 *ht_oper_ie, *ht_cap_ie;
|
||||
|
||||
ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION);
|
||||
@@ -4773,8 +4834,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
|
||||
sband->vht_cap.vht_supported) {
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
|
||||
const u8 *vht_oper_ie, *vht_cap;
|
||||
|
||||
vht_oper_ie = ieee80211_bss_get_ie(cbss,
|
||||
@@ -4784,9 +4844,10 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
if (vht_oper && !ht_oper) {
|
||||
vht_oper = NULL;
|
||||
sdata_info(sdata,
|
||||
"AP advertised VHT without HT, disabling both\n");
|
||||
"AP advertised VHT without HT, disabling HT/VHT/HE\n");
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
}
|
||||
|
||||
vht_cap = ieee80211_bss_get_ie(cbss, WLAN_EID_VHT_CAPABILITY);
|
||||
@@ -4796,9 +4857,6 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
}
|
||||
|
||||
if (!ieee80211_get_he_sta_cap(sband))
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE)) {
|
||||
const struct cfg80211_bss_ies *ies;
|
||||
const u8 *he_oper_ie;
|
||||
@@ -5297,27 +5355,15 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
}
|
||||
|
||||
/* Also disable HT if we don't support it or the AP doesn't use WMM */
|
||||
sband = local->hw.wiphy->bands[req->bss->channel->band];
|
||||
if (!sband->ht_cap.ht_supported ||
|
||||
local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used ||
|
||||
ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
|
||||
if (!bss->wmm_used &&
|
||||
!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM))
|
||||
netdev_info(sdata->dev,
|
||||
"disabling HT as WMM/QoS is not supported by the AP\n");
|
||||
}
|
||||
|
||||
/* disable VHT if we don't support it or the AP doesn't use WMM */
|
||||
if (!sband->vht_cap.vht_supported ||
|
||||
local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used ||
|
||||
ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
|
||||
/* also disable HT/VHT/HE if the AP doesn't use WMM */
|
||||
if (!bss->wmm_used) {
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
if (!bss->wmm_used &&
|
||||
!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM))
|
||||
netdev_info(sdata->dev,
|
||||
"disabling VHT as WMM/QoS is not supported by the AP\n");
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
netdev_info(sdata->dev,
|
||||
"disabling HT/VHT/HE as WMM/QoS is not supported by the AP\n");
|
||||
}
|
||||
|
||||
memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
|
||||
@@ -5449,6 +5495,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
if (req->flags & ASSOC_REQ_DISABLE_HT) {
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
}
|
||||
|
||||
if (req->flags & ASSOC_REQ_DISABLE_VHT)
|
||||
|
Reference in New Issue
Block a user