summaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2017-11-21 08:46:08 -0500
committerJohannes Berg <johannes.berg@intel.com>2017-11-27 05:23:20 -0500
commit7b6ddeaf27eca72795ceeae2f0f347db1b5f9a30 (patch)
treecc562ff138989b1e20f0fb19b2e2be1a0aaf90c9 /net/mac80211/tx.c
parent01a95b2141e337dea15ad48e60a35c72a9b10205 (diff)
mac80211: use QoS NDP for AP probing
When connected to a QoS/WMM AP, mac80211 should use a QoS NDP for probing it, instead of a regular non-QoS one, fix this. Change all the drivers to *not* allow QoS NDP for now, even though it looks like most of them should be OK with that. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 7b8154474b9e..3160954fc406 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4438,13 +4438,15 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
4438EXPORT_SYMBOL(ieee80211_pspoll_get); 4438EXPORT_SYMBOL(ieee80211_pspoll_get);
4439 4439
4440struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw, 4440struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
4441 struct ieee80211_vif *vif) 4441 struct ieee80211_vif *vif,
4442 bool qos_ok)
4442{ 4443{
4443 struct ieee80211_hdr_3addr *nullfunc; 4444 struct ieee80211_hdr_3addr *nullfunc;
4444 struct ieee80211_sub_if_data *sdata; 4445 struct ieee80211_sub_if_data *sdata;
4445 struct ieee80211_if_managed *ifmgd; 4446 struct ieee80211_if_managed *ifmgd;
4446 struct ieee80211_local *local; 4447 struct ieee80211_local *local;
4447 struct sk_buff *skb; 4448 struct sk_buff *skb;
4449 bool qos = false;
4448 4450
4449 if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) 4451 if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
4450 return NULL; 4452 return NULL;
@@ -4453,7 +4455,17 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
4453 ifmgd = &sdata->u.mgd; 4455 ifmgd = &sdata->u.mgd;
4454 local = sdata->local; 4456 local = sdata->local;
4455 4457
4456 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*nullfunc)); 4458 if (qos_ok) {
4459 struct sta_info *sta;
4460
4461 rcu_read_lock();
4462 sta = sta_info_get(sdata, ifmgd->bssid);
4463 qos = sta && sta->sta.wme;
4464 rcu_read_unlock();
4465 }
4466
4467 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
4468 sizeof(*nullfunc) + 2);
4457 if (!skb) 4469 if (!skb)
4458 return NULL; 4470 return NULL;
4459 4471
@@ -4463,6 +4475,19 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
4463 nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 4475 nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
4464 IEEE80211_STYPE_NULLFUNC | 4476 IEEE80211_STYPE_NULLFUNC |
4465 IEEE80211_FCTL_TODS); 4477 IEEE80211_FCTL_TODS);
4478 if (qos) {
4479 __le16 qos = cpu_to_le16(7);
4480
4481 BUILD_BUG_ON((IEEE80211_STYPE_QOS_NULLFUNC |
4482 IEEE80211_STYPE_NULLFUNC) !=
4483 IEEE80211_STYPE_QOS_NULLFUNC);
4484 nullfunc->frame_control |=
4485 cpu_to_le16(IEEE80211_STYPE_QOS_NULLFUNC);
4486 skb->priority = 7;
4487 skb_set_queue_mapping(skb, IEEE80211_AC_VO);
4488 skb_put_data(skb, &qos, sizeof(qos));
4489 }
4490
4466 memcpy(nullfunc->addr1, ifmgd->bssid, ETH_ALEN); 4491 memcpy(nullfunc->addr1, ifmgd->bssid, ETH_ALEN);
4467 memcpy(nullfunc->addr2, vif->addr, ETH_ALEN); 4492 memcpy(nullfunc->addr2, vif->addr, ETH_ALEN);
4468 memcpy(nullfunc->addr3, ifmgd->bssid, ETH_ALEN); 4493 memcpy(nullfunc->addr3, ifmgd->bssid, ETH_ALEN);