aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-07-12 13:44:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-07-12 13:44:50 -0400
commit38a00840638b4932152bca48098dbfa069d942a2 (patch)
treedd12897854f6df8aac237d5fd46551c74be8153a /net/mac80211
parent391e5c22f5f4e55817f8ba18a08ea717ed2d4a1f (diff)
parent2f8684ce7a47c91da7e0ccba2686277c103d02b6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c24
-rw-r--r--net/mac80211/debugfs_key.c16
-rw-r--r--net/mac80211/driver-ops.h22
-rw-r--r--net/mac80211/ieee80211_i.h11
-rw-r--r--net/mac80211/iface.c258
-rw-r--r--net/mac80211/main.c17
-rw-r--r--net/mac80211/mesh_plink.c4
-rw-r--r--net/mac80211/mlme.c28
-rw-r--r--net/mac80211/trace.h7
-rw-r--r--net/mac80211/tx.c16
-rw-r--r--net/mac80211/util.c49
11 files changed, 258 insertions, 194 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c2a2dcbfdf01..ccbe2413142a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2668,8 +2668,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
2668 tf->u.setup_req.capability = 2668 tf->u.setup_req.capability =
2669 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2669 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2670 2670
2671 ieee80211_add_srates_ie(&sdata->vif, skb, false); 2671 ieee80211_add_srates_ie(sdata, skb, false);
2672 ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); 2672 ieee80211_add_ext_srates_ie(sdata, skb, false);
2673 ieee80211_tdls_add_ext_capab(skb); 2673 ieee80211_tdls_add_ext_capab(skb);
2674 break; 2674 break;
2675 case WLAN_TDLS_SETUP_RESPONSE: 2675 case WLAN_TDLS_SETUP_RESPONSE:
@@ -2682,8 +2682,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
2682 tf->u.setup_resp.capability = 2682 tf->u.setup_resp.capability =
2683 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2683 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2684 2684
2685 ieee80211_add_srates_ie(&sdata->vif, skb, false); 2685 ieee80211_add_srates_ie(sdata, skb, false);
2686 ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); 2686 ieee80211_add_ext_srates_ie(sdata, skb, false);
2687 ieee80211_tdls_add_ext_capab(skb); 2687 ieee80211_tdls_add_ext_capab(skb);
2688 break; 2688 break;
2689 case WLAN_TDLS_SETUP_CONFIRM: 2689 case WLAN_TDLS_SETUP_CONFIRM:
@@ -2743,8 +2743,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
2743 mgmt->u.action.u.tdls_discover_resp.capability = 2743 mgmt->u.action.u.tdls_discover_resp.capability =
2744 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2744 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2745 2745
2746 ieee80211_add_srates_ie(&sdata->vif, skb, false); 2746 ieee80211_add_srates_ie(sdata, skb, false);
2747 ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); 2747 ieee80211_add_ext_srates_ie(sdata, skb, false);
2748 ieee80211_tdls_add_ext_capab(skb); 2748 ieee80211_tdls_add_ext_capab(skb);
2749 break; 2749 break;
2750 default: 2750 default:
@@ -2980,14 +2980,14 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
2980 return 0; 2980 return 0;
2981} 2981}
2982 2982
2983static struct ieee80211_channel * 2983static void ieee80211_set_monitor_enabled(struct wiphy *wiphy, bool enabled)
2984ieee80211_wiphy_get_channel(struct wiphy *wiphy,
2985 enum nl80211_channel_type *type)
2986{ 2984{
2987 struct ieee80211_local *local = wiphy_priv(wiphy); 2985 struct ieee80211_local *local = wiphy_priv(wiphy);
2988 2986
2989 *type = local->_oper_channel_type; 2987 if (enabled)
2990 return local->oper_channel; 2988 WARN_ON(ieee80211_add_virtual_monitor(local));
2989 else
2990 ieee80211_del_virtual_monitor(local);
2991} 2991}
2992 2992
2993#ifdef CONFIG_PM 2993#ifdef CONFIG_PM
@@ -3063,8 +3063,8 @@ struct cfg80211_ops mac80211_config_ops = {
3063 .tdls_oper = ieee80211_tdls_oper, 3063 .tdls_oper = ieee80211_tdls_oper,
3064 .tdls_mgmt = ieee80211_tdls_mgmt, 3064 .tdls_mgmt = ieee80211_tdls_mgmt,
3065 .probe_client = ieee80211_probe_client, 3065 .probe_client = ieee80211_probe_client,
3066 .get_channel = ieee80211_wiphy_get_channel,
3067 .set_noack_map = ieee80211_set_noack_map, 3066 .set_noack_map = ieee80211_set_noack_map,
3067 .set_monitor_enabled = ieee80211_set_monitor_enabled,
3068#ifdef CONFIG_PM 3068#ifdef CONFIG_PM
3069 .set_wakeup = ieee80211_set_wakeup, 3069 .set_wakeup = ieee80211_set_wakeup,
3070#endif 3070#endif
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 7932767bb482..090d08ff22c4 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -283,6 +283,11 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
283 283
284 lockdep_assert_held(&sdata->local->key_mtx); 284 lockdep_assert_held(&sdata->local->key_mtx);
285 285
286 if (sdata->debugfs.default_unicast_key) {
287 debugfs_remove(sdata->debugfs.default_unicast_key);
288 sdata->debugfs.default_unicast_key = NULL;
289 }
290
286 if (sdata->default_unicast_key) { 291 if (sdata->default_unicast_key) {
287 key = key_mtx_dereference(sdata->local, 292 key = key_mtx_dereference(sdata->local,
288 sdata->default_unicast_key); 293 sdata->default_unicast_key);
@@ -290,9 +295,11 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
290 sdata->debugfs.default_unicast_key = 295 sdata->debugfs.default_unicast_key =
291 debugfs_create_symlink("default_unicast_key", 296 debugfs_create_symlink("default_unicast_key",
292 sdata->debugfs.dir, buf); 297 sdata->debugfs.dir, buf);
293 } else { 298 }
294 debugfs_remove(sdata->debugfs.default_unicast_key); 299
295 sdata->debugfs.default_unicast_key = NULL; 300 if (sdata->debugfs.default_multicast_key) {
301 debugfs_remove(sdata->debugfs.default_multicast_key);
302 sdata->debugfs.default_multicast_key = NULL;
296 } 303 }
297 304
298 if (sdata->default_multicast_key) { 305 if (sdata->default_multicast_key) {
@@ -302,9 +309,6 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
302 sdata->debugfs.default_multicast_key = 309 sdata->debugfs.default_multicast_key =
303 debugfs_create_symlink("default_multicast_key", 310 debugfs_create_symlink("default_multicast_key",
304 sdata->debugfs.dir, buf); 311 sdata->debugfs.dir, buf);
305 } else {
306 debugfs_remove(sdata->debugfs.default_multicast_key);
307 sdata->debugfs.default_multicast_key = NULL;
308 } 312 }
309} 313}
310 314
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 44e8c1242781..df9203199102 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -27,14 +27,6 @@ static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
27 local->ops->tx(&local->hw, skb); 27 local->ops->tx(&local->hw, skb);
28} 28}
29 29
30static inline void drv_tx_frags(struct ieee80211_local *local,
31 struct ieee80211_vif *vif,
32 struct ieee80211_sta *sta,
33 struct sk_buff_head *skbs)
34{
35 local->ops->tx_frags(&local->hw, vif, sta, skbs);
36}
37
38static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata, 30static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata,
39 u32 sset, u8 *data) 31 u32 sset, u8 *data)
40{ 32{
@@ -860,4 +852,18 @@ static inline int drv_get_rssi(struct ieee80211_local *local,
860 852
861 return ret; 853 return ret;
862} 854}
855
856static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
857 struct ieee80211_sub_if_data *sdata)
858{
859 might_sleep();
860
861 check_sdata_in_driver(sdata);
862 WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
863
864 trace_drv_mgd_prepare_tx(local, sdata);
865 if (local->ops->mgd_prepare_tx)
866 local->ops->mgd_prepare_tx(&local->hw, &sdata->vif);
867 trace_drv_return_void(local);
868}
863#endif /* __MAC80211_DRIVER_OPS */ 869#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f834a005e1c5..e0423f8c0ce1 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1284,7 +1284,6 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
1284 enum nl80211_iftype type); 1284 enum nl80211_iftype type);
1285void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); 1285void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
1286void ieee80211_remove_interfaces(struct ieee80211_local *local); 1286void ieee80211_remove_interfaces(struct ieee80211_local *local);
1287u32 __ieee80211_recalc_idle(struct ieee80211_local *local);
1288void ieee80211_recalc_idle(struct ieee80211_local *local); 1287void ieee80211_recalc_idle(struct ieee80211_local *local);
1289void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, 1288void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
1290 const int offset); 1289 const int offset);
@@ -1481,6 +1480,16 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1481 struct ieee80211_channel *channel, 1480 struct ieee80211_channel *channel,
1482 enum nl80211_channel_type channel_type, 1481 enum nl80211_channel_type channel_type,
1483 u16 prot_mode); 1482 u16 prot_mode);
1483u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
1484 u32 cap);
1485int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1486 struct sk_buff *skb, bool need_basic);
1487int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1488 struct sk_buff *skb, bool need_basic);
1489
1490/* virtual monitor */
1491int ieee80211_add_virtual_monitor(struct ieee80211_local *local);
1492void ieee80211_del_virtual_monitor(struct ieee80211_local *local);
1484 1493
1485/* channel management */ 1494/* channel management */
1486enum ieee80211_chan_mode { 1495enum ieee80211_chan_mode {
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 58c2ab3d483a..fbef7a1ada7a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -43,6 +43,127 @@
43 */ 43 */
44 44
45 45
46static u32 ieee80211_idle_off(struct ieee80211_local *local,
47 const char *reason)
48{
49 if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
50 return 0;
51
52 local->hw.conf.flags &= ~IEEE80211_CONF_IDLE;
53 return IEEE80211_CONF_CHANGE_IDLE;
54}
55
56static u32 ieee80211_idle_on(struct ieee80211_local *local)
57{
58 if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
59 return 0;
60
61 drv_flush(local, false);
62
63 local->hw.conf.flags |= IEEE80211_CONF_IDLE;
64 return IEEE80211_CONF_CHANGE_IDLE;
65}
66
67static u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
68{
69 struct ieee80211_sub_if_data *sdata;
70 int count = 0;
71 bool working = false, scanning = false;
72 unsigned int led_trig_start = 0, led_trig_stop = 0;
73 struct ieee80211_roc_work *roc;
74
75#ifdef CONFIG_PROVE_LOCKING
76 WARN_ON(debug_locks && !lockdep_rtnl_is_held() &&
77 !lockdep_is_held(&local->iflist_mtx));
78#endif
79 lockdep_assert_held(&local->mtx);
80
81 list_for_each_entry(sdata, &local->interfaces, list) {
82 if (!ieee80211_sdata_running(sdata)) {
83 sdata->vif.bss_conf.idle = true;
84 continue;
85 }
86
87 sdata->old_idle = sdata->vif.bss_conf.idle;
88
89 /* do not count disabled managed interfaces */
90 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
91 !sdata->u.mgd.associated &&
92 !sdata->u.mgd.auth_data &&
93 !sdata->u.mgd.assoc_data) {
94 sdata->vif.bss_conf.idle = true;
95 continue;
96 }
97 /* do not count unused IBSS interfaces */
98 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
99 !sdata->u.ibss.ssid_len) {
100 sdata->vif.bss_conf.idle = true;
101 continue;
102 }
103 /* count everything else */
104 sdata->vif.bss_conf.idle = false;
105 count++;
106 }
107
108 if (!local->ops->remain_on_channel) {
109 list_for_each_entry(roc, &local->roc_list, list) {
110 working = true;
111 roc->sdata->vif.bss_conf.idle = false;
112 }
113 }
114
115 if (local->scan_sdata &&
116 !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) {
117 scanning = true;
118 local->scan_sdata->vif.bss_conf.idle = false;
119 }
120
121 list_for_each_entry(sdata, &local->interfaces, list) {
122 if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
123 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
124 continue;
125 if (sdata->old_idle == sdata->vif.bss_conf.idle)
126 continue;
127 if (!ieee80211_sdata_running(sdata))
128 continue;
129 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
130 }
131
132 if (working || scanning)
133 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK;
134 else
135 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK;
136
137 if (count)
138 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
139 else
140 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
141
142 ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
143
144 if (working)
145 return ieee80211_idle_off(local, "working");
146 if (scanning)
147 return ieee80211_idle_off(local, "scanning");
148 if (!count)
149 return ieee80211_idle_on(local);
150 else
151 return ieee80211_idle_off(local, "in use");
152
153 return 0;
154}
155
156void ieee80211_recalc_idle(struct ieee80211_local *local)
157{
158 u32 chg;
159
160 mutex_lock(&local->iflist_mtx);
161 chg = __ieee80211_recalc_idle(local);
162 mutex_unlock(&local->iflist_mtx);
163 if (chg)
164 ieee80211_hw_config(local, chg);
165}
166
46static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) 167static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
47{ 168{
48 int meshhdrlen; 169 int meshhdrlen;
@@ -209,7 +330,7 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata)
209 sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; 330 sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
210} 331}
211 332
212static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) 333int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
213{ 334{
214 struct ieee80211_sub_if_data *sdata; 335 struct ieee80211_sub_if_data *sdata;
215 int ret; 336 int ret;
@@ -250,7 +371,7 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
250 return 0; 371 return 0;
251} 372}
252 373
253static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) 374void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
254{ 375{
255 struct ieee80211_sub_if_data *sdata; 376 struct ieee80211_sub_if_data *sdata;
256 377
@@ -366,12 +487,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
366 break; 487 break;
367 } 488 }
368 489
369 if (local->monitors == 0 && local->open_count == 0) {
370 res = ieee80211_add_virtual_monitor(local);
371 if (res)
372 goto err_stop;
373 }
374
375 /* must be before the call to ieee80211_configure_filter */ 490 /* must be before the call to ieee80211_configure_filter */
376 local->monitors++; 491 local->monitors++;
377 if (local->monitors == 1) { 492 if (local->monitors == 1) {
@@ -386,8 +501,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
386 break; 501 break;
387 default: 502 default:
388 if (coming_up) { 503 if (coming_up) {
389 ieee80211_del_virtual_monitor(local);
390
391 res = drv_add_interface(local, sdata); 504 res = drv_add_interface(local, sdata);
392 if (res) 505 if (res)
393 goto err_stop; 506 goto err_stop;
@@ -622,7 +735,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
622 if (local->monitors == 0) { 735 if (local->monitors == 0) {
623 local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; 736 local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
624 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; 737 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
625 ieee80211_del_virtual_monitor(local);
626 } 738 }
627 739
628 ieee80211_adjust_monitor_flags(sdata, -1); 740 ieee80211_adjust_monitor_flags(sdata, -1);
@@ -696,9 +808,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
696 } 808 }
697 } 809 }
698 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 810 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
699
700 if (local->monitors == local->open_count && local->monitors > 0)
701 ieee80211_add_virtual_monitor(local);
702} 811}
703 812
704static int ieee80211_stop(struct net_device *dev) 813static int ieee80211_stop(struct net_device *dev)
@@ -1403,127 +1512,6 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
1403 list_del(&unreg_list); 1512 list_del(&unreg_list);
1404} 1513}
1405 1514
1406static u32 ieee80211_idle_off(struct ieee80211_local *local,
1407 const char *reason)
1408{
1409 if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
1410 return 0;
1411
1412 local->hw.conf.flags &= ~IEEE80211_CONF_IDLE;
1413 return IEEE80211_CONF_CHANGE_IDLE;
1414}
1415
1416static u32 ieee80211_idle_on(struct ieee80211_local *local)
1417{
1418 if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
1419 return 0;
1420
1421 drv_flush(local, false);
1422
1423 local->hw.conf.flags |= IEEE80211_CONF_IDLE;
1424 return IEEE80211_CONF_CHANGE_IDLE;
1425}
1426
1427u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
1428{
1429 struct ieee80211_sub_if_data *sdata;
1430 int count = 0;
1431 bool working = false, scanning = false;
1432 unsigned int led_trig_start = 0, led_trig_stop = 0;
1433 struct ieee80211_roc_work *roc;
1434
1435#ifdef CONFIG_PROVE_LOCKING
1436 WARN_ON(debug_locks && !lockdep_rtnl_is_held() &&
1437 !lockdep_is_held(&local->iflist_mtx));
1438#endif
1439 lockdep_assert_held(&local->mtx);
1440
1441 list_for_each_entry(sdata, &local->interfaces, list) {
1442 if (!ieee80211_sdata_running(sdata)) {
1443 sdata->vif.bss_conf.idle = true;
1444 continue;
1445 }
1446
1447 sdata->old_idle = sdata->vif.bss_conf.idle;
1448
1449 /* do not count disabled managed interfaces */
1450 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
1451 !sdata->u.mgd.associated &&
1452 !sdata->u.mgd.auth_data &&
1453 !sdata->u.mgd.assoc_data) {
1454 sdata->vif.bss_conf.idle = true;
1455 continue;
1456 }
1457 /* do not count unused IBSS interfaces */
1458 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
1459 !sdata->u.ibss.ssid_len) {
1460 sdata->vif.bss_conf.idle = true;
1461 continue;
1462 }
1463 /* count everything else */
1464 sdata->vif.bss_conf.idle = false;
1465 count++;
1466 }
1467
1468 if (!local->ops->remain_on_channel) {
1469 list_for_each_entry(roc, &local->roc_list, list) {
1470 working = true;
1471 roc->sdata->vif.bss_conf.idle = false;
1472 }
1473 }
1474
1475 if (local->scan_sdata &&
1476 !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) {
1477 scanning = true;
1478 local->scan_sdata->vif.bss_conf.idle = false;
1479 }
1480
1481 list_for_each_entry(sdata, &local->interfaces, list) {
1482 if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
1483 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1484 continue;
1485 if (sdata->old_idle == sdata->vif.bss_conf.idle)
1486 continue;
1487 if (!ieee80211_sdata_running(sdata))
1488 continue;
1489 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
1490 }
1491
1492 if (working || scanning)
1493 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK;
1494 else
1495 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK;
1496
1497 if (count)
1498 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
1499 else
1500 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
1501
1502 ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
1503
1504 if (working)
1505 return ieee80211_idle_off(local, "working");
1506 if (scanning)
1507 return ieee80211_idle_off(local, "scanning");
1508 if (!count)
1509 return ieee80211_idle_on(local);
1510 else
1511 return ieee80211_idle_off(local, "in use");
1512
1513 return 0;
1514}
1515
1516void ieee80211_recalc_idle(struct ieee80211_local *local)
1517{
1518 u32 chg;
1519
1520 mutex_lock(&local->iflist_mtx);
1521 chg = __ieee80211_recalc_idle(local);
1522 mutex_unlock(&local->iflist_mtx);
1523 if (chg)
1524 ieee80211_hw_config(local, chg);
1525}
1526
1527static int netdev_notify(struct notifier_block *nb, 1515static int netdev_notify(struct notifier_block *nb,
1528 unsigned long state, 1516 unsigned long state,
1529 void *ndev) 1517 void *ndev)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0b040fb73673..c794101f8987 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -587,7 +587,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
587 587
588 local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); 588 local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN);
589 589
590 BUG_ON(!ops->tx && !ops->tx_frags); 590 BUG_ON(!ops->tx);
591 BUG_ON(!ops->start); 591 BUG_ON(!ops->start);
592 BUG_ON(!ops->stop); 592 BUG_ON(!ops->stop);
593 BUG_ON(!ops->config); 593 BUG_ON(!ops->config);
@@ -688,7 +688,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
688 int result, i; 688 int result, i;
689 enum ieee80211_band band; 689 enum ieee80211_band band;
690 int channels, max_bitrates; 690 int channels, max_bitrates;
691 bool supp_ht; 691 bool supp_ht, supp_vht;
692 netdev_features_t feature_whitelist; 692 netdev_features_t feature_whitelist;
693 static const u32 cipher_suites[] = { 693 static const u32 cipher_suites[] = {
694 /* keep WEP first, it may be removed below */ 694 /* keep WEP first, it may be removed below */
@@ -706,12 +706,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
706 local->hw.offchannel_tx_hw_queue >= local->hw.queues)) 706 local->hw.offchannel_tx_hw_queue >= local->hw.queues))
707 return -EINVAL; 707 return -EINVAL;
708 708
709 if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns)
710#ifdef CONFIG_PM 709#ifdef CONFIG_PM
711 && (!local->ops->suspend || !local->ops->resume) 710 if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) &&
712#endif 711 (!local->ops->suspend || !local->ops->resume))
713 )
714 return -EINVAL; 712 return -EINVAL;
713#endif
715 714
716 if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) 715 if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan)
717 return -EINVAL; 716 return -EINVAL;
@@ -733,6 +732,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
733 channels = 0; 732 channels = 0;
734 max_bitrates = 0; 733 max_bitrates = 0;
735 supp_ht = false; 734 supp_ht = false;
735 supp_vht = false;
736 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 736 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
737 struct ieee80211_supported_band *sband; 737 struct ieee80211_supported_band *sband;
738 738
@@ -750,6 +750,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
750 if (max_bitrates < sband->n_bitrates) 750 if (max_bitrates < sband->n_bitrates)
751 max_bitrates = sband->n_bitrates; 751 max_bitrates = sband->n_bitrates;
752 supp_ht = supp_ht || sband->ht_cap.ht_supported; 752 supp_ht = supp_ht || sband->ht_cap.ht_supported;
753 supp_vht = supp_vht || sband->vht_cap.vht_supported;
753 } 754 }
754 755
755 local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + 756 local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) +
@@ -825,6 +826,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
825 if (supp_ht) 826 if (supp_ht)
826 local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); 827 local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
827 828
829 if (supp_vht)
830 local->scan_ies_len +=
831 2 + sizeof(struct ieee80211_vht_capabilities);
832
828 if (!local->ops->hw_scan) { 833 if (!local->ops->hw_scan) {
829 /* For hw_scan, driver needs to set these up. */ 834 /* For hw_scan, driver needs to set these up. */
830 local->hw.wiphy->max_scan_ssids = 4; 835 local->hw.wiphy->max_scan_ssids = 4;
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 9ad74dd87a7b..af671b984df3 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -258,8 +258,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
258 pos = skb_put(skb, 2); 258 pos = skb_put(skb, 2);
259 memcpy(pos + 2, &plid, 2); 259 memcpy(pos + 2, &plid, 2);
260 } 260 }
261 if (ieee80211_add_srates_ie(&sdata->vif, skb, true) || 261 if (ieee80211_add_srates_ie(sdata, skb, true) ||
262 ieee80211_add_ext_srates_ie(&sdata->vif, skb, true) || 262 ieee80211_add_ext_srates_ie(sdata, skb, true) ||
263 mesh_add_rsn_ie(skb, sdata) || 263 mesh_add_rsn_ie(skb, sdata) ||
264 mesh_add_meshid_ie(skb, sdata) || 264 mesh_add_meshid_ie(skb, sdata) ||
265 mesh_add_meshconf_ie(skb, sdata)) 265 mesh_add_meshconf_ie(skb, sdata))
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index aa69a331f374..f49f14f8ba82 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -541,6 +541,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
541 memcpy(pos, assoc_data->ie + offset, noffset - offset); 541 memcpy(pos, assoc_data->ie + offset, noffset - offset);
542 } 542 }
543 543
544 drv_mgd_prepare_tx(local, sdata);
545
544 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 546 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
545 ieee80211_tx_skb(sdata, skb); 547 ieee80211_tx_skb(sdata, skb);
546} 548}
@@ -580,6 +582,9 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
580 if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) 582 if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
581 IEEE80211_SKB_CB(skb)->flags |= 583 IEEE80211_SKB_CB(skb)->flags |=
582 IEEE80211_TX_INTFL_DONT_ENCRYPT; 584 IEEE80211_TX_INTFL_DONT_ENCRYPT;
585
586 drv_mgd_prepare_tx(local, sdata);
587
583 ieee80211_tx_skb(sdata, skb); 588 ieee80211_tx_skb(sdata, skb);
584 } 589 }
585} 590}
@@ -902,9 +907,6 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
902 if (!mgd->associated) 907 if (!mgd->associated)
903 return false; 908 return false;
904 909
905 if (!mgd->associated->beacon_ies)
906 return false;
907
908 if (mgd->flags & (IEEE80211_STA_BEACON_POLL | 910 if (mgd->flags & (IEEE80211_STA_BEACON_POLL |
909 IEEE80211_STA_CONNECTION_POLL)) 911 IEEE80211_STA_CONNECTION_POLL))
910 return false; 912 return false;
@@ -1362,6 +1364,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1362 } 1364 }
1363 mutex_unlock(&local->sta_mtx); 1365 mutex_unlock(&local->sta_mtx);
1364 1366
1367 /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */
1368 if (tx)
1369 drv_flush(local, false);
1370
1365 /* deauthenticate/disassociate now */ 1371 /* deauthenticate/disassociate now */
1366 if (tx || frame_buf) 1372 if (tx || frame_buf)
1367 ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, 1373 ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
@@ -1610,6 +1616,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
1610{ 1616{
1611 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 1617 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1612 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1618 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1619 struct cfg80211_bss *cbss;
1613 struct sk_buff *skb; 1620 struct sk_buff *skb;
1614 const u8 *ssid; 1621 const u8 *ssid;
1615 int ssid_len; 1622 int ssid_len;
@@ -1619,16 +1626,22 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
1619 1626
1620 ASSERT_MGD_MTX(ifmgd); 1627 ASSERT_MGD_MTX(ifmgd);
1621 1628
1622 if (!ifmgd->associated) 1629 if (ifmgd->associated)
1630 cbss = ifmgd->associated;
1631 else if (ifmgd->auth_data)
1632 cbss = ifmgd->auth_data->bss;
1633 else if (ifmgd->assoc_data)
1634 cbss = ifmgd->assoc_data->bss;
1635 else
1623 return NULL; 1636 return NULL;
1624 1637
1625 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); 1638 ssid = ieee80211_bss_get_ie(cbss, WLAN_EID_SSID);
1626 if (WARN_ON_ONCE(ssid == NULL)) 1639 if (WARN_ON_ONCE(ssid == NULL))
1627 ssid_len = 0; 1640 ssid_len = 0;
1628 else 1641 else
1629 ssid_len = ssid[1]; 1642 ssid_len = ssid[1];
1630 1643
1631 skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid, 1644 skb = ieee80211_build_probe_req(sdata, cbss->bssid,
1632 (u32) -1, ssid + 2, ssid_len, 1645 (u32) -1, ssid + 2, ssid_len,
1633 NULL, 0, true); 1646 NULL, 0, true);
1634 1647
@@ -1747,6 +1760,7 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1747 if (!elems.challenge) 1760 if (!elems.challenge)
1748 return; 1761 return;
1749 auth_data->expected_transaction = 4; 1762 auth_data->expected_transaction = 4;
1763 drv_mgd_prepare_tx(sdata->local, sdata);
1750 ieee80211_send_auth(sdata, 3, auth_data->algorithm, 1764 ieee80211_send_auth(sdata, 3, auth_data->algorithm,
1751 elems.challenge - 2, elems.challenge_len + 2, 1765 elems.challenge - 2, elems.challenge_len + 2,
1752 auth_data->bss->bssid, auth_data->bss->bssid, 1766 auth_data->bss->bssid, auth_data->bss->bssid,
@@ -2630,6 +2644,8 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
2630 return -ETIMEDOUT; 2644 return -ETIMEDOUT;
2631 } 2645 }
2632 2646
2647 drv_mgd_prepare_tx(local, sdata);
2648
2633 if (auth_data->bss->proberesp_ies) { 2649 if (auth_data->bss->proberesp_ies) {
2634 sdata_info(sdata, "send auth to %pM (try %d/%d)\n", 2650 sdata_info(sdata, "send auth to %pM (try %d/%d)\n",
2635 auth_data->bss->bssid, auth_data->tries, 2651 auth_data->bss->bssid, auth_data->tries,
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 2e60f4acd027..e1e9d10ec2e7 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1244,6 +1244,13 @@ TRACE_EVENT(drv_get_rssi,
1244 ) 1244 )
1245); 1245);
1246 1246
1247DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx,
1248 TP_PROTO(struct ieee80211_local *local,
1249 struct ieee80211_sub_if_data *sdata),
1250
1251 TP_ARGS(local, sdata)
1252);
1253
1247/* 1254/*
1248 * Tracing for API calls that drivers call. 1255 * Tracing for API calls that drivers call.
1249 */ 1256 */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ec8f53467374..c9d2175d15c1 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -140,6 +140,8 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
140 if (r->flags & IEEE80211_RATE_MANDATORY_A) 140 if (r->flags & IEEE80211_RATE_MANDATORY_A)
141 mrate = r->bitrate; 141 mrate = r->bitrate;
142 break; 142 break;
143 case IEEE80211_BAND_60GHZ:
144 /* TODO, for now fall through */
143 case IEEE80211_NUM_BANDS: 145 case IEEE80211_NUM_BANDS:
144 WARN_ON(1); 146 WARN_ON(1);
145 break; 147 break;
@@ -957,8 +959,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
957 info->control.rates[1].idx = -1; 959 info->control.rates[1].idx = -1;
958 info->control.rates[2].idx = -1; 960 info->control.rates[2].idx = -1;
959 info->control.rates[3].idx = -1; 961 info->control.rates[3].idx = -1;
960 info->control.rates[4].idx = -1; 962 BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 4);
961 BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5);
962 info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; 963 info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
963 } else { 964 } else {
964 hdr->frame_control &= ~morefrags; 965 hdr->frame_control &= ~morefrags;
@@ -1293,11 +1294,8 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
1293 break; 1294 break;
1294 } 1295 }
1295 1296
1296 if (local->ops->tx_frags) 1297 result = ieee80211_tx_frags(local, vif, pubsta, skbs,
1297 drv_tx_frags(local, vif, pubsta, skbs); 1298 txpending);
1298 else
1299 result = ieee80211_tx_frags(local, vif, pubsta, skbs,
1300 txpending);
1301 1299
1302 ieee80211_tpt_led_trig_tx(local, fc, led_len); 1300 ieee80211_tpt_led_trig_tx(local, fc, led_len);
1303 ieee80211_led_tx(local, 1); 1301 ieee80211_led_tx(local, 1);
@@ -2420,9 +2418,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2420 *pos++ = WLAN_EID_SSID; 2418 *pos++ = WLAN_EID_SSID;
2421 *pos++ = 0x0; 2419 *pos++ = 0x0;
2422 2420
2423 if (ieee80211_add_srates_ie(&sdata->vif, skb, true) || 2421 if (ieee80211_add_srates_ie(sdata, skb, true) ||
2424 mesh_add_ds_params_ie(skb, sdata) || 2422 mesh_add_ds_params_ie(skb, sdata) ||
2425 ieee80211_add_ext_srates_ie(&sdata->vif, skb, true) || 2423 ieee80211_add_ext_srates_ie(sdata, skb, true) ||
2426 mesh_add_rsn_ie(skb, sdata) || 2424 mesh_add_rsn_ie(skb, sdata) ||
2427 mesh_add_ht_cap_ie(skb, sdata) || 2425 mesh_add_ht_cap_ie(skb, sdata) ||
2428 mesh_add_ht_oper_ie(skb, sdata) || 2426 mesh_add_ht_oper_ie(skb, sdata) ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 242ecde381f6..64493a7bef1a 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -268,6 +268,10 @@ EXPORT_SYMBOL(ieee80211_ctstoself_duration);
268void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) 268void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
269{ 269{
270 struct ieee80211_sub_if_data *sdata; 270 struct ieee80211_sub_if_data *sdata;
271 int n_acs = IEEE80211_NUM_ACS;
272
273 if (local->hw.queues < IEEE80211_NUM_ACS)
274 n_acs = 1;
271 275
272 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 276 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
273 int ac; 277 int ac;
@@ -279,7 +283,7 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
279 local->queue_stop_reasons[sdata->vif.cab_queue] != 0) 283 local->queue_stop_reasons[sdata->vif.cab_queue] != 0)
280 continue; 284 continue;
281 285
282 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 286 for (ac = 0; ac < n_acs; ac++) {
283 int ac_queue = sdata->vif.hw_queue[ac]; 287 int ac_queue = sdata->vif.hw_queue[ac];
284 288
285 if (ac_queue == queue || 289 if (ac_queue == queue ||
@@ -341,6 +345,7 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
341{ 345{
342 struct ieee80211_local *local = hw_to_local(hw); 346 struct ieee80211_local *local = hw_to_local(hw);
343 struct ieee80211_sub_if_data *sdata; 347 struct ieee80211_sub_if_data *sdata;
348 int n_acs = IEEE80211_NUM_ACS;
344 349
345 trace_stop_queue(local, queue, reason); 350 trace_stop_queue(local, queue, reason);
346 351
@@ -352,11 +357,14 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
352 357
353 __set_bit(reason, &local->queue_stop_reasons[queue]); 358 __set_bit(reason, &local->queue_stop_reasons[queue]);
354 359
360 if (local->hw.queues < IEEE80211_NUM_ACS)
361 n_acs = 1;
362
355 rcu_read_lock(); 363 rcu_read_lock();
356 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 364 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
357 int ac; 365 int ac;
358 366
359 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 367 for (ac = 0; ac < n_acs; ac++) {
360 if (sdata->vif.hw_queue[ac] == queue || 368 if (sdata->vif.hw_queue[ac] == queue ||
361 sdata->vif.cab_queue == queue) 369 sdata->vif.cab_queue == queue)
362 netif_stop_subqueue(sdata->dev, ac); 370 netif_stop_subqueue(sdata->dev, ac);
@@ -1072,6 +1080,10 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1072 pos += noffset - offset; 1080 pos += noffset - offset;
1073 } 1081 }
1074 1082
1083 if (sband->vht_cap.vht_supported)
1084 pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap,
1085 sband->vht_cap.cap);
1086
1075 return pos - buffer; 1087 return pos - buffer;
1076} 1088}
1077 1089
@@ -1411,10 +1423,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1411 if (ieee80211_sdata_running(sdata)) 1423 if (ieee80211_sdata_running(sdata))
1412 ieee80211_enable_keys(sdata); 1424 ieee80211_enable_keys(sdata);
1413 1425
1426 wake_up:
1414 local->in_reconfig = false; 1427 local->in_reconfig = false;
1415 barrier(); 1428 barrier();
1416 1429
1417 wake_up:
1418 /* 1430 /*
1419 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation 1431 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation
1420 * sessions can be established after a resume. 1432 * sessions can be established after a resume.
@@ -1699,6 +1711,27 @@ u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1699 return pos; 1711 return pos;
1700} 1712}
1701 1713
1714u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
1715 u32 cap)
1716{
1717 __le32 tmp;
1718
1719 *pos++ = WLAN_EID_VHT_CAPABILITY;
1720 *pos++ = sizeof(struct ieee80211_vht_capabilities);
1721 memset(pos, 0, sizeof(struct ieee80211_vht_capabilities));
1722
1723 /* capability flags */
1724 tmp = cpu_to_le32(cap);
1725 memcpy(pos, &tmp, sizeof(u32));
1726 pos += sizeof(u32);
1727
1728 /* VHT MCS set */
1729 memcpy(pos, &vht_cap->vht_mcs, sizeof(vht_cap->vht_mcs));
1730 pos += sizeof(vht_cap->vht_mcs);
1731
1732 return pos;
1733}
1734
1702u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 1735u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1703 struct ieee80211_channel *channel, 1736 struct ieee80211_channel *channel,
1704 enum nl80211_channel_type channel_type, 1737 enum nl80211_channel_type channel_type,
@@ -1764,15 +1797,14 @@ ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper)
1764 return channel_type; 1797 return channel_type;
1765} 1798}
1766 1799
1767int ieee80211_add_srates_ie(struct ieee80211_vif *vif, 1800int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1768 struct sk_buff *skb, bool need_basic) 1801 struct sk_buff *skb, bool need_basic)
1769{ 1802{
1770 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1771 struct ieee80211_local *local = sdata->local; 1803 struct ieee80211_local *local = sdata->local;
1772 struct ieee80211_supported_band *sband; 1804 struct ieee80211_supported_band *sband;
1773 int rate; 1805 int rate;
1774 u8 i, rates, *pos; 1806 u8 i, rates, *pos;
1775 u32 basic_rates = vif->bss_conf.basic_rates; 1807 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
1776 1808
1777 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1809 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1778 rates = sband->n_bitrates; 1810 rates = sband->n_bitrates;
@@ -1796,15 +1828,14 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif,
1796 return 0; 1828 return 0;
1797} 1829}
1798 1830
1799int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, 1831int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1800 struct sk_buff *skb, bool need_basic) 1832 struct sk_buff *skb, bool need_basic)
1801{ 1833{
1802 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1803 struct ieee80211_local *local = sdata->local; 1834 struct ieee80211_local *local = sdata->local;
1804 struct ieee80211_supported_band *sband; 1835 struct ieee80211_supported_band *sband;
1805 int rate; 1836 int rate;
1806 u8 i, exrates, *pos; 1837 u8 i, exrates, *pos;
1807 u32 basic_rates = vif->bss_conf.basic_rates; 1838 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
1808 1839
1809 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1840 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1810 exrates = sband->n_bitrates; 1841 exrates = sband->n_bitrates;