aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/Kconfig18
-rw-r--r--net/mac80211/Makefile3
-rw-r--r--net/mac80211/agg-tx.c5
-rw-r--r--net/mac80211/cfg.c178
-rw-r--r--net/mac80211/chan.c5
-rw-r--r--net/mac80211/debug.h10
-rw-r--r--net/mac80211/debugfs_key.c12
-rw-r--r--net/mac80211/driver-ops.h74
-rw-r--r--net/mac80211/ieee80211_i.h80
-rw-r--r--net/mac80211/iface.c30
-rw-r--r--net/mac80211/key.c11
-rw-r--r--net/mac80211/main.c38
-rw-r--r--net/mac80211/mesh.h3
-rw-r--r--net/mac80211/mesh_pathtbl.c31
-rw-r--r--net/mac80211/mlme.c281
-rw-r--r--net/mac80211/ocb.c250
-rw-r--r--net/mac80211/rc80211_minstrel.c2
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c313
-rw-r--r--net/mac80211/rc80211_minstrel_ht.h40
-rw-r--r--net/mac80211/rc80211_minstrel_ht_debugfs.c43
-rw-r--r--net/mac80211/rx.c35
-rw-r--r--net/mac80211/sta_info.c4
-rw-r--r--net/mac80211/status.c3
-rw-r--r--net/mac80211/tdls.c8
-rw-r--r--net/mac80211/trace.h100
-rw-r--r--net/mac80211/tx.c15
-rw-r--r--net/mac80211/util.c132
-rw-r--r--net/mac80211/wep.c2
-rw-r--r--net/mac80211/wme.c33
-rw-r--r--net/mac80211/wme.h2
-rw-r--r--net/mac80211/wpa.c5
31 files changed, 1511 insertions, 255 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index aeb6a483b3bc..75cc6801a431 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -33,6 +33,13 @@ config MAC80211_RC_MINSTREL_HT
33 ---help--- 33 ---help---
34 This option enables the 'minstrel_ht' TX rate control algorithm 34 This option enables the 'minstrel_ht' TX rate control algorithm
35 35
36config MAC80211_RC_MINSTREL_VHT
37 bool "Minstrel 802.11ac support" if EXPERT
38 depends on MAC80211_RC_MINSTREL_HT
39 default n
40 ---help---
41 This option enables VHT in the 'minstrel_ht' TX rate control algorithm
42
36choice 43choice
37 prompt "Default rate control algorithm" 44 prompt "Default rate control algorithm"
38 depends on MAC80211_HAS_RC 45 depends on MAC80211_HAS_RC
@@ -169,6 +176,17 @@ config MAC80211_HT_DEBUG
169 176
170 Do not select this option. 177 Do not select this option.
171 178
179config MAC80211_OCB_DEBUG
180 bool "Verbose OCB debugging"
181 depends on MAC80211_DEBUG_MENU
182 ---help---
183 Selecting this option causes mac80211 to print out
184 very verbose OCB debugging messages. It should not
185 be selected on production systems as those messages
186 are remotely triggerable.
187
188 Do not select this option.
189
172config MAC80211_IBSS_DEBUG 190config MAC80211_IBSS_DEBUG
173 bool "Verbose IBSS debugging" 191 bool "Verbose IBSS debugging"
174 depends on MAC80211_DEBUG_MENU 192 depends on MAC80211_DEBUG_MENU
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 7273d2796dd1..e53671b1105e 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -27,7 +27,8 @@ mac80211-y := \
27 event.o \ 27 event.o \
28 chan.o \ 28 chan.o \
29 trace.o mlme.o \ 29 trace.o mlme.o \
30 tdls.o 30 tdls.o \
31 ocb.o
31 32
32mac80211-$(CONFIG_MAC80211_LEDS) += led.o 33mac80211-$(CONFIG_MAC80211_LEDS) += led.o
33mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ 34mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index d6986f3aa5c4..9242c60048cf 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -149,11 +149,6 @@ void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
149 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx); 149 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx);
150} 150}
151 151
152static inline int ieee80211_ac_from_tid(int tid)
153{
154 return ieee802_1d_to_ac[tid & 7];
155}
156
157/* 152/*
158 * When multiple aggregation sessions on multiple stations 153 * When multiple aggregation sessions on multiple stations
159 * are being created/destroyed simultaneously, we need to 154 * are being created/destroyed simultaneously, we need to
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 343da1e35025..06185940cbb6 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -20,6 +20,7 @@
20#include "cfg.h" 20#include "cfg.h"
21#include "rate.h" 21#include "rate.h"
22#include "mesh.h" 22#include "mesh.h"
23#include "wme.h"
23 24
24static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, 25static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
25 const char *name, 26 const char *name,
@@ -190,7 +191,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
190 * receive the key. When wpa_supplicant has roamed 191 * receive the key. When wpa_supplicant has roamed
191 * using FT, it attempts to set the key before 192 * using FT, it attempts to set the key before
192 * association has completed, this rejects that attempt 193 * association has completed, this rejects that attempt
193 * so it will set the key again after assocation. 194 * so it will set the key again after association.
194 * 195 *
195 * TODO: accept the key if we have a station entry and 196 * TODO: accept the key if we have a station entry and
196 * add it to the device after the station. 197 * add it to the device after the station.
@@ -229,6 +230,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
229 case NUM_NL80211_IFTYPES: 230 case NUM_NL80211_IFTYPES:
230 case NL80211_IFTYPE_P2P_CLIENT: 231 case NL80211_IFTYPE_P2P_CLIENT:
231 case NL80211_IFTYPE_P2P_GO: 232 case NL80211_IFTYPE_P2P_GO:
233 case NL80211_IFTYPE_OCB:
232 /* shouldn't happen */ 234 /* shouldn't happen */
233 WARN_ON_ONCE(1); 235 WARN_ON_ONCE(1);
234 break; 236 break;
@@ -1225,14 +1227,14 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
1225} 1227}
1226 1228
1227static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, 1229static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
1228 const u8 *mac) 1230 struct station_del_parameters *params)
1229{ 1231{
1230 struct ieee80211_sub_if_data *sdata; 1232 struct ieee80211_sub_if_data *sdata;
1231 1233
1232 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1234 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1233 1235
1234 if (mac) 1236 if (params->mac)
1235 return sta_info_destroy_addr_bss(sdata, mac); 1237 return sta_info_destroy_addr_bss(sdata, params->mac);
1236 1238
1237 sta_info_flush(sdata); 1239 sta_info_flush(sdata);
1238 return 0; 1240 return 0;
@@ -1516,6 +1518,57 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
1516 return 0; 1518 return 0;
1517} 1519}
1518 1520
1521static void mpp_set_pinfo(struct mesh_path *mpath, u8 *mpp,
1522 struct mpath_info *pinfo)
1523{
1524 memset(pinfo, 0, sizeof(*pinfo));
1525 memcpy(mpp, mpath->mpp, ETH_ALEN);
1526
1527 pinfo->generation = mpp_paths_generation;
1528}
1529
1530static int ieee80211_get_mpp(struct wiphy *wiphy, struct net_device *dev,
1531 u8 *dst, u8 *mpp, struct mpath_info *pinfo)
1532
1533{
1534 struct ieee80211_sub_if_data *sdata;
1535 struct mesh_path *mpath;
1536
1537 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1538
1539 rcu_read_lock();
1540 mpath = mpp_path_lookup(sdata, dst);
1541 if (!mpath) {
1542 rcu_read_unlock();
1543 return -ENOENT;
1544 }
1545 memcpy(dst, mpath->dst, ETH_ALEN);
1546 mpp_set_pinfo(mpath, mpp, pinfo);
1547 rcu_read_unlock();
1548 return 0;
1549}
1550
1551static int ieee80211_dump_mpp(struct wiphy *wiphy, struct net_device *dev,
1552 int idx, u8 *dst, u8 *mpp,
1553 struct mpath_info *pinfo)
1554{
1555 struct ieee80211_sub_if_data *sdata;
1556 struct mesh_path *mpath;
1557
1558 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1559
1560 rcu_read_lock();
1561 mpath = mpp_path_lookup_by_idx(sdata, idx);
1562 if (!mpath) {
1563 rcu_read_unlock();
1564 return -ENOENT;
1565 }
1566 memcpy(dst, mpath->dst, ETH_ALEN);
1567 mpp_set_pinfo(mpath, mpp, pinfo);
1568 rcu_read_unlock();
1569 return 0;
1570}
1571
1519static int ieee80211_get_mesh_config(struct wiphy *wiphy, 1572static int ieee80211_get_mesh_config(struct wiphy *wiphy,
1520 struct net_device *dev, 1573 struct net_device *dev,
1521 struct mesh_config *conf) 1574 struct mesh_config *conf)
@@ -1966,6 +2019,17 @@ static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1966 return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev)); 2019 return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev));
1967} 2020}
1968 2021
2022static int ieee80211_join_ocb(struct wiphy *wiphy, struct net_device *dev,
2023 struct ocb_setup *setup)
2024{
2025 return ieee80211_ocb_join(IEEE80211_DEV_TO_SUB_IF(dev), setup);
2026}
2027
2028static int ieee80211_leave_ocb(struct wiphy *wiphy, struct net_device *dev)
2029{
2030 return ieee80211_ocb_leave(IEEE80211_DEV_TO_SUB_IF(dev));
2031}
2032
1969static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev, 2033static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev,
1970 int rate[IEEE80211_NUM_BANDS]) 2034 int rate[IEEE80211_NUM_BANDS])
1971{ 2035{
@@ -2081,6 +2145,9 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy,
2081 struct ieee80211_local *local = wiphy_priv(wiphy); 2145 struct ieee80211_local *local = wiphy_priv(wiphy);
2082 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 2146 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2083 2147
2148 if (local->ops->get_txpower)
2149 return drv_get_txpower(local, sdata, dbm);
2150
2084 if (!local->use_chanctx) 2151 if (!local->use_chanctx)
2085 *dbm = local->hw.conf.power_level; 2152 *dbm = local->hw.conf.power_level;
2086 else 2153 else
@@ -2850,11 +2917,7 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
2850 if (sdata->reserved_ready) 2917 if (sdata->reserved_ready)
2851 return 0; 2918 return 0;
2852 2919
2853 err = ieee80211_vif_use_reserved_context(sdata); 2920 return ieee80211_vif_use_reserved_context(sdata);
2854 if (err)
2855 return err;
2856
2857 return 0;
2858 } 2921 }
2859 2922
2860 if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef, 2923 if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef,
@@ -2868,7 +2931,6 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
2868 return err; 2931 return err;
2869 2932
2870 ieee80211_bss_info_change_notify(sdata, changed); 2933 ieee80211_bss_info_change_notify(sdata, changed);
2871 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
2872 2934
2873 if (sdata->csa_block_tx) { 2935 if (sdata->csa_block_tx) {
2874 ieee80211_wake_vif_queues(local, sdata, 2936 ieee80211_wake_vif_queues(local, sdata,
@@ -2876,6 +2938,12 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
2876 sdata->csa_block_tx = false; 2938 sdata->csa_block_tx = false;
2877 } 2939 }
2878 2940
2941 err = drv_post_channel_switch(sdata);
2942 if (err)
2943 return err;
2944
2945 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
2946
2879 return 0; 2947 return 0;
2880} 2948}
2881 2949
@@ -3053,9 +3121,11 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3053{ 3121{
3054 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3122 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3055 struct ieee80211_local *local = sdata->local; 3123 struct ieee80211_local *local = sdata->local;
3124 struct ieee80211_channel_switch ch_switch;
3056 struct ieee80211_chanctx_conf *conf; 3125 struct ieee80211_chanctx_conf *conf;
3057 struct ieee80211_chanctx *chanctx; 3126 struct ieee80211_chanctx *chanctx;
3058 int err, changed = 0; 3127 u32 changed = 0;
3128 int err;
3059 3129
3060 sdata_assert_lock(sdata); 3130 sdata_assert_lock(sdata);
3061 lockdep_assert_held(&local->mtx); 3131 lockdep_assert_held(&local->mtx);
@@ -3088,6 +3158,10 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3088 goto out; 3158 goto out;
3089 } 3159 }
3090 3160
3161 err = drv_pre_channel_switch(sdata, &ch_switch);
3162 if (err)
3163 goto out;
3164
3091 err = ieee80211_vif_reserve_chanctx(sdata, &params->chandef, 3165 err = ieee80211_vif_reserve_chanctx(sdata, &params->chandef,
3092 chanctx->mode, 3166 chanctx->mode,
3093 params->radar_required); 3167 params->radar_required);
@@ -3101,6 +3175,12 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3101 goto out; 3175 goto out;
3102 } 3176 }
3103 3177
3178 ch_switch.timestamp = 0;
3179 ch_switch.device_timestamp = 0;
3180 ch_switch.block_tx = params->block_tx;
3181 ch_switch.chandef = params->chandef;
3182 ch_switch.count = params->count;
3183
3104 err = ieee80211_set_csa_beacon(sdata, params, &changed); 3184 err = ieee80211_set_csa_beacon(sdata, params, &changed);
3105 if (err) { 3185 if (err) {
3106 ieee80211_vif_unreserve_chanctx(sdata); 3186 ieee80211_vif_unreserve_chanctx(sdata);
@@ -3521,6 +3601,76 @@ static int ieee80211_set_ap_chanwidth(struct wiphy *wiphy,
3521 return ret; 3601 return ret;
3522} 3602}
3523 3603
3604static int ieee80211_add_tx_ts(struct wiphy *wiphy, struct net_device *dev,
3605 u8 tsid, const u8 *peer, u8 up,
3606 u16 admitted_time)
3607{
3608 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3609 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3610 int ac = ieee802_1d_to_ac[up];
3611
3612 if (sdata->vif.type != NL80211_IFTYPE_STATION)
3613 return -EOPNOTSUPP;
3614
3615 if (!(sdata->wmm_acm & BIT(up)))
3616 return -EINVAL;
3617
3618 if (ifmgd->tx_tspec[ac].admitted_time)
3619 return -EBUSY;
3620
3621 if (admitted_time) {
3622 ifmgd->tx_tspec[ac].admitted_time = 32 * admitted_time;
3623 ifmgd->tx_tspec[ac].tsid = tsid;
3624 ifmgd->tx_tspec[ac].up = up;
3625 }
3626
3627 return 0;
3628}
3629
3630static int ieee80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev,
3631 u8 tsid, const u8 *peer)
3632{
3633 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3634 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3635 struct ieee80211_local *local = wiphy_priv(wiphy);
3636 int ac;
3637
3638 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
3639 struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
3640
3641 /* skip unused entries */
3642 if (!tx_tspec->admitted_time)
3643 continue;
3644
3645 if (tx_tspec->tsid != tsid)
3646 continue;
3647
3648 /* due to this new packets will be reassigned to non-ACM ACs */
3649 tx_tspec->up = -1;
3650
3651 /* Make sure that all packets have been sent to avoid to
3652 * restore the QoS params on packets that are still on the
3653 * queues.
3654 */
3655 synchronize_net();
3656 ieee80211_flush_queues(local, sdata);
3657
3658 /* restore the normal QoS parameters
3659 * (unconditionally to avoid races)
3660 */
3661 tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE;
3662 tx_tspec->downgraded = false;
3663 ieee80211_sta_handle_tspec_ac_params(sdata);
3664
3665 /* finally clear all the data */
3666 memset(tx_tspec, 0, sizeof(*tx_tspec));
3667
3668 return 0;
3669 }
3670
3671 return -ENOENT;
3672}
3673
3524const struct cfg80211_ops mac80211_config_ops = { 3674const struct cfg80211_ops mac80211_config_ops = {
3525 .add_virtual_intf = ieee80211_add_iface, 3675 .add_virtual_intf = ieee80211_add_iface,
3526 .del_virtual_intf = ieee80211_del_iface, 3676 .del_virtual_intf = ieee80211_del_iface,
@@ -3547,11 +3697,15 @@ const struct cfg80211_ops mac80211_config_ops = {
3547 .change_mpath = ieee80211_change_mpath, 3697 .change_mpath = ieee80211_change_mpath,
3548 .get_mpath = ieee80211_get_mpath, 3698 .get_mpath = ieee80211_get_mpath,
3549 .dump_mpath = ieee80211_dump_mpath, 3699 .dump_mpath = ieee80211_dump_mpath,
3700 .get_mpp = ieee80211_get_mpp,
3701 .dump_mpp = ieee80211_dump_mpp,
3550 .update_mesh_config = ieee80211_update_mesh_config, 3702 .update_mesh_config = ieee80211_update_mesh_config,
3551 .get_mesh_config = ieee80211_get_mesh_config, 3703 .get_mesh_config = ieee80211_get_mesh_config,
3552 .join_mesh = ieee80211_join_mesh, 3704 .join_mesh = ieee80211_join_mesh,
3553 .leave_mesh = ieee80211_leave_mesh, 3705 .leave_mesh = ieee80211_leave_mesh,
3554#endif 3706#endif
3707 .join_ocb = ieee80211_join_ocb,
3708 .leave_ocb = ieee80211_leave_ocb,
3555 .change_bss = ieee80211_change_bss, 3709 .change_bss = ieee80211_change_bss,
3556 .set_txq_params = ieee80211_set_txq_params, 3710 .set_txq_params = ieee80211_set_txq_params,
3557 .set_monitor_channel = ieee80211_set_monitor_channel, 3711 .set_monitor_channel = ieee80211_set_monitor_channel,
@@ -3597,4 +3751,6 @@ const struct cfg80211_ops mac80211_config_ops = {
3597 .channel_switch = ieee80211_channel_switch, 3751 .channel_switch = ieee80211_channel_switch,
3598 .set_qos_map = ieee80211_set_qos_map, 3752 .set_qos_map = ieee80211_set_qos_map,
3599 .set_ap_chanwidth = ieee80211_set_ap_chanwidth, 3753 .set_ap_chanwidth = ieee80211_set_ap_chanwidth,
3754 .add_tx_ts = ieee80211_add_tx_ts,
3755 .del_tx_ts = ieee80211_del_tx_ts,
3600}; 3756};
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 4c74e8da64b9..c7c514220298 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -270,6 +270,7 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
270 case NL80211_IFTYPE_ADHOC: 270 case NL80211_IFTYPE_ADHOC:
271 case NL80211_IFTYPE_WDS: 271 case NL80211_IFTYPE_WDS:
272 case NL80211_IFTYPE_MESH_POINT: 272 case NL80211_IFTYPE_MESH_POINT:
273 case NL80211_IFTYPE_OCB:
273 width = vif->bss_conf.chandef.width; 274 width = vif->bss_conf.chandef.width;
274 break; 275 break;
275 case NL80211_IFTYPE_UNSPECIFIED: 276 case NL80211_IFTYPE_UNSPECIFIED:
@@ -674,6 +675,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
674 case NL80211_IFTYPE_ADHOC: 675 case NL80211_IFTYPE_ADHOC:
675 case NL80211_IFTYPE_WDS: 676 case NL80211_IFTYPE_WDS:
676 case NL80211_IFTYPE_MESH_POINT: 677 case NL80211_IFTYPE_MESH_POINT:
678 case NL80211_IFTYPE_OCB:
677 break; 679 break;
678 default: 680 default:
679 WARN_ON_ONCE(1); 681 WARN_ON_ONCE(1);
@@ -909,6 +911,7 @@ ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata)
909 case NL80211_IFTYPE_ADHOC: 911 case NL80211_IFTYPE_ADHOC:
910 case NL80211_IFTYPE_AP: 912 case NL80211_IFTYPE_AP:
911 case NL80211_IFTYPE_MESH_POINT: 913 case NL80211_IFTYPE_MESH_POINT:
914 case NL80211_IFTYPE_OCB:
912 ieee80211_queue_work(&sdata->local->hw, 915 ieee80211_queue_work(&sdata->local->hw,
913 &sdata->csa_finalize_work); 916 &sdata->csa_finalize_work);
914 break; 917 break;
@@ -1634,7 +1637,7 @@ int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1634 } 1637 }
1635 break; 1638 break;
1636 case IEEE80211_CHANCTX_WILL_BE_REPLACED: 1639 case IEEE80211_CHANCTX_WILL_BE_REPLACED:
1637 /* TODO: Perhaps the bandwith change could be treated as a 1640 /* TODO: Perhaps the bandwidth change could be treated as a
1638 * reservation itself? */ 1641 * reservation itself? */
1639 ret = -EBUSY; 1642 ret = -EBUSY;
1640 goto out; 1643 goto out;
diff --git a/net/mac80211/debug.h b/net/mac80211/debug.h
index 493d68061f0c..1956b3115dd5 100644
--- a/net/mac80211/debug.h
+++ b/net/mac80211/debug.h
@@ -2,6 +2,12 @@
2#define __MAC80211_DEBUG_H 2#define __MAC80211_DEBUG_H
3#include <net/cfg80211.h> 3#include <net/cfg80211.h>
4 4
5#ifdef CONFIG_MAC80211_OCB_DEBUG
6#define MAC80211_OCB_DEBUG 1
7#else
8#define MAC80211_OCB_DEBUG 0
9#endif
10
5#ifdef CONFIG_MAC80211_IBSS_DEBUG 11#ifdef CONFIG_MAC80211_IBSS_DEBUG
6#define MAC80211_IBSS_DEBUG 1 12#define MAC80211_IBSS_DEBUG 1
7#else 13#else
@@ -131,6 +137,10 @@ do { \
131 _sdata_dbg(MAC80211_HT_DEBUG && net_ratelimit(), \ 137 _sdata_dbg(MAC80211_HT_DEBUG && net_ratelimit(), \
132 sdata, fmt, ##__VA_ARGS__) 138 sdata, fmt, ##__VA_ARGS__)
133 139
140#define ocb_dbg(sdata, fmt, ...) \
141 _sdata_dbg(MAC80211_OCB_DEBUG, \
142 sdata, fmt, ##__VA_ARGS__)
143
134#define ibss_dbg(sdata, fmt, ...) \ 144#define ibss_dbg(sdata, fmt, ...) \
135 _sdata_dbg(MAC80211_IBSS_DEBUG, \ 145 _sdata_dbg(MAC80211_IBSS_DEBUG, \
136 sdata, fmt, ##__VA_ARGS__) 146 sdata, fmt, ##__VA_ARGS__)
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 1521cabad3d6..5523b94c7c90 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -300,10 +300,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
300 300
301 lockdep_assert_held(&sdata->local->key_mtx); 301 lockdep_assert_held(&sdata->local->key_mtx);
302 302
303 if (sdata->debugfs.default_unicast_key) { 303 debugfs_remove(sdata->debugfs.default_unicast_key);
304 debugfs_remove(sdata->debugfs.default_unicast_key); 304 sdata->debugfs.default_unicast_key = NULL;
305 sdata->debugfs.default_unicast_key = NULL;
306 }
307 305
308 if (sdata->default_unicast_key) { 306 if (sdata->default_unicast_key) {
309 key = key_mtx_dereference(sdata->local, 307 key = key_mtx_dereference(sdata->local,
@@ -314,10 +312,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
314 sdata->vif.debugfs_dir, buf); 312 sdata->vif.debugfs_dir, buf);
315 } 313 }
316 314
317 if (sdata->debugfs.default_multicast_key) { 315 debugfs_remove(sdata->debugfs.default_multicast_key);
318 debugfs_remove(sdata->debugfs.default_multicast_key); 316 sdata->debugfs.default_multicast_key = NULL;
319 sdata->debugfs.default_multicast_key = NULL;
320 }
321 317
322 if (sdata->default_multicast_key) { 318 if (sdata->default_multicast_key) {
323 key = key_mtx_dereference(sdata->local, 319 key = key_mtx_dereference(sdata->local,
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 196d48c68134..9759dd1f0734 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -214,7 +214,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
214 BSS_CHANGED_BEACON_ENABLED) && 214 BSS_CHANGED_BEACON_ENABLED) &&
215 sdata->vif.type != NL80211_IFTYPE_AP && 215 sdata->vif.type != NL80211_IFTYPE_AP &&
216 sdata->vif.type != NL80211_IFTYPE_ADHOC && 216 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
217 sdata->vif.type != NL80211_IFTYPE_MESH_POINT)) 217 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
218 sdata->vif.type != NL80211_IFTYPE_OCB))
218 return; 219 return;
219 220
220 if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || 221 if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
@@ -631,6 +632,12 @@ static inline int drv_conf_tx(struct ieee80211_local *local,
631 if (!check_sdata_in_driver(sdata)) 632 if (!check_sdata_in_driver(sdata))
632 return -EIO; 633 return -EIO;
633 634
635 if (WARN_ONCE(params->cw_min == 0 ||
636 params->cw_min > params->cw_max,
637 "%s: invalid CW_min/CW_max: %d/%d\n",
638 sdata->name, params->cw_min, params->cw_max))
639 return -EINVAL;
640
634 trace_drv_conf_tx(local, sdata, ac, params); 641 trace_drv_conf_tx(local, sdata, ac, params);
635 if (local->ops->conf_tx) 642 if (local->ops->conf_tx)
636 ret = local->ops->conf_tx(&local->hw, &sdata->vif, 643 ret = local->ops->conf_tx(&local->hw, &sdata->vif,
@@ -764,12 +771,13 @@ static inline void drv_flush(struct ieee80211_local *local,
764} 771}
765 772
766static inline void drv_channel_switch(struct ieee80211_local *local, 773static inline void drv_channel_switch(struct ieee80211_local *local,
767 struct ieee80211_channel_switch *ch_switch) 774 struct ieee80211_sub_if_data *sdata,
775 struct ieee80211_channel_switch *ch_switch)
768{ 776{
769 might_sleep(); 777 might_sleep();
770 778
771 trace_drv_channel_switch(local, ch_switch); 779 trace_drv_channel_switch(local, sdata, ch_switch);
772 local->ops->channel_switch(&local->hw, ch_switch); 780 local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch);
773 trace_drv_return_void(local); 781 trace_drv_return_void(local);
774} 782}
775 783
@@ -1144,13 +1152,15 @@ static inline void drv_stop_ap(struct ieee80211_local *local,
1144 trace_drv_return_void(local); 1152 trace_drv_return_void(local);
1145} 1153}
1146 1154
1147static inline void drv_restart_complete(struct ieee80211_local *local) 1155static inline void
1156drv_reconfig_complete(struct ieee80211_local *local,
1157 enum ieee80211_reconfig_type reconfig_type)
1148{ 1158{
1149 might_sleep(); 1159 might_sleep();
1150 1160
1151 trace_drv_restart_complete(local); 1161 trace_drv_reconfig_complete(local, reconfig_type);
1152 if (local->ops->restart_complete) 1162 if (local->ops->reconfig_complete)
1153 local->ops->restart_complete(&local->hw); 1163 local->ops->reconfig_complete(&local->hw, reconfig_type);
1154 trace_drv_return_void(local); 1164 trace_drv_return_void(local);
1155} 1165}
1156 1166
@@ -1196,6 +1206,40 @@ drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
1196 } 1206 }
1197} 1207}
1198 1208
1209static inline int
1210drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
1211 struct ieee80211_channel_switch *ch_switch)
1212{
1213 struct ieee80211_local *local = sdata->local;
1214 int ret = 0;
1215
1216 if (!check_sdata_in_driver(sdata))
1217 return -EIO;
1218
1219 trace_drv_pre_channel_switch(local, sdata, ch_switch);
1220 if (local->ops->pre_channel_switch)
1221 ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif,
1222 ch_switch);
1223 trace_drv_return_int(local, ret);
1224 return ret;
1225}
1226
1227static inline int
1228drv_post_channel_switch(struct ieee80211_sub_if_data *sdata)
1229{
1230 struct ieee80211_local *local = sdata->local;
1231 int ret = 0;
1232
1233 if (!check_sdata_in_driver(sdata))
1234 return -EIO;
1235
1236 trace_drv_post_channel_switch(local, sdata);
1237 if (local->ops->post_channel_switch)
1238 ret = local->ops->post_channel_switch(&local->hw, &sdata->vif);
1239 trace_drv_return_int(local, ret);
1240 return ret;
1241}
1242
1199static inline int drv_join_ibss(struct ieee80211_local *local, 1243static inline int drv_join_ibss(struct ieee80211_local *local,
1200 struct ieee80211_sub_if_data *sdata) 1244 struct ieee80211_sub_if_data *sdata)
1201{ 1245{
@@ -1238,4 +1282,18 @@ static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
1238 return ret; 1282 return ret;
1239} 1283}
1240 1284
1285static inline int drv_get_txpower(struct ieee80211_local *local,
1286 struct ieee80211_sub_if_data *sdata, int *dbm)
1287{
1288 int ret;
1289
1290 if (!local->ops->get_txpower)
1291 return -EOPNOTSUPP;
1292
1293 ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm);
1294 trace_drv_get_txpower(local, sdata, *dbm, ret);
1295
1296 return ret;
1297}
1298
1241#endif /* __MAC80211_DRIVER_OPS */ 1299#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8c68da30595d..842e0661fb57 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -131,7 +131,7 @@ enum ieee80211_bss_corrupt_data_flags {
131 * 131 *
132 * These are bss flags that are attached to a bss in the 132 * These are bss flags that are attached to a bss in the
133 * @valid_data field of &struct ieee80211_bss. They show which parts 133 * @valid_data field of &struct ieee80211_bss. They show which parts
134 * of the data structure were recieved as a result of an un-corrupted 134 * of the data structure were received as a result of an un-corrupted
135 * beacon/probe response. 135 * beacon/probe response.
136 */ 136 */
137enum ieee80211_bss_valid_data_flags { 137enum ieee80211_bss_valid_data_flags {
@@ -399,6 +399,24 @@ struct ieee80211_mgd_assoc_data {
399 u8 ie[]; 399 u8 ie[];
400}; 400};
401 401
402struct ieee80211_sta_tx_tspec {
403 /* timestamp of the first packet in the time slice */
404 unsigned long time_slice_start;
405
406 u32 admitted_time; /* in usecs, unlike over the air */
407 u8 tsid;
408 s8 up; /* signed to be able to invalidate with -1 during teardown */
409
410 /* consumed TX time in microseconds in the time slice */
411 u32 consumed_tx_time;
412 enum {
413 TX_TSPEC_ACTION_NONE = 0,
414 TX_TSPEC_ACTION_DOWNGRADE,
415 TX_TSPEC_ACTION_STOP_DOWNGRADE,
416 } action;
417 bool downgraded;
418};
419
402struct ieee80211_if_managed { 420struct ieee80211_if_managed {
403 struct timer_list timer; 421 struct timer_list timer;
404 struct timer_list conn_mon_timer; 422 struct timer_list conn_mon_timer;
@@ -434,6 +452,8 @@ struct ieee80211_if_managed {
434 452
435 unsigned int flags; 453 unsigned int flags;
436 454
455 bool csa_waiting_bcn;
456
437 bool beacon_crc_valid; 457 bool beacon_crc_valid;
438 u32 beacon_crc; 458 u32 beacon_crc;
439 459
@@ -507,6 +527,16 @@ struct ieee80211_if_managed {
507 527
508 u8 tdls_peer[ETH_ALEN] __aligned(2); 528 u8 tdls_peer[ETH_ALEN] __aligned(2);
509 struct delayed_work tdls_peer_del_work; 529 struct delayed_work tdls_peer_del_work;
530
531 /* WMM-AC TSPEC support */
532 struct ieee80211_sta_tx_tspec tx_tspec[IEEE80211_NUM_ACS];
533 /* Use a separate work struct so that we can do something here
534 * while the sdata->work is flushing the queues, for example.
535 * otherwise, in scenarios where we hardly get any traffic out
536 * on the BE queue, but there's a lot of VO traffic, we might
537 * get stuck in a downgraded situation and flush takes forever.
538 */
539 struct delayed_work tx_tspec_wk;
510}; 540};
511 541
512struct ieee80211_if_ibss { 542struct ieee80211_if_ibss {
@@ -547,6 +577,25 @@ struct ieee80211_if_ibss {
547}; 577};
548 578
549/** 579/**
580 * struct ieee80211_if_ocb - OCB mode state
581 *
582 * @housekeeping_timer: timer for periodic invocation of a housekeeping task
583 * @wrkq_flags: OCB deferred task action
584 * @incomplete_lock: delayed STA insertion lock
585 * @incomplete_stations: list of STAs waiting for delayed insertion
586 * @joined: indication if the interface is connected to an OCB network
587 */
588struct ieee80211_if_ocb {
589 struct timer_list housekeeping_timer;
590 unsigned long wrkq_flags;
591
592 spinlock_t incomplete_lock;
593 struct list_head incomplete_stations;
594
595 bool joined;
596};
597
598/**
550 * struct ieee80211_mesh_sync_ops - Extensible synchronization framework interface 599 * struct ieee80211_mesh_sync_ops - Extensible synchronization framework interface
551 * 600 *
552 * these declarations define the interface, which enables 601 * these declarations define the interface, which enables
@@ -839,6 +888,7 @@ struct ieee80211_sub_if_data {
839 struct ieee80211_if_managed mgd; 888 struct ieee80211_if_managed mgd;
840 struct ieee80211_if_ibss ibss; 889 struct ieee80211_if_ibss ibss;
841 struct ieee80211_if_mesh mesh; 890 struct ieee80211_if_mesh mesh;
891 struct ieee80211_if_ocb ocb;
842 u32 mntr_flags; 892 u32 mntr_flags;
843 } u; 893 } u;
844 894
@@ -1307,6 +1357,9 @@ struct ieee80211_local {
1307 /* virtual monitor interface */ 1357 /* virtual monitor interface */
1308 struct ieee80211_sub_if_data __rcu *monitor_sdata; 1358 struct ieee80211_sub_if_data __rcu *monitor_sdata;
1309 struct cfg80211_chan_def monitor_chandef; 1359 struct cfg80211_chan_def monitor_chandef;
1360
1361 /* extended capabilities provided by mac80211 */
1362 u8 ext_capa[8];
1310}; 1363};
1311 1364
1312static inline struct ieee80211_sub_if_data * 1365static inline struct ieee80211_sub_if_data *
@@ -1454,6 +1507,7 @@ void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,
1454 __le16 fc, bool acked); 1507 __le16 fc, bool acked);
1455void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata); 1508void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata);
1456void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); 1509void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
1510void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata);
1457 1511
1458/* IBSS code */ 1512/* IBSS code */
1459void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); 1513void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
@@ -1471,6 +1525,15 @@ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
1471int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata); 1525int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata);
1472void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata); 1526void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata);
1473 1527
1528/* OCB code */
1529void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata);
1530void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata,
1531 const u8 *bssid, const u8 *addr, u32 supp_rates);
1532void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata);
1533int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata,
1534 struct ocb_setup *setup);
1535int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata);
1536
1474/* mesh code */ 1537/* mesh code */
1475void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata); 1538void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata);
1476void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 1539void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
@@ -1757,6 +1820,13 @@ static inline bool ieee80211_rx_reorder_ready(struct sk_buff_head *frames)
1757 return true; 1820 return true;
1758} 1821}
1759 1822
1823extern const int ieee802_1d_to_ac[8];
1824
1825static inline int ieee80211_ac_from_tid(int tid)
1826{
1827 return ieee802_1d_to_ac[tid & 7];
1828}
1829
1760void ieee80211_dynamic_ps_enable_work(struct work_struct *work); 1830void ieee80211_dynamic_ps_enable_work(struct work_struct *work);
1761void ieee80211_dynamic_ps_disable_work(struct work_struct *work); 1831void ieee80211_dynamic_ps_disable_work(struct work_struct *work);
1762void ieee80211_dynamic_ps_timer(unsigned long data); 1832void ieee80211_dynamic_ps_timer(unsigned long data);
@@ -1766,7 +1836,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
1766void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1836void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1767 struct ieee80211_hdr *hdr); 1837 struct ieee80211_hdr *hdr);
1768void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, 1838void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
1769 struct ieee80211_hdr *hdr, bool ack); 1839 struct ieee80211_hdr *hdr, bool ack, u16 tx_time);
1770 1840
1771void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1841void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
1772 unsigned long queues, 1842 unsigned long queues,
@@ -1832,8 +1902,10 @@ int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata,
1832void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); 1902void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata);
1833void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata); 1903void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata);
1834 1904
1835size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 1905size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
1836 const u8 *ids, int n_ids, size_t offset); 1906 const u8 *ids, int n_ids,
1907 const u8 *after_ric, int n_after_ric,
1908 size_t offset);
1837size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); 1909size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
1838u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 1910u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1839 u16 cap); 1911 u16 cap);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 653f5eb07a27..9df26adb864a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -259,6 +259,15 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
259 list_for_each_entry(nsdata, &local->interfaces, list) { 259 list_for_each_entry(nsdata, &local->interfaces, list) {
260 if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { 260 if (nsdata != sdata && ieee80211_sdata_running(nsdata)) {
261 /* 261 /*
262 * Only OCB and monitor mode may coexist
263 */
264 if ((sdata->vif.type == NL80211_IFTYPE_OCB &&
265 nsdata->vif.type != NL80211_IFTYPE_MONITOR) ||
266 (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
267 nsdata->vif.type == NL80211_IFTYPE_OCB))
268 return -EBUSY;
269
270 /*
262 * Allow only a single IBSS interface to be up at any 271 * Allow only a single IBSS interface to be up at any
263 * time. This is restricted because beacon distribution 272 * time. This is restricted because beacon distribution
264 * cannot work properly if both are in the same IBSS. 273 * cannot work properly if both are in the same IBSS.
@@ -521,6 +530,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
521 case NL80211_IFTYPE_MONITOR: 530 case NL80211_IFTYPE_MONITOR:
522 case NL80211_IFTYPE_ADHOC: 531 case NL80211_IFTYPE_ADHOC:
523 case NL80211_IFTYPE_P2P_DEVICE: 532 case NL80211_IFTYPE_P2P_DEVICE:
533 case NL80211_IFTYPE_OCB:
524 /* no special treatment */ 534 /* no special treatment */
525 break; 535 break;
526 case NL80211_IFTYPE_UNSPECIFIED: 536 case NL80211_IFTYPE_UNSPECIFIED:
@@ -631,6 +641,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
631 case NL80211_IFTYPE_ADHOC: 641 case NL80211_IFTYPE_ADHOC:
632 case NL80211_IFTYPE_AP: 642 case NL80211_IFTYPE_AP:
633 case NL80211_IFTYPE_MESH_POINT: 643 case NL80211_IFTYPE_MESH_POINT:
644 case NL80211_IFTYPE_OCB:
634 netif_carrier_off(dev); 645 netif_carrier_off(dev);
635 break; 646 break;
636 case NL80211_IFTYPE_WDS: 647 case NL80211_IFTYPE_WDS:
@@ -844,6 +855,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
844 sdata_lock(sdata); 855 sdata_lock(sdata);
845 mutex_lock(&local->mtx); 856 mutex_lock(&local->mtx);
846 sdata->vif.csa_active = false; 857 sdata->vif.csa_active = false;
858 if (sdata->vif.type == NL80211_IFTYPE_STATION)
859 sdata->u.mgd.csa_waiting_bcn = false;
847 if (sdata->csa_block_tx) { 860 if (sdata->csa_block_tx) {
848 ieee80211_wake_vif_queues(local, sdata, 861 ieee80211_wake_vif_queues(local, sdata,
849 IEEE80211_QUEUE_STOP_REASON_CSA); 862 IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -1285,6 +1298,9 @@ static void ieee80211_iface_work(struct work_struct *work)
1285 break; 1298 break;
1286 ieee80211_mesh_work(sdata); 1299 ieee80211_mesh_work(sdata);
1287 break; 1300 break;
1301 case NL80211_IFTYPE_OCB:
1302 ieee80211_ocb_work(sdata);
1303 break;
1288 default: 1304 default:
1289 break; 1305 break;
1290 } 1306 }
@@ -1304,6 +1320,9 @@ static void ieee80211_recalc_smps_work(struct work_struct *work)
1304static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, 1320static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1305 enum nl80211_iftype type) 1321 enum nl80211_iftype type)
1306{ 1322{
1323 static const u8 bssid_wildcard[ETH_ALEN] = {0xff, 0xff, 0xff,
1324 0xff, 0xff, 0xff};
1325
1307 /* clear type-dependent union */ 1326 /* clear type-dependent union */
1308 memset(&sdata->u, 0, sizeof(sdata->u)); 1327 memset(&sdata->u, 0, sizeof(sdata->u));
1309 1328
@@ -1355,6 +1374,10 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1355 sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; 1374 sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
1356 ieee80211_sta_setup_sdata(sdata); 1375 ieee80211_sta_setup_sdata(sdata);
1357 break; 1376 break;
1377 case NL80211_IFTYPE_OCB:
1378 sdata->vif.bss_conf.bssid = bssid_wildcard;
1379 ieee80211_ocb_setup_sdata(sdata);
1380 break;
1358 case NL80211_IFTYPE_ADHOC: 1381 case NL80211_IFTYPE_ADHOC:
1359 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; 1382 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
1360 ieee80211_ibss_setup_sdata(sdata); 1383 ieee80211_ibss_setup_sdata(sdata);
@@ -1402,6 +1425,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
1402 case NL80211_IFTYPE_AP: 1425 case NL80211_IFTYPE_AP:
1403 case NL80211_IFTYPE_STATION: 1426 case NL80211_IFTYPE_STATION:
1404 case NL80211_IFTYPE_ADHOC: 1427 case NL80211_IFTYPE_ADHOC:
1428 case NL80211_IFTYPE_OCB:
1405 /* 1429 /*
1406 * Could maybe also all others here? 1430 * Could maybe also all others here?
1407 * Just not sure how that interacts 1431 * Just not sure how that interacts
@@ -1417,6 +1441,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
1417 case NL80211_IFTYPE_AP: 1441 case NL80211_IFTYPE_AP:
1418 case NL80211_IFTYPE_STATION: 1442 case NL80211_IFTYPE_STATION:
1419 case NL80211_IFTYPE_ADHOC: 1443 case NL80211_IFTYPE_ADHOC:
1444 case NL80211_IFTYPE_OCB:
1420 /* 1445 /*
1421 * Could probably support everything 1446 * Could probably support everything
1422 * but WDS here (WDS do_open can fail 1447 * but WDS here (WDS do_open can fail
@@ -1675,7 +1700,10 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1675 } 1700 }
1676 1701
1677 ieee80211_assign_perm_addr(local, ndev->perm_addr, type); 1702 ieee80211_assign_perm_addr(local, ndev->perm_addr, type);
1678 memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); 1703 if (params && is_valid_ether_addr(params->macaddr))
1704 memcpy(ndev->dev_addr, params->macaddr, ETH_ALEN);
1705 else
1706 memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN);
1679 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); 1707 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
1680 1708
1681 /* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */ 1709 /* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 4712150dc210..434a91ad12c8 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -94,8 +94,17 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
94 94
95 might_sleep(); 95 might_sleep();
96 96
97 if (key->flags & KEY_FLAG_TAINTED) 97 if (key->flags & KEY_FLAG_TAINTED) {
98 /* If we get here, it's during resume and the key is
99 * tainted so shouldn't be used/programmed any more.
100 * However, its flags may still indicate that it was
101 * programmed into the device (since we're in resume)
102 * so clear that flag now to avoid trying to remove
103 * it again later.
104 */
105 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
98 return -EINVAL; 106 return -EINVAL;
107 }
99 108
100 if (!key->local->ops->set_key) 109 if (!key->local->ops->set_key)
101 goto out_unsupported; 110 goto out_unsupported;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0de7c93bf62b..282a4f36eb92 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -478,13 +478,9 @@ static const struct ieee80211_vht_cap mac80211_vht_capa_mod_mask = {
478 }, 478 },
479}; 479};
480 480
481static const u8 extended_capabilities[] = { 481struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
482 0, 0, 0, 0, 0, 0, 0, 482 const struct ieee80211_ops *ops,
483 WLAN_EXT_CAPA8_OPMODE_NOTIF, 483 const char *requested_name)
484};
485
486struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
487 const struct ieee80211_ops *ops)
488{ 484{
489 struct ieee80211_local *local; 485 struct ieee80211_local *local;
490 int priv_size, i; 486 int priv_size, i;
@@ -524,7 +520,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
524 */ 520 */
525 priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; 521 priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len;
526 522
527 wiphy = wiphy_new(&mac80211_config_ops, priv_size); 523 wiphy = wiphy_new_nm(&mac80211_config_ops, priv_size, requested_name);
528 524
529 if (!wiphy) 525 if (!wiphy)
530 return NULL; 526 return NULL;
@@ -539,10 +535,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
539 WIPHY_FLAG_REPORTS_OBSS | 535 WIPHY_FLAG_REPORTS_OBSS |
540 WIPHY_FLAG_OFFCHAN_TX; 536 WIPHY_FLAG_OFFCHAN_TX;
541 537
542 wiphy->extended_capabilities = extended_capabilities;
543 wiphy->extended_capabilities_mask = extended_capabilities;
544 wiphy->extended_capabilities_len = ARRAY_SIZE(extended_capabilities);
545
546 if (ops->remain_on_channel) 538 if (ops->remain_on_channel)
547 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 539 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
548 540
@@ -550,6 +542,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
550 NL80211_FEATURE_SAE | 542 NL80211_FEATURE_SAE |
551 NL80211_FEATURE_HT_IBSS | 543 NL80211_FEATURE_HT_IBSS |
552 NL80211_FEATURE_VIF_TXPOWER | 544 NL80211_FEATURE_VIF_TXPOWER |
545 NL80211_FEATURE_MAC_ON_CREATE |
553 NL80211_FEATURE_USERSPACE_MPM; 546 NL80211_FEATURE_USERSPACE_MPM;
554 547
555 if (!ops->hw_scan) 548 if (!ops->hw_scan)
@@ -591,6 +584,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
591 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; 584 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
592 wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask; 585 wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask;
593 586
587 local->ext_capa[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF;
588
589 wiphy->extended_capabilities = local->ext_capa;
590 wiphy->extended_capabilities_mask = local->ext_capa;
591 wiphy->extended_capabilities_len =
592 ARRAY_SIZE(local->ext_capa);
593
594 INIT_LIST_HEAD(&local->interfaces); 594 INIT_LIST_HEAD(&local->interfaces);
595 595
596 __hw_addr_init(&local->mc_list); 596 __hw_addr_init(&local->mc_list);
@@ -651,7 +651,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
651 651
652 return &local->hw; 652 return &local->hw;
653} 653}
654EXPORT_SYMBOL(ieee80211_alloc_hw); 654EXPORT_SYMBOL(ieee80211_alloc_hw_nm);
655 655
656static int ieee80211_init_cipher_suites(struct ieee80211_local *local) 656static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
657{ 657{
@@ -787,13 +787,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
787 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)) 787 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS))
788 return -EINVAL; 788 return -EINVAL;
789 789
790 /* DFS currently not supported with channel context drivers */ 790 /* DFS is not supported with multi-channel combinations yet */
791 for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) { 791 for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) {
792 const struct ieee80211_iface_combination *comb; 792 const struct ieee80211_iface_combination *comb;
793 793
794 comb = &local->hw.wiphy->iface_combinations[i]; 794 comb = &local->hw.wiphy->iface_combinations[i];
795 795
796 if (comb->radar_detect_widths) 796 if (comb->radar_detect_widths &&
797 comb->num_different_channels > 1)
797 return -EINVAL; 798 return -EINVAL;
798 } 799 }
799 } 800 }
@@ -958,6 +959,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
958 if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) 959 if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)
959 local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; 960 local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
960 961
962 /* mac80211 supports eCSA, if the driver supports STA CSA at all */
963 if (local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)
964 local->ext_capa[0] |= WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING;
965
961 local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM; 966 local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM;
962 967
963 result = wiphy_register(local->hw.wiphy); 968 result = wiphy_register(local->hw.wiphy);
@@ -1019,7 +1024,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1019 } 1024 }
1020 1025
1021 /* add one default STA interface if supported */ 1026 /* add one default STA interface if supported */
1022 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { 1027 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) &&
1028 !(hw->flags & IEEE80211_HW_NO_AUTO_VIF)) {
1023 result = ieee80211_if_add(local, "wlan%d", NULL, 1029 result = ieee80211_if_add(local, "wlan%d", NULL,
1024 NL80211_IFTYPE_STATION, NULL); 1030 NL80211_IFTYPE_STATION, NULL);
1025 if (result) 1031 if (result)
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index f39a19f9090f..50c8473cf9dc 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -270,6 +270,8 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
270 const u8 *dst, const u8 *mpp); 270 const u8 *dst, const u8 *mpp);
271struct mesh_path * 271struct mesh_path *
272mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx); 272mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx);
273struct mesh_path *
274mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx);
273void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); 275void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop);
274void mesh_path_expire(struct ieee80211_sub_if_data *sdata); 276void mesh_path_expire(struct ieee80211_sub_if_data *sdata);
275void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, 277void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
@@ -317,6 +319,7 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
317 319
318bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); 320bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
319extern int mesh_paths_generation; 321extern int mesh_paths_generation;
322extern int mpp_paths_generation;
320 323
321#ifdef CONFIG_MAC80211_MESH 324#ifdef CONFIG_MAC80211_MESH
322static inline 325static inline
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index a6699dceae7c..b890e225a8f1 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -44,6 +44,7 @@ static struct mesh_table __rcu *mesh_paths;
44static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */ 44static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */
45 45
46int mesh_paths_generation; 46int mesh_paths_generation;
47int mpp_paths_generation;
47 48
48/* This lock will have the grow table function as writer and add / delete nodes 49/* This lock will have the grow table function as writer and add / delete nodes
49 * as readers. RCU provides sufficient protection only when reading the table 50 * as readers. RCU provides sufficient protection only when reading the table
@@ -410,6 +411,33 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
410} 411}
411 412
412/** 413/**
414 * mpp_path_lookup_by_idx - look up a path in the proxy path table by its index
415 * @idx: index
416 * @sdata: local subif, or NULL for all entries
417 *
418 * Returns: pointer to the proxy path structure, or NULL if not found.
419 *
420 * Locking: must be called within a read rcu section.
421 */
422struct mesh_path *
423mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
424{
425 struct mesh_table *tbl = rcu_dereference(mpp_paths);
426 struct mpath_node *node;
427 int i;
428 int j = 0;
429
430 for_each_mesh_entry(tbl, node, i) {
431 if (sdata && node->mpath->sdata != sdata)
432 continue;
433 if (j++ == idx)
434 return node->mpath;
435 }
436
437 return NULL;
438}
439
440/**
413 * mesh_path_add_gate - add the given mpath to a mesh gate to our path table 441 * mesh_path_add_gate - add the given mpath to a mesh gate to our path table
414 * @mpath: gate path to add to table 442 * @mpath: gate path to add to table
415 */ 443 */
@@ -691,6 +719,9 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
691 719
692 spin_unlock(&tbl->hashwlock[hash_idx]); 720 spin_unlock(&tbl->hashwlock[hash_idx]);
693 read_unlock_bh(&pathtbl_resize_lock); 721 read_unlock_bh(&pathtbl_resize_lock);
722
723 mpp_paths_generation++;
724
694 if (grow) { 725 if (grow) {
695 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); 726 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags);
696 ieee80211_queue_work(&local->hw, &sdata->work); 727 ieee80211_queue_work(&local->hw, &sdata->work);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 93af0f1c9d99..0d166e766dad 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -775,11 +775,30 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
775 WLAN_EID_QOS_CAPA, 775 WLAN_EID_QOS_CAPA,
776 WLAN_EID_RRM_ENABLED_CAPABILITIES, 776 WLAN_EID_RRM_ENABLED_CAPABILITIES,
777 WLAN_EID_MOBILITY_DOMAIN, 777 WLAN_EID_MOBILITY_DOMAIN,
778 WLAN_EID_FAST_BSS_TRANSITION, /* reassoc only */
779 WLAN_EID_RIC_DATA, /* reassoc only */
778 WLAN_EID_SUPPORTED_REGULATORY_CLASSES, 780 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
779 }; 781 };
780 noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len, 782 static const u8 after_ric[] = {
781 before_ht, ARRAY_SIZE(before_ht), 783 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
782 offset); 784 WLAN_EID_HT_CAPABILITY,
785 WLAN_EID_BSS_COEX_2040,
786 WLAN_EID_EXT_CAPABILITY,
787 WLAN_EID_QOS_TRAFFIC_CAPA,
788 WLAN_EID_TIM_BCAST_REQ,
789 WLAN_EID_INTERWORKING,
790 /* 60GHz doesn't happen right now */
791 WLAN_EID_VHT_CAPABILITY,
792 WLAN_EID_OPMODE_NOTIF,
793 };
794
795 noffset = ieee80211_ie_split_ric(assoc_data->ie,
796 assoc_data->ie_len,
797 before_ht,
798 ARRAY_SIZE(before_ht),
799 after_ric,
800 ARRAY_SIZE(after_ric),
801 offset);
783 pos = skb_put(skb, noffset - offset); 802 pos = skb_put(skb, noffset - offset);
784 memcpy(pos, assoc_data->ie + offset, noffset - offset); 803 memcpy(pos, assoc_data->ie + offset, noffset - offset);
785 offset = noffset; 804 offset = noffset;
@@ -813,6 +832,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
813 WLAN_EID_TIM_BCAST_REQ, 832 WLAN_EID_TIM_BCAST_REQ,
814 WLAN_EID_INTERWORKING, 833 WLAN_EID_INTERWORKING,
815 }; 834 };
835
836 /* RIC already taken above, so no need to handle here anymore */
816 noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len, 837 noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len,
817 before_vht, ARRAY_SIZE(before_vht), 838 before_vht, ARRAY_SIZE(before_vht),
818 offset); 839 offset);
@@ -1001,14 +1022,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
1001 /* XXX: shouldn't really modify cfg80211-owned data! */ 1022 /* XXX: shouldn't really modify cfg80211-owned data! */
1002 ifmgd->associated->channel = sdata->csa_chandef.chan; 1023 ifmgd->associated->channel = sdata->csa_chandef.chan;
1003 1024
1004 sdata->vif.csa_active = false; 1025 ifmgd->csa_waiting_bcn = true;
1005
1006 /* XXX: wait for a beacon first? */
1007 if (sdata->csa_block_tx) {
1008 ieee80211_wake_vif_queues(local, sdata,
1009 IEEE80211_QUEUE_STOP_REASON_CSA);
1010 sdata->csa_block_tx = false;
1011 }
1012 1026
1013 ieee80211_sta_reset_beacon_monitor(sdata); 1027 ieee80211_sta_reset_beacon_monitor(sdata);
1014 ieee80211_sta_reset_conn_monitor(sdata); 1028 ieee80211_sta_reset_conn_monitor(sdata);
@@ -1019,6 +1033,35 @@ out:
1019 sdata_unlock(sdata); 1033 sdata_unlock(sdata);
1020} 1034}
1021 1035
1036static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata)
1037{
1038 struct ieee80211_local *local = sdata->local;
1039 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1040 int ret;
1041
1042 sdata_assert_lock(sdata);
1043
1044 WARN_ON(!sdata->vif.csa_active);
1045
1046 if (sdata->csa_block_tx) {
1047 ieee80211_wake_vif_queues(local, sdata,
1048 IEEE80211_QUEUE_STOP_REASON_CSA);
1049 sdata->csa_block_tx = false;
1050 }
1051
1052 sdata->vif.csa_active = false;
1053 ifmgd->csa_waiting_bcn = false;
1054
1055 ret = drv_post_channel_switch(sdata);
1056 if (ret) {
1057 sdata_info(sdata,
1058 "driver post channel switch failed, disconnecting\n");
1059 ieee80211_queue_work(&local->hw,
1060 &ifmgd->csa_connection_drop_work);
1061 return;
1062 }
1063}
1064
1022void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) 1065void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
1023{ 1066{
1024 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 1067 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@@ -1046,7 +1089,8 @@ static void ieee80211_chswitch_timer(unsigned long data)
1046 1089
1047static void 1090static void
1048ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, 1091ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1049 u64 timestamp, struct ieee802_11_elems *elems, 1092 u64 timestamp, u32 device_timestamp,
1093 struct ieee802_11_elems *elems,
1050 bool beacon) 1094 bool beacon)
1051{ 1095{
1052 struct ieee80211_local *local = sdata->local; 1096 struct ieee80211_local *local = sdata->local;
@@ -1056,6 +1100,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1056 struct ieee80211_chanctx *chanctx; 1100 struct ieee80211_chanctx *chanctx;
1057 enum ieee80211_band current_band; 1101 enum ieee80211_band current_band;
1058 struct ieee80211_csa_ie csa_ie; 1102 struct ieee80211_csa_ie csa_ie;
1103 struct ieee80211_channel_switch ch_switch;
1059 int res; 1104 int res;
1060 1105
1061 sdata_assert_lock(sdata); 1106 sdata_assert_lock(sdata);
@@ -1110,21 +1155,31 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1110 1155
1111 chanctx = container_of(conf, struct ieee80211_chanctx, conf); 1156 chanctx = container_of(conf, struct ieee80211_chanctx, conf);
1112 1157
1113 if (local->use_chanctx) { 1158 if (local->use_chanctx &&
1114 u32 num_chanctx = 0; 1159 !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) {
1115 list_for_each_entry(chanctx, &local->chanctx_list, list) 1160 sdata_info(sdata,
1116 num_chanctx++; 1161 "driver doesn't support chan-switch with channel contexts\n");
1162 ieee80211_queue_work(&local->hw,
1163 &ifmgd->csa_connection_drop_work);
1164 mutex_unlock(&local->chanctx_mtx);
1165 mutex_unlock(&local->mtx);
1166 return;
1167 }
1117 1168
1118 if (num_chanctx > 1 || 1169 ch_switch.timestamp = timestamp;
1119 !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { 1170 ch_switch.device_timestamp = device_timestamp;
1120 sdata_info(sdata, 1171 ch_switch.block_tx = csa_ie.mode;
1121 "not handling chan-switch with channel contexts\n"); 1172 ch_switch.chandef = csa_ie.chandef;
1122 ieee80211_queue_work(&local->hw, 1173 ch_switch.count = csa_ie.count;
1123 &ifmgd->csa_connection_drop_work); 1174
1124 mutex_unlock(&local->chanctx_mtx); 1175 if (drv_pre_channel_switch(sdata, &ch_switch)) {
1125 mutex_unlock(&local->mtx); 1176 sdata_info(sdata,
1126 return; 1177 "preparing for channel switch failed, disconnecting\n");
1127 } 1178 ieee80211_queue_work(&local->hw,
1179 &ifmgd->csa_connection_drop_work);
1180 mutex_unlock(&local->chanctx_mtx);
1181 mutex_unlock(&local->mtx);
1182 return;
1128 } 1183 }
1129 1184
1130 res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef, 1185 res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef,
@@ -1152,14 +1207,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1152 1207
1153 if (local->ops->channel_switch) { 1208 if (local->ops->channel_switch) {
1154 /* use driver's channel switch callback */ 1209 /* use driver's channel switch callback */
1155 struct ieee80211_channel_switch ch_switch = { 1210 drv_channel_switch(local, sdata, &ch_switch);
1156 .timestamp = timestamp,
1157 .block_tx = csa_ie.mode,
1158 .chandef = csa_ie.chandef,
1159 .count = csa_ie.count,
1160 };
1161
1162 drv_channel_switch(local, &ch_switch);
1163 return; 1211 return;
1164 } 1212 }
1165 1213
@@ -1580,6 +1628,95 @@ void ieee80211_dfs_cac_timer_work(struct work_struct *work)
1580 mutex_unlock(&sdata->local->mtx); 1628 mutex_unlock(&sdata->local->mtx);
1581} 1629}
1582 1630
1631static bool
1632__ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata)
1633{
1634 struct ieee80211_local *local = sdata->local;
1635 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1636 bool ret;
1637 int ac;
1638
1639 if (local->hw.queues < IEEE80211_NUM_ACS)
1640 return false;
1641
1642 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
1643 struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
1644 int non_acm_ac;
1645 unsigned long now = jiffies;
1646
1647 if (tx_tspec->action == TX_TSPEC_ACTION_NONE &&
1648 tx_tspec->admitted_time &&
1649 time_after(now, tx_tspec->time_slice_start + HZ)) {
1650 tx_tspec->consumed_tx_time = 0;
1651 tx_tspec->time_slice_start = now;
1652
1653 if (tx_tspec->downgraded)
1654 tx_tspec->action =
1655 TX_TSPEC_ACTION_STOP_DOWNGRADE;
1656 }
1657
1658 switch (tx_tspec->action) {
1659 case TX_TSPEC_ACTION_STOP_DOWNGRADE:
1660 /* take the original parameters */
1661 if (drv_conf_tx(local, sdata, ac, &sdata->tx_conf[ac]))
1662 sdata_err(sdata,
1663 "failed to set TX queue parameters for queue %d\n",
1664 ac);
1665 tx_tspec->action = TX_TSPEC_ACTION_NONE;
1666 tx_tspec->downgraded = false;
1667 ret = true;
1668 break;
1669 case TX_TSPEC_ACTION_DOWNGRADE:
1670 if (time_after(now, tx_tspec->time_slice_start + HZ)) {
1671 tx_tspec->action = TX_TSPEC_ACTION_NONE;
1672 ret = true;
1673 break;
1674 }
1675 /* downgrade next lower non-ACM AC */
1676 for (non_acm_ac = ac + 1;
1677 non_acm_ac < IEEE80211_NUM_ACS;
1678 non_acm_ac++)
1679 if (!(sdata->wmm_acm & BIT(7 - 2 * non_acm_ac)))
1680 break;
1681 /* The loop will result in using BK even if it requires
1682 * admission control, such configuration makes no sense
1683 * and we have to transmit somehow - the AC selection
1684 * does the same thing.
1685 */
1686 if (drv_conf_tx(local, sdata, ac,
1687 &sdata->tx_conf[non_acm_ac]))
1688 sdata_err(sdata,
1689 "failed to set TX queue parameters for queue %d\n",
1690 ac);
1691 tx_tspec->action = TX_TSPEC_ACTION_NONE;
1692 ret = true;
1693 schedule_delayed_work(&ifmgd->tx_tspec_wk,
1694 tx_tspec->time_slice_start + HZ - now + 1);
1695 break;
1696 case TX_TSPEC_ACTION_NONE:
1697 /* nothing now */
1698 break;
1699 }
1700 }
1701
1702 return ret;
1703}
1704
1705void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata)
1706{
1707 if (__ieee80211_sta_handle_tspec_ac_params(sdata))
1708 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
1709}
1710
1711static void ieee80211_sta_handle_tspec_ac_params_wk(struct work_struct *work)
1712{
1713 struct ieee80211_sub_if_data *sdata;
1714
1715 sdata = container_of(work, struct ieee80211_sub_if_data,
1716 u.mgd.tx_tspec_wk.work);
1717 ieee80211_sta_handle_tspec_ac_params(sdata);
1718}
1719
1583/* MLME */ 1720/* MLME */
1584static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, 1721static bool ieee80211_sta_wmm_params(struct ieee80211_local *local,
1585 struct ieee80211_sub_if_data *sdata, 1722 struct ieee80211_sub_if_data *sdata,
@@ -1664,12 +1801,14 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local,
1664 params.uapsd = uapsd; 1801 params.uapsd = uapsd;
1665 1802
1666 mlme_dbg(sdata, 1803 mlme_dbg(sdata,
1667 "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d\n", 1804 "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d, downgraded=%d\n",
1668 queue, aci, acm, 1805 queue, aci, acm,
1669 params.aifs, params.cw_min, params.cw_max, 1806 params.aifs, params.cw_min, params.cw_max,
1670 params.txop, params.uapsd); 1807 params.txop, params.uapsd,
1808 ifmgd->tx_tspec[queue].downgraded);
1671 sdata->tx_conf[queue] = params; 1809 sdata->tx_conf[queue] = params;
1672 if (drv_conf_tx(local, sdata, queue, &params)) 1810 if (!ifmgd->tx_tspec[queue].downgraded &&
1811 drv_conf_tx(local, sdata, queue, &params))
1673 sdata_err(sdata, 1812 sdata_err(sdata,
1674 "failed to set TX queue parameters for queue %d\n", 1813 "failed to set TX queue parameters for queue %d\n",
1675 queue); 1814 queue);
@@ -1924,6 +2063,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1924 ieee80211_vif_release_channel(sdata); 2063 ieee80211_vif_release_channel(sdata);
1925 2064
1926 sdata->vif.csa_active = false; 2065 sdata->vif.csa_active = false;
2066 ifmgd->csa_waiting_bcn = false;
1927 if (sdata->csa_block_tx) { 2067 if (sdata->csa_block_tx) {
1928 ieee80211_wake_vif_queues(local, sdata, 2068 ieee80211_wake_vif_queues(local, sdata,
1929 IEEE80211_QUEUE_STOP_REASON_CSA); 2069 IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -1931,6 +2071,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1931 } 2071 }
1932 mutex_unlock(&local->mtx); 2072 mutex_unlock(&local->mtx);
1933 2073
2074 /* existing TX TSPEC sessions no longer exist */
2075 memset(ifmgd->tx_tspec, 0, sizeof(ifmgd->tx_tspec));
2076 cancel_delayed_work_sync(&ifmgd->tx_tspec_wk);
2077
1934 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 2078 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
1935} 2079}
1936 2080
@@ -1983,9 +2127,46 @@ out:
1983 mutex_unlock(&local->mtx); 2127 mutex_unlock(&local->mtx);
1984} 2128}
1985 2129
2130static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata,
2131 struct ieee80211_hdr *hdr,
2132 u16 tx_time)
2133{
2134 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2135 u16 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
2136 int ac = ieee80211_ac_from_tid(tid);
2137 struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
2138 unsigned long now = jiffies;
2139
2140 if (likely(!tx_tspec->admitted_time))
2141 return;
2142
2143 if (time_after(now, tx_tspec->time_slice_start + HZ)) {
2144 tx_tspec->consumed_tx_time = 0;
2145 tx_tspec->time_slice_start = now;
2146
2147 if (tx_tspec->downgraded) {
2148 tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE;
2149 schedule_delayed_work(&ifmgd->tx_tspec_wk, 0);
2150 }
2151 }
2152
2153 if (tx_tspec->downgraded)
2154 return;
2155
2156 tx_tspec->consumed_tx_time += tx_time;
2157
2158 if (tx_tspec->consumed_tx_time >= tx_tspec->admitted_time) {
2159 tx_tspec->downgraded = true;
2160 tx_tspec->action = TX_TSPEC_ACTION_DOWNGRADE;
2161 schedule_delayed_work(&ifmgd->tx_tspec_wk, 0);
2162 }
2163}
2164
1986void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, 2165void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
1987 struct ieee80211_hdr *hdr, bool ack) 2166 struct ieee80211_hdr *hdr, bool ack, u16 tx_time)
1988{ 2167{
2168 ieee80211_sta_tx_wmm_ac_notify(sdata, hdr, tx_time);
2169
1989 if (!ieee80211_is_data(hdr->frame_control)) 2170 if (!ieee80211_is_data(hdr->frame_control))
1990 return; 2171 return;
1991 2172
@@ -2048,8 +2229,6 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
2048 2229
2049 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); 2230 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
2050 run_again(sdata, ifmgd->probe_timeout); 2231 run_again(sdata, ifmgd->probe_timeout);
2051 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
2052 ieee80211_flush_queues(sdata->local, sdata);
2053} 2232}
2054 2233
2055static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, 2234static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
@@ -2172,6 +2351,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2172 true, frame_buf); 2351 true, frame_buf);
2173 mutex_lock(&local->mtx); 2352 mutex_lock(&local->mtx);
2174 sdata->vif.csa_active = false; 2353 sdata->vif.csa_active = false;
2354 ifmgd->csa_waiting_bcn = false;
2175 if (sdata->csa_block_tx) { 2355 if (sdata->csa_block_tx) {
2176 ieee80211_wake_vif_queues(local, sdata, 2356 ieee80211_wake_vif_queues(local, sdata,
2177 IEEE80211_QUEUE_STOP_REASON_CSA); 2357 IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -3196,6 +3376,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3196 } 3376 }
3197 } 3377 }
3198 3378
3379 if (ifmgd->csa_waiting_bcn)
3380 ieee80211_chswitch_post_beacon(sdata);
3381
3199 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) 3382 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
3200 return; 3383 return;
3201 ifmgd->beacon_crc = ncrc; 3384 ifmgd->beacon_crc = ncrc;
@@ -3204,6 +3387,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3204 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); 3387 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
3205 3388
3206 ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, 3389 ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
3390 rx_status->device_timestamp,
3207 &elems, true); 3391 &elems, true);
3208 3392
3209 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && 3393 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) &&
@@ -3335,8 +3519,9 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3335 break; 3519 break;
3336 3520
3337 ieee80211_sta_process_chanswitch(sdata, 3521 ieee80211_sta_process_chanswitch(sdata,
3338 rx_status->mactime, 3522 rx_status->mactime,
3339 &elems, false); 3523 rx_status->device_timestamp,
3524 &elems, false);
3340 } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { 3525 } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
3341 ies_len = skb->len - 3526 ies_len = skb->len -
3342 offsetof(struct ieee80211_mgmt, 3527 offsetof(struct ieee80211_mgmt,
@@ -3357,8 +3542,9 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3357 &mgmt->u.action.u.ext_chan_switch.data; 3542 &mgmt->u.action.u.ext_chan_switch.data;
3358 3543
3359 ieee80211_sta_process_chanswitch(sdata, 3544 ieee80211_sta_process_chanswitch(sdata,
3360 rx_status->mactime, 3545 rx_status->mactime,
3361 &elems, false); 3546 rx_status->device_timestamp,
3547 &elems, false);
3362 } 3548 }
3363 break; 3549 break;
3364 } 3550 }
@@ -3665,11 +3851,12 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data)
3665 struct ieee80211_sub_if_data *sdata = 3851 struct ieee80211_sub_if_data *sdata =
3666 (struct ieee80211_sub_if_data *) data; 3852 (struct ieee80211_sub_if_data *) data;
3667 struct ieee80211_local *local = sdata->local; 3853 struct ieee80211_local *local = sdata->local;
3854 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3668 3855
3669 if (local->quiescing) 3856 if (local->quiescing)
3670 return; 3857 return;
3671 3858
3672 if (sdata->vif.csa_active) 3859 if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn)
3673 return; 3860 return;
3674 3861
3675 sdata->u.mgd.connection_loss = false; 3862 sdata->u.mgd.connection_loss = false;
@@ -3687,7 +3874,7 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data)
3687 if (local->quiescing) 3874 if (local->quiescing)
3688 return; 3875 return;
3689 3876
3690 if (sdata->vif.csa_active) 3877 if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn)
3691 return; 3878 return;
3692 3879
3693 ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); 3880 ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
@@ -3799,6 +3986,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
3799 (unsigned long) sdata); 3986 (unsigned long) sdata);
3800 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, 3987 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer,
3801 (unsigned long) sdata); 3988 (unsigned long) sdata);
3989 INIT_DELAYED_WORK(&ifmgd->tx_tspec_wk,
3990 ieee80211_sta_handle_tspec_ac_params_wk);
3802 3991
3803 ifmgd->flags = 0; 3992 ifmgd->flags = 0;
3804 ifmgd->powersave = sdata->wdev.ps; 3993 ifmgd->powersave = sdata->wdev.ps;
diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c
new file mode 100644
index 000000000000..358d5f9d8207
--- /dev/null
+++ b/net/mac80211/ocb.c
@@ -0,0 +1,250 @@
1/*
2 * OCB mode implementation
3 *
4 * Copyright: (c) 2014 Czech Technical University in Prague
5 * (c) 2014 Volkswagen Group Research
6 * Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz>
7 * Funded by: Volkswagen Group Research
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/delay.h>
15#include <linux/if_ether.h>
16#include <linux/skbuff.h>
17#include <linux/if_arp.h>
18#include <linux/etherdevice.h>
19#include <linux/rtnetlink.h>
20#include <net/mac80211.h>
21#include <asm/unaligned.h>
22
23#include "ieee80211_i.h"
24#include "driver-ops.h"
25#include "rate.h"
26
27#define IEEE80211_OCB_HOUSEKEEPING_INTERVAL (60 * HZ)
28#define IEEE80211_OCB_PEER_INACTIVITY_LIMIT (240 * HZ)
29#define IEEE80211_OCB_MAX_STA_ENTRIES 128
30
31/**
32 * enum ocb_deferred_task_flags - mac80211 OCB deferred tasks
33 * @OCB_WORK_HOUSEKEEPING: run the periodic OCB housekeeping tasks
34 *
35 * These flags are used in @wrkq_flags field of &struct ieee80211_if_ocb
36 */
37enum ocb_deferred_task_flags {
38 OCB_WORK_HOUSEKEEPING,
39};
40
41void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata,
42 const u8 *bssid, const u8 *addr,
43 u32 supp_rates)
44{
45 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
46 struct ieee80211_local *local = sdata->local;
47 struct ieee80211_chanctx_conf *chanctx_conf;
48 struct ieee80211_supported_band *sband;
49 enum nl80211_bss_scan_width scan_width;
50 struct sta_info *sta;
51 int band;
52
53 /* XXX: Consider removing the least recently used entry and
54 * allow new one to be added.
55 */
56 if (local->num_sta >= IEEE80211_OCB_MAX_STA_ENTRIES) {
57 net_info_ratelimited("%s: No room for a new OCB STA entry %pM\n",
58 sdata->name, addr);
59 return;
60 }
61
62 ocb_dbg(sdata, "Adding new OCB station %pM\n", addr);
63
64 rcu_read_lock();
65 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
66 if (WARN_ON_ONCE(!chanctx_conf)) {
67 rcu_read_unlock();
68 return;
69 }
70 band = chanctx_conf->def.chan->band;
71 scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def);
72 rcu_read_unlock();
73
74 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
75 if (!sta)
76 return;
77
78 sta->last_rx = jiffies;
79
80 /* Add only mandatory rates for now */
81 sband = local->hw.wiphy->bands[band];
82 sta->sta.supp_rates[band] =
83 ieee80211_mandatory_rates(sband, scan_width);
84
85 spin_lock(&ifocb->incomplete_lock);
86 list_add(&sta->list, &ifocb->incomplete_stations);
87 spin_unlock(&ifocb->incomplete_lock);
88 ieee80211_queue_work(&local->hw, &sdata->work);
89}
90
91static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta)
92 __acquires(RCU)
93{
94 struct ieee80211_sub_if_data *sdata = sta->sdata;
95 u8 addr[ETH_ALEN];
96
97 memcpy(addr, sta->sta.addr, ETH_ALEN);
98
99 ocb_dbg(sdata, "Adding new IBSS station %pM (dev=%s)\n",
100 addr, sdata->name);
101
102 sta_info_move_state(sta, IEEE80211_STA_AUTH);
103 sta_info_move_state(sta, IEEE80211_STA_ASSOC);
104 sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
105
106 rate_control_rate_init(sta);
107
108 /* If it fails, maybe we raced another insertion? */
109 if (sta_info_insert_rcu(sta))
110 return sta_info_get(sdata, addr);
111 return sta;
112}
113
114static void ieee80211_ocb_housekeeping(struct ieee80211_sub_if_data *sdata)
115{
116 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
117
118 ocb_dbg(sdata, "Running ocb housekeeping\n");
119
120 ieee80211_sta_expire(sdata, IEEE80211_OCB_PEER_INACTIVITY_LIMIT);
121
122 mod_timer(&ifocb->housekeeping_timer,
123 round_jiffies(jiffies + IEEE80211_OCB_HOUSEKEEPING_INTERVAL));
124}
125
126void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata)
127{
128 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
129 struct sta_info *sta;
130
131 if (ifocb->joined != true)
132 return;
133
134 sdata_lock(sdata);
135
136 spin_lock_bh(&ifocb->incomplete_lock);
137 while (!list_empty(&ifocb->incomplete_stations)) {
138 sta = list_first_entry(&ifocb->incomplete_stations,
139 struct sta_info, list);
140 list_del(&sta->list);
141 spin_unlock_bh(&ifocb->incomplete_lock);
142
143 ieee80211_ocb_finish_sta(sta);
144 rcu_read_unlock();
145 spin_lock_bh(&ifocb->incomplete_lock);
146 }
147 spin_unlock_bh(&ifocb->incomplete_lock);
148
149 if (test_and_clear_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags))
150 ieee80211_ocb_housekeeping(sdata);
151
152 sdata_unlock(sdata);
153}
154
155static void ieee80211_ocb_housekeeping_timer(unsigned long data)
156{
157 struct ieee80211_sub_if_data *sdata = (void *)data;
158 struct ieee80211_local *local = sdata->local;
159 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
160
161 set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags);
162
163 ieee80211_queue_work(&local->hw, &sdata->work);
164}
165
166void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata)
167{
168 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
169
170 setup_timer(&ifocb->housekeeping_timer,
171 ieee80211_ocb_housekeeping_timer,
172 (unsigned long)sdata);
173 INIT_LIST_HEAD(&ifocb->incomplete_stations);
174 spin_lock_init(&ifocb->incomplete_lock);
175}
176
177int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata,
178 struct ocb_setup *setup)
179{
180 struct ieee80211_local *local = sdata->local;
181 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
182 u32 changed = BSS_CHANGED_OCB;
183 int err;
184
185 if (ifocb->joined == true)
186 return -EINVAL;
187
188 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
189 sdata->smps_mode = IEEE80211_SMPS_OFF;
190 sdata->needed_rx_chains = sdata->local->rx_chains;
191
192 mutex_lock(&sdata->local->mtx);
193 err = ieee80211_vif_use_channel(sdata, &setup->chandef,
194 IEEE80211_CHANCTX_SHARED);
195 mutex_unlock(&sdata->local->mtx);
196 if (err)
197 return err;
198
199 ieee80211_bss_info_change_notify(sdata, changed);
200
201 ifocb->joined = true;
202
203 set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags);
204 ieee80211_queue_work(&local->hw, &sdata->work);
205
206 netif_carrier_on(sdata->dev);
207 return 0;
208}
209
210int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata)
211{
212 struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
213 struct ieee80211_local *local = sdata->local;
214 struct sta_info *sta;
215
216 ifocb->joined = false;
217 sta_info_flush(sdata);
218
219 spin_lock_bh(&ifocb->incomplete_lock);
220 while (!list_empty(&ifocb->incomplete_stations)) {
221 sta = list_first_entry(&ifocb->incomplete_stations,
222 struct sta_info, list);
223 list_del(&sta->list);
224 spin_unlock_bh(&ifocb->incomplete_lock);
225
226 sta_info_free(local, sta);
227 spin_lock_bh(&ifocb->incomplete_lock);
228 }
229 spin_unlock_bh(&ifocb->incomplete_lock);
230
231 netif_carrier_off(sdata->dev);
232 clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
233 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_OCB);
234
235 mutex_lock(&sdata->local->mtx);
236 ieee80211_vif_release_channel(sdata);
237 mutex_unlock(&sdata->local->mtx);
238
239 skb_queue_purge(&sdata->skb_queue);
240
241 del_timer_sync(&sdata->u.ocb.housekeeping_timer);
242 /* If the timer fired while we waited for it, it will have
243 * requeued the work. Now the work will be running again
244 * but will not rearm the timer again because it checks
245 * whether we are connected to the network or not -- at this
246 * point we shouldn't be anymore.
247 */
248
249 return 0;
250}
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 2baa7ed8789d..c2b91bf47f6d 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -191,7 +191,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
191 * (1) if any success probabilitiy >= 95%, out of those rates 191 * (1) if any success probabilitiy >= 95%, out of those rates
192 * choose the maximum throughput rate as max_prob_rate 192 * choose the maximum throughput rate as max_prob_rate
193 * (2) if all success probabilities < 95%, the rate with 193 * (2) if all success probabilities < 95%, the rate with
194 * highest success probability is choosen as max_prob_rate */ 194 * highest success probability is chosen as max_prob_rate */
195 if (mrs->probability >= MINSTREL_FRAC(95, 100)) { 195 if (mrs->probability >= MINSTREL_FRAC(95, 100)) {
196 if (mrs->cur_tp >= mi->r[tmp_prob_rate].stats.cur_tp) 196 if (mrs->cur_tp >= mi->r[tmp_prob_rate].stats.cur_tp)
197 tmp_prob_rate = i; 197 tmp_prob_rate = i;
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index df90ce2db00c..c50fd94d2aef 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -10,6 +10,7 @@
10#include <linux/skbuff.h> 10#include <linux/skbuff.h>
11#include <linux/debugfs.h> 11#include <linux/debugfs.h>
12#include <linux/random.h> 12#include <linux/random.h>
13#include <linux/moduleparam.h>
13#include <linux/ieee80211.h> 14#include <linux/ieee80211.h>
14#include <net/mac80211.h> 15#include <net/mac80211.h>
15#include "rate.h" 16#include "rate.h"
@@ -34,12 +35,17 @@
34/* Transmit duration for the raw data part of an average sized packet */ 35/* Transmit duration for the raw data part of an average sized packet */
35#define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) 36#define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps)))
36 37
38#define BW_20 0
39#define BW_40 1
40#define BW_80 2
41
37/* 42/*
38 * Define group sort order: HT40 -> SGI -> #streams 43 * Define group sort order: HT40 -> SGI -> #streams
39 */ 44 */
40#define GROUP_IDX(_streams, _sgi, _ht40) \ 45#define GROUP_IDX(_streams, _sgi, _ht40) \
46 MINSTREL_HT_GROUP_0 + \
41 MINSTREL_MAX_STREAMS * 2 * _ht40 + \ 47 MINSTREL_MAX_STREAMS * 2 * _ht40 + \
42 MINSTREL_MAX_STREAMS * _sgi + \ 48 MINSTREL_MAX_STREAMS * _sgi + \
43 _streams - 1 49 _streams - 1
44 50
45/* MCS rate information for an MCS group */ 51/* MCS rate information for an MCS group */
@@ -47,6 +53,7 @@
47 [GROUP_IDX(_streams, _sgi, _ht40)] = { \ 53 [GROUP_IDX(_streams, _sgi, _ht40)] = { \
48 .streams = _streams, \ 54 .streams = _streams, \
49 .flags = \ 55 .flags = \
56 IEEE80211_TX_RC_MCS | \
50 (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ 57 (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \
51 (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ 58 (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \
52 .duration = { \ 59 .duration = { \
@@ -61,6 +68,47 @@
61 } \ 68 } \
62} 69}
63 70
71#define VHT_GROUP_IDX(_streams, _sgi, _bw) \
72 (MINSTREL_VHT_GROUP_0 + \
73 MINSTREL_MAX_STREAMS * 2 * (_bw) + \
74 MINSTREL_MAX_STREAMS * (_sgi) + \
75 (_streams) - 1)
76
77#define BW2VBPS(_bw, r3, r2, r1) \
78 (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
79
80#define VHT_GROUP(_streams, _sgi, _bw) \
81 [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \
82 .streams = _streams, \
83 .flags = \
84 IEEE80211_TX_RC_VHT_MCS | \
85 (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \
86 (_bw == BW_80 ? IEEE80211_TX_RC_80_MHZ_WIDTH : \
87 _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \
88 .duration = { \
89 MCS_DURATION(_streams, _sgi, \
90 BW2VBPS(_bw, 117, 54, 26)), \
91 MCS_DURATION(_streams, _sgi, \
92 BW2VBPS(_bw, 234, 108, 52)), \
93 MCS_DURATION(_streams, _sgi, \
94 BW2VBPS(_bw, 351, 162, 78)), \
95 MCS_DURATION(_streams, _sgi, \
96 BW2VBPS(_bw, 468, 216, 104)), \
97 MCS_DURATION(_streams, _sgi, \
98 BW2VBPS(_bw, 702, 324, 156)), \
99 MCS_DURATION(_streams, _sgi, \
100 BW2VBPS(_bw, 936, 432, 208)), \
101 MCS_DURATION(_streams, _sgi, \
102 BW2VBPS(_bw, 1053, 486, 234)), \
103 MCS_DURATION(_streams, _sgi, \
104 BW2VBPS(_bw, 1170, 540, 260)), \
105 MCS_DURATION(_streams, _sgi, \
106 BW2VBPS(_bw, 1404, 648, 312)), \
107 MCS_DURATION(_streams, _sgi, \
108 BW2VBPS(_bw, 1560, 720, 346)) \
109 } \
110}
111
64#define CCK_DURATION(_bitrate, _short, _len) \ 112#define CCK_DURATION(_bitrate, _short, _len) \
65 (1000 * (10 /* SIFS */ + \ 113 (1000 * (10 /* SIFS */ + \
66 (_short ? 72 + 24 : 144 + 48) + \ 114 (_short ? 72 + 24 : 144 + 48) + \
@@ -76,53 +124,96 @@
76 CCK_ACK_DURATION(55, _short), \ 124 CCK_ACK_DURATION(55, _short), \
77 CCK_ACK_DURATION(110, _short) 125 CCK_ACK_DURATION(110, _short)
78 126
79#define CCK_GROUP \ 127#define CCK_GROUP \
80 [MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS] = { \ 128 [MINSTREL_CCK_GROUP] = { \
81 .streams = 0, \ 129 .streams = 0, \
82 .duration = { \ 130 .flags = 0, \
83 CCK_DURATION_LIST(false), \ 131 .duration = { \
84 CCK_DURATION_LIST(true) \ 132 CCK_DURATION_LIST(false), \
85 } \ 133 CCK_DURATION_LIST(true) \
134 } \
86 } 135 }
87 136
137#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
138static bool minstrel_vht_only = true;
139module_param(minstrel_vht_only, bool, 0644);
140MODULE_PARM_DESC(minstrel_vht_only,
141 "Use only VHT rates when VHT is supported by sta.");
142#endif
143
88/* 144/*
89 * To enable sufficiently targeted rate sampling, MCS rates are divided into 145 * To enable sufficiently targeted rate sampling, MCS rates are divided into
90 * groups, based on the number of streams and flags (HT40, SGI) that they 146 * groups, based on the number of streams and flags (HT40, SGI) that they
91 * use. 147 * use.
92 * 148 *
93 * Sortorder has to be fixed for GROUP_IDX macro to be applicable: 149 * Sortorder has to be fixed for GROUP_IDX macro to be applicable:
94 * HT40 -> SGI -> #streams 150 * BW -> SGI -> #streams
95 */ 151 */
96const struct mcs_group minstrel_mcs_groups[] = { 152const struct mcs_group minstrel_mcs_groups[] = {
97 MCS_GROUP(1, 0, 0), 153 MCS_GROUP(1, 0, BW_20),
98 MCS_GROUP(2, 0, 0), 154 MCS_GROUP(2, 0, BW_20),
99#if MINSTREL_MAX_STREAMS >= 3 155#if MINSTREL_MAX_STREAMS >= 3
100 MCS_GROUP(3, 0, 0), 156 MCS_GROUP(3, 0, BW_20),
101#endif 157#endif
102 158
103 MCS_GROUP(1, 1, 0), 159 MCS_GROUP(1, 1, BW_20),
104 MCS_GROUP(2, 1, 0), 160 MCS_GROUP(2, 1, BW_20),
105#if MINSTREL_MAX_STREAMS >= 3 161#if MINSTREL_MAX_STREAMS >= 3
106 MCS_GROUP(3, 1, 0), 162 MCS_GROUP(3, 1, BW_20),
107#endif 163#endif
108 164
109 MCS_GROUP(1, 0, 1), 165 MCS_GROUP(1, 0, BW_40),
110 MCS_GROUP(2, 0, 1), 166 MCS_GROUP(2, 0, BW_40),
111#if MINSTREL_MAX_STREAMS >= 3 167#if MINSTREL_MAX_STREAMS >= 3
112 MCS_GROUP(3, 0, 1), 168 MCS_GROUP(3, 0, BW_40),
113#endif 169#endif
114 170
115 MCS_GROUP(1, 1, 1), 171 MCS_GROUP(1, 1, BW_40),
116 MCS_GROUP(2, 1, 1), 172 MCS_GROUP(2, 1, BW_40),
117#if MINSTREL_MAX_STREAMS >= 3 173#if MINSTREL_MAX_STREAMS >= 3
118 MCS_GROUP(3, 1, 1), 174 MCS_GROUP(3, 1, BW_40),
119#endif 175#endif
120 176
121 /* must be last */ 177 CCK_GROUP,
122 CCK_GROUP
123};
124 178
125#define MINSTREL_CCK_GROUP (ARRAY_SIZE(minstrel_mcs_groups) - 1) 179#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
180 VHT_GROUP(1, 0, BW_20),
181 VHT_GROUP(2, 0, BW_20),
182#if MINSTREL_MAX_STREAMS >= 3
183 VHT_GROUP(3, 0, BW_20),
184#endif
185
186 VHT_GROUP(1, 1, BW_20),
187 VHT_GROUP(2, 1, BW_20),
188#if MINSTREL_MAX_STREAMS >= 3
189 VHT_GROUP(3, 1, BW_20),
190#endif
191
192 VHT_GROUP(1, 0, BW_40),
193 VHT_GROUP(2, 0, BW_40),
194#if MINSTREL_MAX_STREAMS >= 3
195 VHT_GROUP(3, 0, BW_40),
196#endif
197
198 VHT_GROUP(1, 1, BW_40),
199 VHT_GROUP(2, 1, BW_40),
200#if MINSTREL_MAX_STREAMS >= 3
201 VHT_GROUP(3, 1, BW_40),
202#endif
203
204 VHT_GROUP(1, 0, BW_80),
205 VHT_GROUP(2, 0, BW_80),
206#if MINSTREL_MAX_STREAMS >= 3
207 VHT_GROUP(3, 0, BW_80),
208#endif
209
210 VHT_GROUP(1, 1, BW_80),
211 VHT_GROUP(2, 1, BW_80),
212#if MINSTREL_MAX_STREAMS >= 3
213 VHT_GROUP(3, 1, BW_80),
214#endif
215#endif
216};
126 217
127static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; 218static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
128 219
@@ -130,16 +221,64 @@ static void
130minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi); 221minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi);
131 222
132/* 223/*
224 * Some VHT MCSes are invalid (when Ndbps / Nes is not an integer)
225 * e.g for MCS9@20MHzx1Nss: Ndbps=8x52*(5/6) Nes=1
226 *
227 * Returns the valid mcs map for struct minstrel_mcs_group_data.supported
228 */
229static u16
230minstrel_get_valid_vht_rates(int bw, int nss, __le16 mcs_map)
231{
232 u16 mask = 0;
233
234 if (bw == BW_20) {
235 if (nss != 3 && nss != 6)
236 mask = BIT(9);
237 } else if (bw == BW_80) {
238 if (nss == 3 || nss == 7)
239 mask = BIT(6);
240 else if (nss == 6)
241 mask = BIT(9);
242 } else {
243 WARN_ON(bw != BW_40);
244 }
245
246 switch ((le16_to_cpu(mcs_map) >> (2 * (nss - 1))) & 3) {
247 case IEEE80211_VHT_MCS_SUPPORT_0_7:
248 mask |= 0x300;
249 break;
250 case IEEE80211_VHT_MCS_SUPPORT_0_8:
251 mask |= 0x200;
252 break;
253 case IEEE80211_VHT_MCS_SUPPORT_0_9:
254 break;
255 default:
256 mask = 0x3ff;
257 }
258
259 return 0x3ff & ~mask;
260}
261
262/*
133 * Look up an MCS group index based on mac80211 rate information 263 * Look up an MCS group index based on mac80211 rate information
134 */ 264 */
135static int 265static int
136minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) 266minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate)
137{ 267{
138 return GROUP_IDX((rate->idx / MCS_GROUP_RATES) + 1, 268 return GROUP_IDX((rate->idx / 8) + 1,
139 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), 269 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI),
140 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); 270 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH));
141} 271}
142 272
273static int
274minstrel_vht_get_group_idx(struct ieee80211_tx_rate *rate)
275{
276 return VHT_GROUP_IDX(ieee80211_rate_get_vht_nss(rate),
277 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI),
278 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) +
279 2*!!(rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH));
280}
281
143static struct minstrel_rate_stats * 282static struct minstrel_rate_stats *
144minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, 283minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
145 struct ieee80211_tx_rate *rate) 284 struct ieee80211_tx_rate *rate)
@@ -149,6 +288,9 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
149 if (rate->flags & IEEE80211_TX_RC_MCS) { 288 if (rate->flags & IEEE80211_TX_RC_MCS) {
150 group = minstrel_ht_get_group_idx(rate); 289 group = minstrel_ht_get_group_idx(rate);
151 idx = rate->idx % 8; 290 idx = rate->idx % 8;
291 } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
292 group = minstrel_vht_get_group_idx(rate);
293 idx = ieee80211_rate_get_vht_mcs(rate);
152 } else { 294 } else {
153 group = MINSTREL_CCK_GROUP; 295 group = MINSTREL_CCK_GROUP;
154 296
@@ -240,8 +382,8 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
240 * MCS groups, CCK rates do not provide aggregation and are therefore at last. 382 * MCS groups, CCK rates do not provide aggregation and are therefore at last.
241 */ 383 */
242static void 384static void
243minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index, 385minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u16 index,
244 u8 *tp_list) 386 u16 *tp_list)
245{ 387{
246 int cur_group, cur_idx, cur_thr, cur_prob; 388 int cur_group, cur_idx, cur_thr, cur_prob;
247 int tmp_group, tmp_idx, tmp_thr, tmp_prob; 389 int tmp_group, tmp_idx, tmp_thr, tmp_prob;
@@ -278,7 +420,7 @@ minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index,
278 * Find and set the topmost probability rate per sta and per group 420 * Find and set the topmost probability rate per sta and per group
279 */ 421 */
280static void 422static void
281minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u8 index) 423minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index)
282{ 424{
283 struct minstrel_mcs_group_data *mg; 425 struct minstrel_mcs_group_data *mg;
284 struct minstrel_rate_stats *mr; 426 struct minstrel_rate_stats *mr;
@@ -321,8 +463,8 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u8 index)
321 */ 463 */
322static void 464static void
323minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi, 465minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi,
324 u8 tmp_mcs_tp_rate[MAX_THR_RATES], 466 u16 tmp_mcs_tp_rate[MAX_THR_RATES],
325 u8 tmp_cck_tp_rate[MAX_THR_RATES]) 467 u16 tmp_cck_tp_rate[MAX_THR_RATES])
326{ 468{
327 unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp; 469 unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp;
328 int i; 470 int i;
@@ -386,8 +528,8 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
386 struct minstrel_mcs_group_data *mg; 528 struct minstrel_mcs_group_data *mg;
387 struct minstrel_rate_stats *mr; 529 struct minstrel_rate_stats *mr;
388 int group, i, j; 530 int group, i, j;
389 u8 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; 531 u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES];
390 u8 tmp_cck_tp_rate[MAX_THR_RATES], index; 532 u16 tmp_cck_tp_rate[MAX_THR_RATES], index;
391 533
392 if (mi->ampdu_packets > 0) { 534 if (mi->ampdu_packets > 0) {
393 mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, 535 mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len,
@@ -485,7 +627,8 @@ minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct ieee80211_tx_rate *rat
485 if (!rate->count) 627 if (!rate->count)
486 return false; 628 return false;
487 629
488 if (rate->flags & IEEE80211_TX_RC_MCS) 630 if (rate->flags & IEEE80211_TX_RC_MCS ||
631 rate->flags & IEEE80211_TX_RC_VHT_MCS)
489 return true; 632 return true;
490 633
491 return rate->idx == mp->cck_rates[0] || 634 return rate->idx == mp->cck_rates[0] ||
@@ -517,7 +660,7 @@ minstrel_next_sample_idx(struct minstrel_ht_sta *mi)
517} 660}
518 661
519static void 662static void
520minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u8 *idx, bool primary) 663minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
521{ 664{
522 int group, orig_group; 665 int group, orig_group;
523 666
@@ -714,7 +857,7 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
714 const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; 857 const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
715 struct minstrel_rate_stats *mr; 858 struct minstrel_rate_stats *mr;
716 u8 idx; 859 u8 idx;
717 u16 flags; 860 u16 flags = group->flags;
718 861
719 mr = minstrel_get_ratestats(mi, index); 862 mr = minstrel_get_ratestats(mi, index);
720 if (!mr->retry_updated) 863 if (!mr->retry_updated)
@@ -730,13 +873,13 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
730 ratetbl->rate[offset].count_rts = mr->retry_count_rtscts; 873 ratetbl->rate[offset].count_rts = mr->retry_count_rtscts;
731 } 874 }
732 875
733 if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { 876 if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP)
734 idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; 877 idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)];
735 flags = 0; 878 else if (flags & IEEE80211_TX_RC_VHT_MCS)
736 } else { 879 idx = ((group->streams - 1) << 4) |
880 ((index % MCS_GROUP_RATES) & 0xF);
881 else
737 idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; 882 idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8;
738 flags = IEEE80211_TX_RC_MCS | group->flags;
739 }
740 883
741 if (offset > 0) { 884 if (offset > 0) {
742 ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; 885 ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts;
@@ -916,13 +1059,15 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
916 if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { 1059 if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {
917 int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); 1060 int idx = sample_idx % ARRAY_SIZE(mp->cck_rates);
918 rate->idx = mp->cck_rates[idx]; 1061 rate->idx = mp->cck_rates[idx];
919 rate->flags = 0; 1062 } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) {
920 return; 1063 ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES,
1064 sample_group->streams);
1065 } else {
1066 rate->idx = sample_idx % MCS_GROUP_RATES +
1067 (sample_group->streams - 1) * 8;
921 } 1068 }
922 1069
923 rate->idx = sample_idx % MCS_GROUP_RATES + 1070 rate->flags = sample_group->flags;
924 (sample_group->streams - 1) * 8;
925 rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags;
926} 1071}
927 1072
928static void 1073static void
@@ -962,6 +1107,8 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
962 struct minstrel_ht_sta *mi = &msp->ht; 1107 struct minstrel_ht_sta *mi = &msp->ht;
963 struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; 1108 struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
964 u16 sta_cap = sta->ht_cap.cap; 1109 u16 sta_cap = sta->ht_cap.cap;
1110 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
1111 int use_vht;
965 int n_supported = 0; 1112 int n_supported = 0;
966 int ack_dur; 1113 int ack_dur;
967 int stbc; 1114 int stbc;
@@ -971,8 +1118,14 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
971 if (!sta->ht_cap.ht_supported) 1118 if (!sta->ht_cap.ht_supported)
972 goto use_legacy; 1119 goto use_legacy;
973 1120
974 BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != 1121 BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB);
975 MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1); 1122
1123#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
1124 if (vht_cap->vht_supported)
1125 use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0);
1126 else
1127#endif
1128 use_vht = 0;
976 1129
977 msp->is_ht = true; 1130 msp->is_ht = true;
978 memset(mi, 0, sizeof(*mi)); 1131 memset(mi, 0, sizeof(*mi));
@@ -997,22 +1150,28 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
997 } 1150 }
998 mi->sample_tries = 4; 1151 mi->sample_tries = 4;
999 1152
1000 stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> 1153 /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */
1001 IEEE80211_HT_CAP_RX_STBC_SHIFT; 1154 if (!use_vht) {
1002 mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; 1155 stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >>
1156 IEEE80211_HT_CAP_RX_STBC_SHIFT;
1157 mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
1003 1158
1004 if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) 1159 if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING)
1005 mi->tx_flags |= IEEE80211_TX_CTL_LDPC; 1160 mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
1161 }
1006 1162
1007 for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { 1163 for (i = 0; i < ARRAY_SIZE(mi->groups); i++) {
1164 u32 gflags = minstrel_mcs_groups[i].flags;
1165 int bw, nss;
1166
1008 mi->groups[i].supported = 0; 1167 mi->groups[i].supported = 0;
1009 if (i == MINSTREL_CCK_GROUP) { 1168 if (i == MINSTREL_CCK_GROUP) {
1010 minstrel_ht_update_cck(mp, mi, sband, sta); 1169 minstrel_ht_update_cck(mp, mi, sband, sta);
1011 continue; 1170 continue;
1012 } 1171 }
1013 1172
1014 if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_SHORT_GI) { 1173 if (gflags & IEEE80211_TX_RC_SHORT_GI) {
1015 if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { 1174 if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1016 if (!(sta_cap & IEEE80211_HT_CAP_SGI_40)) 1175 if (!(sta_cap & IEEE80211_HT_CAP_SGI_40))
1017 continue; 1176 continue;
1018 } else { 1177 } else {
@@ -1021,17 +1180,51 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
1021 } 1180 }
1022 } 1181 }
1023 1182
1024 if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH && 1183 if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH &&
1025 sta->bandwidth < IEEE80211_STA_RX_BW_40) 1184 sta->bandwidth < IEEE80211_STA_RX_BW_40)
1026 continue; 1185 continue;
1027 1186
1187 nss = minstrel_mcs_groups[i].streams;
1188
1028 /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */ 1189 /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */
1029 if (sta->smps_mode == IEEE80211_SMPS_STATIC && 1190 if (sta->smps_mode == IEEE80211_SMPS_STATIC && nss > 1)
1030 minstrel_mcs_groups[i].streams > 1) 1191 continue;
1192
1193 /* HT rate */
1194 if (gflags & IEEE80211_TX_RC_MCS) {
1195#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
1196 if (use_vht && minstrel_vht_only)
1197 continue;
1198#endif
1199 mi->groups[i].supported = mcs->rx_mask[nss - 1];
1200 if (mi->groups[i].supported)
1201 n_supported++;
1031 continue; 1202 continue;
1203 }
1204
1205 /* VHT rate */
1206 if (!vht_cap->vht_supported ||
1207 WARN_ON(!(gflags & IEEE80211_TX_RC_VHT_MCS)) ||
1208 WARN_ON(gflags & IEEE80211_TX_RC_160_MHZ_WIDTH))
1209 continue;
1210
1211 if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) {
1212 if (sta->bandwidth < IEEE80211_STA_RX_BW_80 ||
1213 ((gflags & IEEE80211_TX_RC_SHORT_GI) &&
1214 !(vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80))) {
1215 continue;
1216 }
1217 }
1218
1219 if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1220 bw = BW_40;
1221 else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH)
1222 bw = BW_80;
1223 else
1224 bw = BW_20;
1032 1225
1033 mi->groups[i].supported = 1226 mi->groups[i].supported = minstrel_get_valid_vht_rates(bw, nss,
1034 mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; 1227 vht_cap->vht_mcs.tx_mcs_map);
1035 1228
1036 if (mi->groups[i].supported) 1229 if (mi->groups[i].supported)
1037 n_supported++; 1230 n_supported++;
diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h
index 01570e0e014b..f2217d6aa0c2 100644
--- a/net/mac80211/rc80211_minstrel_ht.h
+++ b/net/mac80211/rc80211_minstrel_ht.h
@@ -13,10 +13,32 @@
13 * The number of streams can be changed to 2 to reduce code 13 * The number of streams can be changed to 2 to reduce code
14 * size and memory footprint. 14 * size and memory footprint.
15 */ 15 */
16#define MINSTREL_MAX_STREAMS 3 16#define MINSTREL_MAX_STREAMS 3
17#define MINSTREL_STREAM_GROUPS 4 17#define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */
18#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
19#define MINSTREL_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */
20#else
21#define MINSTREL_VHT_STREAM_GROUPS 0
22#endif
18 23
19#define MCS_GROUP_RATES 8 24#define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \
25 MINSTREL_HT_STREAM_GROUPS)
26#define MINSTREL_VHT_GROUPS_NB (MINSTREL_MAX_STREAMS * \
27 MINSTREL_VHT_STREAM_GROUPS)
28#define MINSTREL_CCK_GROUPS_NB 1
29#define MINSTREL_GROUPS_NB (MINSTREL_HT_GROUPS_NB + \
30 MINSTREL_VHT_GROUPS_NB + \
31 MINSTREL_CCK_GROUPS_NB)
32
33#define MINSTREL_HT_GROUP_0 0
34#define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB)
35#define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1)
36
37#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
38#define MCS_GROUP_RATES 10
39#else
40#define MCS_GROUP_RATES 8
41#endif
20 42
21struct mcs_group { 43struct mcs_group {
22 u32 flags; 44 u32 flags;
@@ -31,11 +53,11 @@ struct minstrel_mcs_group_data {
31 u8 column; 53 u8 column;
32 54
33 /* bitfield of supported MCS rates of this group */ 55 /* bitfield of supported MCS rates of this group */
34 u8 supported; 56 u16 supported;
35 57
36 /* sorted rate set within a MCS group*/ 58 /* sorted rate set within a MCS group*/
37 u8 max_group_tp_rate[MAX_THR_RATES]; 59 u16 max_group_tp_rate[MAX_THR_RATES];
38 u8 max_group_prob_rate; 60 u16 max_group_prob_rate;
39 61
40 /* MCS rate statistics */ 62 /* MCS rate statistics */
41 struct minstrel_rate_stats rates[MCS_GROUP_RATES]; 63 struct minstrel_rate_stats rates[MCS_GROUP_RATES];
@@ -52,8 +74,8 @@ struct minstrel_ht_sta {
52 unsigned int avg_ampdu_len; 74 unsigned int avg_ampdu_len;
53 75
54 /* overall sorted rate set */ 76 /* overall sorted rate set */
55 u8 max_tp_rate[MAX_THR_RATES]; 77 u16 max_tp_rate[MAX_THR_RATES];
56 u8 max_prob_rate; 78 u16 max_prob_rate;
57 79
58 /* time of last status update */ 80 /* time of last status update */
59 unsigned long stats_update; 81 unsigned long stats_update;
@@ -80,7 +102,7 @@ struct minstrel_ht_sta {
80 u8 cck_supported_short; 102 u8 cck_supported_short;
81 103
82 /* MCS rate group info and statistics */ 104 /* MCS rate group info and statistics */
83 struct minstrel_mcs_group_data groups[MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1]; 105 struct minstrel_mcs_group_data groups[MINSTREL_GROUPS_NB];
84}; 106};
85 107
86struct minstrel_ht_sta_priv { 108struct minstrel_ht_sta_priv {
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c
index d537bec93754..20c676b8e5b6 100644
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -18,19 +18,23 @@
18static char * 18static char *
19minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) 19minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
20{ 20{
21 unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS;
22 const struct mcs_group *mg; 21 const struct mcs_group *mg;
23 unsigned int j, tp, prob, eprob; 22 unsigned int j, tp, prob, eprob;
24 char htmode = '2'; 23 char htmode = '2';
25 char gimode = 'L'; 24 char gimode = 'L';
25 u32 gflags;
26 26
27 if (!mi->groups[i].supported) 27 if (!mi->groups[i].supported)
28 return p; 28 return p;
29 29
30 mg = &minstrel_mcs_groups[i]; 30 mg = &minstrel_mcs_groups[i];
31 if (mg->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 31 gflags = mg->flags;
32
33 if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH)
32 htmode = '4'; 34 htmode = '4';
33 if (mg->flags & IEEE80211_TX_RC_SHORT_GI) 35 else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH)
36 htmode = '8';
37 if (gflags & IEEE80211_TX_RC_SHORT_GI)
34 gimode = 'S'; 38 gimode = 'S';
35 39
36 for (j = 0; j < MCS_GROUP_RATES; j++) { 40 for (j = 0; j < MCS_GROUP_RATES; j++) {
@@ -41,10 +45,12 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
41 if (!(mi->groups[i].supported & BIT(j))) 45 if (!(mi->groups[i].supported & BIT(j)))
42 continue; 46 continue;
43 47
44 if (i == max_mcs) 48 if (gflags & IEEE80211_TX_RC_MCS)
45 p += sprintf(p, "CCK/%cP ", j < 4 ? 'L' : 'S'); 49 p += sprintf(p, " HT%c0/%cGI ", htmode, gimode);
50 else if (gflags & IEEE80211_TX_RC_VHT_MCS)
51 p += sprintf(p, "VHT%c0/%cGI ", htmode, gimode);
46 else 52 else
47 p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); 53 p += sprintf(p, " CCK/%cP ", j < 4 ? 'L' : 'S');
48 54
49 *(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' '; 55 *(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' ';
50 *(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' '; 56 *(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' ';
@@ -52,11 +58,14 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
52 *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' '; 58 *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' ';
53 *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; 59 *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' ';
54 60
55 if (i == max_mcs) { 61 if (gflags & IEEE80211_TX_RC_MCS) {
56 int r = bitrates[j % 4]; 62 p += sprintf(p, " MCS%-2u ", (mg->streams - 1) * 8 + j);
57 p += sprintf(p, " %2u.%1uM", r / 10, r % 10); 63 } else if (gflags & IEEE80211_TX_RC_VHT_MCS) {
64 p += sprintf(p, " MCS%-1u/%1u", j, mg->streams);
58 } else { 65 } else {
59 p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j); 66 int r = bitrates[j % 4];
67
68 p += sprintf(p, " %2u.%1uM ", r / 10, r % 10);
60 } 69 }
61 70
62 tp = mr->cur_tp / 10; 71 tp = mr->cur_tp / 10;
@@ -85,7 +94,6 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
85 struct minstrel_ht_sta *mi = &msp->ht; 94 struct minstrel_ht_sta *mi = &msp->ht;
86 struct minstrel_debugfs_info *ms; 95 struct minstrel_debugfs_info *ms;
87 unsigned int i; 96 unsigned int i;
88 unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS;
89 char *p; 97 char *p;
90 int ret; 98 int ret;
91 99
@@ -96,18 +104,19 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
96 return ret; 104 return ret;
97 } 105 }
98 106
99 ms = kmalloc(8192, GFP_KERNEL); 107 ms = kmalloc(32768, GFP_KERNEL);
100 if (!ms) 108 if (!ms)
101 return -ENOMEM; 109 return -ENOMEM;
102 110
103 file->private_data = ms; 111 file->private_data = ms;
104 p = ms->buf; 112 p = ms->buf;
105 p += sprintf(p, "type rate tpt eprob *prob " 113 p += sprintf(p, " type rate tpt eprob *prob "
106 "ret *ok(*cum) ok( cum)\n"); 114 "ret *ok(*cum) ok( cum)\n");
107 115
108 116 p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p);
109 p = minstrel_ht_stats_dump(mi, max_mcs, p); 117 for (i = 0; i < MINSTREL_CCK_GROUP; i++)
110 for (i = 0; i < max_mcs; i++) 118 p = minstrel_ht_stats_dump(mi, i, p);
119 for (i++; i < ARRAY_SIZE(mi->groups); i++)
111 p = minstrel_ht_stats_dump(mi, i, p); 120 p = minstrel_ht_stats_dump(mi, i, p);
112 121
113 p += sprintf(p, "\nTotal packet count:: ideal %d " 122 p += sprintf(p, "\nTotal packet count:: ideal %d "
@@ -119,7 +128,7 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
119 MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); 128 MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10);
120 ms->len = p - ms->buf; 129 ms->len = p - ms->buf;
121 130
122 WARN_ON(ms->len + sizeof(*ms) > 8192); 131 WARN_ON(ms->len + sizeof(*ms) > 32768);
123 132
124 return nonseekable_open(inode, file); 133 return nonseekable_open(inode, file);
125} 134}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index a37f9af634cb..a726bb169302 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1032,6 +1032,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
1032 ieee80211_is_pspoll(hdr->frame_control)) && 1032 ieee80211_is_pspoll(hdr->frame_control)) &&
1033 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && 1033 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1034 rx->sdata->vif.type != NL80211_IFTYPE_WDS && 1034 rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
1035 rx->sdata->vif.type != NL80211_IFTYPE_OCB &&
1035 (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) { 1036 (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) {
1036 /* 1037 /*
1037 * accept port control frames from the AP even when it's not 1038 * accept port control frames from the AP even when it's not
@@ -1272,6 +1273,12 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1272 sta->last_rx_rate_vht_nss = status->vht_nss; 1273 sta->last_rx_rate_vht_nss = status->vht_nss;
1273 } 1274 }
1274 } 1275 }
1276 } else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) {
1277 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
1278 NL80211_IFTYPE_OCB);
1279 /* OCB uses wild-card BSSID */
1280 if (is_broadcast_ether_addr(bssid))
1281 sta->last_rx = jiffies;
1275 } else if (!is_multicast_ether_addr(hdr->addr1)) { 1282 } else if (!is_multicast_ether_addr(hdr->addr1)) {
1276 /* 1283 /*
1277 * Mesh beacons will update last_rx when if they are found to 1284 * Mesh beacons will update last_rx when if they are found to
@@ -2820,6 +2827,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
2820 2827
2821 if (!ieee80211_vif_is_mesh(&sdata->vif) && 2828 if (!ieee80211_vif_is_mesh(&sdata->vif) &&
2822 sdata->vif.type != NL80211_IFTYPE_ADHOC && 2829 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
2830 sdata->vif.type != NL80211_IFTYPE_OCB &&
2823 sdata->vif.type != NL80211_IFTYPE_STATION) 2831 sdata->vif.type != NL80211_IFTYPE_STATION)
2824 return RX_DROP_MONITOR; 2832 return RX_DROP_MONITOR;
2825 2833
@@ -3130,6 +3138,33 @@ static bool prepare_for_handlers(struct ieee80211_rx_data *rx,
3130 BIT(rate_idx)); 3138 BIT(rate_idx));
3131 } 3139 }
3132 break; 3140 break;
3141 case NL80211_IFTYPE_OCB:
3142 if (!bssid)
3143 return false;
3144 if (ieee80211_is_beacon(hdr->frame_control)) {
3145 return false;
3146 } else if (!is_broadcast_ether_addr(bssid)) {
3147 ocb_dbg(sdata, "BSSID mismatch in OCB mode!\n");
3148 return false;
3149 } else if (!multicast &&
3150 !ether_addr_equal(sdata->dev->dev_addr,
3151 hdr->addr1)) {
3152 /* if we are in promisc mode we also accept
3153 * packets not destined for us
3154 */
3155 if (!(sdata->dev->flags & IFF_PROMISC))
3156 return false;
3157 rx->flags &= ~IEEE80211_RX_RA_MATCH;
3158 } else if (!rx->sta) {
3159 int rate_idx;
3160 if (status->flag & RX_FLAG_HT)
3161 rate_idx = 0; /* TODO: HT rates */
3162 else
3163 rate_idx = status->rate_idx;
3164 ieee80211_ocb_rx_no_sta(sdata, bssid, hdr->addr2,
3165 BIT(rate_idx));
3166 }
3167 break;
3133 case NL80211_IFTYPE_MESH_POINT: 3168 case NL80211_IFTYPE_MESH_POINT:
3134 if (!multicast && 3169 if (!multicast &&
3135 !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { 3170 !ether_addr_equal(sdata->vif.addr, hdr->addr1)) {
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index de494df3bab8..adc25371b171 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -501,7 +501,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
501 /* make the station visible */ 501 /* make the station visible */
502 sta_info_hash_add(local, sta); 502 sta_info_hash_add(local, sta);
503 503
504 list_add_rcu(&sta->list, &local->sta_list); 504 list_add_tail_rcu(&sta->list, &local->sta_list);
505 505
506 /* notify driver */ 506 /* notify driver */
507 err = sta_info_insert_drv_state(local, sdata, sta); 507 err = sta_info_insert_drv_state(local, sdata, sta);
@@ -1531,7 +1531,7 @@ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta)
1531 break; 1531 break;
1532 case 0: 1532 case 0:
1533 /* XXX: what is a good value? */ 1533 /* XXX: what is a good value? */
1534 n_frames = 8; 1534 n_frames = 128;
1535 break; 1535 break;
1536 } 1536 }
1537 1537
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 89290e33dafe..9612d89fad56 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -704,7 +704,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
704 704
705 if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) && 705 if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) &&
706 (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) 706 (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
707 ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, acked); 707 ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data,
708 acked, info->status.tx_time);
708 709
709 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { 710 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
710 if (info->flags & IEEE80211_TX_STAT_ACK) { 711 if (info->flags & IEEE80211_TX_STAT_ACK) {
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index 4ea25dec0698..b4f368e2cb3b 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -562,8 +562,10 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
562 /* infer the initiator if we can, to support old userspace */ 562 /* infer the initiator if we can, to support old userspace */
563 switch (action_code) { 563 switch (action_code) {
564 case WLAN_TDLS_SETUP_REQUEST: 564 case WLAN_TDLS_SETUP_REQUEST:
565 if (sta) 565 if (sta) {
566 set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR); 566 set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
567 sta->sta.tdls_initiator = false;
568 }
567 /* fall-through */ 569 /* fall-through */
568 case WLAN_TDLS_SETUP_CONFIRM: 570 case WLAN_TDLS_SETUP_CONFIRM:
569 case WLAN_TDLS_DISCOVERY_REQUEST: 571 case WLAN_TDLS_DISCOVERY_REQUEST:
@@ -575,8 +577,10 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
575 * Make the last packet sent take effect for the initiator 577 * Make the last packet sent take effect for the initiator
576 * value. 578 * value.
577 */ 579 */
578 if (sta) 580 if (sta) {
579 clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR); 581 clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
582 sta->sta.tdls_initiator = true;
583 }
580 /* fall-through */ 584 /* fall-through */
581 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: 585 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
582 initiator = false; 586 initiator = false;
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 38fae7ebe984..809a4983eb4a 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -987,29 +987,34 @@ TRACE_EVENT(drv_flush,
987 987
988TRACE_EVENT(drv_channel_switch, 988TRACE_EVENT(drv_channel_switch,
989 TP_PROTO(struct ieee80211_local *local, 989 TP_PROTO(struct ieee80211_local *local,
990 struct ieee80211_sub_if_data *sdata,
990 struct ieee80211_channel_switch *ch_switch), 991 struct ieee80211_channel_switch *ch_switch),
991 992
992 TP_ARGS(local, ch_switch), 993 TP_ARGS(local, sdata, ch_switch),
993 994
994 TP_STRUCT__entry( 995 TP_STRUCT__entry(
995 LOCAL_ENTRY 996 LOCAL_ENTRY
997 VIF_ENTRY
996 CHANDEF_ENTRY 998 CHANDEF_ENTRY
997 __field(u64, timestamp) 999 __field(u64, timestamp)
1000 __field(u32, device_timestamp)
998 __field(bool, block_tx) 1001 __field(bool, block_tx)
999 __field(u8, count) 1002 __field(u8, count)
1000 ), 1003 ),
1001 1004
1002 TP_fast_assign( 1005 TP_fast_assign(
1003 LOCAL_ASSIGN; 1006 LOCAL_ASSIGN;
1007 VIF_ASSIGN;
1004 CHANDEF_ASSIGN(&ch_switch->chandef) 1008 CHANDEF_ASSIGN(&ch_switch->chandef)
1005 __entry->timestamp = ch_switch->timestamp; 1009 __entry->timestamp = ch_switch->timestamp;
1010 __entry->device_timestamp = ch_switch->device_timestamp;
1006 __entry->block_tx = ch_switch->block_tx; 1011 __entry->block_tx = ch_switch->block_tx;
1007 __entry->count = ch_switch->count; 1012 __entry->count = ch_switch->count;
1008 ), 1013 ),
1009 1014
1010 TP_printk( 1015 TP_printk(
1011 LOCAL_PR_FMT " new " CHANDEF_PR_FMT " count:%d", 1016 LOCAL_PR_FMT VIF_PR_FMT " new " CHANDEF_PR_FMT " count:%d",
1012 LOCAL_PR_ARG, CHANDEF_PR_ARG, __entry->count 1017 LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count
1013 ) 1018 )
1014); 1019);
1015 1020
@@ -1557,9 +1562,26 @@ DEFINE_EVENT(local_sdata_evt, drv_stop_ap,
1557 TP_ARGS(local, sdata) 1562 TP_ARGS(local, sdata)
1558); 1563);
1559 1564
1560DEFINE_EVENT(local_only_evt, drv_restart_complete, 1565TRACE_EVENT(drv_reconfig_complete,
1561 TP_PROTO(struct ieee80211_local *local), 1566 TP_PROTO(struct ieee80211_local *local,
1562 TP_ARGS(local) 1567 enum ieee80211_reconfig_type reconfig_type),
1568 TP_ARGS(local, reconfig_type),
1569
1570 TP_STRUCT__entry(
1571 LOCAL_ENTRY
1572 __field(u8, reconfig_type)
1573 ),
1574
1575 TP_fast_assign(
1576 LOCAL_ASSIGN;
1577 __entry->reconfig_type = reconfig_type;
1578 ),
1579
1580 TP_printk(
1581 LOCAL_PR_FMT " reconfig_type:%d",
1582 LOCAL_PR_ARG, __entry->reconfig_type
1583 )
1584
1563); 1585);
1564 1586
1565#if IS_ENABLED(CONFIG_IPV6) 1587#if IS_ENABLED(CONFIG_IPV6)
@@ -2106,6 +2128,72 @@ TRACE_EVENT(drv_channel_switch_beacon,
2106 ) 2128 )
2107); 2129);
2108 2130
2131TRACE_EVENT(drv_pre_channel_switch,
2132 TP_PROTO(struct ieee80211_local *local,
2133 struct ieee80211_sub_if_data *sdata,
2134 struct ieee80211_channel_switch *ch_switch),
2135
2136 TP_ARGS(local, sdata, ch_switch),
2137
2138 TP_STRUCT__entry(
2139 LOCAL_ENTRY
2140 VIF_ENTRY
2141 CHANDEF_ENTRY
2142 __field(u64, timestamp)
2143 __field(bool, block_tx)
2144 __field(u8, count)
2145 ),
2146
2147 TP_fast_assign(
2148 LOCAL_ASSIGN;
2149 VIF_ASSIGN;
2150 CHANDEF_ASSIGN(&ch_switch->chandef)
2151 __entry->timestamp = ch_switch->timestamp;
2152 __entry->block_tx = ch_switch->block_tx;
2153 __entry->count = ch_switch->count;
2154 ),
2155
2156 TP_printk(
2157 LOCAL_PR_FMT VIF_PR_FMT " prepare channel switch to "
2158 CHANDEF_PR_FMT " count:%d block_tx:%d timestamp:%llu",
2159 LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count,
2160 __entry->block_tx, __entry->timestamp
2161 )
2162);
2163
2164DEFINE_EVENT(local_sdata_evt, drv_post_channel_switch,
2165 TP_PROTO(struct ieee80211_local *local,
2166 struct ieee80211_sub_if_data *sdata),
2167 TP_ARGS(local, sdata)
2168);
2169
2170TRACE_EVENT(drv_get_txpower,
2171 TP_PROTO(struct ieee80211_local *local,
2172 struct ieee80211_sub_if_data *sdata,
2173 int dbm, int ret),
2174
2175 TP_ARGS(local, sdata, dbm, ret),
2176
2177 TP_STRUCT__entry(
2178 LOCAL_ENTRY
2179 VIF_ENTRY
2180 __field(int, dbm)
2181 __field(int, ret)
2182 ),
2183
2184 TP_fast_assign(
2185 LOCAL_ASSIGN;
2186 VIF_ASSIGN;
2187 __entry->dbm = dbm;
2188 __entry->ret = ret;
2189 ),
2190
2191 TP_printk(
2192 LOCAL_PR_FMT VIF_PR_FMT " dbm:%d ret:%d",
2193 LOCAL_PR_ARG, VIF_PR_ARG, __entry->dbm, __entry->ret
2194 )
2195);
2196
2109 2197
2110#ifdef CONFIG_MAC80211_MESSAGE_TRACING 2198#ifdef CONFIG_MAC80211_MESSAGE_TRACING
2111#undef TRACE_SYSTEM 2199#undef TRACE_SYSTEM
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 900632a250ec..3ffd91f295a6 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -296,6 +296,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
296 */ 296 */
297 return TX_DROP; 297 return TX_DROP;
298 298
299 if (tx->sdata->vif.type == NL80211_IFTYPE_OCB)
300 return TX_CONTINUE;
301
299 if (tx->sdata->vif.type == NL80211_IFTYPE_WDS) 302 if (tx->sdata->vif.type == NL80211_IFTYPE_WDS)
300 return TX_CONTINUE; 303 return TX_CONTINUE;
301 304
@@ -2013,6 +2016,17 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
2013 goto fail_rcu; 2016 goto fail_rcu;
2014 band = chanctx_conf->def.chan->band; 2017 band = chanctx_conf->def.chan->band;
2015 break; 2018 break;
2019 case NL80211_IFTYPE_OCB:
2020 /* DA SA BSSID */
2021 memcpy(hdr.addr1, skb->data, ETH_ALEN);
2022 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
2023 eth_broadcast_addr(hdr.addr3);
2024 hdrlen = 24;
2025 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2026 if (!chanctx_conf)
2027 goto fail_rcu;
2028 band = chanctx_conf->def.chan->band;
2029 break;
2016 case NL80211_IFTYPE_ADHOC: 2030 case NL80211_IFTYPE_ADHOC:
2017 /* DA SA BSSID */ 2031 /* DA SA BSSID */
2018 memcpy(hdr.addr1, skb->data, ETH_ALEN); 2032 memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -2057,6 +2071,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
2057 * EAPOL frames from the local station. 2071 * EAPOL frames from the local station.
2058 */ 2072 */
2059 if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) && 2073 if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) &&
2074 (sdata->vif.type != NL80211_IFTYPE_OCB) &&
2060 !multicast && !authorized && 2075 !multicast && !authorized &&
2061 (cpu_to_be16(ethertype) != sdata->control_port_protocol || 2076 (cpu_to_be16(ethertype) != sdata->control_port_protocol ||
2062 !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { 2077 !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) {
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 3c61060a4d2b..f9319a5dca64 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -693,6 +693,34 @@ void ieee80211_iterate_active_interfaces_rtnl(
693} 693}
694EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl); 694EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl);
695 695
696static void __iterate_stations(struct ieee80211_local *local,
697 void (*iterator)(void *data,
698 struct ieee80211_sta *sta),
699 void *data)
700{
701 struct sta_info *sta;
702
703 list_for_each_entry_rcu(sta, &local->sta_list, list) {
704 if (!sta->uploaded)
705 continue;
706
707 iterator(data, &sta->sta);
708 }
709}
710
711void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
712 void (*iterator)(void *data,
713 struct ieee80211_sta *sta),
714 void *data)
715{
716 struct ieee80211_local *local = hw_to_local(hw);
717
718 rcu_read_lock();
719 __iterate_stations(local, iterator, data);
720 rcu_read_unlock();
721}
722EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_atomic);
723
696struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev) 724struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev)
697{ 725{
698 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 726 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
@@ -1073,6 +1101,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1073 struct ieee80211_chanctx_conf *chanctx_conf; 1101 struct ieee80211_chanctx_conf *chanctx_conf;
1074 int ac; 1102 int ac;
1075 bool use_11b, enable_qos; 1103 bool use_11b, enable_qos;
1104 bool is_ocb; /* Use another EDCA parameters if dot11OCBActivated=true */
1076 int aCWmin, aCWmax; 1105 int aCWmin, aCWmax;
1077 1106
1078 if (!local->ops->conf_tx) 1107 if (!local->ops->conf_tx)
@@ -1097,6 +1126,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1097 */ 1126 */
1098 enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION); 1127 enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION);
1099 1128
1129 is_ocb = (sdata->vif.type == NL80211_IFTYPE_OCB);
1130
1100 /* Set defaults according to 802.11-2007 Table 7-37 */ 1131 /* Set defaults according to 802.11-2007 Table 7-37 */
1101 aCWmax = 1023; 1132 aCWmax = 1023;
1102 if (use_11b) 1133 if (use_11b)
@@ -1118,7 +1149,10 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1118 qparam.cw_max = aCWmax; 1149 qparam.cw_max = aCWmax;
1119 qparam.cw_min = aCWmin; 1150 qparam.cw_min = aCWmin;
1120 qparam.txop = 0; 1151 qparam.txop = 0;
1121 qparam.aifs = 7; 1152 if (is_ocb)
1153 qparam.aifs = 9;
1154 else
1155 qparam.aifs = 7;
1122 break; 1156 break;
1123 /* never happens but let's not leave undefined */ 1157 /* never happens but let's not leave undefined */
1124 default: 1158 default:
@@ -1126,21 +1160,32 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1126 qparam.cw_max = aCWmax; 1160 qparam.cw_max = aCWmax;
1127 qparam.cw_min = aCWmin; 1161 qparam.cw_min = aCWmin;
1128 qparam.txop = 0; 1162 qparam.txop = 0;
1129 qparam.aifs = 3; 1163 if (is_ocb)
1164 qparam.aifs = 6;
1165 else
1166 qparam.aifs = 3;
1130 break; 1167 break;
1131 case IEEE80211_AC_VI: 1168 case IEEE80211_AC_VI:
1132 qparam.cw_max = aCWmin; 1169 qparam.cw_max = aCWmin;
1133 qparam.cw_min = (aCWmin + 1) / 2 - 1; 1170 qparam.cw_min = (aCWmin + 1) / 2 - 1;
1134 if (use_11b) 1171 if (is_ocb)
1172 qparam.txop = 0;
1173 else if (use_11b)
1135 qparam.txop = 6016/32; 1174 qparam.txop = 6016/32;
1136 else 1175 else
1137 qparam.txop = 3008/32; 1176 qparam.txop = 3008/32;
1138 qparam.aifs = 2; 1177
1178 if (is_ocb)
1179 qparam.aifs = 3;
1180 else
1181 qparam.aifs = 2;
1139 break; 1182 break;
1140 case IEEE80211_AC_VO: 1183 case IEEE80211_AC_VO:
1141 qparam.cw_max = (aCWmin + 1) / 2 - 1; 1184 qparam.cw_max = (aCWmin + 1) / 2 - 1;
1142 qparam.cw_min = (aCWmin + 1) / 4 - 1; 1185 qparam.cw_min = (aCWmin + 1) / 4 - 1;
1143 if (use_11b) 1186 if (is_ocb)
1187 qparam.txop = 0;
1188 else if (use_11b)
1144 qparam.txop = 3264/32; 1189 qparam.txop = 3264/32;
1145 else 1190 else
1146 qparam.txop = 1504/32; 1191 qparam.txop = 1504/32;
@@ -1813,6 +1858,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1813 ieee80211_bss_info_change_notify(sdata, changed); 1858 ieee80211_bss_info_change_notify(sdata, changed);
1814 sdata_unlock(sdata); 1859 sdata_unlock(sdata);
1815 break; 1860 break;
1861 case NL80211_IFTYPE_OCB:
1862 changed |= BSS_CHANGED_OCB;
1863 ieee80211_bss_info_change_notify(sdata, changed);
1864 break;
1816 case NL80211_IFTYPE_ADHOC: 1865 case NL80211_IFTYPE_ADHOC:
1817 changed |= BSS_CHANGED_IBSS; 1866 changed |= BSS_CHANGED_IBSS;
1818 /* fall through */ 1867 /* fall through */
@@ -1949,7 +1998,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1949 * We may want to change that later, however. 1998 * We may want to change that later, however.
1950 */ 1999 */
1951 if (!local->suspended || reconfig_due_to_wowlan) 2000 if (!local->suspended || reconfig_due_to_wowlan)
1952 drv_restart_complete(local); 2001 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);
1953 2002
1954 if (!local->suspended) 2003 if (!local->suspended)
1955 return 0; 2004 return 0;
@@ -1960,6 +2009,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1960 mb(); 2009 mb();
1961 local->resuming = false; 2010 local->resuming = false;
1962 2011
2012 if (!reconfig_due_to_wowlan)
2013 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);
2014
1963 list_for_each_entry(sdata, &local->interfaces, list) { 2015 list_for_each_entry(sdata, &local->interfaces, list) {
1964 if (!ieee80211_sdata_running(sdata)) 2016 if (!ieee80211_sdata_running(sdata))
1965 continue; 2017 continue;
@@ -2052,42 +2104,36 @@ static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id)
2052 return false; 2104 return false;
2053} 2105}
2054 2106
2055/** 2107size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
2056 * ieee80211_ie_split - split an IE buffer according to ordering 2108 const u8 *ids, int n_ids,
2057 * 2109 const u8 *after_ric, int n_after_ric,
2058 * @ies: the IE buffer 2110 size_t offset)
2059 * @ielen: the length of the IE buffer
2060 * @ids: an array with element IDs that are allowed before
2061 * the split
2062 * @n_ids: the size of the element ID array
2063 * @offset: offset where to start splitting in the buffer
2064 *
2065 * This function splits an IE buffer by updating the @offset
2066 * variable to point to the location where the buffer should be
2067 * split.
2068 *
2069 * It assumes that the given IE buffer is well-formed, this
2070 * has to be guaranteed by the caller!
2071 *
2072 * It also assumes that the IEs in the buffer are ordered
2073 * correctly, if not the result of using this function will not
2074 * be ordered correctly either, i.e. it does no reordering.
2075 *
2076 * The function returns the offset where the next part of the
2077 * buffer starts, which may be @ielen if the entire (remainder)
2078 * of the buffer should be used.
2079 */
2080size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
2081 const u8 *ids, int n_ids, size_t offset)
2082{ 2111{
2083 size_t pos = offset; 2112 size_t pos = offset;
2084 2113
2085 while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) 2114 while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) {
2086 pos += 2 + ies[pos + 1]; 2115 if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) {
2116 pos += 2 + ies[pos + 1];
2117
2118 while (pos < ielen &&
2119 !ieee80211_id_in_list(after_ric, n_after_ric,
2120 ies[pos]))
2121 pos += 2 + ies[pos + 1];
2122 } else {
2123 pos += 2 + ies[pos + 1];
2124 }
2125 }
2087 2126
2088 return pos; 2127 return pos;
2089} 2128}
2090 2129
2130size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
2131 const u8 *ids, int n_ids, size_t offset)
2132{
2133 return ieee80211_ie_split_ric(ies, ielen, ids, n_ids, NULL, 0, offset);
2134}
2135EXPORT_SYMBOL(ieee80211_ie_split);
2136
2091size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) 2137size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
2092{ 2138{
2093 size_t pos = offset; 2139 size_t pos = offset;
@@ -2526,11 +2572,23 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work)
2526 struct ieee80211_local *local = 2572 struct ieee80211_local *local =
2527 container_of(work, struct ieee80211_local, radar_detected_work); 2573 container_of(work, struct ieee80211_local, radar_detected_work);
2528 struct cfg80211_chan_def chandef = local->hw.conf.chandef; 2574 struct cfg80211_chan_def chandef = local->hw.conf.chandef;
2575 struct ieee80211_chanctx *ctx;
2576 int num_chanctx = 0;
2577
2578 mutex_lock(&local->chanctx_mtx);
2579 list_for_each_entry(ctx, &local->chanctx_list, list) {
2580 if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
2581 continue;
2582
2583 num_chanctx++;
2584 chandef = ctx->conf.def;
2585 }
2586 mutex_unlock(&local->chanctx_mtx);
2529 2587
2530 ieee80211_dfs_cac_cancel(local); 2588 ieee80211_dfs_cac_cancel(local);
2531 2589
2532 if (local->use_chanctx) 2590 if (num_chanctx > 1)
2533 /* currently not handled */ 2591 /* XXX: multi-channel is not supported yet */
2534 WARN_ON(1); 2592 WARN_ON(1);
2535 else 2593 else
2536 cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); 2594 cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 9181fb6d6437..a4220e92f0cc 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -111,8 +111,6 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
111 (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) 111 (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
112 return newhdr + hdrlen; 112 return newhdr + hdrlen;
113 113
114 skb_set_network_header(skb, skb_network_offset(skb) +
115 IEEE80211_WEP_IV_LEN);
116 ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); 114 ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen);
117 return newhdr + hdrlen; 115 return newhdr + hdrlen;
118} 116}
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 3b873989992c..fdf52db95b33 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -54,10 +54,18 @@ static int wme_downgrade_ac(struct sk_buff *skb)
54} 54}
55 55
56static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, 56static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata,
57 struct sk_buff *skb) 57 struct sta_info *sta, struct sk_buff *skb)
58{ 58{
59 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
60
59 /* in case we are a client verify acm is not set for this ac */ 61 /* in case we are a client verify acm is not set for this ac */
60 while (unlikely(sdata->wmm_acm & BIT(skb->priority))) { 62 while (sdata->wmm_acm & BIT(skb->priority)) {
63 int ac = ieee802_1d_to_ac[skb->priority];
64
65 if (ifmgd->tx_tspec[ac].admitted_time &&
66 skb->priority == ifmgd->tx_tspec[ac].up)
67 return ac;
68
61 if (wme_downgrade_ac(skb)) { 69 if (wme_downgrade_ac(skb)) {
62 /* 70 /*
63 * This should not really happen. The AP has marked all 71 * This should not really happen. The AP has marked all
@@ -96,7 +104,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
96 p = ieee80211_get_qos_ctl(hdr); 104 p = ieee80211_get_qos_ctl(hdr);
97 skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; 105 skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
98 106
99 return ieee80211_downgrade_queue(sdata, skb); 107 return ieee80211_downgrade_queue(sdata, NULL, skb);
100} 108}
101 109
102/* Indicate which queue to use. */ 110/* Indicate which queue to use. */
@@ -108,6 +116,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
108 const u8 *ra = NULL; 116 const u8 *ra = NULL;
109 bool qos = false; 117 bool qos = false;
110 struct mac80211_qos_map *qos_map; 118 struct mac80211_qos_map *qos_map;
119 u16 ret;
111 120
112 if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { 121 if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {
113 skb->priority = 0; /* required for correct WPA/11i MIC */ 122 skb->priority = 0; /* required for correct WPA/11i MIC */
@@ -139,6 +148,10 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
139 case NL80211_IFTYPE_ADHOC: 148 case NL80211_IFTYPE_ADHOC:
140 ra = skb->data; 149 ra = skb->data;
141 break; 150 break;
151 case NL80211_IFTYPE_OCB:
152 /* all stations are required to support WME */
153 qos = true;
154 break;
142 default: 155 default:
143 break; 156 break;
144 } 157 }
@@ -148,27 +161,29 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
148 if (sta) 161 if (sta)
149 qos = sta->sta.wme; 162 qos = sta->sta.wme;
150 } 163 }
151 rcu_read_unlock();
152 164
153 if (!qos) { 165 if (!qos) {
154 skb->priority = 0; /* required for correct WPA/11i MIC */ 166 skb->priority = 0; /* required for correct WPA/11i MIC */
155 return IEEE80211_AC_BE; 167 ret = IEEE80211_AC_BE;
168 goto out;
156 } 169 }
157 170
158 if (skb->protocol == sdata->control_port_protocol) { 171 if (skb->protocol == sdata->control_port_protocol) {
159 skb->priority = 7; 172 skb->priority = 7;
160 return ieee80211_downgrade_queue(sdata, skb); 173 goto downgrade;
161 } 174 }
162 175
163 /* use the data classifier to determine what 802.1d tag the 176 /* use the data classifier to determine what 802.1d tag the
164 * data frame has */ 177 * data frame has */
165 rcu_read_lock();
166 qos_map = rcu_dereference(sdata->qos_map); 178 qos_map = rcu_dereference(sdata->qos_map);
167 skb->priority = cfg80211_classify8021d(skb, qos_map ? 179 skb->priority = cfg80211_classify8021d(skb, qos_map ?
168 &qos_map->qos_map : NULL); 180 &qos_map->qos_map : NULL);
169 rcu_read_unlock();
170 181
171 return ieee80211_downgrade_queue(sdata, skb); 182 downgrade:
183 ret = ieee80211_downgrade_queue(sdata, sta, skb);
184 out:
185 rcu_read_unlock();
186 return ret;
172} 187}
173 188
174/** 189/**
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index 7fea4bb8acbc..80151edc5195 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -13,8 +13,6 @@
13#include <linux/netdevice.h> 13#include <linux/netdevice.h>
14#include "ieee80211_i.h" 14#include "ieee80211_i.h"
15 15
16extern const int ieee802_1d_to_ac[8];
17
18u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, 16u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
19 struct sk_buff *skb, 17 struct sk_buff *skb,
20 struct ieee80211_hdr *hdr); 18 struct ieee80211_hdr *hdr);
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 983527a4c1ab..12398fde02e8 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -209,8 +209,6 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
209 209
210 pos = skb_push(skb, IEEE80211_TKIP_IV_LEN); 210 pos = skb_push(skb, IEEE80211_TKIP_IV_LEN);
211 memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen); 211 memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen);
212 skb_set_network_header(skb, skb_network_offset(skb) +
213 IEEE80211_TKIP_IV_LEN);
214 pos += hdrlen; 212 pos += hdrlen;
215 213
216 /* the HW only needs room for the IV, but not the actual IV */ 214 /* the HW only needs room for the IV, but not the actual IV */
@@ -434,8 +432,6 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
434 432
435 pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN); 433 pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN);
436 memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen); 434 memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen);
437 skb_set_network_header(skb, skb_network_offset(skb) +
438 IEEE80211_CCMP_HDR_LEN);
439 435
440 /* the HW only needs room for the IV, but not the actual IV */ 436 /* the HW only needs room for the IV, but not the actual IV */
441 if (info->control.hw_key && 437 if (info->control.hw_key &&
@@ -575,7 +571,6 @@ ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
575 571
576 pos = skb_push(skb, cs->hdr_len); 572 pos = skb_push(skb, cs->hdr_len);
577 memmove(pos, pos + cs->hdr_len, hdrlen); 573 memmove(pos, pos + cs->hdr_len, hdrlen);
578 skb_set_network_header(skb, skb_network_offset(skb) + cs->hdr_len);
579 574
580 return TX_CONTINUE; 575 return TX_CONTINUE;
581} 576}