Commit 48b810d9 authored by David S. Miller's avatar David S. Miller

Merge tag 'mac80211-for-davem-2015-03-16' of...

Merge tag 'mac80211-for-davem-2015-03-16' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211

Johannes Berg says:

====================
Here are a few fixes that I'd like to still get in:
 * disable U-APSD for better interoperability, from Michal Kazior
 * drop unencrypted frames in mesh forwarding, from Bob Copeland
 * treat non-QoS/WMM HT stations as non-HT, to fix confusion when
   they connect and then get QoS packets anyway due to HT
 * fix counting interfaces for combination checks, otherwise the
   interface combinations aren't properly enforced (from Andrei)
 * fix pure ECSA by reacting to the IE change
 * ignore erroneous (E)CSA to the current channel which sometimes
   happens due to AP/GO bugs
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ca00942a f84eaa10
...@@ -58,13 +58,24 @@ struct ieee80211_local; ...@@ -58,13 +58,24 @@ struct ieee80211_local;
#define IEEE80211_UNSET_POWER_LEVEL INT_MIN #define IEEE80211_UNSET_POWER_LEVEL INT_MIN
/* /*
* Some APs experience problems when working with U-APSD. Decrease the * Some APs experience problems when working with U-APSD. Decreasing the
* probability of that happening by using legacy mode for all ACs but VO. * probability of that happening by using legacy mode for all ACs but VO isn't
* The AP that caused us trouble was a Cisco 4410N. It ignores our * enough.
* setting, and always treats non-VO ACs as legacy. *
* Cisco 4410N originally forced us to enable VO by default only because it
* treated non-VO ACs as legacy.
*
* However some APs (notably Netgear R7000) silently reclassify packets to
* different ACs. Since u-APSD ACs require trigger frames for frame retrieval
* clients would never see some frames (e.g. ARP responses) or would fetch them
* accidentally after a long time.
*
* It makes little sense to enable u-APSD queues by default because it needs
* userspace applications to be aware of it to actually take advantage of the
* possible additional powersavings. Implicitly depending on driver autotrigger
* frame support doesn't make much sense.
*/ */
#define IEEE80211_DEFAULT_UAPSD_QUEUES \ #define IEEE80211_DEFAULT_UAPSD_QUEUES 0
IEEE80211_WMM_IE_STA_QOSINFO_AC_VO
#define IEEE80211_DEFAULT_MAX_SP_LEN \ #define IEEE80211_DEFAULT_MAX_SP_LEN \
IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL
...@@ -453,6 +464,7 @@ struct ieee80211_if_managed { ...@@ -453,6 +464,7 @@ struct ieee80211_if_managed {
unsigned int flags; unsigned int flags;
bool csa_waiting_bcn; bool csa_waiting_bcn;
bool csa_ignored_same_chan;
bool beacon_crc_valid; bool beacon_crc_valid;
u32 beacon_crc; u32 beacon_crc;
......
...@@ -1150,6 +1150,17 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, ...@@ -1150,6 +1150,17 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
return; return;
} }
if (cfg80211_chandef_identical(&csa_ie.chandef,
&sdata->vif.bss_conf.chandef)) {
if (ifmgd->csa_ignored_same_chan)
return;
sdata_info(sdata,
"AP %pM tries to chanswitch to same channel, ignore\n",
ifmgd->associated->bssid);
ifmgd->csa_ignored_same_chan = true;
return;
}
mutex_lock(&local->mtx); mutex_lock(&local->mtx);
mutex_lock(&local->chanctx_mtx); mutex_lock(&local->chanctx_mtx);
conf = rcu_dereference_protected(sdata->vif.chanctx_conf, conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
...@@ -1210,6 +1221,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, ...@@ -1210,6 +1221,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
sdata->vif.csa_active = true; sdata->vif.csa_active = true;
sdata->csa_chandef = csa_ie.chandef; sdata->csa_chandef = csa_ie.chandef;
sdata->csa_block_tx = csa_ie.mode; sdata->csa_block_tx = csa_ie.mode;
ifmgd->csa_ignored_same_chan = false;
if (sdata->csa_block_tx) if (sdata->csa_block_tx)
ieee80211_stop_vif_queues(local, sdata, ieee80211_stop_vif_queues(local, sdata,
...@@ -2090,6 +2102,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, ...@@ -2090,6 +2102,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
sdata->vif.csa_active = false; sdata->vif.csa_active = false;
ifmgd->csa_waiting_bcn = false; ifmgd->csa_waiting_bcn = false;
ifmgd->csa_ignored_same_chan = false;
if (sdata->csa_block_tx) { if (sdata->csa_block_tx) {
ieee80211_wake_vif_queues(local, sdata, ieee80211_wake_vif_queues(local, sdata,
IEEE80211_QUEUE_STOP_REASON_CSA); IEEE80211_QUEUE_STOP_REASON_CSA);
...@@ -3204,7 +3217,8 @@ static const u64 care_about_ies = ...@@ -3204,7 +3217,8 @@ static const u64 care_about_ies =
(1ULL << WLAN_EID_CHANNEL_SWITCH) | (1ULL << WLAN_EID_CHANNEL_SWITCH) |
(1ULL << WLAN_EID_PWR_CONSTRAINT) | (1ULL << WLAN_EID_PWR_CONSTRAINT) |
(1ULL << WLAN_EID_HT_CAPABILITY) | (1ULL << WLAN_EID_HT_CAPABILITY) |
(1ULL << WLAN_EID_HT_OPERATION); (1ULL << WLAN_EID_HT_OPERATION) |
(1ULL << WLAN_EID_EXT_CHANSWITCH_ANN);
static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_mgmt *mgmt, size_t len,
......
...@@ -2214,6 +2214,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) ...@@ -2214,6 +2214,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
hdr = (struct ieee80211_hdr *) skb->data; hdr = (struct ieee80211_hdr *) skb->data;
mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
if (ieee80211_drop_unencrypted(rx, hdr->frame_control))
return RX_DROP_MONITOR;
/* frame is in RMC, don't forward */ /* frame is in RMC, don't forward */
if (ieee80211_is_data(hdr->frame_control) && if (ieee80211_is_data(hdr->frame_control) &&
is_multicast_ether_addr(hdr->addr1) && is_multicast_ether_addr(hdr->addr1) &&
......
...@@ -3178,7 +3178,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, ...@@ -3178,7 +3178,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
wdev_iter = &sdata_iter->wdev; wdev_iter = &sdata_iter->wdev;
if (sdata_iter == sdata || if (sdata_iter == sdata ||
rcu_access_pointer(sdata_iter->vif.chanctx_conf) == NULL || !ieee80211_sdata_running(sdata_iter) ||
local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype)) local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype))
continue; continue;
......
...@@ -4400,6 +4400,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) ...@@ -4400,6 +4400,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params)) if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
return -EINVAL; return -EINVAL;
/* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
* as userspace might just pass through the capabilities from the IEs
* directly, rather than enforcing this restriction and returning an
* error in this case.
*/
if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
params.ht_capa = NULL;
params.vht_capa = NULL;
}
/* When you run into this, adjust the code below for the new flag */ /* When you run into this, adjust the code below for the new flag */
BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7); BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment