Skip to content

Commit 7b6ddea

Browse files
committed
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 <[email protected]>
1 parent 01a95b2 commit 7b6ddea

File tree

7 files changed

+42
-10
lines changed

7 files changed

+42
-10
lines changed

drivers/net/wireless/ath/ath9k/channel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,7 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
11131113
if (!avp->assoc)
11141114
return false;
11151115

1116-
skb = ieee80211_nullfunc_get(sc->hw, vif);
1116+
skb = ieee80211_nullfunc_get(sc->hw, vif, false);
11171117
if (!skb)
11181118
return false;
11191119

drivers/net/wireless/st/cw1200/sta.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
198198

199199
priv->bss_loss_state++;
200200

201-
skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
201+
skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
202202
WARN_ON(!skb);
203203
if (skb)
204204
cw1200_tx(priv->hw, NULL, skb);
@@ -2265,7 +2265,7 @@ static int cw1200_upload_null(struct cw1200_common *priv)
22652265
.rate = 0xFF,
22662266
};
22672267

2268-
frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
2268+
frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
22692269
if (!frame.skb)
22702270
return -ENOMEM;
22712271

drivers/net/wireless/ti/wl1251/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ static int wl1251_build_null_data(struct wl1251 *wl)
566566
size = sizeof(struct wl12xx_null_data_template);
567567
ptr = NULL;
568568
} else {
569-
skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
569+
skb = ieee80211_nullfunc_get(wl->hw, wl->vif, false);
570570
if (!skb)
571571
goto out;
572572
size = skb->len;

drivers/net/wireless/ti/wlcore/cmd.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,8 @@ int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif)
10691069
ptr = NULL;
10701070
} else {
10711071
skb = ieee80211_nullfunc_get(wl->hw,
1072-
wl12xx_wlvif_to_vif(wlvif));
1072+
wl12xx_wlvif_to_vif(wlvif),
1073+
false);
10731074
if (!skb)
10741075
goto out;
10751076
size = skb->len;
@@ -1096,7 +1097,7 @@ int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl,
10961097
struct sk_buff *skb = NULL;
10971098
int ret = -ENOMEM;
10981099

1099-
skb = ieee80211_nullfunc_get(wl->hw, vif);
1100+
skb = ieee80211_nullfunc_get(wl->hw, vif, false);
11001101
if (!skb)
11011102
goto out;
11021103

include/net/mac80211.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4470,18 +4470,24 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
44704470
* ieee80211_nullfunc_get - retrieve a nullfunc template
44714471
* @hw: pointer obtained from ieee80211_alloc_hw().
44724472
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
4473+
* @qos_ok: QoS NDP is acceptable to the caller, this should be set
4474+
* if at all possible
44734475
*
44744476
* Creates a Nullfunc template which can, for example, uploaded to
44754477
* hardware. The template must be updated after association so that correct
44764478
* BSSID and address is used.
44774479
*
4480+
* If @qos_ndp is set and the association is to an AP with QoS/WMM, the
4481+
* returned packet will be QoS NDP.
4482+
*
44784483
* Note: Caller (or hardware) is responsible for setting the
44794484
* &IEEE80211_FCTL_PM bit as well as Duration and Sequence Control fields.
44804485
*
44814486
* Return: The nullfunc template. %NULL on error.
44824487
*/
44834488
struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
4484-
struct ieee80211_vif *vif);
4489+
struct ieee80211_vif *vif,
4490+
bool qos_ok);
44854491

44864492
/**
44874493
* ieee80211_probereq_get - retrieve a Probe Request template

net/mac80211/mlme.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
895895
struct ieee80211_hdr_3addr *nullfunc;
896896
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
897897

898-
skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif);
898+
skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif, true);
899899
if (!skb)
900900
return;
901901

net/mac80211/tx.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4438,13 +4438,15 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
44384438
EXPORT_SYMBOL(ieee80211_pspoll_get);
44394439

44404440
struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
4441-
struct ieee80211_vif *vif)
4441+
struct ieee80211_vif *vif,
4442+
bool qos_ok)
44424443
{
44434444
struct ieee80211_hdr_3addr *nullfunc;
44444445
struct ieee80211_sub_if_data *sdata;
44454446
struct ieee80211_if_managed *ifmgd;
44464447
struct ieee80211_local *local;
44474448
struct sk_buff *skb;
4449+
bool qos = false;
44484450

44494451
if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
44504452
return NULL;
@@ -4453,7 +4455,17 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
44534455
ifmgd = &sdata->u.mgd;
44544456
local = sdata->local;
44554457

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);
44574469
if (!skb)
44584470
return NULL;
44594471

@@ -4463,6 +4475,19 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
44634475
nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
44644476
IEEE80211_STYPE_NULLFUNC |
44654477
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+
44664491
memcpy(nullfunc->addr1, ifmgd->bssid, ETH_ALEN);
44674492
memcpy(nullfunc->addr2, vif->addr, ETH_ALEN);
44684493
memcpy(nullfunc->addr3, ifmgd->bssid, ETH_ALEN);

0 commit comments

Comments
 (0)