aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-12-23 13:13:30 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-23 13:13:30 -0500
commita130883d9528eefb66285728ba6a232d8fff9465 (patch)
tree304b63e59d910be2ee2798404fe4a940bdfdd2af /net
parentd9f4fbaf7053af43e6c72909c2aff18654717aed (diff)
parent65a6538a56d4c7ae8465f2a8420ddc65877b6779 (diff)
Merge branch 'for-davem' of ssh://master.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/agg-tx.c7
-rw-r--r--net/mac80211/cfg.c53
-rw-r--r--net/mac80211/debugfs_key.c37
-rw-r--r--net/mac80211/debugfs_key.h8
-rw-r--r--net/mac80211/debugfs_sta.c2
-rw-r--r--net/mac80211/driver-ops.h2
-rw-r--r--net/mac80211/ieee80211_i.h25
-rw-r--r--net/mac80211/iface.c15
-rw-r--r--net/mac80211/key.c45
-rw-r--r--net/mac80211/key.h3
-rw-r--r--net/mac80211/led.c186
-rw-r--r--net/mac80211/led.h45
-rw-r--r--net/mac80211/main.c17
-rw-r--r--net/mac80211/mesh.c52
-rw-r--r--net/mac80211/mesh.h22
-rw-r--r--net/mac80211/mesh_plink.c3
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c2
-rw-r--r--net/mac80211/rx.c53
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/tx.c25
-rw-r--r--net/mac80211/util.c3
-rw-r--r--net/wireless/core.c22
-rw-r--r--net/wireless/core.h5
-rw-r--r--net/wireless/mesh.c24
-rw-r--r--net/wireless/mlme.c22
-rw-r--r--net/wireless/nl80211.c276
-rw-r--r--net/wireless/nl80211.h6
-rw-r--r--net/wireless/reg.c3
-rw-r--r--net/wireless/scan.c11
-rw-r--r--net/wireless/util.c3
-rw-r--r--net/wireless/wext-compat.c8
31 files changed, 769 insertions, 218 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index d4679b265ba8..9cc472c6a6a5 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -342,10 +342,11 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
342 /* send AddBA request */ 342 /* send AddBA request */
343 ieee80211_send_addba_request(sdata, sta->sta.addr, tid, 343 ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
344 tid_tx->dialog_token, start_seq_num, 344 tid_tx->dialog_token, start_seq_num,
345 0x40, 5000); 345 0x40, tid_tx->timeout);
346} 346}
347 347
348int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) 348int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
349 u16 timeout)
349{ 350{
350 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); 351 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
351 struct ieee80211_sub_if_data *sdata = sta->sdata; 352 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -420,6 +421,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
420 skb_queue_head_init(&tid_tx->pending); 421 skb_queue_head_init(&tid_tx->pending);
421 __set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); 422 __set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
422 423
424 tid_tx->timeout = timeout;
425
423 /* Tx timer */ 426 /* Tx timer */
424 tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired; 427 tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired;
425 tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid]; 428 tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid];
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c30b8b72eedb..5892b0302454 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -295,11 +295,12 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
295 295
296static int ieee80211_config_default_key(struct wiphy *wiphy, 296static int ieee80211_config_default_key(struct wiphy *wiphy,
297 struct net_device *dev, 297 struct net_device *dev,
298 u8 key_idx) 298 u8 key_idx, bool uni,
299 bool multi)
299{ 300{
300 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 301 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
301 302
302 ieee80211_set_default_key(sdata, key_idx); 303 ieee80211_set_default_key(sdata, key_idx, uni, multi);
303 304
304 return 0; 305 return 0;
305} 306}
@@ -983,7 +984,7 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
983 return 0; 984 return 0;
984} 985}
985 986
986static int ieee80211_get_mesh_params(struct wiphy *wiphy, 987static int ieee80211_get_mesh_config(struct wiphy *wiphy,
987 struct net_device *dev, 988 struct net_device *dev,
988 struct mesh_config *conf) 989 struct mesh_config *conf)
989{ 990{
@@ -999,7 +1000,37 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
999 return (mask >> (parm-1)) & 0x1; 1000 return (mask >> (parm-1)) & 0x1;
1000} 1001}
1001 1002
1002static int ieee80211_update_mesh_params(struct wiphy *wiphy, 1003static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
1004 const struct mesh_setup *setup)
1005{
1006 u8 *new_ie;
1007 const u8 *old_ie;
1008
1009 /* first allocate the new vendor information element */
1010 new_ie = NULL;
1011 old_ie = ifmsh->vendor_ie;
1012
1013 ifmsh->vendor_ie_len = setup->vendor_ie_len;
1014 if (setup->vendor_ie_len) {
1015 new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len,
1016 GFP_KERNEL);
1017 if (!new_ie)
1018 return -ENOMEM;
1019 }
1020
1021 /* now copy the rest of the setup parameters */
1022 ifmsh->mesh_id_len = setup->mesh_id_len;
1023 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
1024 ifmsh->mesh_pp_id = setup->path_sel_proto;
1025 ifmsh->mesh_pm_id = setup->path_metric;
1026 ifmsh->vendor_ie = new_ie;
1027
1028 kfree(old_ie);
1029
1030 return 0;
1031}
1032
1033static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1003 struct net_device *dev, u32 mask, 1034 struct net_device *dev, u32 mask,
1004 const struct mesh_config *nconf) 1035 const struct mesh_config *nconf)
1005{ 1036{
@@ -1058,11 +1089,12 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
1058{ 1089{
1059 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1090 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1060 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 1091 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1092 int err;
1061 1093
1062 memcpy(&sdata->u.mesh.mshcfg, conf, sizeof(struct mesh_config)); 1094 memcpy(&ifmsh->mshcfg, conf, sizeof(struct mesh_config));
1063 ifmsh->mesh_id_len = setup->mesh_id_len; 1095 err = copy_mesh_setup(ifmsh, setup);
1064 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); 1096 if (err)
1065 1097 return err;
1066 ieee80211_start_mesh(sdata); 1098 ieee80211_start_mesh(sdata);
1067 1099
1068 return 0; 1100 return 0;
@@ -1638,6 +1670,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1638 case NL80211_IFTYPE_AP: 1670 case NL80211_IFTYPE_AP:
1639 case NL80211_IFTYPE_AP_VLAN: 1671 case NL80211_IFTYPE_AP_VLAN:
1640 case NL80211_IFTYPE_P2P_GO: 1672 case NL80211_IFTYPE_P2P_GO:
1673 case NL80211_IFTYPE_MESH_POINT:
1641 if (!ieee80211_is_action(mgmt->frame_control) || 1674 if (!ieee80211_is_action(mgmt->frame_control) ||
1642 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) 1675 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
1643 break; 1676 break;
@@ -1786,8 +1819,8 @@ struct cfg80211_ops mac80211_config_ops = {
1786 .change_mpath = ieee80211_change_mpath, 1819 .change_mpath = ieee80211_change_mpath,
1787 .get_mpath = ieee80211_get_mpath, 1820 .get_mpath = ieee80211_get_mpath,
1788 .dump_mpath = ieee80211_dump_mpath, 1821 .dump_mpath = ieee80211_dump_mpath,
1789 .update_mesh_params = ieee80211_update_mesh_params, 1822 .update_mesh_config = ieee80211_update_mesh_config,
1790 .get_mesh_params = ieee80211_get_mesh_params, 1823 .get_mesh_config = ieee80211_get_mesh_config,
1791 .join_mesh = ieee80211_join_mesh, 1824 .join_mesh = ieee80211_join_mesh,
1792 .leave_mesh = ieee80211_leave_mesh, 1825 .leave_mesh = ieee80211_leave_mesh,
1793#endif 1826#endif
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 5822a6ce7671..f7ef3477c24a 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -274,7 +274,8 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
274 debugfs_remove_recursive(key->debugfs.dir); 274 debugfs_remove_recursive(key->debugfs.dir);
275 key->debugfs.dir = NULL; 275 key->debugfs.dir = NULL;
276} 276}
277void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) 277
278void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
278{ 279{
279 char buf[50]; 280 char buf[50];
280 struct ieee80211_key *key; 281 struct ieee80211_key *key;
@@ -282,25 +283,29 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
282 if (!sdata->debugfs.dir) 283 if (!sdata->debugfs.dir)
283 return; 284 return;
284 285
285 /* this is running under the key lock */ 286 lockdep_assert_held(&sdata->local->key_mtx);
286 287
287 key = sdata->default_key; 288 if (sdata->default_unicast_key) {
288 if (key) { 289 key = sdata->default_unicast_key;
289 sprintf(buf, "../keys/%d", key->debugfs.cnt); 290 sprintf(buf, "../keys/%d", key->debugfs.cnt);
290 sdata->debugfs.default_key = 291 sdata->debugfs.default_unicast_key =
291 debugfs_create_symlink("default_key", 292 debugfs_create_symlink("default_unicast_key",
292 sdata->debugfs.dir, buf); 293 sdata->debugfs.dir, buf);
293 } else 294 } else {
294 ieee80211_debugfs_key_remove_default(sdata); 295 debugfs_remove(sdata->debugfs.default_unicast_key);
295} 296 sdata->debugfs.default_unicast_key = NULL;
296 297 }
297void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
298{
299 if (!sdata)
300 return;
301 298
302 debugfs_remove(sdata->debugfs.default_key); 299 if (sdata->default_multicast_key) {
303 sdata->debugfs.default_key = NULL; 300 key = sdata->default_multicast_key;
301 sprintf(buf, "../keys/%d", key->debugfs.cnt);
302 sdata->debugfs.default_multicast_key =
303 debugfs_create_symlink("default_multicast_key",
304 sdata->debugfs.dir, buf);
305 } else {
306 debugfs_remove(sdata->debugfs.default_multicast_key);
307 sdata->debugfs.default_multicast_key = NULL;
308 }
304} 309}
305 310
306void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata) 311void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/debugfs_key.h b/net/mac80211/debugfs_key.h
index 54717b4e1371..32adc77e9c77 100644
--- a/net/mac80211/debugfs_key.h
+++ b/net/mac80211/debugfs_key.h
@@ -4,8 +4,7 @@
4#ifdef CONFIG_MAC80211_DEBUGFS 4#ifdef CONFIG_MAC80211_DEBUGFS
5void ieee80211_debugfs_key_add(struct ieee80211_key *key); 5void ieee80211_debugfs_key_add(struct ieee80211_key *key);
6void ieee80211_debugfs_key_remove(struct ieee80211_key *key); 6void ieee80211_debugfs_key_remove(struct ieee80211_key *key);
7void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata); 7void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata);
8void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata);
9void ieee80211_debugfs_key_add_mgmt_default( 8void ieee80211_debugfs_key_add_mgmt_default(
10 struct ieee80211_sub_if_data *sdata); 9 struct ieee80211_sub_if_data *sdata);
11void ieee80211_debugfs_key_remove_mgmt_default( 10void ieee80211_debugfs_key_remove_mgmt_default(
@@ -17,10 +16,7 @@ static inline void ieee80211_debugfs_key_add(struct ieee80211_key *key)
17{} 16{}
18static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key) 17static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
19{} 18{}
20static inline void ieee80211_debugfs_key_add_default( 19static inline void ieee80211_debugfs_key_update_default(
21 struct ieee80211_sub_if_data *sdata)
22{}
23static inline void ieee80211_debugfs_key_remove_default(
24 struct ieee80211_sub_if_data *sdata) 20 struct ieee80211_sub_if_data *sdata)
25{} 21{}
26static inline void ieee80211_debugfs_key_add_mgmt_default( 22static inline void ieee80211_debugfs_key_add_mgmt_default(
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 8bb5af85f469..c04a1396cf8d 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -189,7 +189,7 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu
189 189
190 if (tx) { 190 if (tx) {
191 if (start) 191 if (start)
192 ret = ieee80211_start_tx_ba_session(&sta->sta, tid); 192 ret = ieee80211_start_tx_ba_session(&sta->sta, tid, 5000);
193 else 193 else
194 ret = ieee80211_stop_tx_ba_session(&sta->sta, tid); 194 ret = ieee80211_stop_tx_ba_session(&sta->sta, tid);
195 } else { 195 } else {
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 4244554d218a..af0c4398cceb 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -367,7 +367,7 @@ static inline void drv_reset_tsf(struct ieee80211_local *local)
367 367
368static inline int drv_tx_last_beacon(struct ieee80211_local *local) 368static inline int drv_tx_last_beacon(struct ieee80211_local *local)
369{ 369{
370 int ret = 1; 370 int ret = 0; /* default unsuported op for less congestion */
371 371
372 might_sleep(); 372 might_sleep();
373 373
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 72499fe5fc36..a05893a238b7 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -23,6 +23,7 @@
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/etherdevice.h> 25#include <linux/etherdevice.h>
26#include <linux/leds.h>
26#include <net/ieee80211_radiotap.h> 27#include <net/ieee80211_radiotap.h>
27#include <net/cfg80211.h> 28#include <net/cfg80211.h>
28#include <net/mac80211.h> 29#include <net/mac80211.h>
@@ -484,6 +485,8 @@ struct ieee80211_if_mesh {
484 struct mesh_config mshcfg; 485 struct mesh_config mshcfg;
485 u32 mesh_seqnum; 486 u32 mesh_seqnum;
486 bool accepting_plinks; 487 bool accepting_plinks;
488 const u8 *vendor_ie;
489 u8 vendor_ie_len;
487}; 490};
488 491
489#ifdef CONFIG_MAC80211_MESH 492#ifdef CONFIG_MAC80211_MESH
@@ -557,7 +560,7 @@ struct ieee80211_sub_if_data {
557 unsigned int fragment_next; 560 unsigned int fragment_next;
558 561
559 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 562 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
560 struct ieee80211_key *default_key; 563 struct ieee80211_key *default_unicast_key, *default_multicast_key;
561 struct ieee80211_key *default_mgmt_key; 564 struct ieee80211_key *default_mgmt_key;
562 565
563 u16 sequence_number; 566 u16 sequence_number;
@@ -585,9 +588,7 @@ struct ieee80211_sub_if_data {
585 struct ieee80211_if_vlan vlan; 588 struct ieee80211_if_vlan vlan;
586 struct ieee80211_if_managed mgd; 589 struct ieee80211_if_managed mgd;
587 struct ieee80211_if_ibss ibss; 590 struct ieee80211_if_ibss ibss;
588#ifdef CONFIG_MAC80211_MESH
589 struct ieee80211_if_mesh mesh; 591 struct ieee80211_if_mesh mesh;
590#endif
591 u32 mntr_flags; 592 u32 mntr_flags;
592 } u; 593 } u;
593 594
@@ -595,7 +596,8 @@ struct ieee80211_sub_if_data {
595 struct { 596 struct {
596 struct dentry *dir; 597 struct dentry *dir;
597 struct dentry *subdir_stations; 598 struct dentry *subdir_stations;
598 struct dentry *default_key; 599 struct dentry *default_unicast_key;
600 struct dentry *default_multicast_key;
599 struct dentry *default_mgmt_key; 601 struct dentry *default_mgmt_key;
600 } debugfs; 602 } debugfs;
601#endif 603#endif
@@ -629,6 +631,20 @@ enum queue_stop_reason {
629 IEEE80211_QUEUE_STOP_REASON_SKB_ADD, 631 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
630}; 632};
631 633
634#ifdef CONFIG_MAC80211_LEDS
635struct tpt_led_trigger {
636 struct led_trigger trig;
637 char name[32];
638 const struct ieee80211_tpt_blink *blink_table;
639 unsigned int blink_table_len;
640 struct timer_list timer;
641 unsigned long prev_traffic;
642 unsigned long tx_bytes, rx_bytes;
643 unsigned int active, want;
644 bool running;
645};
646#endif
647
632/** 648/**
633 * mac80211 scan flags - currently active scan mode 649 * mac80211 scan flags - currently active scan mode
634 * 650 *
@@ -837,6 +853,7 @@ struct ieee80211_local {
837#ifdef CONFIG_MAC80211_LEDS 853#ifdef CONFIG_MAC80211_LEDS
838 int tx_led_counter, rx_led_counter; 854 int tx_led_counter, rx_led_counter;
839 struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led; 855 struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led;
856 struct tpt_led_trigger *tpt_led_trigger;
840 char tx_led_name[32], rx_led_name[32], 857 char tx_led_name[32], rx_led_name[32],
841 assoc_led_name[32], radio_led_name[32]; 858 assoc_led_name[32], radio_led_name[32];
842#endif 859#endif
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index f0f11bb794af..b6db237672ff 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -220,6 +220,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
220 /* we're brought up, everything changes */ 220 /* we're brought up, everything changes */
221 hw_reconf_flags = ~0; 221 hw_reconf_flags = ~0;
222 ieee80211_led_radio(local, true); 222 ieee80211_led_radio(local, true);
223 ieee80211_mod_tpt_led_trig(local,
224 IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
223 } 225 }
224 226
225 /* 227 /*
@@ -1264,6 +1266,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
1264 int count = 0; 1266 int count = 0;
1265 bool working = false, scanning = false; 1267 bool working = false, scanning = false;
1266 struct ieee80211_work *wk; 1268 struct ieee80211_work *wk;
1269 unsigned int led_trig_start = 0, led_trig_stop = 0;
1267 1270
1268#ifdef CONFIG_PROVE_LOCKING 1271#ifdef CONFIG_PROVE_LOCKING
1269 WARN_ON(debug_locks && !lockdep_rtnl_is_held() && 1272 WARN_ON(debug_locks && !lockdep_rtnl_is_held() &&
@@ -1313,6 +1316,18 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
1313 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); 1316 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
1314 } 1317 }
1315 1318
1319 if (working || scanning)
1320 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK;
1321 else
1322 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK;
1323
1324 if (count)
1325 led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
1326 else
1327 led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED;
1328
1329 ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
1330
1316 if (working) 1331 if (working)
1317 return ieee80211_idle_off(local, "working"); 1332 return ieee80211_idle_off(local, "working");
1318 if (scanning) 1333 if (scanning)
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 72df1ca7299b..84cf9196820f 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -178,7 +178,7 @@ void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
178EXPORT_SYMBOL_GPL(ieee80211_key_removed); 178EXPORT_SYMBOL_GPL(ieee80211_key_removed);
179 179
180static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, 180static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
181 int idx) 181 int idx, bool uni, bool multi)
182{ 182{
183 struct ieee80211_key *key = NULL; 183 struct ieee80211_key *key = NULL;
184 184
@@ -187,18 +187,19 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
187 if (idx >= 0 && idx < NUM_DEFAULT_KEYS) 187 if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
188 key = sdata->keys[idx]; 188 key = sdata->keys[idx];
189 189
190 rcu_assign_pointer(sdata->default_key, key); 190 if (uni)
191 rcu_assign_pointer(sdata->default_unicast_key, key);
192 if (multi)
193 rcu_assign_pointer(sdata->default_multicast_key, key);
191 194
192 if (key) { 195 ieee80211_debugfs_key_update_default(sdata);
193 ieee80211_debugfs_key_remove_default(key->sdata);
194 ieee80211_debugfs_key_add_default(key->sdata);
195 }
196} 196}
197 197
198void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx) 198void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
199 bool uni, bool multi)
199{ 200{
200 mutex_lock(&sdata->local->key_mtx); 201 mutex_lock(&sdata->local->key_mtx);
201 __ieee80211_set_default_key(sdata, idx); 202 __ieee80211_set_default_key(sdata, idx, uni, multi);
202 mutex_unlock(&sdata->local->key_mtx); 203 mutex_unlock(&sdata->local->key_mtx);
203} 204}
204 205
@@ -215,10 +216,7 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
215 216
216 rcu_assign_pointer(sdata->default_mgmt_key, key); 217 rcu_assign_pointer(sdata->default_mgmt_key, key);
217 218
218 if (key) { 219 ieee80211_debugfs_key_update_default(sdata);
219 ieee80211_debugfs_key_remove_mgmt_default(key->sdata);
220 ieee80211_debugfs_key_add_mgmt_default(key->sdata);
221 }
222} 220}
223 221
224void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, 222void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
@@ -236,7 +234,8 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
236 struct ieee80211_key *old, 234 struct ieee80211_key *old,
237 struct ieee80211_key *new) 235 struct ieee80211_key *new)
238{ 236{
239 int idx, defkey, defmgmtkey; 237 int idx;
238 bool defunikey, defmultikey, defmgmtkey;
240 239
241 if (new) 240 if (new)
242 list_add(&new->list, &sdata->key_list); 241 list_add(&new->list, &sdata->key_list);
@@ -257,17 +256,24 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
257 else 256 else
258 idx = new->conf.keyidx; 257 idx = new->conf.keyidx;
259 258
260 defkey = old && sdata->default_key == old; 259 defunikey = old && sdata->default_unicast_key == old;
260 defmultikey = old && sdata->default_multicast_key == old;
261 defmgmtkey = old && sdata->default_mgmt_key == old; 261 defmgmtkey = old && sdata->default_mgmt_key == old;
262 262
263 if (defkey && !new) 263 if (defunikey && !new)
264 __ieee80211_set_default_key(sdata, -1); 264 __ieee80211_set_default_key(sdata, -1, true, false);
265 if (defmultikey && !new)
266 __ieee80211_set_default_key(sdata, -1, false, true);
265 if (defmgmtkey && !new) 267 if (defmgmtkey && !new)
266 __ieee80211_set_default_mgmt_key(sdata, -1); 268 __ieee80211_set_default_mgmt_key(sdata, -1);
267 269
268 rcu_assign_pointer(sdata->keys[idx], new); 270 rcu_assign_pointer(sdata->keys[idx], new);
269 if (defkey && new) 271 if (defunikey && new)
270 __ieee80211_set_default_key(sdata, new->conf.keyidx); 272 __ieee80211_set_default_key(sdata, new->conf.keyidx,
273 true, false);
274 if (defmultikey && new)
275 __ieee80211_set_default_key(sdata, new->conf.keyidx,
276 false, true);
271 if (defmgmtkey && new) 277 if (defmgmtkey && new)
272 __ieee80211_set_default_mgmt_key(sdata, 278 __ieee80211_set_default_mgmt_key(sdata,
273 new->conf.keyidx); 279 new->conf.keyidx);
@@ -509,11 +515,12 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
509 515
510 mutex_lock(&sdata->local->key_mtx); 516 mutex_lock(&sdata->local->key_mtx);
511 517
512 ieee80211_debugfs_key_remove_default(sdata);
513 ieee80211_debugfs_key_remove_mgmt_default(sdata); 518 ieee80211_debugfs_key_remove_mgmt_default(sdata);
514 519
515 list_for_each_entry_safe(key, tmp, &sdata->key_list, list) 520 list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
516 __ieee80211_key_free(key); 521 __ieee80211_key_free(key);
517 522
523 ieee80211_debugfs_key_update_default(sdata);
524
518 mutex_unlock(&sdata->local->key_mtx); 525 mutex_unlock(&sdata->local->key_mtx);
519} 526}
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 0db1c0f5f697..8106aa1b7466 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -138,7 +138,8 @@ int __must_check ieee80211_key_link(struct ieee80211_key *key,
138 struct sta_info *sta); 138 struct sta_info *sta);
139void ieee80211_key_free(struct ieee80211_local *local, 139void ieee80211_key_free(struct ieee80211_local *local,
140 struct ieee80211_key *key); 140 struct ieee80211_key *key);
141void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); 141void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
142 bool uni, bool multi);
142void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, 143void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
143 int idx); 144 int idx);
144void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); 145void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/led.c b/net/mac80211/led.c
index 063aad944246..4905eb8af572 100644
--- a/net/mac80211/led.c
+++ b/net/mac80211/led.c
@@ -54,12 +54,22 @@ void ieee80211_led_radio(struct ieee80211_local *local, bool enabled)
54 led_trigger_event(local->radio_led, LED_OFF); 54 led_trigger_event(local->radio_led, LED_OFF);
55} 55}
56 56
57void ieee80211_led_names(struct ieee80211_local *local)
58{
59 snprintf(local->rx_led_name, sizeof(local->rx_led_name),
60 "%srx", wiphy_name(local->hw.wiphy));
61 snprintf(local->tx_led_name, sizeof(local->tx_led_name),
62 "%stx", wiphy_name(local->hw.wiphy));
63 snprintf(local->assoc_led_name, sizeof(local->assoc_led_name),
64 "%sassoc", wiphy_name(local->hw.wiphy));
65 snprintf(local->radio_led_name, sizeof(local->radio_led_name),
66 "%sradio", wiphy_name(local->hw.wiphy));
67}
68
57void ieee80211_led_init(struct ieee80211_local *local) 69void ieee80211_led_init(struct ieee80211_local *local)
58{ 70{
59 local->rx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); 71 local->rx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
60 if (local->rx_led) { 72 if (local->rx_led) {
61 snprintf(local->rx_led_name, sizeof(local->rx_led_name),
62 "%srx", wiphy_name(local->hw.wiphy));
63 local->rx_led->name = local->rx_led_name; 73 local->rx_led->name = local->rx_led_name;
64 if (led_trigger_register(local->rx_led)) { 74 if (led_trigger_register(local->rx_led)) {
65 kfree(local->rx_led); 75 kfree(local->rx_led);
@@ -69,8 +79,6 @@ void ieee80211_led_init(struct ieee80211_local *local)
69 79
70 local->tx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); 80 local->tx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
71 if (local->tx_led) { 81 if (local->tx_led) {
72 snprintf(local->tx_led_name, sizeof(local->tx_led_name),
73 "%stx", wiphy_name(local->hw.wiphy));
74 local->tx_led->name = local->tx_led_name; 82 local->tx_led->name = local->tx_led_name;
75 if (led_trigger_register(local->tx_led)) { 83 if (led_trigger_register(local->tx_led)) {
76 kfree(local->tx_led); 84 kfree(local->tx_led);
@@ -80,8 +88,6 @@ void ieee80211_led_init(struct ieee80211_local *local)
80 88
81 local->assoc_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); 89 local->assoc_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
82 if (local->assoc_led) { 90 if (local->assoc_led) {
83 snprintf(local->assoc_led_name, sizeof(local->assoc_led_name),
84 "%sassoc", wiphy_name(local->hw.wiphy));
85 local->assoc_led->name = local->assoc_led_name; 91 local->assoc_led->name = local->assoc_led_name;
86 if (led_trigger_register(local->assoc_led)) { 92 if (led_trigger_register(local->assoc_led)) {
87 kfree(local->assoc_led); 93 kfree(local->assoc_led);
@@ -91,14 +97,19 @@ void ieee80211_led_init(struct ieee80211_local *local)
91 97
92 local->radio_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); 98 local->radio_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
93 if (local->radio_led) { 99 if (local->radio_led) {
94 snprintf(local->radio_led_name, sizeof(local->radio_led_name),
95 "%sradio", wiphy_name(local->hw.wiphy));
96 local->radio_led->name = local->radio_led_name; 100 local->radio_led->name = local->radio_led_name;
97 if (led_trigger_register(local->radio_led)) { 101 if (led_trigger_register(local->radio_led)) {
98 kfree(local->radio_led); 102 kfree(local->radio_led);
99 local->radio_led = NULL; 103 local->radio_led = NULL;
100 } 104 }
101 } 105 }
106
107 if (local->tpt_led_trigger) {
108 if (led_trigger_register(&local->tpt_led_trigger->trig)) {
109 kfree(local->tpt_led_trigger);
110 local->tpt_led_trigger = NULL;
111 }
112 }
102} 113}
103 114
104void ieee80211_led_exit(struct ieee80211_local *local) 115void ieee80211_led_exit(struct ieee80211_local *local)
@@ -119,15 +130,18 @@ void ieee80211_led_exit(struct ieee80211_local *local)
119 led_trigger_unregister(local->rx_led); 130 led_trigger_unregister(local->rx_led);
120 kfree(local->rx_led); 131 kfree(local->rx_led);
121 } 132 }
133
134 if (local->tpt_led_trigger) {
135 led_trigger_unregister(&local->tpt_led_trigger->trig);
136 kfree(local->tpt_led_trigger);
137 }
122} 138}
123 139
124char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw) 140char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw)
125{ 141{
126 struct ieee80211_local *local = hw_to_local(hw); 142 struct ieee80211_local *local = hw_to_local(hw);
127 143
128 if (local->radio_led) 144 return local->radio_led_name;
129 return local->radio_led_name;
130 return NULL;
131} 145}
132EXPORT_SYMBOL(__ieee80211_get_radio_led_name); 146EXPORT_SYMBOL(__ieee80211_get_radio_led_name);
133 147
@@ -135,9 +149,7 @@ char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)
135{ 149{
136 struct ieee80211_local *local = hw_to_local(hw); 150 struct ieee80211_local *local = hw_to_local(hw);
137 151
138 if (local->assoc_led) 152 return local->assoc_led_name;
139 return local->assoc_led_name;
140 return NULL;
141} 153}
142EXPORT_SYMBOL(__ieee80211_get_assoc_led_name); 154EXPORT_SYMBOL(__ieee80211_get_assoc_led_name);
143 155
@@ -145,9 +157,7 @@ char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw)
145{ 157{
146 struct ieee80211_local *local = hw_to_local(hw); 158 struct ieee80211_local *local = hw_to_local(hw);
147 159
148 if (local->tx_led) 160 return local->tx_led_name;
149 return local->tx_led_name;
150 return NULL;
151} 161}
152EXPORT_SYMBOL(__ieee80211_get_tx_led_name); 162EXPORT_SYMBOL(__ieee80211_get_tx_led_name);
153 163
@@ -155,8 +165,144 @@ char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw)
155{ 165{
156 struct ieee80211_local *local = hw_to_local(hw); 166 struct ieee80211_local *local = hw_to_local(hw);
157 167
158 if (local->rx_led) 168 return local->rx_led_name;
159 return local->rx_led_name;
160 return NULL;
161} 169}
162EXPORT_SYMBOL(__ieee80211_get_rx_led_name); 170EXPORT_SYMBOL(__ieee80211_get_rx_led_name);
171
172static unsigned long tpt_trig_traffic(struct ieee80211_local *local,
173 struct tpt_led_trigger *tpt_trig)
174{
175 unsigned long traffic, delta;
176
177 traffic = tpt_trig->tx_bytes + tpt_trig->rx_bytes;
178
179 delta = traffic - tpt_trig->prev_traffic;
180 tpt_trig->prev_traffic = traffic;
181 return DIV_ROUND_UP(delta, 1024 / 8);
182}
183
184static void tpt_trig_timer(unsigned long data)
185{
186 struct ieee80211_local *local = (void *)data;
187 struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
188 struct led_classdev *led_cdev;
189 unsigned long on, off, tpt;
190 int i;
191
192 if (!tpt_trig->running)
193 return;
194
195 mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ));
196
197 tpt = tpt_trig_traffic(local, tpt_trig);
198
199 /* default to just solid on */
200 on = 1;
201 off = 0;
202
203 for (i = tpt_trig->blink_table_len - 1; i >= 0; i--) {
204 if (tpt_trig->blink_table[i].throughput < 0 ||
205 tpt > tpt_trig->blink_table[i].throughput) {
206 off = tpt_trig->blink_table[i].blink_time / 2;
207 on = tpt_trig->blink_table[i].blink_time - off;
208 break;
209 }
210 }
211
212 read_lock(&tpt_trig->trig.leddev_list_lock);
213 list_for_each_entry(led_cdev, &tpt_trig->trig.led_cdevs, trig_list)
214 led_blink_set(led_cdev, &on, &off);
215 read_unlock(&tpt_trig->trig.leddev_list_lock);
216}
217
218extern char *__ieee80211_create_tpt_led_trigger(
219 struct ieee80211_hw *hw, unsigned int flags,
220 const struct ieee80211_tpt_blink *blink_table,
221 unsigned int blink_table_len)
222{
223 struct ieee80211_local *local = hw_to_local(hw);
224 struct tpt_led_trigger *tpt_trig;
225
226 if (WARN_ON(local->tpt_led_trigger))
227 return NULL;
228
229 tpt_trig = kzalloc(sizeof(struct tpt_led_trigger), GFP_KERNEL);
230 if (!tpt_trig)
231 return NULL;
232
233 snprintf(tpt_trig->name, sizeof(tpt_trig->name),
234 "%stpt", wiphy_name(local->hw.wiphy));
235
236 tpt_trig->trig.name = tpt_trig->name;
237
238 tpt_trig->blink_table = blink_table;
239 tpt_trig->blink_table_len = blink_table_len;
240 tpt_trig->want = flags;
241
242 setup_timer(&tpt_trig->timer, tpt_trig_timer, (unsigned long)local);
243
244 local->tpt_led_trigger = tpt_trig;
245
246 return tpt_trig->name;
247}
248EXPORT_SYMBOL(__ieee80211_create_tpt_led_trigger);
249
250static void ieee80211_start_tpt_led_trig(struct ieee80211_local *local)
251{
252 struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
253
254 if (tpt_trig->running)
255 return;
256
257 /* reset traffic */
258 tpt_trig_traffic(local, tpt_trig);
259 tpt_trig->running = true;
260
261 tpt_trig_timer((unsigned long)local);
262 mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ));
263}
264
265static void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local)
266{
267 struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
268 struct led_classdev *led_cdev;
269
270 if (!tpt_trig->running)
271 return;
272
273 tpt_trig->running = false;
274 del_timer_sync(&tpt_trig->timer);
275
276 read_lock(&tpt_trig->trig.leddev_list_lock);
277 list_for_each_entry(led_cdev, &tpt_trig->trig.led_cdevs, trig_list)
278 led_brightness_set(led_cdev, LED_OFF);
279 read_unlock(&tpt_trig->trig.leddev_list_lock);
280}
281
282void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
283 unsigned int types_on, unsigned int types_off)
284{
285 struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
286 bool allowed;
287
288 WARN_ON(types_on & types_off);
289
290 if (!tpt_trig)
291 return;
292
293 tpt_trig->active &= ~types_off;
294 tpt_trig->active |= types_on;
295
296 /*
297 * Regardless of wanted state, we shouldn't blink when
298 * the radio is disabled -- this can happen due to some
299 * code ordering issues with __ieee80211_recalc_idle()
300 * being called before the radio is started.
301 */
302 allowed = tpt_trig->active & IEEE80211_TPT_LEDTRIG_FL_RADIO;
303
304 if (!allowed || !(tpt_trig->active & tpt_trig->want))
305 ieee80211_stop_tpt_led_trig(local);
306 else
307 ieee80211_start_tpt_led_trig(local);
308}
diff --git a/net/mac80211/led.h b/net/mac80211/led.h
index 77b1e1ba6039..e0275d9befa8 100644
--- a/net/mac80211/led.h
+++ b/net/mac80211/led.h
@@ -12,14 +12,17 @@
12#include "ieee80211_i.h" 12#include "ieee80211_i.h"
13 13
14#ifdef CONFIG_MAC80211_LEDS 14#ifdef CONFIG_MAC80211_LEDS
15extern void ieee80211_led_rx(struct ieee80211_local *local); 15void ieee80211_led_rx(struct ieee80211_local *local);
16extern void ieee80211_led_tx(struct ieee80211_local *local, int q); 16void ieee80211_led_tx(struct ieee80211_local *local, int q);
17extern void ieee80211_led_assoc(struct ieee80211_local *local, 17void ieee80211_led_assoc(struct ieee80211_local *local,
18 bool associated); 18 bool associated);
19extern void ieee80211_led_radio(struct ieee80211_local *local, 19void ieee80211_led_radio(struct ieee80211_local *local,
20 bool enabled); 20 bool enabled);
21extern void ieee80211_led_init(struct ieee80211_local *local); 21void ieee80211_led_names(struct ieee80211_local *local);
22extern void ieee80211_led_exit(struct ieee80211_local *local); 22void ieee80211_led_init(struct ieee80211_local *local);
23void ieee80211_led_exit(struct ieee80211_local *local);
24void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
25 unsigned int types_on, unsigned int types_off);
23#else 26#else
24static inline void ieee80211_led_rx(struct ieee80211_local *local) 27static inline void ieee80211_led_rx(struct ieee80211_local *local)
25{ 28{
@@ -35,10 +38,36 @@ static inline void ieee80211_led_radio(struct ieee80211_local *local,
35 bool enabled) 38 bool enabled)
36{ 39{
37} 40}
41static inline void ieee80211_led_names(struct ieee80211_local *local)
42{
43}
38static inline void ieee80211_led_init(struct ieee80211_local *local) 44static inline void ieee80211_led_init(struct ieee80211_local *local)
39{ 45{
40} 46}
41static inline void ieee80211_led_exit(struct ieee80211_local *local) 47static inline void ieee80211_led_exit(struct ieee80211_local *local)
42{ 48{
43} 49}
50static inline void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
51 unsigned int types_on,
52 unsigned int types_off)
53{
54}
55#endif
56
57static inline void
58ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, __le16 fc, int bytes)
59{
60#ifdef CONFIG_MAC80211_LEDS
61 if (local->tpt_led_trigger && ieee80211_is_data(fc))
62 local->tpt_led_trigger->tx_bytes += bytes;
63#endif
64}
65
66static inline void
67ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, __le16 fc, int bytes)
68{
69#ifdef CONFIG_MAC80211_LEDS
70 if (local->tpt_led_trigger && ieee80211_is_data(fc))
71 local->tpt_led_trigger->rx_bytes += bytes;
44#endif 72#endif
73}
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 973fee9f7d69..bbe8e0ac6e52 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -484,6 +484,10 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
484 BIT(IEEE80211_STYPE_DEAUTH >> 4) | 484 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
485 BIT(IEEE80211_STYPE_ACTION >> 4), 485 BIT(IEEE80211_STYPE_ACTION >> 4),
486 }, 486 },
487 [NL80211_IFTYPE_MESH_POINT] = {
488 .tx = 0xffff,
489 .rx = BIT(IEEE80211_STYPE_ACTION >> 4),
490 },
487}; 491};
488 492
489struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, 493struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
@@ -517,10 +521,15 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
517 521
518 wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes; 522 wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes;
519 523
524 wiphy->privid = mac80211_wiphy_privid;
525
520 wiphy->flags |= WIPHY_FLAG_NETNS_OK | 526 wiphy->flags |= WIPHY_FLAG_NETNS_OK |
521 WIPHY_FLAG_4ADDR_AP | 527 WIPHY_FLAG_4ADDR_AP |
522 WIPHY_FLAG_4ADDR_STATION; 528 WIPHY_FLAG_4ADDR_STATION |
523 wiphy->privid = mac80211_wiphy_privid; 529 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
530
531 if (!ops->set_key)
532 wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
524 533
525 wiphy->bss_priv_size = sizeof(struct ieee80211_bss); 534 wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
526 535
@@ -596,6 +605,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
596 /* init dummy netdev for use w/ NAPI */ 605 /* init dummy netdev for use w/ NAPI */
597 init_dummy_netdev(&local->napi_dev); 606 init_dummy_netdev(&local->napi_dev);
598 607
608 ieee80211_led_names(local);
609
599 return local_to_hw(local); 610 return local_to_hw(local);
600} 611}
601EXPORT_SYMBOL(ieee80211_alloc_hw); 612EXPORT_SYMBOL(ieee80211_alloc_hw);
@@ -740,6 +751,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
740 } 751 }
741 } 752 }
742 753
754 local->hw.wiphy->max_remain_on_channel_duration = 5000;
755
743 result = wiphy_register(local->hw.wiphy); 756 result = wiphy_register(local->hw.wiphy);
744 if (result < 0) 757 if (result < 0)
745 goto fail_wiphy_register; 758 goto fail_wiphy_register;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 63e1188d5062..ca3af4685b0a 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -124,15 +124,6 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
124 ieee80211_mesh_housekeeping_timer((unsigned long) sdata); 124 ieee80211_mesh_housekeeping_timer((unsigned long) sdata);
125} 125}
126 126
127void mesh_ids_set_default(struct ieee80211_if_mesh *sta)
128{
129 sta->mesh_pp_id = 0; /* HWMP */
130 sta->mesh_pm_id = 0; /* Airtime */
131 sta->mesh_cc_id = 0; /* Disabled */
132 sta->mesh_sp_id = 0; /* Neighbor Offset */
133 sta->mesh_auth_id = 0; /* Disabled */
134}
135
136int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 127int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
137{ 128{
138 int i; 129 int i;
@@ -287,6 +278,13 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
287 *pos++ |= sdata->u.mesh.accepting_plinks ? 278 *pos++ |= sdata->u.mesh.accepting_plinks ?
288 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 279 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
289 *pos++ = 0x00; 280 *pos++ = 0x00;
281
282 if (sdata->u.mesh.vendor_ie) {
283 int len = sdata->u.mesh.vendor_ie_len;
284 const u8 *data = sdata->u.mesh.vendor_ie;
285 if (skb_tailroom(skb) > len)
286 memcpy(skb_put(skb, len), data, len);
287 }
290} 288}
291 289
292u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl) 290u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl)
@@ -412,39 +410,33 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
412 * ieee80211_new_mesh_header - create a new mesh header 410 * ieee80211_new_mesh_header - create a new mesh header
413 * @meshhdr: uninitialized mesh header 411 * @meshhdr: uninitialized mesh header
414 * @sdata: mesh interface to be used 412 * @sdata: mesh interface to be used
415 * @addr4: addr4 of the mesh frame (1st in ae header) 413 * @addr4or5: 1st address in the ae header, which may correspond to address 4
416 * may be NULL 414 * (if addr6 is NULL) or address 5 (if addr6 is present). It may
417 * @addr5: addr5 of the mesh frame (1st or 2nd in ae header) 415 * be NULL.
418 * may be NULL unless addr6 is present 416 * @addr6: 2nd address in the ae header, which corresponds to addr6 of the
419 * @addr6: addr6 of the mesh frame (2nd or 3rd in ae header) 417 * mesh frame
420 * may be NULL unless addr5 is present
421 * 418 *
422 * Return the header length. 419 * Return the header length.
423 */ 420 */
424int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 421int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
425 struct ieee80211_sub_if_data *sdata, char *addr4, 422 struct ieee80211_sub_if_data *sdata, char *addr4or5,
426 char *addr5, char *addr6) 423 char *addr6)
427{ 424{
428 int aelen = 0; 425 int aelen = 0;
426 BUG_ON(!addr4or5 && addr6);
429 memset(meshhdr, 0, sizeof(*meshhdr)); 427 memset(meshhdr, 0, sizeof(*meshhdr));
430 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; 428 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
431 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); 429 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
432 sdata->u.mesh.mesh_seqnum++; 430 sdata->u.mesh.mesh_seqnum++;
433 if (addr4) { 431 if (addr4or5 && !addr6) {
434 meshhdr->flags |= MESH_FLAGS_AE_A4; 432 meshhdr->flags |= MESH_FLAGS_AE_A4;
435 aelen += ETH_ALEN; 433 aelen += ETH_ALEN;
436 memcpy(meshhdr->eaddr1, addr4, ETH_ALEN); 434 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
437 } 435 } else if (addr4or5 && addr6) {
438 if (addr5 && addr6) {
439 meshhdr->flags |= MESH_FLAGS_AE_A5_A6; 436 meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
440 aelen += 2 * ETH_ALEN; 437 aelen += 2 * ETH_ALEN;
441 if (!addr4) { 438 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
442 memcpy(meshhdr->eaddr1, addr5, ETH_ALEN); 439 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
443 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
444 } else {
445 memcpy(meshhdr->eaddr2, addr5, ETH_ALEN);
446 memcpy(meshhdr->eaddr3, addr6, ETH_ALEN);
447 }
448 } 440 }
449 return 6 + aelen; 441 return 6 + aelen;
450} 442}
@@ -518,6 +510,9 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
518 atomic_inc(&local->iff_allmultis); 510 atomic_inc(&local->iff_allmultis);
519 ieee80211_configure_filter(local); 511 ieee80211_configure_filter(local);
520 512
513 ifmsh->mesh_cc_id = 0; /* Disabled */
514 ifmsh->mesh_sp_id = 0; /* Neighbor Offset */
515 ifmsh->mesh_auth_id = 0; /* Disabled */
521 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); 516 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
522 ieee80211_mesh_root_setup(ifmsh); 517 ieee80211_mesh_root_setup(ifmsh);
523 ieee80211_queue_work(&local->hw, &sdata->work); 518 ieee80211_queue_work(&local->hw, &sdata->work);
@@ -688,7 +683,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
688 /* Allocate all mesh structures when creating the first mesh interface. */ 683 /* Allocate all mesh structures when creating the first mesh interface. */
689 if (!mesh_allocated) 684 if (!mesh_allocated)
690 ieee80211s_init(); 685 ieee80211s_init();
691 mesh_ids_set_default(ifmsh);
692 setup_timer(&ifmsh->mesh_path_timer, 686 setup_timer(&ifmsh->mesh_path_timer,
693 ieee80211_mesh_path_timer, 687 ieee80211_mesh_path_timer,
694 (unsigned long) sdata); 688 (unsigned long) sdata);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 039d7fa0af74..b99e230fe31c 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -164,17 +164,6 @@ struct mesh_rmc {
164}; 164};
165 165
166 166
167/*
168 * MESH_CFG_COMP_LEN Includes:
169 * - Active path selection protocol ID.
170 * - Active path selection metric ID.
171 * - Congestion control mode identifier.
172 * - Channel precedence.
173 * Does not include mesh capabilities, which may vary across nodes in the same
174 * mesh
175 */
176#define MESH_CFG_CMP_LEN (IEEE80211_MESH_CONFIG_LEN - 2)
177
178#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */ 167#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */
179 168
180#define MESH_PATH_EXPIRE (600 * HZ) 169#define MESH_PATH_EXPIRE (600 * HZ)
@@ -198,8 +187,8 @@ struct mesh_rmc {
198int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, 187int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
199 const u8 *da, const u8 *sa); 188 const u8 *da, const u8 *sa);
200int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 189int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
201 struct ieee80211_sub_if_data *sdata, char *addr4, 190 struct ieee80211_sub_if_data *sdata, char *addr4or5,
202 char *addr5, char *addr6); 191 char *addr6);
203int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr, 192int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
204 struct ieee80211_sub_if_data *sdata); 193 struct ieee80211_sub_if_data *sdata);
205bool mesh_matches_local(struct ieee802_11_elems *ie, 194bool mesh_matches_local(struct ieee802_11_elems *ie,
@@ -295,6 +284,11 @@ static inline void mesh_path_activate(struct mesh_path *mpath)
295 mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED; 284 mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED;
296} 285}
297 286
287static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
288{
289 return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
290}
291
298#define for_each_mesh_entry(x, p, node, i) \ 292#define for_each_mesh_entry(x, p, node, i) \
299 for (i = 0; i <= x->hash_mask; i++) \ 293 for (i = 0; i <= x->hash_mask; i++) \
300 hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list) 294 hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list)
@@ -315,6 +309,8 @@ static inline void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
315{} 309{}
316static inline void mesh_plink_quiesce(struct sta_info *sta) {} 310static inline void mesh_plink_quiesce(struct sta_info *sta) {}
317static inline void mesh_plink_restart(struct sta_info *sta) {} 311static inline void mesh_plink_restart(struct sta_info *sta) {}
312static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
313{ return false; }
318#endif 314#endif
319 315
320#endif /* IEEE80211S_H */ 316#endif /* IEEE80211S_H */
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 1c91f0f3c307..44b53931ba5e 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -160,7 +160,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
160 enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid, 160 enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid,
161 __le16 reason) { 161 __le16 reason) {
162 struct ieee80211_local *local = sdata->local; 162 struct ieee80211_local *local = sdata->local;
163 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 163 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
164 sdata->u.mesh.vendor_ie_len);
164 struct ieee80211_mgmt *mgmt; 165 struct ieee80211_mgmt *mgmt;
165 bool include_plid = false; 166 bool include_plid = false;
166 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; 167 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 4ad7a362fcc1..165a4518bb48 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -374,7 +374,7 @@ minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, stru
374 if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) 374 if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
375 return; 375 return;
376 376
377 ieee80211_start_tx_ba_session(pubsta, tid); 377 ieee80211_start_tx_ba_session(pubsta, tid, 5000);
378} 378}
379 379
380static void 380static void
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 2fe8f5f86499..01a3f2630eaf 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -955,12 +955,31 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
955 * have been expected. 955 * have been expected.
956 */ 956 */
957 struct ieee80211_key *key = NULL; 957 struct ieee80211_key *key = NULL;
958 struct ieee80211_sub_if_data *sdata = rx->sdata;
959 int i;
960
958 if (ieee80211_is_mgmt(fc) && 961 if (ieee80211_is_mgmt(fc) &&
959 is_multicast_ether_addr(hdr->addr1) && 962 is_multicast_ether_addr(hdr->addr1) &&
960 (key = rcu_dereference(rx->sdata->default_mgmt_key))) 963 (key = rcu_dereference(rx->sdata->default_mgmt_key)))
961 rx->key = key; 964 rx->key = key;
962 else if ((key = rcu_dereference(rx->sdata->default_key))) 965 else {
963 rx->key = key; 966 if (rx->sta) {
967 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
968 key = rcu_dereference(rx->sta->gtk[i]);
969 if (key)
970 break;
971 }
972 }
973 if (!key) {
974 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
975 key = rcu_dereference(sdata->keys[i]);
976 if (key)
977 break;
978 }
979 }
980 if (key)
981 rx->key = key;
982 }
964 return RX_CONTINUE; 983 return RX_CONTINUE;
965 } else { 984 } else {
966 u8 keyid; 985 u8 keyid;
@@ -1521,12 +1540,30 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1521 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { 1540 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
1522 if (unlikely(!ieee80211_has_protected(fc) && 1541 if (unlikely(!ieee80211_has_protected(fc) &&
1523 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && 1542 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1524 rx->key)) 1543 rx->key)) {
1544 if (ieee80211_is_deauth(fc))
1545 cfg80211_send_unprot_deauth(rx->sdata->dev,
1546 rx->skb->data,
1547 rx->skb->len);
1548 else if (ieee80211_is_disassoc(fc))
1549 cfg80211_send_unprot_disassoc(rx->sdata->dev,
1550 rx->skb->data,
1551 rx->skb->len);
1525 return -EACCES; 1552 return -EACCES;
1553 }
1526 /* BIP does not use Protected field, so need to check MMIE */ 1554 /* BIP does not use Protected field, so need to check MMIE */
1527 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && 1555 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
1528 ieee80211_get_mmie_keyidx(rx->skb) < 0)) 1556 ieee80211_get_mmie_keyidx(rx->skb) < 0)) {
1557 if (ieee80211_is_deauth(fc))
1558 cfg80211_send_unprot_deauth(rx->sdata->dev,
1559 rx->skb->data,
1560 rx->skb->len);
1561 else if (ieee80211_is_disassoc(fc))
1562 cfg80211_send_unprot_disassoc(rx->sdata->dev,
1563 rx->skb->data,
1564 rx->skb->len);
1529 return -EACCES; 1565 return -EACCES;
1566 }
1530 /* 1567 /*
1531 * When using MFP, Action frames are not allowed prior to 1568 * When using MFP, Action frames are not allowed prior to
1532 * having configured keys. 1569 * having configured keys.
@@ -2124,10 +2161,13 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2124 } 2161 }
2125 break; 2162 break;
2126 case WLAN_CATEGORY_MESH_PLINK: 2163 case WLAN_CATEGORY_MESH_PLINK:
2127 case WLAN_CATEGORY_MESH_PATH_SEL:
2128 if (!ieee80211_vif_is_mesh(&sdata->vif)) 2164 if (!ieee80211_vif_is_mesh(&sdata->vif))
2129 break; 2165 break;
2130 goto queue; 2166 goto queue;
2167 case WLAN_CATEGORY_MESH_PATH_SEL:
2168 if (!mesh_path_sel_is_hwmp(sdata))
2169 break;
2170 goto queue;
2131 } 2171 }
2132 2172
2133 return RX_CONTINUE; 2173 return RX_CONTINUE;
@@ -2888,6 +2928,9 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
2888 return; 2928 return;
2889 } 2929 }
2890 2930
2931 ieee80211_tpt_led_trig_rx(local,
2932 ((struct ieee80211_hdr *)skb->data)->frame_control,
2933 skb->len);
2891 __ieee80211_rx_handle_packet(hw, skb); 2934 __ieee80211_rx_handle_packet(hw, skb);
2892 2935
2893 rcu_read_unlock(); 2936 rcu_read_unlock();
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index fdca52cf88de..bbdd2a86a94b 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -78,6 +78,7 @@ enum ieee80211_sta_info_flags {
78 * @addba_resp_timer: timer for peer's response to addba request 78 * @addba_resp_timer: timer for peer's response to addba request
79 * @pending: pending frames queue -- use sta's spinlock to protect 79 * @pending: pending frames queue -- use sta's spinlock to protect
80 * @dialog_token: dialog token for aggregation session 80 * @dialog_token: dialog token for aggregation session
81 * @timeout: session timeout value to be filled in ADDBA requests
81 * @state: session state (see above) 82 * @state: session state (see above)
82 * @stop_initiator: initiator of a session stop 83 * @stop_initiator: initiator of a session stop
83 * @tx_stop: TX DelBA frame when stopping 84 * @tx_stop: TX DelBA frame when stopping
@@ -96,6 +97,7 @@ struct tid_ampdu_tx {
96 struct timer_list addba_resp_timer; 97 struct timer_list addba_resp_timer;
97 struct sk_buff_head pending; 98 struct sk_buff_head pending;
98 unsigned long state; 99 unsigned long state;
100 u16 timeout;
99 u8 dialog_token; 101 u8 dialog_token;
100 u8 stop_initiator; 102 u8 stop_initiator;
101 bool tx_stop; 103 bool tx_stop;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 0ee56bb0ea7e..68c2fbd16ebb 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -539,7 +539,11 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
539 ieee80211_is_robust_mgmt_frame(hdr) && 539 ieee80211_is_robust_mgmt_frame(hdr) &&
540 (key = rcu_dereference(tx->sdata->default_mgmt_key))) 540 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
541 tx->key = key; 541 tx->key = key;
542 else if ((key = rcu_dereference(tx->sdata->default_key))) 542 else if (is_multicast_ether_addr(hdr->addr1) &&
543 (key = rcu_dereference(tx->sdata->default_multicast_key)))
544 tx->key = key;
545 else if (!is_multicast_ether_addr(hdr->addr1) &&
546 (key = rcu_dereference(tx->sdata->default_unicast_key)))
543 tx->key = key; 547 tx->key = key;
544 else if (tx->sdata->drop_unencrypted && 548 else if (tx->sdata->drop_unencrypted &&
545 (tx->skb->protocol != tx->sdata->control_port_protocol) && 549 (tx->skb->protocol != tx->sdata->control_port_protocol) &&
@@ -1293,6 +1297,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
1293 1297
1294 while (skb) { 1298 while (skb) {
1295 int q = skb_get_queue_mapping(skb); 1299 int q = skb_get_queue_mapping(skb);
1300 __le16 fc;
1296 1301
1297 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 1302 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
1298 ret = IEEE80211_TX_OK; 1303 ret = IEEE80211_TX_OK;
@@ -1335,6 +1340,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
1335 else 1340 else
1336 info->control.sta = NULL; 1341 info->control.sta = NULL;
1337 1342
1343 fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
1338 ret = drv_tx(local, skb); 1344 ret = drv_tx(local, skb);
1339 if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { 1345 if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) {
1340 dev_kfree_skb(skb); 1346 dev_kfree_skb(skb);
@@ -1345,6 +1351,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
1345 return IEEE80211_TX_AGAIN; 1351 return IEEE80211_TX_AGAIN;
1346 } 1352 }
1347 1353
1354 ieee80211_tpt_led_trig_tx(local, fc, len);
1348 *skbp = skb = next; 1355 *skbp = skb = next;
1349 ieee80211_led_tx(local, 1); 1356 ieee80211_led_tx(local, 1);
1350 fragm = true; 1357 fragm = true;
@@ -1542,8 +1549,10 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
1542 1549
1543 if (skb_header_cloned(skb)) 1550 if (skb_header_cloned(skb))
1544 I802_DEBUG_INC(local->tx_expand_skb_head_cloned); 1551 I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
1545 else 1552 else if (head_need || tail_need)
1546 I802_DEBUG_INC(local->tx_expand_skb_head); 1553 I802_DEBUG_INC(local->tx_expand_skb_head);
1554 else
1555 return 0;
1547 1556
1548 if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) { 1557 if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) {
1549 wiphy_debug(local->hw.wiphy, 1558 wiphy_debug(local->hw.wiphy,
@@ -1735,7 +1744,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1735{ 1744{
1736 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1745 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1737 struct ieee80211_local *local = sdata->local; 1746 struct ieee80211_local *local = sdata->local;
1738 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1747 struct ieee80211_tx_info *info;
1739 int ret = NETDEV_TX_BUSY, head_need; 1748 int ret = NETDEV_TX_BUSY, head_need;
1740 u16 ethertype, hdrlen, meshhdrlen = 0; 1749 u16 ethertype, hdrlen, meshhdrlen = 0;
1741 __le16 fc; 1750 __le16 fc;
@@ -1807,7 +1816,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1807 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, 1816 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
1808 skb->data, skb->data + ETH_ALEN); 1817 skb->data, skb->data + ETH_ALEN);
1809 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, 1818 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
1810 sdata, NULL, NULL, NULL); 1819 sdata, NULL, NULL);
1811 } else { 1820 } else {
1812 /* packet from other interface */ 1821 /* packet from other interface */
1813 struct mesh_path *mppath; 1822 struct mesh_path *mppath;
@@ -1840,13 +1849,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1840 ieee80211_new_mesh_header(&mesh_hdr, 1849 ieee80211_new_mesh_header(&mesh_hdr,
1841 sdata, 1850 sdata,
1842 skb->data + ETH_ALEN, 1851 skb->data + ETH_ALEN,
1843 NULL,
1844 NULL); 1852 NULL);
1845 else 1853 else
1846 meshhdrlen = 1854 meshhdrlen =
1847 ieee80211_new_mesh_header(&mesh_hdr, 1855 ieee80211_new_mesh_header(&mesh_hdr,
1848 sdata, 1856 sdata,
1849 NULL,
1850 skb->data, 1857 skb->data,
1851 skb->data + ETH_ALEN); 1858 skb->data + ETH_ALEN);
1852 1859
@@ -1930,7 +1937,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1930 */ 1937 */
1931 if (skb_shared(skb)) { 1938 if (skb_shared(skb)) {
1932 tmp_skb = skb; 1939 tmp_skb = skb;
1933 skb = skb_copy(skb, GFP_ATOMIC); 1940 skb = skb_clone(skb, GFP_ATOMIC);
1934 kfree_skb(tmp_skb); 1941 kfree_skb(tmp_skb);
1935 1942
1936 if (!skb) { 1943 if (!skb) {
@@ -2026,6 +2033,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
2026 skb_set_network_header(skb, nh_pos); 2033 skb_set_network_header(skb, nh_pos);
2027 skb_set_transport_header(skb, h_pos); 2034 skb_set_transport_header(skb, h_pos);
2028 2035
2036 info = IEEE80211_SKB_CB(skb);
2029 memset(info, 0, sizeof(*info)); 2037 memset(info, 0, sizeof(*info));
2030 2038
2031 dev->trans_start = jiffies; 2039 dev->trans_start = jiffies;
@@ -2286,7 +2294,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2286 u8 *pos; 2294 u8 *pos;
2287 2295
2288 /* headroom, head length, tail length and maximum TIM length */ 2296 /* headroom, head length, tail length and maximum TIM length */
2289 skb = dev_alloc_skb(local->tx_headroom + 400); 2297 skb = dev_alloc_skb(local->tx_headroom + 400 +
2298 sdata->u.mesh.vendor_ie_len);
2290 if (!skb) 2299 if (!skb)
2291 goto out; 2300 goto out;
2292 2301
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index e497476174ce..cf68700abffa 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1116,6 +1116,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
1116void ieee80211_stop_device(struct ieee80211_local *local) 1116void ieee80211_stop_device(struct ieee80211_local *local)
1117{ 1117{
1118 ieee80211_led_radio(local, false); 1118 ieee80211_led_radio(local, false);
1119 ieee80211_mod_tpt_led_trig(local, 0, IEEE80211_TPT_LEDTRIG_FL_RADIO);
1119 1120
1120 cancel_work_sync(&local->reconfig_filter); 1121 cancel_work_sync(&local->reconfig_filter);
1121 1122
@@ -1150,6 +1151,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1150 } 1151 }
1151 1152
1152 ieee80211_led_radio(local, true); 1153 ieee80211_led_radio(local, true);
1154 ieee80211_mod_tpt_led_trig(local,
1155 IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
1153 } 1156 }
1154 1157
1155 /* add interfaces */ 1158 /* add interfaces */
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 79772fcc37bc..e9a5f8ca4c27 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -789,13 +789,23 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
789 cfg80211_mgd_wext_connect(rdev, wdev); 789 cfg80211_mgd_wext_connect(rdev, wdev);
790 break; 790 break;
791#endif 791#endif
792#ifdef CONFIG_MAC80211_MESH
792 case NL80211_IFTYPE_MESH_POINT: 793 case NL80211_IFTYPE_MESH_POINT:
793 /* backward compat code ... */ 794 {
794 if (wdev->mesh_id_up_len) 795 /* backward compat code... */
795 __cfg80211_join_mesh(rdev, dev, wdev->ssid, 796 struct mesh_setup setup;
796 wdev->mesh_id_up_len, 797 memcpy(&setup, &default_mesh_setup,
797 &default_mesh_config); 798 sizeof(setup));
798 break; 799 /* back compat only needed for mesh_id */
800 setup.mesh_id = wdev->ssid;
801 setup.mesh_id_len = wdev->mesh_id_up_len;
802 if (wdev->mesh_id_up_len)
803 __cfg80211_join_mesh(rdev, dev,
804 &setup,
805 &default_mesh_config);
806 break;
807 }
808#endif
799 default: 809 default:
800 break; 810 break;
801 } 811 }
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 743203bb61ac..26a0a084e16b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -287,13 +287,14 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
287 287
288/* mesh */ 288/* mesh */
289extern const struct mesh_config default_mesh_config; 289extern const struct mesh_config default_mesh_config;
290extern const struct mesh_setup default_mesh_setup;
290int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 291int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
291 struct net_device *dev, 292 struct net_device *dev,
292 const u8 *mesh_id, u8 mesh_id_len, 293 const struct mesh_setup *setup,
293 const struct mesh_config *conf); 294 const struct mesh_config *conf);
294int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 295int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
295 struct net_device *dev, 296 struct net_device *dev,
296 const u8 *mesh_id, u8 mesh_id_len, 297 const struct mesh_setup *setup,
297 const struct mesh_config *conf); 298 const struct mesh_config *conf);
298int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 299int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
299 struct net_device *dev); 300 struct net_device *dev);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index e0b9747fe50a..73e39c171ffb 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -50,17 +50,19 @@ const struct mesh_config default_mesh_config = {
50 .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, 50 .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
51}; 51};
52 52
53const struct mesh_setup default_mesh_setup = {
54 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
55 .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
56 .vendor_ie = NULL,
57 .vendor_ie_len = 0,
58};
53 59
54int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 60int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
55 struct net_device *dev, 61 struct net_device *dev,
56 const u8 *mesh_id, u8 mesh_id_len, 62 const struct mesh_setup *setup,
57 const struct mesh_config *conf) 63 const struct mesh_config *conf)
58{ 64{
59 struct wireless_dev *wdev = dev->ieee80211_ptr; 65 struct wireless_dev *wdev = dev->ieee80211_ptr;
60 struct mesh_setup setup = {
61 .mesh_id = mesh_id,
62 .mesh_id_len = mesh_id_len,
63 };
64 int err; 66 int err;
65 67
66 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); 68 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN);
@@ -73,16 +75,16 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
73 if (wdev->mesh_id_len) 75 if (wdev->mesh_id_len)
74 return -EALREADY; 76 return -EALREADY;
75 77
76 if (!mesh_id_len) 78 if (!setup->mesh_id_len)
77 return -EINVAL; 79 return -EINVAL;
78 80
79 if (!rdev->ops->join_mesh) 81 if (!rdev->ops->join_mesh)
80 return -EOPNOTSUPP; 82 return -EOPNOTSUPP;
81 83
82 err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, &setup); 84 err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup);
83 if (!err) { 85 if (!err) {
84 memcpy(wdev->ssid, mesh_id, mesh_id_len); 86 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
85 wdev->mesh_id_len = mesh_id_len; 87 wdev->mesh_id_len = setup->mesh_id_len;
86 } 88 }
87 89
88 return err; 90 return err;
@@ -90,14 +92,14 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
90 92
91int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 93int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
92 struct net_device *dev, 94 struct net_device *dev,
93 const u8 *mesh_id, u8 mesh_id_len, 95 const struct mesh_setup *setup,
94 const struct mesh_config *conf) 96 const struct mesh_config *conf)
95{ 97{
96 struct wireless_dev *wdev = dev->ieee80211_ptr; 98 struct wireless_dev *wdev = dev->ieee80211_ptr;
97 int err; 99 int err;
98 100
99 wdev_lock(wdev); 101 wdev_lock(wdev);
100 err = __cfg80211_join_mesh(rdev, dev, mesh_id, mesh_id_len, conf); 102 err = __cfg80211_join_mesh(rdev, dev, setup, conf);
101 wdev_unlock(wdev); 103 wdev_unlock(wdev);
102 104
103 return err; 105 return err;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index d7680f2a4c5b..aa5df8865ff7 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -263,6 +263,28 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
263} 263}
264EXPORT_SYMBOL(cfg80211_send_disassoc); 264EXPORT_SYMBOL(cfg80211_send_disassoc);
265 265
266void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
267 size_t len)
268{
269 struct wireless_dev *wdev = dev->ieee80211_ptr;
270 struct wiphy *wiphy = wdev->wiphy;
271 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
272
273 nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC);
274}
275EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
276
277void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
278 size_t len)
279{
280 struct wireless_dev *wdev = dev->ieee80211_ptr;
281 struct wiphy *wiphy = wdev->wiphy;
282 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
283
284 nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC);
285}
286EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
287
266static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr) 288static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
267{ 289{
268 int i; 290 int i;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c3f80e565365..9b62710891a2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -123,7 +123,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
123 .len = NL80211_MAX_SUPP_RATES }, 123 .len = NL80211_MAX_SUPP_RATES },
124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, 124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
125 125
126 [NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED }, 126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
127 127
128 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 128 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
129 .len = NL80211_HT_CAPABILITY_LEN }, 129 .len = NL80211_HT_CAPABILITY_LEN },
@@ -171,6 +171,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
171 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 }, 171 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
172 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, 172 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
173 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, 173 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
174 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
174}; 175};
175 176
176/* policy for the key attributes */ 177/* policy for the key attributes */
@@ -182,6 +183,14 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
182 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, 183 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
183 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, 184 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
184 [NL80211_KEY_TYPE] = { .type = NLA_U32 }, 185 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
186 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
187};
188
189/* policy for the key default flags */
190static const struct nla_policy
191nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
192 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
193 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
185}; 194};
186 195
187/* ifidx get helper */ 196/* ifidx get helper */
@@ -314,6 +323,7 @@ struct key_parse {
314 int idx; 323 int idx;
315 int type; 324 int type;
316 bool def, defmgmt; 325 bool def, defmgmt;
326 bool def_uni, def_multi;
317}; 327};
318 328
319static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) 329static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
@@ -327,6 +337,13 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
327 k->def = !!tb[NL80211_KEY_DEFAULT]; 337 k->def = !!tb[NL80211_KEY_DEFAULT];
328 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT]; 338 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
329 339
340 if (k->def) {
341 k->def_uni = true;
342 k->def_multi = true;
343 }
344 if (k->defmgmt)
345 k->def_multi = true;
346
330 if (tb[NL80211_KEY_IDX]) 347 if (tb[NL80211_KEY_IDX])
331 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]); 348 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
332 349
@@ -349,6 +366,19 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
349 return -EINVAL; 366 return -EINVAL;
350 } 367 }
351 368
369 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
370 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
371 int err = nla_parse_nested(kdt,
372 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
373 tb[NL80211_KEY_DEFAULT_TYPES],
374 nl80211_key_default_policy);
375 if (err)
376 return err;
377
378 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
379 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
380 }
381
352 return 0; 382 return 0;
353} 383}
354 384
@@ -373,12 +403,32 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
373 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT]; 403 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
374 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]; 404 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
375 405
406 if (k->def) {
407 k->def_uni = true;
408 k->def_multi = true;
409 }
410 if (k->defmgmt)
411 k->def_multi = true;
412
376 if (info->attrs[NL80211_ATTR_KEY_TYPE]) { 413 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
377 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); 414 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
378 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) 415 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
379 return -EINVAL; 416 return -EINVAL;
380 } 417 }
381 418
419 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
420 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
421 int err = nla_parse_nested(
422 kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
423 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
424 nl80211_key_default_policy);
425 if (err)
426 return err;
427
428 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
429 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
430 }
431
382 return 0; 432 return 0;
383} 433}
384 434
@@ -401,6 +451,11 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
401 if (k->def && k->defmgmt) 451 if (k->def && k->defmgmt)
402 return -EINVAL; 452 return -EINVAL;
403 453
454 if (k->defmgmt) {
455 if (k->def_uni || !k->def_multi)
456 return -EINVAL;
457 }
458
404 if (k->idx != -1) { 459 if (k->idx != -1) {
405 if (k->defmgmt) { 460 if (k->defmgmt) {
406 if (k->idx < 4 || k->idx > 5) 461 if (k->idx < 4 || k->idx > 5)
@@ -450,6 +505,8 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
450 goto error; 505 goto error;
451 def = 1; 506 def = 1;
452 result->def = parse.idx; 507 result->def = parse.idx;
508 if (!parse.def_uni || !parse.def_multi)
509 goto error;
453 } else if (parse.defmgmt) 510 } else if (parse.defmgmt)
454 goto error; 511 goto error;
455 err = cfg80211_validate_key_settings(rdev, &parse.p, 512 err = cfg80211_validate_key_settings(rdev, &parse.p,
@@ -548,7 +605,13 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
548 if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) 605 if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL)
549 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); 606 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE);
550 607
551 if (dev->ops->get_antenna) { 608 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
609 dev->wiphy.available_antennas_tx);
610 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
611 dev->wiphy.available_antennas_rx);
612
613 if ((dev->wiphy.available_antennas_tx ||
614 dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) {
552 u32 tx_ant = 0, rx_ant = 0; 615 u32 tx_ant = 0, rx_ant = 0;
553 int res; 616 int res;
554 res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); 617 res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant);
@@ -662,7 +725,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
662 CMD(add_beacon, NEW_BEACON); 725 CMD(add_beacon, NEW_BEACON);
663 CMD(add_station, NEW_STATION); 726 CMD(add_station, NEW_STATION);
664 CMD(add_mpath, NEW_MPATH); 727 CMD(add_mpath, NEW_MPATH);
665 CMD(update_mesh_params, SET_MESH_PARAMS); 728 CMD(update_mesh_config, SET_MESH_CONFIG);
666 CMD(change_bss, SET_BSS); 729 CMD(change_bss, SET_BSS);
667 CMD(auth, AUTHENTICATE); 730 CMD(auth, AUTHENTICATE);
668 CMD(assoc, ASSOCIATE); 731 CMD(assoc, ASSOCIATE);
@@ -698,6 +761,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
698 761
699 nla_nest_end(msg, nl_cmds); 762 nla_nest_end(msg, nl_cmds);
700 763
764 if (dev->ops->remain_on_channel)
765 NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
766 dev->wiphy.max_remain_on_channel_duration);
767
701 /* for now at least assume all drivers have it */ 768 /* for now at least assume all drivers have it */
702 if (dev->ops->mgmt_tx) 769 if (dev->ops->mgmt_tx)
703 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); 770 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
@@ -1046,7 +1113,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1046 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && 1113 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
1047 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { 1114 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
1048 u32 tx_ant, rx_ant; 1115 u32 tx_ant, rx_ant;
1049 if (!rdev->ops->set_antenna) { 1116 if ((!rdev->wiphy.available_antennas_tx &&
1117 !rdev->wiphy.available_antennas_rx) ||
1118 !rdev->ops->set_antenna) {
1050 result = -EOPNOTSUPP; 1119 result = -EOPNOTSUPP;
1051 goto bad_res; 1120 goto bad_res;
1052 } 1121 }
@@ -1054,6 +1123,17 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1054 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]); 1123 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
1055 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); 1124 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
1056 1125
1126 /* reject antenna configurations which don't match the
1127 * available antenna masks, except for the "all" mask */
1128 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
1129 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
1130 result = -EINVAL;
1131 goto bad_res;
1132 }
1133
1134 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
1135 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
1136
1057 result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); 1137 result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
1058 if (result) 1138 if (result)
1059 goto bad_res; 1139 goto bad_res;
@@ -1575,8 +1655,6 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1575 struct key_parse key; 1655 struct key_parse key;
1576 int err; 1656 int err;
1577 struct net_device *dev = info->user_ptr[1]; 1657 struct net_device *dev = info->user_ptr[1];
1578 int (*func)(struct wiphy *wiphy, struct net_device *netdev,
1579 u8 key_index);
1580 1658
1581 err = nl80211_parse_key(info, &key); 1659 err = nl80211_parse_key(info, &key);
1582 if (err) 1660 if (err)
@@ -1589,27 +1667,61 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1589 if (!key.def && !key.defmgmt) 1667 if (!key.def && !key.defmgmt)
1590 return -EINVAL; 1668 return -EINVAL;
1591 1669
1592 if (key.def) 1670 wdev_lock(dev->ieee80211_ptr);
1593 func = rdev->ops->set_default_key;
1594 else
1595 func = rdev->ops->set_default_mgmt_key;
1596 1671
1597 if (!func) 1672 if (key.def) {
1598 return -EOPNOTSUPP; 1673 if (!rdev->ops->set_default_key) {
1674 err = -EOPNOTSUPP;
1675 goto out;
1676 }
1599 1677
1600 wdev_lock(dev->ieee80211_ptr); 1678 err = nl80211_key_allowed(dev->ieee80211_ptr);
1601 err = nl80211_key_allowed(dev->ieee80211_ptr); 1679 if (err)
1602 if (!err) 1680 goto out;
1603 err = func(&rdev->wiphy, dev, key.idx); 1681
1682 if (!(rdev->wiphy.flags &
1683 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) {
1684 if (!key.def_uni || !key.def_multi) {
1685 err = -EOPNOTSUPP;
1686 goto out;
1687 }
1688 }
1689
1690 err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx,
1691 key.def_uni, key.def_multi);
1692
1693 if (err)
1694 goto out;
1604 1695
1605#ifdef CONFIG_CFG80211_WEXT 1696#ifdef CONFIG_CFG80211_WEXT
1606 if (!err) { 1697 dev->ieee80211_ptr->wext.default_key = key.idx;
1607 if (func == rdev->ops->set_default_key)
1608 dev->ieee80211_ptr->wext.default_key = key.idx;
1609 else
1610 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
1611 }
1612#endif 1698#endif
1699 } else {
1700 if (key.def_uni || !key.def_multi) {
1701 err = -EINVAL;
1702 goto out;
1703 }
1704
1705 if (!rdev->ops->set_default_mgmt_key) {
1706 err = -EOPNOTSUPP;
1707 goto out;
1708 }
1709
1710 err = nl80211_key_allowed(dev->ieee80211_ptr);
1711 if (err)
1712 goto out;
1713
1714 err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
1715 dev, key.idx);
1716 if (err)
1717 goto out;
1718
1719#ifdef CONFIG_CFG80211_WEXT
1720 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
1721#endif
1722 }
1723
1724 out:
1613 wdev_unlock(dev->ieee80211_ptr); 1725 wdev_unlock(dev->ieee80211_ptr);
1614 1726
1615 return err; 1727 return err;
@@ -2569,7 +2681,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
2569 return r; 2681 return r;
2570} 2682}
2571 2683
2572static int nl80211_get_mesh_params(struct sk_buff *skb, 2684static int nl80211_get_mesh_config(struct sk_buff *skb,
2573 struct genl_info *info) 2685 struct genl_info *info)
2574{ 2686{
2575 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2687 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2584,7 +2696,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2584 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) 2696 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
2585 return -EOPNOTSUPP; 2697 return -EOPNOTSUPP;
2586 2698
2587 if (!rdev->ops->get_mesh_params) 2699 if (!rdev->ops->get_mesh_config)
2588 return -EOPNOTSUPP; 2700 return -EOPNOTSUPP;
2589 2701
2590 wdev_lock(wdev); 2702 wdev_lock(wdev);
@@ -2592,7 +2704,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2592 if (!wdev->mesh_id_len) 2704 if (!wdev->mesh_id_len)
2593 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); 2705 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
2594 else 2706 else
2595 err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, 2707 err = rdev->ops->get_mesh_config(&rdev->wiphy, dev,
2596 &cur_params); 2708 &cur_params);
2597 wdev_unlock(wdev); 2709 wdev_unlock(wdev);
2598 2710
@@ -2604,10 +2716,10 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2604 if (!msg) 2716 if (!msg)
2605 return -ENOMEM; 2717 return -ENOMEM;
2606 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 2718 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2607 NL80211_CMD_GET_MESH_PARAMS); 2719 NL80211_CMD_GET_MESH_CONFIG);
2608 if (!hdr) 2720 if (!hdr)
2609 goto nla_put_failure; 2721 goto nla_put_failure;
2610 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS); 2722 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
2611 if (!pinfoattr) 2723 if (!pinfoattr)
2612 goto nla_put_failure; 2724 goto nla_put_failure;
2613 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 2725 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
@@ -2669,7 +2781,15 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
2669 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, 2781 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
2670}; 2782};
2671 2783
2672static int nl80211_parse_mesh_params(struct genl_info *info, 2784static const struct nla_policy
2785 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
2786 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
2787 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
2788 [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY,
2789 .len = IEEE80211_MAX_DATA_LEN },
2790};
2791
2792static int nl80211_parse_mesh_config(struct genl_info *info,
2673 struct mesh_config *cfg, 2793 struct mesh_config *cfg,
2674 u32 *mask_out) 2794 u32 *mask_out)
2675{ 2795{
@@ -2685,10 +2805,10 @@ do {\
2685} while (0);\ 2805} while (0);\
2686 2806
2687 2807
2688 if (!info->attrs[NL80211_ATTR_MESH_PARAMS]) 2808 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
2689 return -EINVAL; 2809 return -EINVAL;
2690 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX, 2810 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
2691 info->attrs[NL80211_ATTR_MESH_PARAMS], 2811 info->attrs[NL80211_ATTR_MESH_CONFIG],
2692 nl80211_meshconf_params_policy)) 2812 nl80211_meshconf_params_policy))
2693 return -EINVAL; 2813 return -EINVAL;
2694 2814
@@ -2735,15 +2855,51 @@ do {\
2735 dot11MeshHWMPRootMode, mask, 2855 dot11MeshHWMPRootMode, mask,
2736 NL80211_MESHCONF_HWMP_ROOTMODE, 2856 NL80211_MESHCONF_HWMP_ROOTMODE,
2737 nla_get_u8); 2857 nla_get_u8);
2738
2739 if (mask_out) 2858 if (mask_out)
2740 *mask_out = mask; 2859 *mask_out = mask;
2860
2741 return 0; 2861 return 0;
2742 2862
2743#undef FILL_IN_MESH_PARAM_IF_SET 2863#undef FILL_IN_MESH_PARAM_IF_SET
2744} 2864}
2745 2865
2746static int nl80211_update_mesh_params(struct sk_buff *skb, 2866static int nl80211_parse_mesh_setup(struct genl_info *info,
2867 struct mesh_setup *setup)
2868{
2869 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
2870
2871 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
2872 return -EINVAL;
2873 if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
2874 info->attrs[NL80211_ATTR_MESH_SETUP],
2875 nl80211_mesh_setup_params_policy))
2876 return -EINVAL;
2877
2878 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
2879 setup->path_sel_proto =
2880 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
2881 IEEE80211_PATH_PROTOCOL_VENDOR :
2882 IEEE80211_PATH_PROTOCOL_HWMP;
2883
2884 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
2885 setup->path_metric =
2886 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
2887 IEEE80211_PATH_METRIC_VENDOR :
2888 IEEE80211_PATH_METRIC_AIRTIME;
2889
2890 if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) {
2891 struct nlattr *ieattr =
2892 tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE];
2893 if (!is_valid_ie_attr(ieattr))
2894 return -EINVAL;
2895 setup->vendor_ie = nla_data(ieattr);
2896 setup->vendor_ie_len = nla_len(ieattr);
2897 }
2898
2899 return 0;
2900}
2901
2902static int nl80211_update_mesh_config(struct sk_buff *skb,
2747 struct genl_info *info) 2903 struct genl_info *info)
2748{ 2904{
2749 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2905 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2756,10 +2912,10 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
2756 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) 2912 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
2757 return -EOPNOTSUPP; 2913 return -EOPNOTSUPP;
2758 2914
2759 if (!rdev->ops->update_mesh_params) 2915 if (!rdev->ops->update_mesh_config)
2760 return -EOPNOTSUPP; 2916 return -EOPNOTSUPP;
2761 2917
2762 err = nl80211_parse_mesh_params(info, &cfg, &mask); 2918 err = nl80211_parse_mesh_config(info, &cfg, &mask);
2763 if (err) 2919 if (err)
2764 return err; 2920 return err;
2765 2921
@@ -2768,7 +2924,7 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
2768 err = -ENOLINK; 2924 err = -ENOLINK;
2769 2925
2770 if (!err) 2926 if (!err)
2771 err = rdev->ops->update_mesh_params(&rdev->wiphy, dev, 2927 err = rdev->ops->update_mesh_config(&rdev->wiphy, dev,
2772 mask, &cfg); 2928 mask, &cfg);
2773 2929
2774 wdev_unlock(wdev); 2930 wdev_unlock(wdev);
@@ -4128,7 +4284,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
4128 * We should be on that channel for at least one jiffie, 4284 * We should be on that channel for at least one jiffie,
4129 * and more than 5 seconds seems excessive. 4285 * and more than 5 seconds seems excessive.
4130 */ 4286 */
4131 if (!duration || !msecs_to_jiffies(duration) || duration > 5000) 4287 if (!duration || !msecs_to_jiffies(duration) ||
4288 duration > rdev->wiphy.max_remain_on_channel_duration)
4132 return -EINVAL; 4289 return -EINVAL;
4133 4290
4134 if (!rdev->ops->remain_on_channel) 4291 if (!rdev->ops->remain_on_channel)
@@ -4296,6 +4453,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
4296 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && 4453 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4297 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 4454 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4298 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 4455 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4456 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4299 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4457 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4300 return -EOPNOTSUPP; 4458 return -EOPNOTSUPP;
4301 4459
@@ -4336,6 +4494,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4336 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && 4494 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4337 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 4495 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4338 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 4496 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4497 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4339 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4498 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4340 return -EOPNOTSUPP; 4499 return -EOPNOTSUPP;
4341 4500
@@ -4562,14 +4721,16 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
4562 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4721 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4563 struct net_device *dev = info->user_ptr[1]; 4722 struct net_device *dev = info->user_ptr[1];
4564 struct mesh_config cfg; 4723 struct mesh_config cfg;
4724 struct mesh_setup setup;
4565 int err; 4725 int err;
4566 4726
4567 /* start with default */ 4727 /* start with default */
4568 memcpy(&cfg, &default_mesh_config, sizeof(cfg)); 4728 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
4729 memcpy(&setup, &default_mesh_setup, sizeof(setup));
4569 4730
4570 if (info->attrs[NL80211_ATTR_MESH_PARAMS]) { 4731 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
4571 /* and parse parameters if given */ 4732 /* and parse parameters if given */
4572 err = nl80211_parse_mesh_params(info, &cfg, NULL); 4733 err = nl80211_parse_mesh_config(info, &cfg, NULL);
4573 if (err) 4734 if (err)
4574 return err; 4735 return err;
4575 } 4736 }
@@ -4578,10 +4739,17 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
4578 !nla_len(info->attrs[NL80211_ATTR_MESH_ID])) 4739 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
4579 return -EINVAL; 4740 return -EINVAL;
4580 4741
4581 return cfg80211_join_mesh(rdev, dev, 4742 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
4582 nla_data(info->attrs[NL80211_ATTR_MESH_ID]), 4743 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
4583 nla_len(info->attrs[NL80211_ATTR_MESH_ID]), 4744
4584 &cfg); 4745 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
4746 /* parse additional setup parameters if given */
4747 err = nl80211_parse_mesh_setup(info, &setup);
4748 if (err)
4749 return err;
4750 }
4751
4752 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
4585} 4753}
4586 4754
4587static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) 4755static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
@@ -4847,16 +5015,16 @@ static struct genl_ops nl80211_ops[] = {
4847 .flags = GENL_ADMIN_PERM, 5015 .flags = GENL_ADMIN_PERM,
4848 }, 5016 },
4849 { 5017 {
4850 .cmd = NL80211_CMD_GET_MESH_PARAMS, 5018 .cmd = NL80211_CMD_GET_MESH_CONFIG,
4851 .doit = nl80211_get_mesh_params, 5019 .doit = nl80211_get_mesh_config,
4852 .policy = nl80211_policy, 5020 .policy = nl80211_policy,
4853 /* can be retrieved by unprivileged users */ 5021 /* can be retrieved by unprivileged users */
4854 .internal_flags = NL80211_FLAG_NEED_NETDEV | 5022 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4855 NL80211_FLAG_NEED_RTNL, 5023 NL80211_FLAG_NEED_RTNL,
4856 }, 5024 },
4857 { 5025 {
4858 .cmd = NL80211_CMD_SET_MESH_PARAMS, 5026 .cmd = NL80211_CMD_SET_MESH_CONFIG,
4859 .doit = nl80211_update_mesh_params, 5027 .doit = nl80211_update_mesh_config,
4860 .policy = nl80211_policy, 5028 .policy = nl80211_policy,
4861 .flags = GENL_ADMIN_PERM, 5029 .flags = GENL_ADMIN_PERM,
4862 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 5030 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
@@ -5368,6 +5536,22 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
5368 NL80211_CMD_DISASSOCIATE, gfp); 5536 NL80211_CMD_DISASSOCIATE, gfp);
5369} 5537}
5370 5538
5539void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
5540 struct net_device *netdev, const u8 *buf,
5541 size_t len, gfp_t gfp)
5542{
5543 nl80211_send_mlme_event(rdev, netdev, buf, len,
5544 NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp);
5545}
5546
5547void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
5548 struct net_device *netdev, const u8 *buf,
5549 size_t len, gfp_t gfp)
5550{
5551 nl80211_send_mlme_event(rdev, netdev, buf, len,
5552 NL80211_CMD_UNPROT_DISASSOCIATE, gfp);
5553}
5554
5371static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, 5555static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
5372 struct net_device *netdev, int cmd, 5556 struct net_device *netdev, int cmd,
5373 const u8 *addr, gfp_t gfp) 5557 const u8 *addr, gfp_t gfp)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 16c2f7190768..e3f7fa886966 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -25,6 +25,12 @@ void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
25void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, 25void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
26 struct net_device *netdev, 26 struct net_device *netdev,
27 const u8 *buf, size_t len, gfp_t gfp); 27 const u8 *buf, size_t len, gfp_t gfp);
28void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
29 struct net_device *netdev,
30 const u8 *buf, size_t len, gfp_t gfp);
31void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
32 struct net_device *netdev,
33 const u8 *buf, size_t len, gfp_t gfp);
28void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, 34void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
29 struct net_device *netdev, 35 struct net_device *netdev,
30 const u8 *addr, gfp_t gfp); 36 const u8 *addr, gfp_t gfp);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 5ed615f94e0c..99d41831d76e 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -661,7 +661,8 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
661 * Follow the driver's regulatory domain, if present, unless a country 661 * Follow the driver's regulatory domain, if present, unless a country
662 * IE has been processed or a user wants to help complaince further 662 * IE has been processed or a user wants to help complaince further
663 */ 663 */
664 if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && 664 if (!custom_regd &&
665 last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
665 last_request->initiator != NL80211_REGDOM_SET_BY_USER && 666 last_request->initiator != NL80211_REGDOM_SET_BY_USER &&
666 wiphy->regd) 667 wiphy->regd)
667 regd = wiphy->regd; 668 regd = wiphy->regd;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 503ebb86ba18..ea427f418f64 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -464,6 +464,9 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
464 if (res->pub.beacon_ies) { 464 if (res->pub.beacon_ies) {
465 size_t used = dev->wiphy.bss_priv_size + sizeof(*res); 465 size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
466 size_t ielen = res->pub.len_beacon_ies; 466 size_t ielen = res->pub.len_beacon_ies;
467 bool information_elements_is_beacon_ies =
468 (found->pub.information_elements ==
469 found->pub.beacon_ies);
467 470
468 if (found->pub.beacon_ies && 471 if (found->pub.beacon_ies &&
469 !found->beacon_ies_allocated && 472 !found->beacon_ies_allocated &&
@@ -487,6 +490,14 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
487 found->pub.len_beacon_ies = ielen; 490 found->pub.len_beacon_ies = ielen;
488 } 491 }
489 } 492 }
493
494 /* Override IEs if they were from a beacon before */
495 if (information_elements_is_beacon_ies) {
496 found->pub.information_elements =
497 found->pub.beacon_ies;
498 found->pub.len_information_elements =
499 found->pub.len_beacon_ies;
500 }
490 } 501 }
491 502
492 kref_put(&res->ref, bss_release); 503 kref_put(&res->ref, bss_release);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4de624ca4c63..7620ae2fcf18 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -689,7 +689,8 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
689 continue; 689 continue;
690 } 690 }
691 if (wdev->connect_keys->def == i) 691 if (wdev->connect_keys->def == i)
692 if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) { 692 if (rdev->ops->set_default_key(wdev->wiphy, dev,
693 i, true, true)) {
693 netdev_err(dev, "failed to set defkey %d\n", i); 694 netdev_err(dev, "failed to set defkey %d\n", i);
694 continue; 695 continue;
695 } 696 }
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 12222ee6ebf2..3e5dbd4e4cd5 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -548,8 +548,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
548 __cfg80211_leave_ibss(rdev, wdev->netdev, true); 548 __cfg80211_leave_ibss(rdev, wdev->netdev, true);
549 rejoin = true; 549 rejoin = true;
550 } 550 }
551 err = rdev->ops->set_default_key(&rdev->wiphy, 551 err = rdev->ops->set_default_key(&rdev->wiphy, dev,
552 dev, idx); 552 idx, true, true);
553 } 553 }
554 if (!err) { 554 if (!err) {
555 wdev->wext.default_key = idx; 555 wdev->wext.default_key = idx;
@@ -627,8 +627,8 @@ int cfg80211_wext_siwencode(struct net_device *dev,
627 err = 0; 627 err = 0;
628 wdev_lock(wdev); 628 wdev_lock(wdev);
629 if (wdev->current_bss) 629 if (wdev->current_bss)
630 err = rdev->ops->set_default_key(&rdev->wiphy, 630 err = rdev->ops->set_default_key(&rdev->wiphy, dev,
631 dev, idx); 631 idx, true, true);
632 if (!err) 632 if (!err)
633 wdev->wext.default_key = idx; 633 wdev->wext.default_key = idx;
634 wdev_unlock(wdev); 634 wdev_unlock(wdev);