Skip to content

Commit 0f2be42

Browse files
committed
Merge tag 'mac80211-for-davem-2017-09-07' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says: ==================== Back from a long absence, so we have a number of things: * a remain-on-channel fix from Avi * hwsim TX power fix from Beni * null-PTR dereference with iTXQ in some rare configurations (Chunho) * 40 MHz custom regdomain fixes (Emmanuel) * look at right place in HT/VHT capability parsing (Igor) * complete A-MPDU teardown properly (Ilan) * Mesh ID Element ordering fix (Liad) * avoid tracing warning in ht_dbg() (Sharon) * fix print of assoc/reassoc (Simon) * fix encrypted VLAN with iTXQ (myself) * fix calling context of TX queue wake (myself) * fix a deadlock with ath10k aggregation (myself) ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 8e0deed + bde59c4 commit 0f2be42

File tree

13 files changed

+124
-47
lines changed

13 files changed

+124
-47
lines changed

drivers/net/wireless/mac80211_hwsim.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,8 +1362,6 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
13621362
txi->control.rates,
13631363
ARRAY_SIZE(txi->control.rates));
13641364

1365-
txi->rate_driver_data[0] = channel;
1366-
13671365
if (skb->len >= 24 + 8 &&
13681366
ieee80211_is_probe_resp(hdr->frame_control)) {
13691367
/* fake header transmission time */

include/net/mac80211.h

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -919,21 +919,10 @@ struct ieee80211_tx_info {
919919
unsigned long jiffies;
920920
};
921921
/* NB: vif can be NULL for injected frames */
922-
union {
923-
/* NB: vif can be NULL for injected frames */
924-
struct ieee80211_vif *vif;
925-
926-
/* When packets are enqueued on txq it's easy
927-
* to re-construct the vif pointer. There's no
928-
* more space in tx_info so it can be used to
929-
* store the necessary enqueue time for packet
930-
* sojourn time computation.
931-
*/
932-
codel_time_t enqueue_time;
933-
};
922+
struct ieee80211_vif *vif;
934923
struct ieee80211_key_conf *hw_key;
935924
u32 flags;
936-
/* 4 bytes free */
925+
codel_time_t enqueue_time;
937926
} control;
938927
struct {
939928
u64 cookie;

net/mac80211/agg-rx.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,10 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
245245
ieee80211_tx_skb(sdata, skb);
246246
}
247247

248-
void __ieee80211_start_rx_ba_session(struct sta_info *sta,
249-
u8 dialog_token, u16 timeout,
250-
u16 start_seq_num, u16 ba_policy, u16 tid,
251-
u16 buf_size, bool tx, bool auto_seq)
248+
void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
249+
u8 dialog_token, u16 timeout,
250+
u16 start_seq_num, u16 ba_policy, u16 tid,
251+
u16 buf_size, bool tx, bool auto_seq)
252252
{
253253
struct ieee80211_local *local = sta->sdata->local;
254254
struct tid_ampdu_rx *tid_agg_rx;
@@ -267,22 +267,22 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
267267
ht_dbg(sta->sdata,
268268
"STA %pM requests BA session on unsupported tid %d\n",
269269
sta->sta.addr, tid);
270-
goto end_no_lock;
270+
goto end;
271271
}
272272

273273
if (!sta->sta.ht_cap.ht_supported) {
274274
ht_dbg(sta->sdata,
275275
"STA %pM erroneously requests BA session on tid %d w/o QoS\n",
276276
sta->sta.addr, tid);
277277
/* send a response anyway, it's an error case if we get here */
278-
goto end_no_lock;
278+
goto end;
279279
}
280280

281281
if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
282282
ht_dbg(sta->sdata,
283283
"Suspend in progress - Denying ADDBA request (%pM tid %d)\n",
284284
sta->sta.addr, tid);
285-
goto end_no_lock;
285+
goto end;
286286
}
287287

288288
/* sanity check for incoming parameters:
@@ -296,7 +296,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
296296
ht_dbg_ratelimited(sta->sdata,
297297
"AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n",
298298
sta->sta.addr, tid, ba_policy, buf_size);
299-
goto end_no_lock;
299+
goto end;
300300
}
301301
/* determine default buffer size */
302302
if (buf_size == 0)
@@ -311,7 +311,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
311311
buf_size, sta->sta.addr);
312312

313313
/* examine state machine */
314-
mutex_lock(&sta->ampdu_mlme.mtx);
314+
lockdep_assert_held(&sta->ampdu_mlme.mtx);
315315

316316
if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) {
317317
if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) {
@@ -415,15 +415,25 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
415415
__clear_bit(tid, sta->ampdu_mlme.unexpected_agg);
416416
sta->ampdu_mlme.tid_rx_token[tid] = dialog_token;
417417
}
418-
mutex_unlock(&sta->ampdu_mlme.mtx);
419418

420-
end_no_lock:
421419
if (tx)
422420
ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
423421
dialog_token, status, 1, buf_size,
424422
timeout);
425423
}
426424

425+
void __ieee80211_start_rx_ba_session(struct sta_info *sta,
426+
u8 dialog_token, u16 timeout,
427+
u16 start_seq_num, u16 ba_policy, u16 tid,
428+
u16 buf_size, bool tx, bool auto_seq)
429+
{
430+
mutex_lock(&sta->ampdu_mlme.mtx);
431+
___ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
432+
start_seq_num, ba_policy, tid,
433+
buf_size, tx, auto_seq);
434+
mutex_unlock(&sta->ampdu_mlme.mtx);
435+
}
436+
427437
void ieee80211_process_addba_request(struct ieee80211_local *local,
428438
struct sta_info *sta,
429439
struct ieee80211_mgmt *mgmt,

net/mac80211/agg-tx.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,11 @@ ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable)
226226
clear_bit(IEEE80211_TXQ_AMPDU, &txqi->flags);
227227

228228
clear_bit(IEEE80211_TXQ_STOP, &txqi->flags);
229+
local_bh_disable();
230+
rcu_read_lock();
229231
drv_wake_tx_queue(sta->sdata->local, txqi);
232+
rcu_read_unlock();
233+
local_bh_enable();
230234
}
231235

232236
/*
@@ -436,7 +440,7 @@ static void sta_addba_resp_timer_expired(unsigned long data)
436440
test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) {
437441
rcu_read_unlock();
438442
ht_dbg(sta->sdata,
439-
"timer expired on %pM tid %d but we are not (or no longer) expecting addBA response there\n",
443+
"timer expired on %pM tid %d not expecting addBA response\n",
440444
sta->sta.addr, tid);
441445
return;
442446
}
@@ -639,7 +643,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
639643
time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] +
640644
HT_AGG_RETRIES_PERIOD)) {
641645
ht_dbg(sdata,
642-
"BA request denied - waiting a grace period after %d failed requests on %pM tid %u\n",
646+
"BA request denied - %d failed requests on %pM tid %u\n",
643647
sta->ampdu_mlme.addba_req_num[tid], sta->sta.addr, tid);
644648
ret = -EBUSY;
645649
goto err_unlock_sta;

net/mac80211/ht.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,24 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
300300

301301
/* stopping might queue the work again - so cancel only afterwards */
302302
cancel_work_sync(&sta->ampdu_mlme.work);
303+
304+
/*
305+
* In case the tear down is part of a reconfigure due to HW restart
306+
* request, it is possible that the low level driver requested to stop
307+
* the BA session, so handle it to properly clean tid_tx data.
308+
*/
309+
mutex_lock(&sta->ampdu_mlme.mtx);
310+
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
311+
struct tid_ampdu_tx *tid_tx =
312+
rcu_dereference_protected_tid_tx(sta, i);
313+
314+
if (!tid_tx)
315+
continue;
316+
317+
if (test_and_clear_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state))
318+
ieee80211_stop_tx_ba_cb(sta, i, tid_tx);
319+
}
320+
mutex_unlock(&sta->ampdu_mlme.mtx);
303321
}
304322

305323
void ieee80211_ba_session_work(struct work_struct *work)
@@ -333,9 +351,9 @@ void ieee80211_ba_session_work(struct work_struct *work)
333351

334352
if (test_and_clear_bit(tid,
335353
sta->ampdu_mlme.tid_rx_manage_offl))
336-
__ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid,
337-
IEEE80211_MAX_AMPDU_BUF,
338-
false, true);
354+
___ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid,
355+
IEEE80211_MAX_AMPDU_BUF,
356+
false, true);
339357

340358
if (test_and_clear_bit(tid + IEEE80211_NUM_TIDS,
341359
sta->ampdu_mlme.tid_rx_manage_offl))

net/mac80211/ieee80211_i.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,6 +1760,10 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
17601760
u8 dialog_token, u16 timeout,
17611761
u16 start_seq_num, u16 ba_policy, u16 tid,
17621762
u16 buf_size, bool tx, bool auto_seq);
1763+
void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
1764+
u8 dialog_token, u16 timeout,
1765+
u16 start_seq_num, u16 ba_policy, u16 tid,
1766+
u16 buf_size, bool tx, bool auto_seq);
17631767
void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
17641768
enum ieee80211_agg_stop_reason reason);
17651769
void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,

net/mac80211/iface.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
731731
sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
732732
local->ops->wake_tx_queue) {
733733
/* XXX: for AP_VLAN, actually track AP queues */
734-
netif_tx_start_all_queues(dev);
734+
if (dev)
735+
netif_tx_start_all_queues(dev);
735736
} else if (dev) {
736737
unsigned long flags;
737738
int n_acs = IEEE80211_NUM_ACS;
@@ -792,6 +793,7 @@ static int ieee80211_open(struct net_device *dev)
792793
static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
793794
bool going_down)
794795
{
796+
struct ieee80211_sub_if_data *txq_sdata = sdata;
795797
struct ieee80211_local *local = sdata->local;
796798
struct fq *fq = &local->fq;
797799
unsigned long flags;
@@ -937,6 +939,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
937939

938940
switch (sdata->vif.type) {
939941
case NL80211_IFTYPE_AP_VLAN:
942+
txq_sdata = container_of(sdata->bss,
943+
struct ieee80211_sub_if_data, u.ap);
944+
940945
mutex_lock(&local->mtx);
941946
list_del(&sdata->u.vlan.list);
942947
mutex_unlock(&local->mtx);
@@ -1007,8 +1012,17 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
10071012
}
10081013
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
10091014

1010-
if (sdata->vif.txq) {
1011-
struct txq_info *txqi = to_txq_info(sdata->vif.txq);
1015+
if (txq_sdata->vif.txq) {
1016+
struct txq_info *txqi = to_txq_info(txq_sdata->vif.txq);
1017+
1018+
/*
1019+
* FIXME FIXME
1020+
*
1021+
* We really shouldn't purge the *entire* txqi since that
1022+
* contains frames for the other AP_VLANs (and possibly
1023+
* the AP itself) as well, but there's no API in FQ now
1024+
* to be able to filter.
1025+
*/
10121026

10131027
spin_lock_bh(&fq->lock);
10141028
ieee80211_txq_purge(local, txqi);

net/mac80211/mlme.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3155,7 +3155,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
31553155
if (len < 24 + 6)
31563156
return;
31573157

3158-
reassoc = ieee80211_is_reassoc_req(mgmt->frame_control);
3158+
reassoc = ieee80211_is_reassoc_resp(mgmt->frame_control);
31593159
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
31603160
status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
31613161
aid = le16_to_cpu(mgmt->u.assoc_resp.aid);

net/mac80211/offchannel.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
707707
if (!cookie)
708708
return -ENOENT;
709709

710+
flush_work(&local->hw_roc_start);
711+
710712
mutex_lock(&local->mtx);
711713
list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
712714
if (!mgmt_tx && roc->cookie != cookie)

net/mac80211/tx.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,11 +1276,6 @@ static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb)
12761276
IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time();
12771277
}
12781278

1279-
static void ieee80211_set_skb_vif(struct sk_buff *skb, struct txq_info *txqi)
1280-
{
1281-
IEEE80211_SKB_CB(skb)->control.vif = txqi->txq.vif;
1282-
}
1283-
12841279
static u32 codel_skb_len_func(const struct sk_buff *skb)
12851280
{
12861281
return skb->len;
@@ -3414,6 +3409,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
34143409
struct ieee80211_tx_info *info;
34153410
struct ieee80211_tx_data tx;
34163411
ieee80211_tx_result r;
3412+
struct ieee80211_vif *vif;
34173413

34183414
spin_lock_bh(&fq->lock);
34193415

@@ -3430,8 +3426,6 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
34303426
if (!skb)
34313427
goto out;
34323428

3433-
ieee80211_set_skb_vif(skb, txqi);
3434-
34353429
hdr = (struct ieee80211_hdr *)skb->data;
34363430
info = IEEE80211_SKB_CB(skb);
34373431

@@ -3488,6 +3482,34 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
34883482
}
34893483
}
34903484

3485+
switch (tx.sdata->vif.type) {
3486+
case NL80211_IFTYPE_MONITOR:
3487+
if (tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
3488+
vif = &tx.sdata->vif;
3489+
break;
3490+
}
3491+
tx.sdata = rcu_dereference(local->monitor_sdata);
3492+
if (tx.sdata) {
3493+
vif = &tx.sdata->vif;
3494+
info->hw_queue =
3495+
vif->hw_queue[skb_get_queue_mapping(skb)];
3496+
} else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
3497+
ieee80211_free_txskb(&local->hw, skb);
3498+
goto begin;
3499+
} else {
3500+
vif = NULL;
3501+
}
3502+
break;
3503+
case NL80211_IFTYPE_AP_VLAN:
3504+
tx.sdata = container_of(tx.sdata->bss,
3505+
struct ieee80211_sub_if_data, u.ap);
3506+
/* fall through */
3507+
default:
3508+
vif = &tx.sdata->vif;
3509+
break;
3510+
}
3511+
3512+
IEEE80211_SKB_CB(skb)->control.vif = vif;
34913513
out:
34923514
spin_unlock_bh(&fq->lock);
34933515

net/mac80211/util.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1436,7 +1436,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local,
14361436
WLAN_EID_SSID_LIST,
14371437
WLAN_EID_CHANNEL_USAGE,
14381438
WLAN_EID_INTERWORKING,
1439-
/* mesh ID can't happen here */
1439+
WLAN_EID_MESH_ID,
14401440
/* 60 GHz can't happen here right now */
14411441
};
14421442
noffset = ieee80211_ie_split(ie, ie_len,

net/wireless/nl80211.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3791,8 +3791,8 @@ static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
37913791
static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
37923792
{
37933793
const struct cfg80211_beacon_data *bcn = &params->beacon;
3794-
size_t ies_len = bcn->beacon_ies_len;
3795-
const u8 *ies = bcn->beacon_ies;
3794+
size_t ies_len = bcn->tail_len;
3795+
const u8 *ies = bcn->tail;
37963796
const u8 *rates;
37973797
const u8 *cap;
37983798

net/wireless/reg.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
55
* Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
66
* Copyright 2013-2014 Intel Mobile Communications GmbH
7+
* Copyright 2017 Intel Deutschland GmbH
78
*
89
* Permission to use, copy, modify, and/or distribute this software for any
910
* purpose with or without fee is hereby granted, provided that the above
@@ -1483,7 +1484,9 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy,
14831484
{
14841485
struct ieee80211_supported_band *sband = wiphy->bands[channel->band];
14851486
struct ieee80211_channel *channel_before = NULL, *channel_after = NULL;
1487+
const struct ieee80211_regdomain *regd;
14861488
unsigned int i;
1489+
u32 flags;
14871490

14881491
if (!is_ht40_allowed(channel)) {
14891492
channel->flags |= IEEE80211_CHAN_NO_HT40;
@@ -1503,17 +1506,30 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy,
15031506
channel_after = c;
15041507
}
15051508

1509+
flags = 0;
1510+
regd = get_wiphy_regdom(wiphy);
1511+
if (regd) {
1512+
const struct ieee80211_reg_rule *reg_rule =
1513+
freq_reg_info_regd(MHZ_TO_KHZ(channel->center_freq),
1514+
regd, MHZ_TO_KHZ(20));
1515+
1516+
if (!IS_ERR(reg_rule))
1517+
flags = reg_rule->flags;
1518+
}
1519+
15061520
/*
15071521
* Please note that this assumes target bandwidth is 20 MHz,
15081522
* if that ever changes we also need to change the below logic
15091523
* to include that as well.
15101524
*/
1511-
if (!is_ht40_allowed(channel_before))
1525+
if (!is_ht40_allowed(channel_before) ||
1526+
flags & NL80211_RRF_NO_HT40MINUS)
15121527
channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
15131528
else
15141529
channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
15151530

1516-
if (!is_ht40_allowed(channel_after))
1531+
if (!is_ht40_allowed(channel_after) ||
1532+
flags & NL80211_RRF_NO_HT40PLUS)
15171533
channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
15181534
else
15191535
channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;

0 commit comments

Comments
 (0)