Skip to content

Commit 30d237a

Browse files
committed
Merge tag 'mac80211-for-davem-2016-04-06' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says: ==================== For the current RC series, we have the following fixes: * TDLS fixes from Arik and Ilan * rhashtable fixes from Ben and myself * documentation fixes from Luis * U-APSD fixes from Emmanuel * a TXQ fix from Felix * and a compiler warning suppression from Jeff ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 3430284 + b4201cc commit 30d237a

File tree

9 files changed

+88
-25
lines changed

9 files changed

+88
-25
lines changed

include/net/mac80211.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
10011001
* flag indicates that the PN was verified for replay protection.
10021002
* Note that this flag is also currently only supported when a frame
10031003
* is also decrypted (ie. @RX_FLAG_DECRYPTED must be set)
1004+
* @RX_FLAG_DUP_VALIDATED: The driver should set this flag if it did
1005+
* de-duplication by itself.
10041006
* @RX_FLAG_FAILED_FCS_CRC: Set this flag if the FCS check failed on
10051007
* the frame.
10061008
* @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on

net/mac80211/chan.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,10 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
343343
struct ieee80211_chanctx *ctx,
344344
const struct cfg80211_chan_def *chandef)
345345
{
346-
if (cfg80211_chandef_identical(&ctx->conf.def, chandef))
346+
if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) {
347+
ieee80211_recalc_chanctx_min_def(local, ctx);
347348
return;
349+
}
348350

349351
WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
350352

net/mac80211/ieee80211_i.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,6 +1719,10 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
17191719
enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta);
17201720
enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta);
17211721
void ieee80211_sta_set_rx_nss(struct sta_info *sta);
1722+
enum ieee80211_sta_rx_bandwidth
1723+
ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width);
1724+
enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta);
1725+
void ieee80211_sta_set_rx_nss(struct sta_info *sta);
17221726
void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata,
17231727
struct ieee80211_mgmt *mgmt);
17241728
u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,

net/mac80211/mesh_hwmp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
530530
const u8 *target_addr, *orig_addr;
531531
const u8 *da;
532532
u8 target_flags, ttl, flags;
533-
u32 orig_sn, target_sn, lifetime, target_metric;
533+
u32 orig_sn, target_sn, lifetime, target_metric = 0;
534534
bool reply = false;
535535
bool forward = true;
536536
bool root_is_gate;

net/mac80211/sta_info.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767

6868
static const struct rhashtable_params sta_rht_params = {
6969
.nelem_hint = 3, /* start small */
70+
.insecure_elasticity = true, /* Disable chain-length checks. */
7071
.automatic_shrinking = true,
7172
.head_offset = offsetof(struct sta_info, hash_node),
7273
.key_offset = offsetof(struct sta_info, addr),
@@ -258,11 +259,11 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
258259
}
259260

260261
/* Caller must hold local->sta_mtx */
261-
static void sta_info_hash_add(struct ieee80211_local *local,
262-
struct sta_info *sta)
262+
static int sta_info_hash_add(struct ieee80211_local *local,
263+
struct sta_info *sta)
263264
{
264-
rhashtable_insert_fast(&local->sta_hash, &sta->hash_node,
265-
sta_rht_params);
265+
return rhashtable_insert_fast(&local->sta_hash, &sta->hash_node,
266+
sta_rht_params);
266267
}
267268

268269
static void sta_deliver_ps_frames(struct work_struct *wk)
@@ -524,7 +525,9 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
524525
set_sta_flag(sta, WLAN_STA_BLOCK_BA);
525526

526527
/* make the station visible */
527-
sta_info_hash_add(local, sta);
528+
err = sta_info_hash_add(local, sta);
529+
if (err)
530+
goto out_drop_sta;
528531

529532
list_add_tail_rcu(&sta->list, &local->sta_list);
530533

@@ -557,6 +560,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
557560
out_remove:
558561
sta_info_hash_del(local, sta);
559562
list_del_rcu(&sta->list);
563+
out_drop_sta:
560564
local->num_sta--;
561565
synchronize_net();
562566
__cleanup_single_sta(sta);

net/mac80211/sta_info.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,6 @@ DECLARE_EWMA(signal, 1024, 8)
377377
* @uploaded: set to true when sta is uploaded to the driver
378378
* @sta: station information we share with the driver
379379
* @sta_state: duplicates information about station state (for debug)
380-
* @beacon_loss_count: number of times beacon loss has triggered
381380
* @rcu_head: RCU head used for freeing this station struct
382381
* @cur_max_bandwidth: maximum bandwidth to use for TX to the station,
383382
* taken from HT/VHT capabilities or VHT operating mode notification

net/mac80211/tdls.c

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
55
* Copyright 2014, Intel Corporation
66
* Copyright 2014 Intel Mobile Communications GmbH
7-
* Copyright 2015 Intel Deutschland GmbH
7+
* Copyright 2015 - 2016 Intel Deutschland GmbH
88
*
99
* This file is GPLv2 as found in COPYING.
1010
*/
@@ -15,6 +15,7 @@
1515
#include <linux/rtnetlink.h>
1616
#include "ieee80211_i.h"
1717
#include "driver-ops.h"
18+
#include "rate.h"
1819

1920
/* give usermode some time for retries in setting up the TDLS session */
2021
#define TDLS_PEER_SETUP_TIMEOUT (15 * HZ)
@@ -302,7 +303,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata,
302303
/* IEEE802.11ac-2013 Table E-4 */
303304
u16 centers_80mhz[] = { 5210, 5290, 5530, 5610, 5690, 5775 };
304305
struct cfg80211_chan_def uc = sta->tdls_chandef;
305-
enum nl80211_chan_width max_width = ieee80211_get_sta_bw(&sta->sta);
306+
enum nl80211_chan_width max_width = ieee80211_sta_cap_chan_bw(sta);
306307
int i;
307308

308309
/* only support upgrading non-narrow channels up to 80Mhz */
@@ -313,7 +314,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata,
313314
if (max_width > NL80211_CHAN_WIDTH_80)
314315
max_width = NL80211_CHAN_WIDTH_80;
315316

316-
if (uc.width == max_width)
317+
if (uc.width >= max_width)
317318
return;
318319
/*
319320
* Channel usage constrains in the IEEE802.11ac-2013 specification only
@@ -324,6 +325,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata,
324325
for (i = 0; i < ARRAY_SIZE(centers_80mhz); i++)
325326
if (abs(uc.chan->center_freq - centers_80mhz[i]) <= 30) {
326327
uc.center_freq1 = centers_80mhz[i];
328+
uc.center_freq2 = 0;
327329
uc.width = NL80211_CHAN_WIDTH_80;
328330
break;
329331
}
@@ -332,7 +334,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata,
332334
return;
333335

334336
/* proceed to downgrade the chandef until usable or the same */
335-
while (uc.width > max_width &&
337+
while (uc.width > max_width ||
336338
!cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc,
337339
sdata->wdev.iftype))
338340
ieee80211_chandef_downgrade(&uc);
@@ -1242,18 +1244,44 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12421244
return ret;
12431245
}
12441246

1245-
static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata)
1247+
static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata,
1248+
struct sta_info *sta)
12461249
{
12471250
struct ieee80211_local *local = sdata->local;
12481251
struct ieee80211_chanctx_conf *conf;
12491252
struct ieee80211_chanctx *ctx;
1253+
enum nl80211_chan_width width;
1254+
struct ieee80211_supported_band *sband;
12501255

12511256
mutex_lock(&local->chanctx_mtx);
12521257
conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
12531258
lockdep_is_held(&local->chanctx_mtx));
12541259
if (conf) {
1260+
width = conf->def.width;
1261+
sband = local->hw.wiphy->bands[conf->def.chan->band];
12551262
ctx = container_of(conf, struct ieee80211_chanctx, conf);
12561263
ieee80211_recalc_chanctx_chantype(local, ctx);
1264+
1265+
/* if width changed and a peer is given, update its BW */
1266+
if (width != conf->def.width && sta &&
1267+
test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW)) {
1268+
enum ieee80211_sta_rx_bandwidth bw;
1269+
1270+
bw = ieee80211_chan_width_to_rx_bw(conf->def.width);
1271+
bw = min(bw, ieee80211_sta_cap_rx_bw(sta));
1272+
if (bw != sta->sta.bandwidth) {
1273+
sta->sta.bandwidth = bw;
1274+
rate_control_rate_update(local, sband, sta,
1275+
IEEE80211_RC_BW_CHANGED);
1276+
/*
1277+
* if a TDLS peer BW was updated, we need to
1278+
* recalc the chandef width again, to get the
1279+
* correct chanctx min_def
1280+
*/
1281+
ieee80211_recalc_chanctx_chantype(local, ctx);
1282+
}
1283+
}
1284+
12571285
}
12581286
mutex_unlock(&local->chanctx_mtx);
12591287
}
@@ -1350,8 +1378,6 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13501378
break;
13511379
}
13521380

1353-
iee80211_tdls_recalc_chanctx(sdata);
1354-
13551381
mutex_lock(&local->sta_mtx);
13561382
sta = sta_info_get(sdata, peer);
13571383
if (!sta) {
@@ -1360,6 +1386,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13601386
break;
13611387
}
13621388

1389+
iee80211_tdls_recalc_chanctx(sdata, sta);
13631390
iee80211_tdls_recalc_ht_protection(sdata, sta);
13641391

13651392
set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
@@ -1390,7 +1417,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13901417
iee80211_tdls_recalc_ht_protection(sdata, NULL);
13911418
mutex_unlock(&local->sta_mtx);
13921419

1393-
iee80211_tdls_recalc_chanctx(sdata);
1420+
iee80211_tdls_recalc_chanctx(sdata, NULL);
13941421
break;
13951422
default:
13961423
ret = -ENOTSUPP;

net/mac80211/tx.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,11 +1116,15 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
11161116
reset_agg_timer = true;
11171117
} else {
11181118
queued = true;
1119+
if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) {
1120+
clear_sta_flag(tx->sta, WLAN_STA_SP);
1121+
ps_dbg(tx->sta->sdata,
1122+
"STA %pM aid %d: SP frame queued, close the SP w/o telling the peer\n",
1123+
tx->sta->sta.addr, tx->sta->sta.aid);
1124+
}
11191125
info->control.vif = &tx->sdata->vif;
11201126
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1121-
info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS |
1122-
IEEE80211_TX_CTL_NO_PS_BUFFER |
1123-
IEEE80211_TX_STATUS_EOSP;
1127+
info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
11241128
__skb_queue_tail(&tid_tx->pending, skb);
11251129
if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER)
11261130
purge_skb = __skb_dequeue(&tid_tx->pending);
@@ -1247,7 +1251,8 @@ static void ieee80211_drv_tx(struct ieee80211_local *local,
12471251
struct txq_info *txqi;
12481252
u8 ac;
12491253

1250-
if (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)
1254+
if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) ||
1255+
(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE))
12511256
goto tx_normal;
12521257

12531258
if (!ieee80211_is_data(hdr->frame_control))

net/mac80211/vht.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,30 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta)
319319
return IEEE80211_STA_RX_BW_80;
320320
}
321321

322-
static enum ieee80211_sta_rx_bandwidth
322+
enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta)
323+
{
324+
struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
325+
u32 cap_width;
326+
327+
if (!vht_cap->vht_supported) {
328+
if (!sta->sta.ht_cap.ht_supported)
329+
return NL80211_CHAN_WIDTH_20_NOHT;
330+
331+
return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
332+
NL80211_CHAN_WIDTH_40 : NL80211_CHAN_WIDTH_20;
333+
}
334+
335+
cap_width = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
336+
337+
if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)
338+
return NL80211_CHAN_WIDTH_160;
339+
else if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
340+
return NL80211_CHAN_WIDTH_80P80;
341+
342+
return NL80211_CHAN_WIDTH_80;
343+
}
344+
345+
enum ieee80211_sta_rx_bandwidth
323346
ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width)
324347
{
325348
switch (width) {
@@ -347,10 +370,7 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta)
347370

348371
bw = ieee80211_sta_cap_rx_bw(sta);
349372
bw = min(bw, sta->cur_max_bandwidth);
350-
351-
/* do not cap the BW of TDLS WIDER_BW peers by the bss */
352-
if (!test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW))
353-
bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));
373+
bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));
354374

355375
return bw;
356376
}

0 commit comments

Comments
 (0)