aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/agg-rx.c3
-rw-r--r--net/mac80211/agg-tx.c59
-rw-r--r--net/mac80211/cfg.c135
-rw-r--r--net/mac80211/debugfs.c2
-rw-r--r--net/mac80211/debugfs_key.c21
-rw-r--r--net/mac80211/driver-ops.h56
-rw-r--r--net/mac80211/driver-trace.h228
-rw-r--r--net/mac80211/ht.c27
-rw-r--r--net/mac80211/ibss.c11
-rw-r--r--net/mac80211/ieee80211_i.h41
-rw-r--r--net/mac80211/iface.c3
-rw-r--r--net/mac80211/key.c30
-rw-r--r--net/mac80211/key.h4
-rw-r--r--net/mac80211/main.c37
-rw-r--r--net/mac80211/mesh.c47
-rw-r--r--net/mac80211/mesh.h6
-rw-r--r--net/mac80211/mesh_hwmp.c38
-rw-r--r--net/mac80211/mesh_pathtbl.c123
-rw-r--r--net/mac80211/mesh_plink.c83
-rw-r--r--net/mac80211/mlme.c22
-rw-r--r--net/mac80211/pm.c13
-rw-r--r--net/mac80211/rc80211_minstrel.c4
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c27
-rw-r--r--net/mac80211/rx.c17
-rw-r--r--net/mac80211/scan.c122
-rw-r--r--net/mac80211/sta_info.c19
-rw-r--r--net/mac80211/sta_info.h50
-rw-r--r--net/mac80211/tx.c10
-rw-r--r--net/mac80211/util.c19
29 files changed, 835 insertions, 422 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 0c9d0c07eae6..9c0d76cdca92 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -63,7 +63,8 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
63 63
64 lockdep_assert_held(&sta->ampdu_mlme.mtx); 64 lockdep_assert_held(&sta->ampdu_mlme.mtx);
65 65
66 tid_rx = sta->ampdu_mlme.tid_rx[tid]; 66 tid_rx = rcu_dereference_protected(sta->ampdu_mlme.tid_rx[tid],
67 lockdep_is_held(&sta->ampdu_mlme.mtx));
67 68
68 if (!tid_rx) 69 if (!tid_rx)
69 return; 70 return;
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 63d852cb4ca2..cd5125f77cc5 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -136,6 +136,14 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
136 ieee80211_tx_skb(sdata, skb); 136 ieee80211_tx_skb(sdata, skb);
137} 137}
138 138
139void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
140 struct tid_ampdu_tx *tid_tx)
141{
142 lockdep_assert_held(&sta->ampdu_mlme.mtx);
143 lockdep_assert_held(&sta->lock);
144 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx);
145}
146
139static void kfree_tid_tx(struct rcu_head *rcu_head) 147static void kfree_tid_tx(struct rcu_head *rcu_head)
140{ 148{
141 struct tid_ampdu_tx *tid_tx = 149 struct tid_ampdu_tx *tid_tx =
@@ -149,19 +157,22 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
149 bool tx) 157 bool tx)
150{ 158{
151 struct ieee80211_local *local = sta->local; 159 struct ieee80211_local *local = sta->local;
152 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; 160 struct tid_ampdu_tx *tid_tx;
153 int ret; 161 int ret;
154 162
155 lockdep_assert_held(&sta->ampdu_mlme.mtx); 163 lockdep_assert_held(&sta->ampdu_mlme.mtx);
156 164
157 if (!tid_tx)
158 return -ENOENT;
159
160 spin_lock_bh(&sta->lock); 165 spin_lock_bh(&sta->lock);
161 166
167 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
168 if (!tid_tx) {
169 spin_unlock_bh(&sta->lock);
170 return -ENOENT;
171 }
172
162 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { 173 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
163 /* not even started yet! */ 174 /* not even started yet! */
164 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL); 175 ieee80211_assign_tid_tx(sta, tid, NULL);
165 spin_unlock_bh(&sta->lock); 176 spin_unlock_bh(&sta->lock);
166 call_rcu(&tid_tx->rcu_head, kfree_tid_tx); 177 call_rcu(&tid_tx->rcu_head, kfree_tid_tx);
167 return 0; 178 return 0;
@@ -283,13 +294,13 @@ ieee80211_wake_queue_agg(struct ieee80211_local *local, int tid)
283 294
284void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) 295void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
285{ 296{
286 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; 297 struct tid_ampdu_tx *tid_tx;
287 struct ieee80211_local *local = sta->local; 298 struct ieee80211_local *local = sta->local;
288 struct ieee80211_sub_if_data *sdata = sta->sdata; 299 struct ieee80211_sub_if_data *sdata = sta->sdata;
289 u16 start_seq_num; 300 u16 start_seq_num;
290 int ret; 301 int ret;
291 302
292 lockdep_assert_held(&sta->ampdu_mlme.mtx); 303 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
293 304
294 /* 305 /*
295 * While we're asking the driver about the aggregation, 306 * While we're asking the driver about the aggregation,
@@ -318,7 +329,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
318 " tid %d\n", tid); 329 " tid %d\n", tid);
319#endif 330#endif
320 spin_lock_bh(&sta->lock); 331 spin_lock_bh(&sta->lock);
321 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL); 332 ieee80211_assign_tid_tx(sta, tid, NULL);
322 spin_unlock_bh(&sta->lock); 333 spin_unlock_bh(&sta->lock);
323 334
324 ieee80211_wake_queue_agg(local, tid); 335 ieee80211_wake_queue_agg(local, tid);
@@ -396,9 +407,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
396 goto err_unlock_sta; 407 goto err_unlock_sta;
397 } 408 }
398 409
399 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 410 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
400 /* check if the TID is not in aggregation flow already */ 411 /* check if the TID is not in aggregation flow already */
401 if (tid_tx) { 412 if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) {
402#ifdef CONFIG_MAC80211_HT_DEBUG 413#ifdef CONFIG_MAC80211_HT_DEBUG
403 printk(KERN_DEBUG "BA request denied - session is not " 414 printk(KERN_DEBUG "BA request denied - session is not "
404 "idle on tid %u\n", tid); 415 "idle on tid %u\n", tid);
@@ -433,8 +444,11 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
433 sta->ampdu_mlme.dialog_token_allocator++; 444 sta->ampdu_mlme.dialog_token_allocator++;
434 tid_tx->dialog_token = sta->ampdu_mlme.dialog_token_allocator; 445 tid_tx->dialog_token = sta->ampdu_mlme.dialog_token_allocator;
435 446
436 /* finally, assign it to the array */ 447 /*
437 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx); 448 * Finally, assign it to the start array; the work item will
449 * collect it and move it to the normal array.
450 */
451 sta->ampdu_mlme.tid_start_tx[tid] = tid_tx;
438 452
439 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work); 453 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
440 454
@@ -480,16 +494,19 @@ ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
480static void ieee80211_agg_tx_operational(struct ieee80211_local *local, 494static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
481 struct sta_info *sta, u16 tid) 495 struct sta_info *sta, u16 tid)
482{ 496{
497 struct tid_ampdu_tx *tid_tx;
498
483 lockdep_assert_held(&sta->ampdu_mlme.mtx); 499 lockdep_assert_held(&sta->ampdu_mlme.mtx);
484 500
501 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
502
485#ifdef CONFIG_MAC80211_HT_DEBUG 503#ifdef CONFIG_MAC80211_HT_DEBUG
486 printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid); 504 printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid);
487#endif 505#endif
488 506
489 drv_ampdu_action(local, sta->sdata, 507 drv_ampdu_action(local, sta->sdata,
490 IEEE80211_AMPDU_TX_OPERATIONAL, 508 IEEE80211_AMPDU_TX_OPERATIONAL,
491 &sta->sta, tid, NULL, 509 &sta->sta, tid, NULL, tid_tx->buf_size);
492 sta->ampdu_mlme.tid_tx[tid]->buf_size);
493 510
494 /* 511 /*
495 * synchronize with TX path, while splicing the TX path 512 * synchronize with TX path, while splicing the TX path
@@ -497,13 +514,13 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
497 */ 514 */
498 spin_lock_bh(&sta->lock); 515 spin_lock_bh(&sta->lock);
499 516
500 ieee80211_agg_splice_packets(local, sta->ampdu_mlme.tid_tx[tid], tid); 517 ieee80211_agg_splice_packets(local, tid_tx, tid);
501 /* 518 /*
502 * Now mark as operational. This will be visible 519 * Now mark as operational. This will be visible
503 * in the TX path, and lets it go lock-free in 520 * in the TX path, and lets it go lock-free in
504 * the common case. 521 * the common case.
505 */ 522 */
506 set_bit(HT_AGG_STATE_OPERATIONAL, &sta->ampdu_mlme.tid_tx[tid]->state); 523 set_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
507 ieee80211_agg_splice_finish(local, tid); 524 ieee80211_agg_splice_finish(local, tid);
508 525
509 spin_unlock_bh(&sta->lock); 526 spin_unlock_bh(&sta->lock);
@@ -537,7 +554,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
537 } 554 }
538 555
539 mutex_lock(&sta->ampdu_mlme.mtx); 556 mutex_lock(&sta->ampdu_mlme.mtx);
540 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 557 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
541 558
542 if (WARN_ON(!tid_tx)) { 559 if (WARN_ON(!tid_tx)) {
543#ifdef CONFIG_MAC80211_HT_DEBUG 560#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -615,7 +632,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
615 return -EINVAL; 632 return -EINVAL;
616 633
617 spin_lock_bh(&sta->lock); 634 spin_lock_bh(&sta->lock);
618 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 635 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
619 636
620 if (!tid_tx) { 637 if (!tid_tx) {
621 ret = -ENOENT; 638 ret = -ENOENT;
@@ -671,7 +688,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
671 688
672 mutex_lock(&sta->ampdu_mlme.mtx); 689 mutex_lock(&sta->ampdu_mlme.mtx);
673 spin_lock_bh(&sta->lock); 690 spin_lock_bh(&sta->lock);
674 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 691 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
675 692
676 if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { 693 if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
677#ifdef CONFIG_MAC80211_HT_DEBUG 694#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -697,7 +714,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
697 ieee80211_agg_splice_packets(local, tid_tx, tid); 714 ieee80211_agg_splice_packets(local, tid_tx, tid);
698 715
699 /* future packets must not find the tid_tx struct any more */ 716 /* future packets must not find the tid_tx struct any more */
700 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL); 717 ieee80211_assign_tid_tx(sta, tid, NULL);
701 718
702 ieee80211_agg_splice_finish(local, tid); 719 ieee80211_agg_splice_finish(local, tid);
703 720
@@ -752,7 +769,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
752 769
753 mutex_lock(&sta->ampdu_mlme.mtx); 770 mutex_lock(&sta->ampdu_mlme.mtx);
754 771
755 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 772 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
756 if (!tid_tx) 773 if (!tid_tx)
757 goto out; 774 goto out;
758 775
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 12d52cec9515..be70c70d3f5b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -136,7 +136,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
136 mutex_lock(&sdata->local->sta_mtx); 136 mutex_lock(&sdata->local->sta_mtx);
137 137
138 if (mac_addr) { 138 if (mac_addr) {
139 sta = sta_info_get_bss(sdata, mac_addr); 139 if (ieee80211_vif_is_mesh(&sdata->vif))
140 sta = sta_info_get(sdata, mac_addr);
141 else
142 sta = sta_info_get_bss(sdata, mac_addr);
140 if (!sta) { 143 if (!sta) {
141 ieee80211_key_free(sdata->local, key); 144 ieee80211_key_free(sdata->local, key);
142 err = -ENOENT; 145 err = -ENOENT;
@@ -157,13 +160,14 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
157static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 160static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
158 u8 key_idx, bool pairwise, const u8 *mac_addr) 161 u8 key_idx, bool pairwise, const u8 *mac_addr)
159{ 162{
160 struct ieee80211_sub_if_data *sdata; 163 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
164 struct ieee80211_local *local = sdata->local;
161 struct sta_info *sta; 165 struct sta_info *sta;
166 struct ieee80211_key *key = NULL;
162 int ret; 167 int ret;
163 168
164 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 169 mutex_lock(&local->sta_mtx);
165 170 mutex_lock(&local->key_mtx);
166 mutex_lock(&sdata->local->sta_mtx);
167 171
168 if (mac_addr) { 172 if (mac_addr) {
169 ret = -ENOENT; 173 ret = -ENOENT;
@@ -172,33 +176,24 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
172 if (!sta) 176 if (!sta)
173 goto out_unlock; 177 goto out_unlock;
174 178
175 if (pairwise) { 179 if (pairwise)
176 if (sta->ptk) { 180 key = key_mtx_dereference(local, sta->ptk);
177 ieee80211_key_free(sdata->local, sta->ptk); 181 else
178 ret = 0; 182 key = key_mtx_dereference(local, sta->gtk[key_idx]);
179 } 183 } else
180 } else { 184 key = key_mtx_dereference(local, sdata->keys[key_idx]);
181 if (sta->gtk[key_idx]) {
182 ieee80211_key_free(sdata->local,
183 sta->gtk[key_idx]);
184 ret = 0;
185 }
186 }
187
188 goto out_unlock;
189 }
190 185
191 if (!sdata->keys[key_idx]) { 186 if (!key) {
192 ret = -ENOENT; 187 ret = -ENOENT;
193 goto out_unlock; 188 goto out_unlock;
194 } 189 }
195 190
196 ieee80211_key_free(sdata->local, sdata->keys[key_idx]); 191 __ieee80211_key_free(key);
197 WARN_ON(sdata->keys[key_idx]);
198 192
199 ret = 0; 193 ret = 0;
200 out_unlock: 194 out_unlock:
201 mutex_unlock(&sdata->local->sta_mtx); 195 mutex_unlock(&local->key_mtx);
196 mutex_unlock(&local->sta_mtx);
202 197
203 return ret; 198 return ret;
204} 199}
@@ -228,11 +223,11 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
228 goto out; 223 goto out;
229 224
230 if (pairwise) 225 if (pairwise)
231 key = sta->ptk; 226 key = rcu_dereference(sta->ptk);
232 else if (key_idx < NUM_DEFAULT_KEYS) 227 else if (key_idx < NUM_DEFAULT_KEYS)
233 key = sta->gtk[key_idx]; 228 key = rcu_dereference(sta->gtk[key_idx]);
234 } else 229 } else
235 key = sdata->keys[key_idx]; 230 key = rcu_dereference(sdata->keys[key_idx]);
236 231
237 if (!key) 232 if (!key)
238 goto out; 233 goto out;
@@ -468,7 +463,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
468 int size; 463 int size;
469 int err = -EINVAL; 464 int err = -EINVAL;
470 465
471 old = sdata->u.ap.beacon; 466 old = rtnl_dereference(sdata->u.ap.beacon);
472 467
473 /* head must not be zero-length */ 468 /* head must not be zero-length */
474 if (params->head && !params->head_len) 469 if (params->head && !params->head_len)
@@ -563,8 +558,7 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
563 558
564 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 559 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
565 560
566 old = sdata->u.ap.beacon; 561 old = rtnl_dereference(sdata->u.ap.beacon);
567
568 if (old) 562 if (old)
569 return -EALREADY; 563 return -EALREADY;
570 564
@@ -579,8 +573,7 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
579 573
580 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 574 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
581 575
582 old = sdata->u.ap.beacon; 576 old = rtnl_dereference(sdata->u.ap.beacon);
583
584 if (!old) 577 if (!old)
585 return -ENOENT; 578 return -ENOENT;
586 579
@@ -594,8 +587,7 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
594 587
595 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 588 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
596 589
597 old = sdata->u.ap.beacon; 590 old = rtnl_dereference(sdata->u.ap.beacon);
598
599 if (!old) 591 if (!old)
600 return -ENOENT; 592 return -ENOENT;
601 593
@@ -734,15 +726,29 @@ static void sta_apply_parameters(struct ieee80211_local *local,
734 params->ht_capa, 726 params->ht_capa,
735 &sta->sta.ht_cap); 727 &sta->sta.ht_cap);
736 728
737 if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { 729 if (ieee80211_vif_is_mesh(&sdata->vif)) {
738 switch (params->plink_action) { 730#ifdef CONFIG_MAC80211_MESH
739 case PLINK_ACTION_OPEN: 731 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED)
740 mesh_plink_open(sta); 732 switch (params->plink_state) {
741 break; 733 case NL80211_PLINK_LISTEN:
742 case PLINK_ACTION_BLOCK: 734 case NL80211_PLINK_ESTAB:
743 mesh_plink_block(sta); 735 case NL80211_PLINK_BLOCKED:
744 break; 736 sta->plink_state = params->plink_state;
745 } 737 break;
738 default:
739 /* nothing */
740 break;
741 }
742 else
743 switch (params->plink_action) {
744 case PLINK_ACTION_OPEN:
745 mesh_plink_open(sta);
746 break;
747 case PLINK_ACTION_BLOCK:
748 mesh_plink_block(sta);
749 break;
750 }
751#endif
746 } 752 }
747} 753}
748 754
@@ -943,8 +949,10 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
943static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, 949static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
944 struct mpath_info *pinfo) 950 struct mpath_info *pinfo)
945{ 951{
946 if (mpath->next_hop) 952 struct sta_info *next_hop_sta = rcu_dereference(mpath->next_hop);
947 memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN); 953
954 if (next_hop_sta)
955 memcpy(next_hop, next_hop_sta->sta.addr, ETH_ALEN);
948 else 956 else
949 memset(next_hop, 0, ETH_ALEN); 957 memset(next_hop, 0, ETH_ALEN);
950 958
@@ -1064,7 +1072,11 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
1064 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); 1072 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
1065 ifmsh->mesh_pp_id = setup->path_sel_proto; 1073 ifmsh->mesh_pp_id = setup->path_sel_proto;
1066 ifmsh->mesh_pm_id = setup->path_metric; 1074 ifmsh->mesh_pm_id = setup->path_metric;
1067 ifmsh->is_secure = setup->is_secure; 1075 ifmsh->security = IEEE80211_MESH_SEC_NONE;
1076 if (setup->is_authenticated)
1077 ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
1078 if (setup->is_secure)
1079 ifmsh->security |= IEEE80211_MESH_SEC_SECURED;
1068 1080
1069 return 0; 1081 return 0;
1070} 1082}
@@ -1297,9 +1309,10 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
1297} 1309}
1298 1310
1299#ifdef CONFIG_PM 1311#ifdef CONFIG_PM
1300static int ieee80211_suspend(struct wiphy *wiphy) 1312static int ieee80211_suspend(struct wiphy *wiphy,
1313 struct cfg80211_wowlan *wowlan)
1301{ 1314{
1302 return __ieee80211_suspend(wiphy_priv(wiphy)); 1315 return __ieee80211_suspend(wiphy_priv(wiphy), wowlan);
1303} 1316}
1304 1317
1305static int ieee80211_resume(struct wiphy *wiphy) 1318static int ieee80211_resume(struct wiphy *wiphy)
@@ -1342,6 +1355,30 @@ static int ieee80211_scan(struct wiphy *wiphy,
1342 return ieee80211_request_scan(sdata, req); 1355 return ieee80211_request_scan(sdata, req);
1343} 1356}
1344 1357
1358static int
1359ieee80211_sched_scan_start(struct wiphy *wiphy,
1360 struct net_device *dev,
1361 struct cfg80211_sched_scan_request *req)
1362{
1363 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1364
1365 if (!sdata->local->ops->sched_scan_start)
1366 return -EOPNOTSUPP;
1367
1368 return ieee80211_request_sched_scan_start(sdata, req);
1369}
1370
1371static int
1372ieee80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
1373{
1374 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1375
1376 if (!sdata->local->ops->sched_scan_stop)
1377 return -EOPNOTSUPP;
1378
1379 return ieee80211_request_sched_scan_stop(sdata);
1380}
1381
1345static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev, 1382static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
1346 struct cfg80211_auth_request *req) 1383 struct cfg80211_auth_request *req)
1347{ 1384{
@@ -2083,6 +2120,8 @@ struct cfg80211_ops mac80211_config_ops = {
2083 .suspend = ieee80211_suspend, 2120 .suspend = ieee80211_suspend,
2084 .resume = ieee80211_resume, 2121 .resume = ieee80211_resume,
2085 .scan = ieee80211_scan, 2122 .scan = ieee80211_scan,
2123 .sched_scan_start = ieee80211_sched_scan_start,
2124 .sched_scan_stop = ieee80211_sched_scan_stop,
2086 .auth = ieee80211_auth, 2125 .auth = ieee80211_auth,
2087 .assoc = ieee80211_assoc, 2126 .assoc = ieee80211_assoc,
2088 .deauth = ieee80211_deauth, 2127 .deauth = ieee80211_deauth,
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 0a602dbfdb2b..186e02f7cc32 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -135,7 +135,7 @@ static ssize_t reset_write(struct file *file, const char __user *user_buf,
135 struct ieee80211_local *local = file->private_data; 135 struct ieee80211_local *local = file->private_data;
136 136
137 rtnl_lock(); 137 rtnl_lock();
138 __ieee80211_suspend(&local->hw); 138 __ieee80211_suspend(&local->hw, NULL);
139 __ieee80211_resume(&local->hw); 139 __ieee80211_resume(&local->hw);
140 rtnl_unlock(); 140 rtnl_unlock();
141 141
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index f7ef3477c24a..33c58b85c911 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -241,16 +241,12 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
241 if (!key->debugfs.dir) 241 if (!key->debugfs.dir)
242 return; 242 return;
243 243
244 rcu_read_lock(); 244 sta = key->sta;
245 sta = rcu_dereference(key->sta); 245 if (sta) {
246 if (sta)
247 sprintf(buf, "../../stations/%pM", sta->sta.addr); 246 sprintf(buf, "../../stations/%pM", sta->sta.addr);
248 rcu_read_unlock();
249
250 /* using sta as a boolean is fine outside RCU lock */
251 if (sta)
252 key->debugfs.stalink = 247 key->debugfs.stalink =
253 debugfs_create_symlink("station", key->debugfs.dir, buf); 248 debugfs_create_symlink("station", key->debugfs.dir, buf);
249 }
254 250
255 DEBUGFS_ADD(keylen); 251 DEBUGFS_ADD(keylen);
256 DEBUGFS_ADD(flags); 252 DEBUGFS_ADD(flags);
@@ -286,7 +282,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
286 lockdep_assert_held(&sdata->local->key_mtx); 282 lockdep_assert_held(&sdata->local->key_mtx);
287 283
288 if (sdata->default_unicast_key) { 284 if (sdata->default_unicast_key) {
289 key = sdata->default_unicast_key; 285 key = key_mtx_dereference(sdata->local,
286 sdata->default_unicast_key);
290 sprintf(buf, "../keys/%d", key->debugfs.cnt); 287 sprintf(buf, "../keys/%d", key->debugfs.cnt);
291 sdata->debugfs.default_unicast_key = 288 sdata->debugfs.default_unicast_key =
292 debugfs_create_symlink("default_unicast_key", 289 debugfs_create_symlink("default_unicast_key",
@@ -297,7 +294,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
297 } 294 }
298 295
299 if (sdata->default_multicast_key) { 296 if (sdata->default_multicast_key) {
300 key = sdata->default_multicast_key; 297 key = key_mtx_dereference(sdata->local,
298 sdata->default_multicast_key);
301 sprintf(buf, "../keys/%d", key->debugfs.cnt); 299 sprintf(buf, "../keys/%d", key->debugfs.cnt);
302 sdata->debugfs.default_multicast_key = 300 sdata->debugfs.default_multicast_key =
303 debugfs_create_symlink("default_multicast_key", 301 debugfs_create_symlink("default_multicast_key",
@@ -316,9 +314,8 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
316 if (!sdata->debugfs.dir) 314 if (!sdata->debugfs.dir)
317 return; 315 return;
318 316
319 /* this is running under the key lock */ 317 key = key_mtx_dereference(sdata->local,
320 318 sdata->default_mgmt_key);
321 key = sdata->default_mgmt_key;
322 if (key) { 319 if (key) {
323 sprintf(buf, "../keys/%d", key->debugfs.cnt); 320 sprintf(buf, "../keys/%d", key->debugfs.cnt);
324 sdata->debugfs.default_mgmt_key = 321 sdata->debugfs.default_mgmt_key =
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 2ddb56e5b51f..eebf7a67daf7 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -41,6 +41,33 @@ static inline void drv_stop(struct ieee80211_local *local)
41 local->started = false; 41 local->started = false;
42} 42}
43 43
44#ifdef CONFIG_PM
45static inline int drv_suspend(struct ieee80211_local *local,
46 struct cfg80211_wowlan *wowlan)
47{
48 int ret;
49
50 might_sleep();
51
52 trace_drv_suspend(local);
53 ret = local->ops->suspend(&local->hw, wowlan);
54 trace_drv_return_int(local, ret);
55 return ret;
56}
57
58static inline int drv_resume(struct ieee80211_local *local)
59{
60 int ret;
61
62 might_sleep();
63
64 trace_drv_resume(local);
65 ret = local->ops->resume(&local->hw);
66 trace_drv_return_int(local, ret);
67 return ret;
68}
69#endif
70
44static inline int drv_add_interface(struct ieee80211_local *local, 71static inline int drv_add_interface(struct ieee80211_local *local,
45 struct ieee80211_vif *vif) 72 struct ieee80211_vif *vif)
46{ 73{
@@ -185,12 +212,39 @@ static inline int drv_hw_scan(struct ieee80211_local *local,
185 212
186 might_sleep(); 213 might_sleep();
187 214
188 trace_drv_hw_scan(local, sdata, req); 215 trace_drv_hw_scan(local, sdata);
189 ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); 216 ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
190 trace_drv_return_int(local, ret); 217 trace_drv_return_int(local, ret);
191 return ret; 218 return ret;
192} 219}
193 220
221static inline int
222drv_sched_scan_start(struct ieee80211_local *local,
223 struct ieee80211_sub_if_data *sdata,
224 struct cfg80211_sched_scan_request *req,
225 struct ieee80211_sched_scan_ies *ies)
226{
227 int ret;
228
229 might_sleep();
230
231 trace_drv_sched_scan_start(local, sdata);
232 ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
233 req, ies);
234 trace_drv_return_int(local, ret);
235 return ret;
236}
237
238static inline void drv_sched_scan_stop(struct ieee80211_local *local,
239 struct ieee80211_sub_if_data *sdata)
240{
241 might_sleep();
242
243 trace_drv_sched_scan_stop(local, sdata);
244 local->ops->sched_scan_stop(&local->hw, &sdata->vif);
245 trace_drv_return_void(local);
246}
247
194static inline void drv_sw_scan_start(struct ieee80211_local *local) 248static inline void drv_sw_scan_start(struct ieee80211_local *local)
195{ 249{
196 might_sleep(); 250 might_sleep();
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 191e834ec46b..ed9edcbd9aa5 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -55,6 +55,70 @@ DECLARE_EVENT_CLASS(local_only_evt,
55 TP_printk(LOCAL_PR_FMT, LOCAL_PR_ARG) 55 TP_printk(LOCAL_PR_FMT, LOCAL_PR_ARG)
56); 56);
57 57
58DECLARE_EVENT_CLASS(local_sdata_addr_evt,
59 TP_PROTO(struct ieee80211_local *local,
60 struct ieee80211_sub_if_data *sdata),
61 TP_ARGS(local, sdata),
62
63 TP_STRUCT__entry(
64 LOCAL_ENTRY
65 VIF_ENTRY
66 __array(char, addr, 6)
67 ),
68
69 TP_fast_assign(
70 LOCAL_ASSIGN;
71 VIF_ASSIGN;
72 memcpy(__entry->addr, sdata->vif.addr, 6);
73 ),
74
75 TP_printk(
76 LOCAL_PR_FMT VIF_PR_FMT " addr:%pM",
77 LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr
78 )
79);
80
81DECLARE_EVENT_CLASS(local_u32_evt,
82 TP_PROTO(struct ieee80211_local *local, u32 value),
83 TP_ARGS(local, value),
84
85 TP_STRUCT__entry(
86 LOCAL_ENTRY
87 __field(u32, value)
88 ),
89
90 TP_fast_assign(
91 LOCAL_ASSIGN;
92 __entry->value = value;
93 ),
94
95 TP_printk(
96 LOCAL_PR_FMT " value:%d",
97 LOCAL_PR_ARG, __entry->value
98 )
99);
100
101DECLARE_EVENT_CLASS(local_sdata_evt,
102 TP_PROTO(struct ieee80211_local *local,
103 struct ieee80211_sub_if_data *sdata),
104 TP_ARGS(local, sdata),
105
106 TP_STRUCT__entry(
107 LOCAL_ENTRY
108 VIF_ENTRY
109 ),
110
111 TP_fast_assign(
112 LOCAL_ASSIGN;
113 VIF_ASSIGN;
114 ),
115
116 TP_printk(
117 LOCAL_PR_FMT VIF_PR_FMT,
118 LOCAL_PR_ARG, VIF_PR_ARG
119 )
120);
121
58DEFINE_EVENT(local_only_evt, drv_return_void, 122DEFINE_EVENT(local_only_evt, drv_return_void,
59 TP_PROTO(struct ieee80211_local *local), 123 TP_PROTO(struct ieee80211_local *local),
60 TP_ARGS(local) 124 TP_ARGS(local)
@@ -108,33 +172,25 @@ DEFINE_EVENT(local_only_evt, drv_start,
108 TP_ARGS(local) 172 TP_ARGS(local)
109); 173);
110 174
175DEFINE_EVENT(local_only_evt, drv_suspend,
176 TP_PROTO(struct ieee80211_local *local),
177 TP_ARGS(local)
178);
179
180DEFINE_EVENT(local_only_evt, drv_resume,
181 TP_PROTO(struct ieee80211_local *local),
182 TP_ARGS(local)
183);
184
111DEFINE_EVENT(local_only_evt, drv_stop, 185DEFINE_EVENT(local_only_evt, drv_stop,
112 TP_PROTO(struct ieee80211_local *local), 186 TP_PROTO(struct ieee80211_local *local),
113 TP_ARGS(local) 187 TP_ARGS(local)
114); 188);
115 189
116TRACE_EVENT(drv_add_interface, 190DEFINE_EVENT(local_sdata_addr_evt, drv_add_interface,
117 TP_PROTO(struct ieee80211_local *local, 191 TP_PROTO(struct ieee80211_local *local,
118 struct ieee80211_sub_if_data *sdata), 192 struct ieee80211_sub_if_data *sdata),
119 193 TP_ARGS(local, sdata)
120 TP_ARGS(local, sdata),
121
122 TP_STRUCT__entry(
123 LOCAL_ENTRY
124 VIF_ENTRY
125 __array(char, addr, 6)
126 ),
127
128 TP_fast_assign(
129 LOCAL_ASSIGN;
130 VIF_ASSIGN;
131 memcpy(__entry->addr, sdata->vif.addr, 6);
132 ),
133
134 TP_printk(
135 LOCAL_PR_FMT VIF_PR_FMT " addr:%pM",
136 LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr
137 )
138); 194);
139 195
140TRACE_EVENT(drv_change_interface, 196TRACE_EVENT(drv_change_interface,
@@ -165,27 +221,10 @@ TRACE_EVENT(drv_change_interface,
165 ) 221 )
166); 222);
167 223
168TRACE_EVENT(drv_remove_interface, 224DEFINE_EVENT(local_sdata_addr_evt, drv_remove_interface,
169 TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata), 225 TP_PROTO(struct ieee80211_local *local,
170 226 struct ieee80211_sub_if_data *sdata),
171 TP_ARGS(local, sdata), 227 TP_ARGS(local, sdata)
172
173 TP_STRUCT__entry(
174 LOCAL_ENTRY
175 VIF_ENTRY
176 __array(char, addr, 6)
177 ),
178
179 TP_fast_assign(
180 LOCAL_ASSIGN;
181 VIF_ASSIGN;
182 memcpy(__entry->addr, sdata->vif.addr, 6);
183 ),
184
185 TP_printk(
186 LOCAL_PR_FMT VIF_PR_FMT " addr:%pM",
187 LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr
188 )
189); 228);
190 229
191TRACE_EVENT(drv_config, 230TRACE_EVENT(drv_config,
@@ -415,27 +454,22 @@ TRACE_EVENT(drv_update_tkip_key,
415 ) 454 )
416); 455);
417 456
418TRACE_EVENT(drv_hw_scan, 457DEFINE_EVENT(local_sdata_evt, drv_hw_scan,
419 TP_PROTO(struct ieee80211_local *local, 458 TP_PROTO(struct ieee80211_local *local,
420 struct ieee80211_sub_if_data *sdata, 459 struct ieee80211_sub_if_data *sdata),
421 struct cfg80211_scan_request *req), 460 TP_ARGS(local, sdata)
422 461);
423 TP_ARGS(local, sdata, req),
424
425 TP_STRUCT__entry(
426 LOCAL_ENTRY
427 VIF_ENTRY
428 ),
429 462
430 TP_fast_assign( 463DEFINE_EVENT(local_sdata_evt, drv_sched_scan_start,
431 LOCAL_ASSIGN; 464 TP_PROTO(struct ieee80211_local *local,
432 VIF_ASSIGN; 465 struct ieee80211_sub_if_data *sdata),
433 ), 466 TP_ARGS(local, sdata)
467);
434 468
435 TP_printk( 469DEFINE_EVENT(local_sdata_evt, drv_sched_scan_stop,
436 LOCAL_PR_FMT VIF_PR_FMT, 470 TP_PROTO(struct ieee80211_local *local,
437 LOCAL_PR_ARG,VIF_PR_ARG 471 struct ieee80211_sub_if_data *sdata),
438 ) 472 TP_ARGS(local, sdata)
439); 473);
440 474
441DEFINE_EVENT(local_only_evt, drv_sw_scan_start, 475DEFINE_EVENT(local_only_evt, drv_sw_scan_start,
@@ -504,46 +538,14 @@ TRACE_EVENT(drv_get_tkip_seq,
504 ) 538 )
505); 539);
506 540
507TRACE_EVENT(drv_set_frag_threshold, 541DEFINE_EVENT(local_u32_evt, drv_set_frag_threshold,
508 TP_PROTO(struct ieee80211_local *local, u32 value), 542 TP_PROTO(struct ieee80211_local *local, u32 value),
509 543 TP_ARGS(local, value)
510 TP_ARGS(local, value),
511
512 TP_STRUCT__entry(
513 LOCAL_ENTRY
514 __field(u32, value)
515 ),
516
517 TP_fast_assign(
518 LOCAL_ASSIGN;
519 __entry->value = value;
520 ),
521
522 TP_printk(
523 LOCAL_PR_FMT " value:%d",
524 LOCAL_PR_ARG, __entry->value
525 )
526); 544);
527 545
528TRACE_EVENT(drv_set_rts_threshold, 546DEFINE_EVENT(local_u32_evt, drv_set_rts_threshold,
529 TP_PROTO(struct ieee80211_local *local, u32 value), 547 TP_PROTO(struct ieee80211_local *local, u32 value),
530 548 TP_ARGS(local, value)
531 TP_ARGS(local, value),
532
533 TP_STRUCT__entry(
534 LOCAL_ENTRY
535 __field(u32, value)
536 ),
537
538 TP_fast_assign(
539 LOCAL_ASSIGN;
540 __entry->value = value;
541 ),
542
543 TP_printk(
544 LOCAL_PR_FMT " value:%d",
545 LOCAL_PR_ARG, __entry->value
546 )
547); 549);
548 550
549TRACE_EVENT(drv_set_coverage_class, 551TRACE_EVENT(drv_set_coverage_class,
@@ -1194,6 +1196,42 @@ TRACE_EVENT(api_scan_completed,
1194 ) 1196 )
1195); 1197);
1196 1198
1199TRACE_EVENT(api_sched_scan_results,
1200 TP_PROTO(struct ieee80211_local *local),
1201
1202 TP_ARGS(local),
1203
1204 TP_STRUCT__entry(
1205 LOCAL_ENTRY
1206 ),
1207
1208 TP_fast_assign(
1209 LOCAL_ASSIGN;
1210 ),
1211
1212 TP_printk(
1213 LOCAL_PR_FMT, LOCAL_PR_ARG
1214 )
1215);
1216
1217TRACE_EVENT(api_sched_scan_stopped,
1218 TP_PROTO(struct ieee80211_local *local),
1219
1220 TP_ARGS(local),
1221
1222 TP_STRUCT__entry(
1223 LOCAL_ENTRY
1224 ),
1225
1226 TP_fast_assign(
1227 LOCAL_ASSIGN;
1228 ),
1229
1230 TP_printk(
1231 LOCAL_PR_FMT, LOCAL_PR_ARG
1232 )
1233);
1234
1197TRACE_EVENT(api_sta_block_awake, 1235TRACE_EVENT(api_sta_block_awake,
1198 TP_PROTO(struct ieee80211_local *local, 1236 TP_PROTO(struct ieee80211_local *local,
1199 struct ieee80211_sta *sta, bool block), 1237 struct ieee80211_sta *sta, bool block),
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index b9e4b9bd2179..591add22bcc0 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -140,14 +140,29 @@ void ieee80211_ba_session_work(struct work_struct *work)
140 sta, tid, WLAN_BACK_RECIPIENT, 140 sta, tid, WLAN_BACK_RECIPIENT,
141 WLAN_REASON_QSTA_TIMEOUT, true); 141 WLAN_REASON_QSTA_TIMEOUT, true);
142 142
143 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 143 tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
144 if (!tid_tx) 144 if (tid_tx) {
145 continue; 145 /*
146 * Assign it over to the normal tid_tx array
147 * where it "goes live".
148 */
149 spin_lock_bh(&sta->lock);
150
151 sta->ampdu_mlme.tid_start_tx[tid] = NULL;
152 /* could there be a race? */
153 if (sta->ampdu_mlme.tid_tx[tid])
154 kfree(tid_tx);
155 else
156 ieee80211_assign_tid_tx(sta, tid, tid_tx);
157 spin_unlock_bh(&sta->lock);
146 158
147 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state))
148 ieee80211_tx_ba_session_handle_start(sta, tid); 159 ieee80211_tx_ba_session_handle_start(sta, tid);
149 else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, 160 continue;
150 &tid_tx->state)) 161 }
162
163 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
164 if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
165 &tid_tx->state))
151 ___ieee80211_stop_tx_ba_session(sta, tid, 166 ___ieee80211_stop_tx_ba_session(sta, tid,
152 WLAN_BACK_INITIATOR, 167 WLAN_BACK_INITIATOR,
153 true); 168 true);
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index b81860c94698..421eaa6b0c2b 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -662,12 +662,16 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
662 int tx_last_beacon, len = req->len; 662 int tx_last_beacon, len = req->len;
663 struct sk_buff *skb; 663 struct sk_buff *skb;
664 struct ieee80211_mgmt *resp; 664 struct ieee80211_mgmt *resp;
665 struct sk_buff *presp;
665 u8 *pos, *end; 666 u8 *pos, *end;
666 667
667 lockdep_assert_held(&ifibss->mtx); 668 lockdep_assert_held(&ifibss->mtx);
668 669
670 presp = rcu_dereference_protected(ifibss->presp,
671 lockdep_is_held(&ifibss->mtx));
672
669 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || 673 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
670 len < 24 + 2 || !ifibss->presp) 674 len < 24 + 2 || !presp)
671 return; 675 return;
672 676
673 tx_last_beacon = drv_tx_last_beacon(local); 677 tx_last_beacon = drv_tx_last_beacon(local);
@@ -705,7 +709,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
705 } 709 }
706 710
707 /* Reply with ProbeResp */ 711 /* Reply with ProbeResp */
708 skb = skb_copy(ifibss->presp, GFP_KERNEL); 712 skb = skb_copy(presp, GFP_KERNEL);
709 if (!skb) 713 if (!skb)
710 return; 714 return;
711 715
@@ -985,7 +989,8 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
985 989
986 /* remove beacon */ 990 /* remove beacon */
987 kfree(sdata->u.ibss.ie); 991 kfree(sdata->u.ibss.ie);
988 skb = sdata->u.ibss.presp; 992 skb = rcu_dereference_protected(sdata->u.ibss.presp,
993 lockdep_is_held(&sdata->u.ibss.mtx));
989 rcu_assign_pointer(sdata->u.ibss.presp, NULL); 994 rcu_assign_pointer(sdata->u.ibss.presp, NULL);
990 sdata->vif.bss_conf.ibss_joined = false; 995 sdata->vif.bss_conf.ibss_joined = false;
991 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | 996 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 027c0467d7a3..2025af52b195 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -214,7 +214,7 @@ struct beacon_data {
214}; 214};
215 215
216struct ieee80211_if_ap { 216struct ieee80211_if_ap {
217 struct beacon_data *beacon; 217 struct beacon_data __rcu *beacon;
218 218
219 struct list_head vlans; 219 struct list_head vlans;
220 220
@@ -237,7 +237,7 @@ struct ieee80211_if_vlan {
237 struct list_head list; 237 struct list_head list;
238 238
239 /* used for all tx if the VLAN is configured to 4-addr mode */ 239 /* used for all tx if the VLAN is configured to 4-addr mode */
240 struct sta_info *sta; 240 struct sta_info __rcu *sta;
241}; 241};
242 242
243struct mesh_stats { 243struct mesh_stats {
@@ -442,7 +442,8 @@ struct ieee80211_if_ibss {
442 442
443 unsigned long ibss_join_req; 443 unsigned long ibss_join_req;
444 /* probe response/beacon for IBSS */ 444 /* probe response/beacon for IBSS */
445 struct sk_buff *presp, *skb; 445 struct sk_buff __rcu *presp;
446 struct sk_buff *skb;
446 447
447 enum { 448 enum {
448 IEEE80211_IBSS_MLME_SEARCH, 449 IEEE80211_IBSS_MLME_SEARCH,
@@ -490,7 +491,11 @@ struct ieee80211_if_mesh {
490 bool accepting_plinks; 491 bool accepting_plinks;
491 const u8 *ie; 492 const u8 *ie;
492 u8 ie_len; 493 u8 ie_len;
493 bool is_secure; 494 enum {
495 IEEE80211_MESH_SEC_NONE = 0x0,
496 IEEE80211_MESH_SEC_AUTHED = 0x1,
497 IEEE80211_MESH_SEC_SECURED = 0x2,
498 } security;
494}; 499};
495 500
496#ifdef CONFIG_MAC80211_MESH 501#ifdef CONFIG_MAC80211_MESH
@@ -563,9 +568,10 @@ struct ieee80211_sub_if_data {
563 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; 568 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
564 unsigned int fragment_next; 569 unsigned int fragment_next;
565 570
566 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 571 struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
567 struct ieee80211_key *default_unicast_key, *default_multicast_key; 572 struct ieee80211_key __rcu *default_unicast_key;
568 struct ieee80211_key *default_mgmt_key; 573 struct ieee80211_key __rcu *default_multicast_key;
574 struct ieee80211_key __rcu *default_mgmt_key;
569 575
570 u16 sequence_number; 576 u16 sequence_number;
571 __be16 control_port_protocol; 577 __be16 control_port_protocol;
@@ -764,6 +770,9 @@ struct ieee80211_local {
764 /* device is started */ 770 /* device is started */
765 bool started; 771 bool started;
766 772
773 /* wowlan is enabled -- don't reconfig on resume */
774 bool wowlan;
775
767 int tx_headroom; /* required headroom for hardware/radiotap */ 776 int tx_headroom; /* required headroom for hardware/radiotap */
768 777
769 /* count for keys needing tailroom space allocation */ 778 /* count for keys needing tailroom space allocation */
@@ -798,7 +807,7 @@ struct ieee80211_local {
798 spinlock_t sta_lock; 807 spinlock_t sta_lock;
799 unsigned long num_sta; 808 unsigned long num_sta;
800 struct list_head sta_list, sta_pending_list; 809 struct list_head sta_list, sta_pending_list;
801 struct sta_info *sta_hash[STA_HASH_SIZE]; 810 struct sta_info __rcu *sta_hash[STA_HASH_SIZE];
802 struct timer_list sta_cleanup; 811 struct timer_list sta_cleanup;
803 struct work_struct sta_finish_work; 812 struct work_struct sta_finish_work;
804 int sta_generation; 813 int sta_generation;
@@ -840,6 +849,10 @@ struct ieee80211_local {
840 int scan_channel_idx; 849 int scan_channel_idx;
841 int scan_ies_len; 850 int scan_ies_len;
842 851
852 bool sched_scanning;
853 struct ieee80211_sched_scan_ies sched_scan_ies;
854 struct work_struct sched_scan_stopped_work;
855
843 unsigned long leave_oper_channel_time; 856 unsigned long leave_oper_channel_time;
844 enum mac80211_scan_state next_scan_state; 857 enum mac80211_scan_state next_scan_state;
845 struct delayed_work scan_work; 858 struct delayed_work scan_work;
@@ -1147,6 +1160,12 @@ ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
1147void ieee80211_rx_bss_put(struct ieee80211_local *local, 1160void ieee80211_rx_bss_put(struct ieee80211_local *local,
1148 struct ieee80211_bss *bss); 1161 struct ieee80211_bss *bss);
1149 1162
1163/* scheduled scan handling */
1164int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
1165 struct cfg80211_sched_scan_request *req);
1166int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
1167void ieee80211_sched_scan_stopped_work(struct work_struct *work);
1168
1150/* off-channel helpers */ 1169/* off-channel helpers */
1151bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local); 1170bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local);
1152void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local, 1171void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local,
@@ -1250,7 +1269,8 @@ int ieee80211_reconfig(struct ieee80211_local *local);
1250void ieee80211_stop_device(struct ieee80211_local *local); 1269void ieee80211_stop_device(struct ieee80211_local *local);
1251 1270
1252#ifdef CONFIG_PM 1271#ifdef CONFIG_PM
1253int __ieee80211_suspend(struct ieee80211_hw *hw); 1272int __ieee80211_suspend(struct ieee80211_hw *hw,
1273 struct cfg80211_wowlan *wowlan);
1254 1274
1255static inline int __ieee80211_resume(struct ieee80211_hw *hw) 1275static inline int __ieee80211_resume(struct ieee80211_hw *hw)
1256{ 1276{
@@ -1263,7 +1283,8 @@ static inline int __ieee80211_resume(struct ieee80211_hw *hw)
1263 return ieee80211_reconfig(hw_to_local(hw)); 1283 return ieee80211_reconfig(hw_to_local(hw));
1264} 1284}
1265#else 1285#else
1266static inline int __ieee80211_suspend(struct ieee80211_hw *hw) 1286static inline int __ieee80211_suspend(struct ieee80211_hw *hw,
1287 struct cfg80211_wowlan *wowlan)
1267{ 1288{
1268 return 0; 1289 return 0;
1269} 1290}
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 80c29d626aa4..7dfbe71dc637 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -449,7 +449,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
449 /* APs need special treatment */ 449 /* APs need special treatment */
450 if (sdata->vif.type == NL80211_IFTYPE_AP) { 450 if (sdata->vif.type == NL80211_IFTYPE_AP) {
451 struct ieee80211_sub_if_data *vlan, *tmpsdata; 451 struct ieee80211_sub_if_data *vlan, *tmpsdata;
452 struct beacon_data *old_beacon = sdata->u.ap.beacon; 452 struct beacon_data *old_beacon =
453 rtnl_dereference(sdata->u.ap.beacon);
453 454
454 /* sdata_running will return false, so this will disable */ 455 /* sdata_running will return false, so this will disable */
455 ieee80211_bss_info_change_notify(sdata, 456 ieee80211_bss_info_change_notify(sdata,
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index b510721e3b3d..31afd712930d 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -195,7 +195,7 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
195 assert_key_lock(sdata->local); 195 assert_key_lock(sdata->local);
196 196
197 if (idx >= 0 && idx < NUM_DEFAULT_KEYS) 197 if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
198 key = sdata->keys[idx]; 198 key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
199 199
200 if (uni) 200 if (uni)
201 rcu_assign_pointer(sdata->default_unicast_key, key); 201 rcu_assign_pointer(sdata->default_unicast_key, key);
@@ -222,7 +222,7 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
222 222
223 if (idx >= NUM_DEFAULT_KEYS && 223 if (idx >= NUM_DEFAULT_KEYS &&
224 idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) 224 idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
225 key = sdata->keys[idx]; 225 key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
226 226
227 rcu_assign_pointer(sdata->default_mgmt_key, key); 227 rcu_assign_pointer(sdata->default_mgmt_key, key);
228 228
@@ -266,9 +266,15 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
266 else 266 else
267 idx = new->conf.keyidx; 267 idx = new->conf.keyidx;
268 268
269 defunikey = old && sdata->default_unicast_key == old; 269 defunikey = old &&
270 defmultikey = old && sdata->default_multicast_key == old; 270 old == key_mtx_dereference(sdata->local,
271 defmgmtkey = old && sdata->default_mgmt_key == old; 271 sdata->default_unicast_key);
272 defmultikey = old &&
273 old == key_mtx_dereference(sdata->local,
274 sdata->default_multicast_key);
275 defmgmtkey = old &&
276 old == key_mtx_dereference(sdata->local,
277 sdata->default_mgmt_key);
272 278
273 if (defunikey && !new) 279 if (defunikey && !new)
274 __ieee80211_set_default_key(sdata, -1, true, false); 280 __ieee80211_set_default_key(sdata, -1, true, false);
@@ -451,11 +457,11 @@ int ieee80211_key_link(struct ieee80211_key *key,
451 mutex_lock(&sdata->local->key_mtx); 457 mutex_lock(&sdata->local->key_mtx);
452 458
453 if (sta && pairwise) 459 if (sta && pairwise)
454 old_key = sta->ptk; 460 old_key = key_mtx_dereference(sdata->local, sta->ptk);
455 else if (sta) 461 else if (sta)
456 old_key = sta->gtk[idx]; 462 old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]);
457 else 463 else
458 old_key = sdata->keys[idx]; 464 old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
459 465
460 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key); 466 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
461 __ieee80211_key_destroy(old_key); 467 __ieee80211_key_destroy(old_key);
@@ -471,8 +477,11 @@ int ieee80211_key_link(struct ieee80211_key *key,
471 return ret; 477 return ret;
472} 478}
473 479
474static void __ieee80211_key_free(struct ieee80211_key *key) 480void __ieee80211_key_free(struct ieee80211_key *key)
475{ 481{
482 if (!key)
483 return;
484
476 /* 485 /*
477 * Replace key with nothingness if it was ever used. 486 * Replace key with nothingness if it was ever used.
478 */ 487 */
@@ -486,9 +495,6 @@ static void __ieee80211_key_free(struct ieee80211_key *key)
486void ieee80211_key_free(struct ieee80211_local *local, 495void ieee80211_key_free(struct ieee80211_local *local,
487 struct ieee80211_key *key) 496 struct ieee80211_key *key)
488{ 497{
489 if (!key)
490 return;
491
492 mutex_lock(&local->key_mtx); 498 mutex_lock(&local->key_mtx);
493 __ieee80211_key_free(key); 499 __ieee80211_key_free(key);
494 mutex_unlock(&local->key_mtx); 500 mutex_unlock(&local->key_mtx);
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 4ddbe27eb570..d801d5351336 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -135,6 +135,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
135int __must_check ieee80211_key_link(struct ieee80211_key *key, 135int __must_check ieee80211_key_link(struct ieee80211_key *key,
136 struct ieee80211_sub_if_data *sdata, 136 struct ieee80211_sub_if_data *sdata,
137 struct sta_info *sta); 137 struct sta_info *sta);
138void __ieee80211_key_free(struct ieee80211_key *key);
138void ieee80211_key_free(struct ieee80211_local *local, 139void ieee80211_key_free(struct ieee80211_local *local,
139 struct ieee80211_key *key); 140 struct ieee80211_key *key);
140void 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,
@@ -145,4 +146,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
145void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); 146void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
146void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata); 147void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata);
147 148
149#define key_mtx_dereference(local, ref) \
150 rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx)))
151
148#endif /* IEEE80211_KEY_H */ 152#endif /* IEEE80211_KEY_H */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 61877662e8f8..0d7b08db8e56 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -358,7 +358,8 @@ static void ieee80211_restart_work(struct work_struct *work)
358 flush_workqueue(local->workqueue); 358 flush_workqueue(local->workqueue);
359 359
360 mutex_lock(&local->mtx); 360 mutex_lock(&local->mtx);
361 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), 361 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
362 local->sched_scanning,
362 "%s called with hardware scan in progress\n", __func__); 363 "%s called with hardware scan in progress\n", __func__);
363 mutex_unlock(&local->mtx); 364 mutex_unlock(&local->mtx);
364 365
@@ -580,8 +581,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
580 581
581 wiphy->flags |= WIPHY_FLAG_NETNS_OK | 582 wiphy->flags |= WIPHY_FLAG_NETNS_OK |
582 WIPHY_FLAG_4ADDR_AP | 583 WIPHY_FLAG_4ADDR_AP |
583 WIPHY_FLAG_4ADDR_STATION | 584 WIPHY_FLAG_4ADDR_STATION;
584 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
585 585
586 if (!ops->set_key) 586 if (!ops->set_key)
587 wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 587 wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
@@ -652,6 +652,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
652 setup_timer(&local->dynamic_ps_timer, 652 setup_timer(&local->dynamic_ps_timer,
653 ieee80211_dynamic_ps_timer, (unsigned long) local); 653 ieee80211_dynamic_ps_timer, (unsigned long) local);
654 654
655 INIT_WORK(&local->sched_scan_stopped_work,
656 ieee80211_sched_scan_stopped_work);
657
655 sta_info_init(local); 658 sta_info_init(local);
656 659
657 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { 660 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
@@ -682,7 +685,7 @@ EXPORT_SYMBOL(ieee80211_alloc_hw);
682int ieee80211_register_hw(struct ieee80211_hw *hw) 685int ieee80211_register_hw(struct ieee80211_hw *hw)
683{ 686{
684 struct ieee80211_local *local = hw_to_local(hw); 687 struct ieee80211_local *local = hw_to_local(hw);
685 int result; 688 int result, i;
686 enum ieee80211_band band; 689 enum ieee80211_band band;
687 int channels, max_bitrates; 690 int channels, max_bitrates;
688 bool supp_ht; 691 bool supp_ht;
@@ -697,6 +700,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
697 WLAN_CIPHER_SUITE_AES_CMAC 700 WLAN_CIPHER_SUITE_AES_CMAC
698 }; 701 };
699 702
703 if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns)
704#ifdef CONFIG_PM
705 && (!local->ops->suspend || !local->ops->resume)
706#endif
707 )
708 return -EINVAL;
709
700 if (hw->max_report_rates == 0) 710 if (hw->max_report_rates == 0)
701 hw->max_report_rates = hw->max_rates; 711 hw->max_report_rates = hw->max_rates;
702 712
@@ -733,11 +743,19 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
733 return -ENOMEM; 743 return -ENOMEM;
734 744
735 /* if low-level driver supports AP, we also support VLAN */ 745 /* if low-level driver supports AP, we also support VLAN */
736 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) 746 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) {
737 local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); 747 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
748 hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN);
749 }
738 750
739 /* mac80211 always supports monitor */ 751 /* mac80211 always supports monitor */
740 local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); 752 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
753 hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
754
755 /* mac80211 doesn't support more than 1 channel */
756 for (i = 0; i < hw->wiphy->n_iface_combinations; i++)
757 if (hw->wiphy->iface_combinations[i].num_different_channels > 1)
758 return -EINVAL;
741 759
742#ifndef CONFIG_MAC80211_MESH 760#ifndef CONFIG_MAC80211_MESH
743 /* mesh depends on Kconfig, but drivers should set it if they want */ 761 /* mesh depends on Kconfig, but drivers should set it if they want */
@@ -827,6 +845,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
827 if (!local->ops->remain_on_channel) 845 if (!local->ops->remain_on_channel)
828 local->hw.wiphy->max_remain_on_channel_duration = 5000; 846 local->hw.wiphy->max_remain_on_channel_duration = 5000;
829 847
848 if (local->ops->sched_scan_start)
849 local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
850
830 result = wiphy_register(local->hw.wiphy); 851 result = wiphy_register(local->hw.wiphy);
831 if (result < 0) 852 if (result < 0)
832 goto fail_wiphy_register; 853 goto fail_wiphy_register;
@@ -850,8 +871,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
850 * and we need some headroom for passing the frame to monitor 871 * and we need some headroom for passing the frame to monitor
851 * interfaces, but never both at the same time. 872 * interfaces, but never both at the same time.
852 */ 873 */
874#ifndef __CHECKER__
853 BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM != 875 BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM !=
854 sizeof(struct ieee80211_tx_status_rtap_hdr)); 876 sizeof(struct ieee80211_tx_status_rtap_hdr));
877#endif
855 local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, 878 local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
856 sizeof(struct ieee80211_tx_status_rtap_hdr)); 879 sizeof(struct ieee80211_tx_status_rtap_hdr));
857 880
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c1299e249541..29e9980c8e60 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -287,49 +287,6 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
287 } 287 }
288} 288}
289 289
290u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl)
291{
292 /* Use last four bytes of hw addr and interface index as hash index */
293 return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd)
294 & tbl->hash_mask;
295}
296
297struct mesh_table *mesh_table_alloc(int size_order)
298{
299 int i;
300 struct mesh_table *newtbl;
301
302 newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL);
303 if (!newtbl)
304 return NULL;
305
306 newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) *
307 (1 << size_order), GFP_KERNEL);
308
309 if (!newtbl->hash_buckets) {
310 kfree(newtbl);
311 return NULL;
312 }
313
314 newtbl->hashwlock = kmalloc(sizeof(spinlock_t) *
315 (1 << size_order), GFP_KERNEL);
316 if (!newtbl->hashwlock) {
317 kfree(newtbl->hash_buckets);
318 kfree(newtbl);
319 return NULL;
320 }
321
322 newtbl->size_order = size_order;
323 newtbl->hash_mask = (1 << size_order) - 1;
324 atomic_set(&newtbl->entries, 0);
325 get_random_bytes(&newtbl->hash_rnd,
326 sizeof(newtbl->hash_rnd));
327 for (i = 0; i <= newtbl->hash_mask; i++)
328 spin_lock_init(&newtbl->hashwlock[i]);
329
330 return newtbl;
331}
332
333 290
334static void ieee80211_mesh_path_timer(unsigned long data) 291static void ieee80211_mesh_path_timer(unsigned long data)
335{ 292{
@@ -574,7 +531,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
574 &elems); 531 &elems);
575 532
576 /* ignore beacons from secure mesh peers if our security is off */ 533 /* ignore beacons from secure mesh peers if our security is off */
577 if (elems.rsn_len && !sdata->u.mesh.is_secure) 534 if (elems.rsn_len && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE)
578 return; 535 return;
579 536
580 if (elems.ds_params && elems.ds_params_len == 1) 537 if (elems.ds_params && elems.ds_params_len == 1)
@@ -600,7 +557,7 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
600 struct ieee80211_rx_status *rx_status) 557 struct ieee80211_rx_status *rx_status)
601{ 558{
602 switch (mgmt->u.action.category) { 559 switch (mgmt->u.action.category) {
603 case WLAN_CATEGORY_MESH_PLINK: 560 case WLAN_CATEGORY_MESH_ACTION:
604 mesh_rx_plink_frame(sdata, mgmt, len, rx_status); 561 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
605 break; 562 break;
606 case WLAN_CATEGORY_MESH_PATH_SEL: 563 case WLAN_CATEGORY_MESH_PATH_SEL:
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 10acf1cc8082..e7c5fddb4804 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -92,7 +92,7 @@ struct mesh_path {
92 u8 dst[ETH_ALEN]; 92 u8 dst[ETH_ALEN];
93 u8 mpp[ETH_ALEN]; /* used for MPP or MAP */ 93 u8 mpp[ETH_ALEN]; /* used for MPP or MAP */
94 struct ieee80211_sub_if_data *sdata; 94 struct ieee80211_sub_if_data *sdata;
95 struct sta_info *next_hop; 95 struct sta_info __rcu *next_hop;
96 struct timer_list timer; 96 struct timer_list timer;
97 struct sk_buff_head frame_queue; 97 struct sk_buff_head frame_queue;
98 struct rcu_head rcu; 98 struct rcu_head rcu;
@@ -240,12 +240,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
240 240
241/* Private interfaces */ 241/* Private interfaces */
242/* Mesh tables */ 242/* Mesh tables */
243struct mesh_table *mesh_table_alloc(int size_order);
244void mesh_table_free(struct mesh_table *tbl, bool free_leafs);
245void mesh_mpath_table_grow(void); 243void mesh_mpath_table_grow(void);
246void mesh_mpp_table_grow(void); 244void mesh_mpp_table_grow(void);
247u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
248 struct mesh_table *tbl);
249/* Mesh paths */ 245/* Mesh paths */
250int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode, 246int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode,
251 const u8 *ra, struct ieee80211_sub_if_data *sdata); 247 const u8 *ra, struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index e57f2e728cfe..2b18053070c1 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -391,7 +391,6 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
391 (mpath->flags & MESH_PATH_SN_VALID)) { 391 (mpath->flags & MESH_PATH_SN_VALID)) {
392 if (SN_GT(mpath->sn, orig_sn) || 392 if (SN_GT(mpath->sn, orig_sn) ||
393 (mpath->sn == orig_sn && 393 (mpath->sn == orig_sn &&
394 action == MPATH_PREQ &&
395 new_metric >= mpath->metric)) { 394 new_metric >= mpath->metric)) {
396 process = false; 395 process = false;
397 fresh_info = false; 396 fresh_info = false;
@@ -561,6 +560,14 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
561} 560}
562 561
563 562
563static inline struct sta_info *
564next_hop_deref_protected(struct mesh_path *mpath)
565{
566 return rcu_dereference_protected(mpath->next_hop,
567 lockdep_is_held(&mpath->state_lock));
568}
569
570
564static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, 571static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
565 struct ieee80211_mgmt *mgmt, 572 struct ieee80211_mgmt *mgmt,
566 u8 *prep_elem, u32 metric) 573 u8 *prep_elem, u32 metric)
@@ -600,7 +607,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
600 spin_unlock_bh(&mpath->state_lock); 607 spin_unlock_bh(&mpath->state_lock);
601 goto fail; 608 goto fail;
602 } 609 }
603 memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN); 610 memcpy(next_hop, next_hop_deref_protected(mpath)->sta.addr, ETH_ALEN);
604 spin_unlock_bh(&mpath->state_lock); 611 spin_unlock_bh(&mpath->state_lock);
605 --ttl; 612 --ttl;
606 flags = PREP_IE_FLAGS(prep_elem); 613 flags = PREP_IE_FLAGS(prep_elem);
@@ -652,7 +659,8 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
652 if (mpath) { 659 if (mpath) {
653 spin_lock_bh(&mpath->state_lock); 660 spin_lock_bh(&mpath->state_lock);
654 if (mpath->flags & MESH_PATH_ACTIVE && 661 if (mpath->flags & MESH_PATH_ACTIVE &&
655 memcmp(ta, mpath->next_hop->sta.addr, ETH_ALEN) == 0 && 662 memcmp(ta, next_hop_deref_protected(mpath)->sta.addr,
663 ETH_ALEN) == 0 &&
656 (!(mpath->flags & MESH_PATH_SN_VALID) || 664 (!(mpath->flags & MESH_PATH_SN_VALID) ||
657 SN_GT(target_sn, mpath->sn))) { 665 SN_GT(target_sn, mpath->sn))) {
658 mpath->flags &= ~MESH_PATH_ACTIVE; 666 mpath->flags &= ~MESH_PATH_ACTIVE;
@@ -914,6 +922,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
914{ 922{
915 struct sk_buff *skb_to_free = NULL; 923 struct sk_buff *skb_to_free = NULL;
916 struct mesh_path *mpath; 924 struct mesh_path *mpath;
925 struct sta_info *next_hop;
917 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 926 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
918 u8 *target_addr = hdr->addr3; 927 u8 *target_addr = hdr->addr3;
919 int err = 0; 928 int err = 0;
@@ -941,7 +950,11 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
941 mesh_queue_preq(mpath, 950 mesh_queue_preq(mpath,
942 PREQ_Q_F_START | PREQ_Q_F_REFRESH); 951 PREQ_Q_F_START | PREQ_Q_F_REFRESH);
943 } 952 }
944 memcpy(hdr->addr1, mpath->next_hop->sta.addr, ETH_ALEN); 953 next_hop = rcu_dereference(mpath->next_hop);
954 if (next_hop)
955 memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
956 else
957 err = -ENOENT;
945 } else { 958 } else {
946 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 959 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
947 if (!(mpath->flags & MESH_PATH_RESOLVING)) { 960 if (!(mpath->flags & MESH_PATH_RESOLVING)) {
@@ -967,20 +980,11 @@ endlookup:
967 980
968void mesh_path_timer(unsigned long data) 981void mesh_path_timer(unsigned long data)
969{ 982{
970 struct ieee80211_sub_if_data *sdata; 983 struct mesh_path *mpath = (void *) data;
971 struct mesh_path *mpath; 984 struct ieee80211_sub_if_data *sdata = mpath->sdata;
972
973 rcu_read_lock();
974 mpath = (struct mesh_path *) data;
975 mpath = rcu_dereference(mpath);
976 if (!mpath)
977 goto endmpathtimer;
978 sdata = mpath->sdata;
979 985
980 if (sdata->local->quiescing) { 986 if (sdata->local->quiescing)
981 rcu_read_unlock();
982 return; 987 return;
983 }
984 988
985 spin_lock_bh(&mpath->state_lock); 989 spin_lock_bh(&mpath->state_lock);
986 if (mpath->flags & MESH_PATH_RESOLVED || 990 if (mpath->flags & MESH_PATH_RESOLVED ||
@@ -997,8 +1001,6 @@ void mesh_path_timer(unsigned long data)
997 } 1001 }
998 1002
999 spin_unlock_bh(&mpath->state_lock); 1003 spin_unlock_bh(&mpath->state_lock);
1000endmpathtimer:
1001 rcu_read_unlock();
1002} 1004}
1003 1005
1004void 1006void
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 35c715adaae2..83ce48e31913 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -40,6 +40,50 @@ static struct mesh_table *mesh_paths;
40static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */ 40static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */
41 41
42int mesh_paths_generation; 42int mesh_paths_generation;
43
44/* This lock will have the grow table function as writer and add / delete nodes
45 * as readers. When reading the table (i.e. doing lookups) we are well protected
46 * by RCU
47 */
48static DEFINE_RWLOCK(pathtbl_resize_lock);
49
50
51static struct mesh_table *mesh_table_alloc(int size_order)
52{
53 int i;
54 struct mesh_table *newtbl;
55
56 newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL);
57 if (!newtbl)
58 return NULL;
59
60 newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) *
61 (1 << size_order), GFP_KERNEL);
62
63 if (!newtbl->hash_buckets) {
64 kfree(newtbl);
65 return NULL;
66 }
67
68 newtbl->hashwlock = kmalloc(sizeof(spinlock_t) *
69 (1 << size_order), GFP_KERNEL);
70 if (!newtbl->hashwlock) {
71 kfree(newtbl->hash_buckets);
72 kfree(newtbl);
73 return NULL;
74 }
75
76 newtbl->size_order = size_order;
77 newtbl->hash_mask = (1 << size_order) - 1;
78 atomic_set(&newtbl->entries, 0);
79 get_random_bytes(&newtbl->hash_rnd,
80 sizeof(newtbl->hash_rnd));
81 for (i = 0; i <= newtbl->hash_mask; i++)
82 spin_lock_init(&newtbl->hashwlock[i]);
83
84 return newtbl;
85}
86
43static void __mesh_table_free(struct mesh_table *tbl) 87static void __mesh_table_free(struct mesh_table *tbl)
44{ 88{
45 kfree(tbl->hash_buckets); 89 kfree(tbl->hash_buckets);
@@ -47,7 +91,7 @@ static void __mesh_table_free(struct mesh_table *tbl)
47 kfree(tbl); 91 kfree(tbl);
48} 92}
49 93
50void mesh_table_free(struct mesh_table *tbl, bool free_leafs) 94static void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
51{ 95{
52 struct hlist_head *mesh_hash; 96 struct hlist_head *mesh_hash;
53 struct hlist_node *p, *q; 97 struct hlist_node *p, *q;
@@ -55,18 +99,18 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
55 99
56 mesh_hash = tbl->hash_buckets; 100 mesh_hash = tbl->hash_buckets;
57 for (i = 0; i <= tbl->hash_mask; i++) { 101 for (i = 0; i <= tbl->hash_mask; i++) {
58 spin_lock(&tbl->hashwlock[i]); 102 spin_lock_bh(&tbl->hashwlock[i]);
59 hlist_for_each_safe(p, q, &mesh_hash[i]) { 103 hlist_for_each_safe(p, q, &mesh_hash[i]) {
60 tbl->free_node(p, free_leafs); 104 tbl->free_node(p, free_leafs);
61 atomic_dec(&tbl->entries); 105 atomic_dec(&tbl->entries);
62 } 106 }
63 spin_unlock(&tbl->hashwlock[i]); 107 spin_unlock_bh(&tbl->hashwlock[i]);
64 } 108 }
65 __mesh_table_free(tbl); 109 __mesh_table_free(tbl);
66} 110}
67 111
68static int mesh_table_grow(struct mesh_table *oldtbl, 112static int mesh_table_grow(struct mesh_table *oldtbl,
69 struct mesh_table *newtbl) 113 struct mesh_table *newtbl)
70{ 114{
71 struct hlist_head *oldhash; 115 struct hlist_head *oldhash;
72 struct hlist_node *p, *q; 116 struct hlist_node *p, *q;
@@ -76,7 +120,6 @@ static int mesh_table_grow(struct mesh_table *oldtbl,
76 < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1)) 120 < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1))
77 return -EAGAIN; 121 return -EAGAIN;
78 122
79
80 newtbl->free_node = oldtbl->free_node; 123 newtbl->free_node = oldtbl->free_node;
81 newtbl->mean_chain_len = oldtbl->mean_chain_len; 124 newtbl->mean_chain_len = oldtbl->mean_chain_len;
82 newtbl->copy_node = oldtbl->copy_node; 125 newtbl->copy_node = oldtbl->copy_node;
@@ -98,12 +141,14 @@ errcopy:
98 return -ENOMEM; 141 return -ENOMEM;
99} 142}
100 143
144static u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
145 struct mesh_table *tbl)
146{
147 /* Use last four bytes of hw addr and interface index as hash index */
148 return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd)
149 & tbl->hash_mask;
150}
101 151
102/* This lock will have the grow table function as writer and add / delete nodes
103 * as readers. When reading the table (i.e. doing lookups) we are well protected
104 * by RCU
105 */
106static DEFINE_RWLOCK(pathtbl_resize_lock);
107 152
108/** 153/**
109 * 154 *
@@ -275,7 +320,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
275 if (!new_node) 320 if (!new_node)
276 goto err_node_alloc; 321 goto err_node_alloc;
277 322
278 read_lock(&pathtbl_resize_lock); 323 read_lock_bh(&pathtbl_resize_lock);
279 memcpy(new_mpath->dst, dst, ETH_ALEN); 324 memcpy(new_mpath->dst, dst, ETH_ALEN);
280 new_mpath->sdata = sdata; 325 new_mpath->sdata = sdata;
281 new_mpath->flags = 0; 326 new_mpath->flags = 0;
@@ -290,7 +335,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
290 hash_idx = mesh_table_hash(dst, sdata, mesh_paths); 335 hash_idx = mesh_table_hash(dst, sdata, mesh_paths);
291 bucket = &mesh_paths->hash_buckets[hash_idx]; 336 bucket = &mesh_paths->hash_buckets[hash_idx];
292 337
293 spin_lock(&mesh_paths->hashwlock[hash_idx]); 338 spin_lock_bh(&mesh_paths->hashwlock[hash_idx]);
294 339
295 err = -EEXIST; 340 err = -EEXIST;
296 hlist_for_each_entry(node, n, bucket, list) { 341 hlist_for_each_entry(node, n, bucket, list) {
@@ -306,8 +351,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
306 351
307 mesh_paths_generation++; 352 mesh_paths_generation++;
308 353
309 spin_unlock(&mesh_paths->hashwlock[hash_idx]); 354 spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]);
310 read_unlock(&pathtbl_resize_lock); 355 read_unlock_bh(&pathtbl_resize_lock);
311 if (grow) { 356 if (grow) {
312 set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); 357 set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags);
313 ieee80211_queue_work(&local->hw, &sdata->work); 358 ieee80211_queue_work(&local->hw, &sdata->work);
@@ -315,8 +360,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
315 return 0; 360 return 0;
316 361
317err_exists: 362err_exists:
318 spin_unlock(&mesh_paths->hashwlock[hash_idx]); 363 spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]);
319 read_unlock(&pathtbl_resize_lock); 364 read_unlock_bh(&pathtbl_resize_lock);
320 kfree(new_node); 365 kfree(new_node);
321err_node_alloc: 366err_node_alloc:
322 kfree(new_mpath); 367 kfree(new_mpath);
@@ -329,18 +374,21 @@ void mesh_mpath_table_grow(void)
329{ 374{
330 struct mesh_table *oldtbl, *newtbl; 375 struct mesh_table *oldtbl, *newtbl;
331 376
332 newtbl = mesh_table_alloc(mesh_paths->size_order + 1); 377 rcu_read_lock();
378 newtbl = mesh_table_alloc(rcu_dereference(mesh_paths)->size_order + 1);
333 if (!newtbl) 379 if (!newtbl)
334 return; 380 return;
335 write_lock(&pathtbl_resize_lock); 381 write_lock_bh(&pathtbl_resize_lock);
336 oldtbl = mesh_paths; 382 oldtbl = mesh_paths;
337 if (mesh_table_grow(mesh_paths, newtbl) < 0) { 383 if (mesh_table_grow(mesh_paths, newtbl) < 0) {
384 rcu_read_unlock();
338 __mesh_table_free(newtbl); 385 __mesh_table_free(newtbl);
339 write_unlock(&pathtbl_resize_lock); 386 write_unlock_bh(&pathtbl_resize_lock);
340 return; 387 return;
341 } 388 }
389 rcu_read_unlock();
342 rcu_assign_pointer(mesh_paths, newtbl); 390 rcu_assign_pointer(mesh_paths, newtbl);
343 write_unlock(&pathtbl_resize_lock); 391 write_unlock_bh(&pathtbl_resize_lock);
344 392
345 synchronize_rcu(); 393 synchronize_rcu();
346 mesh_table_free(oldtbl, false); 394 mesh_table_free(oldtbl, false);
@@ -350,18 +398,21 @@ void mesh_mpp_table_grow(void)
350{ 398{
351 struct mesh_table *oldtbl, *newtbl; 399 struct mesh_table *oldtbl, *newtbl;
352 400
353 newtbl = mesh_table_alloc(mpp_paths->size_order + 1); 401 rcu_read_lock();
402 newtbl = mesh_table_alloc(rcu_dereference(mpp_paths)->size_order + 1);
354 if (!newtbl) 403 if (!newtbl)
355 return; 404 return;
356 write_lock(&pathtbl_resize_lock); 405 write_lock_bh(&pathtbl_resize_lock);
357 oldtbl = mpp_paths; 406 oldtbl = mpp_paths;
358 if (mesh_table_grow(mpp_paths, newtbl) < 0) { 407 if (mesh_table_grow(mpp_paths, newtbl) < 0) {
408 rcu_read_unlock();
359 __mesh_table_free(newtbl); 409 __mesh_table_free(newtbl);
360 write_unlock(&pathtbl_resize_lock); 410 write_unlock_bh(&pathtbl_resize_lock);
361 return; 411 return;
362 } 412 }
413 rcu_read_unlock();
363 rcu_assign_pointer(mpp_paths, newtbl); 414 rcu_assign_pointer(mpp_paths, newtbl);
364 write_unlock(&pathtbl_resize_lock); 415 write_unlock_bh(&pathtbl_resize_lock);
365 416
366 synchronize_rcu(); 417 synchronize_rcu();
367 mesh_table_free(oldtbl, false); 418 mesh_table_free(oldtbl, false);
@@ -395,7 +446,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
395 if (!new_node) 446 if (!new_node)
396 goto err_node_alloc; 447 goto err_node_alloc;
397 448
398 read_lock(&pathtbl_resize_lock); 449 read_lock_bh(&pathtbl_resize_lock);
399 memcpy(new_mpath->dst, dst, ETH_ALEN); 450 memcpy(new_mpath->dst, dst, ETH_ALEN);
400 memcpy(new_mpath->mpp, mpp, ETH_ALEN); 451 memcpy(new_mpath->mpp, mpp, ETH_ALEN);
401 new_mpath->sdata = sdata; 452 new_mpath->sdata = sdata;
@@ -408,7 +459,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
408 hash_idx = mesh_table_hash(dst, sdata, mpp_paths); 459 hash_idx = mesh_table_hash(dst, sdata, mpp_paths);
409 bucket = &mpp_paths->hash_buckets[hash_idx]; 460 bucket = &mpp_paths->hash_buckets[hash_idx];
410 461
411 spin_lock(&mpp_paths->hashwlock[hash_idx]); 462 spin_lock_bh(&mpp_paths->hashwlock[hash_idx]);
412 463
413 err = -EEXIST; 464 err = -EEXIST;
414 hlist_for_each_entry(node, n, bucket, list) { 465 hlist_for_each_entry(node, n, bucket, list) {
@@ -422,8 +473,8 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
422 mpp_paths->mean_chain_len * (mpp_paths->hash_mask + 1)) 473 mpp_paths->mean_chain_len * (mpp_paths->hash_mask + 1))
423 grow = 1; 474 grow = 1;
424 475
425 spin_unlock(&mpp_paths->hashwlock[hash_idx]); 476 spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]);
426 read_unlock(&pathtbl_resize_lock); 477 read_unlock_bh(&pathtbl_resize_lock);
427 if (grow) { 478 if (grow) {
428 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); 479 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags);
429 ieee80211_queue_work(&local->hw, &sdata->work); 480 ieee80211_queue_work(&local->hw, &sdata->work);
@@ -431,8 +482,8 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
431 return 0; 482 return 0;
432 483
433err_exists: 484err_exists:
434 spin_unlock(&mpp_paths->hashwlock[hash_idx]); 485 spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]);
435 read_unlock(&pathtbl_resize_lock); 486 read_unlock_bh(&pathtbl_resize_lock);
436 kfree(new_node); 487 kfree(new_node);
437err_node_alloc: 488err_node_alloc:
438 kfree(new_mpath); 489 kfree(new_mpath);
@@ -545,11 +596,11 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
545 int hash_idx; 596 int hash_idx;
546 int err = 0; 597 int err = 0;
547 598
548 read_lock(&pathtbl_resize_lock); 599 read_lock_bh(&pathtbl_resize_lock);
549 hash_idx = mesh_table_hash(addr, sdata, mesh_paths); 600 hash_idx = mesh_table_hash(addr, sdata, mesh_paths);
550 bucket = &mesh_paths->hash_buckets[hash_idx]; 601 bucket = &mesh_paths->hash_buckets[hash_idx];
551 602
552 spin_lock(&mesh_paths->hashwlock[hash_idx]); 603 spin_lock_bh(&mesh_paths->hashwlock[hash_idx]);
553 hlist_for_each_entry(node, n, bucket, list) { 604 hlist_for_each_entry(node, n, bucket, list) {
554 mpath = node->mpath; 605 mpath = node->mpath;
555 if (mpath->sdata == sdata && 606 if (mpath->sdata == sdata &&
@@ -567,8 +618,8 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
567 err = -ENXIO; 618 err = -ENXIO;
568enddel: 619enddel:
569 mesh_paths_generation++; 620 mesh_paths_generation++;
570 spin_unlock(&mesh_paths->hashwlock[hash_idx]); 621 spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]);
571 read_unlock(&pathtbl_resize_lock); 622 read_unlock_bh(&pathtbl_resize_lock);
572 return err; 623 return err;
573} 624}
574 625
@@ -720,7 +771,7 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
720 struct hlist_node *p; 771 struct hlist_node *p;
721 int i; 772 int i;
722 773
723 read_lock(&pathtbl_resize_lock); 774 read_lock_bh(&pathtbl_resize_lock);
724 for_each_mesh_entry(mesh_paths, p, node, i) { 775 for_each_mesh_entry(mesh_paths, p, node, i) {
725 if (node->mpath->sdata != sdata) 776 if (node->mpath->sdata != sdata)
726 continue; 777 continue;
@@ -735,7 +786,7 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
735 } else 786 } else
736 spin_unlock_bh(&mpath->state_lock); 787 spin_unlock_bh(&mpath->state_lock);
737 } 788 }
738 read_unlock(&pathtbl_resize_lock); 789 read_unlock_bh(&pathtbl_resize_lock);
739} 790}
740 791
741void mesh_pathtbl_unregister(void) 792void mesh_pathtbl_unregister(void)
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 84e5b056af02..f4adc0917888 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -43,7 +43,7 @@
43#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) 43#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
44 44
45enum plink_frame_type { 45enum plink_frame_type {
46 PLINK_OPEN = 0, 46 PLINK_OPEN = 1,
47 PLINK_CONFIRM, 47 PLINK_CONFIRM,
48 PLINK_CLOSE 48 PLINK_CLOSE
49}; 49};
@@ -83,7 +83,7 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
83 */ 83 */
84static inline void mesh_plink_fsm_restart(struct sta_info *sta) 84static inline void mesh_plink_fsm_restart(struct sta_info *sta)
85{ 85{
86 sta->plink_state = PLINK_LISTEN; 86 sta->plink_state = NL80211_PLINK_LISTEN;
87 sta->llid = sta->plid = sta->reason = 0; 87 sta->llid = sta->plid = sta->reason = 0;
88 sta->plink_retries = 0; 88 sta->plink_retries = 0;
89} 89}
@@ -126,11 +126,11 @@ static bool __mesh_plink_deactivate(struct sta_info *sta)
126 struct ieee80211_sub_if_data *sdata = sta->sdata; 126 struct ieee80211_sub_if_data *sdata = sta->sdata;
127 bool deactivated = false; 127 bool deactivated = false;
128 128
129 if (sta->plink_state == PLINK_ESTAB) { 129 if (sta->plink_state == NL80211_PLINK_ESTAB) {
130 mesh_plink_dec_estab_count(sdata); 130 mesh_plink_dec_estab_count(sdata);
131 deactivated = true; 131 deactivated = true;
132 } 132 }
133 sta->plink_state = PLINK_BLOCKED; 133 sta->plink_state = NL80211_PLINK_BLOCKED;
134 mesh_path_flush_by_nexthop(sta); 134 mesh_path_flush_by_nexthop(sta);
135 135
136 return deactivated; 136 return deactivated;
@@ -181,8 +181,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
181 IEEE80211_STYPE_ACTION); 181 IEEE80211_STYPE_ACTION);
182 memcpy(mgmt->da, da, ETH_ALEN); 182 memcpy(mgmt->da, da, ETH_ALEN);
183 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 183 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
184 /* BSSID is left zeroed, wildcard value */ 184 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
185 mgmt->u.action.category = WLAN_CATEGORY_MESH_PLINK; 185 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
186 mgmt->u.action.u.plink_action.action_code = action; 186 mgmt->u.action.u.plink_action.action_code = action;
187 187
188 if (action == PLINK_CLOSE) 188 if (action == PLINK_CLOSE)
@@ -251,7 +251,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
251 rcu_read_unlock(); 251 rcu_read_unlock();
252 /* Userspace handles peer allocation when security is enabled 252 /* Userspace handles peer allocation when security is enabled
253 * */ 253 * */
254 if (sdata->u.mesh.is_secure) 254 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
255 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, 255 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr,
256 elems->ie_start, elems->total_len, 256 elems->ie_start, elems->total_len,
257 GFP_KERNEL); 257 GFP_KERNEL);
@@ -268,7 +268,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
268 sta->last_rx = jiffies; 268 sta->last_rx = jiffies;
269 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 269 sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
270 if (mesh_peer_accepts_plinks(elems) && 270 if (mesh_peer_accepts_plinks(elems) &&
271 sta->plink_state == PLINK_LISTEN && 271 sta->plink_state == NL80211_PLINK_LISTEN &&
272 sdata->u.mesh.accepting_plinks && 272 sdata->u.mesh.accepting_plinks &&
273 sdata->u.mesh.mshcfg.auto_open_plinks) 273 sdata->u.mesh.mshcfg.auto_open_plinks)
274 mesh_plink_open(sta); 274 mesh_plink_open(sta);
@@ -308,8 +308,8 @@ static void mesh_plink_timer(unsigned long data)
308 sdata = sta->sdata; 308 sdata = sta->sdata;
309 309
310 switch (sta->plink_state) { 310 switch (sta->plink_state) {
311 case PLINK_OPN_RCVD: 311 case NL80211_PLINK_OPN_RCVD:
312 case PLINK_OPN_SNT: 312 case NL80211_PLINK_OPN_SNT:
313 /* retry timer */ 313 /* retry timer */
314 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { 314 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
315 u32 rand; 315 u32 rand;
@@ -328,17 +328,17 @@ static void mesh_plink_timer(unsigned long data)
328 } 328 }
329 reason = cpu_to_le16(MESH_MAX_RETRIES); 329 reason = cpu_to_le16(MESH_MAX_RETRIES);
330 /* fall through on else */ 330 /* fall through on else */
331 case PLINK_CNF_RCVD: 331 case NL80211_PLINK_CNF_RCVD:
332 /* confirm timer */ 332 /* confirm timer */
333 if (!reason) 333 if (!reason)
334 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); 334 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
335 sta->plink_state = PLINK_HOLDING; 335 sta->plink_state = NL80211_PLINK_HOLDING;
336 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 336 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
337 spin_unlock_bh(&sta->lock); 337 spin_unlock_bh(&sta->lock);
338 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid, 338 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid,
339 reason); 339 reason);
340 break; 340 break;
341 case PLINK_HOLDING: 341 case NL80211_PLINK_HOLDING:
342 /* holding timer */ 342 /* holding timer */
343 del_timer(&sta->plink_timer); 343 del_timer(&sta->plink_timer);
344 mesh_plink_fsm_restart(sta); 344 mesh_plink_fsm_restart(sta);
@@ -386,11 +386,11 @@ int mesh_plink_open(struct sta_info *sta)
386 spin_lock_bh(&sta->lock); 386 spin_lock_bh(&sta->lock);
387 get_random_bytes(&llid, 2); 387 get_random_bytes(&llid, 2);
388 sta->llid = llid; 388 sta->llid = llid;
389 if (sta->plink_state != PLINK_LISTEN) { 389 if (sta->plink_state != NL80211_PLINK_LISTEN) {
390 spin_unlock_bh(&sta->lock); 390 spin_unlock_bh(&sta->lock);
391 return -EBUSY; 391 return -EBUSY;
392 } 392 }
393 sta->plink_state = PLINK_OPN_SNT; 393 sta->plink_state = NL80211_PLINK_OPN_SNT;
394 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 394 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
395 spin_unlock_bh(&sta->lock); 395 spin_unlock_bh(&sta->lock);
396 mpl_dbg("Mesh plink: starting establishment with %pM\n", 396 mpl_dbg("Mesh plink: starting establishment with %pM\n",
@@ -407,7 +407,7 @@ void mesh_plink_block(struct sta_info *sta)
407 407
408 spin_lock_bh(&sta->lock); 408 spin_lock_bh(&sta->lock);
409 deactivated = __mesh_plink_deactivate(sta); 409 deactivated = __mesh_plink_deactivate(sta);
410 sta->plink_state = PLINK_BLOCKED; 410 sta->plink_state = NL80211_PLINK_BLOCKED;
411 spin_unlock_bh(&sta->lock); 411 spin_unlock_bh(&sta->lock);
412 412
413 if (deactivated) 413 if (deactivated)
@@ -430,13 +430,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
430 __le16 plid, llid, reason; 430 __le16 plid, llid, reason;
431#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG 431#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
432 static const char *mplstates[] = { 432 static const char *mplstates[] = {
433 [PLINK_LISTEN] = "LISTEN", 433 [NL80211_PLINK_LISTEN] = "LISTEN",
434 [PLINK_OPN_SNT] = "OPN-SNT", 434 [NL80211_PLINK_OPN_SNT] = "OPN-SNT",
435 [PLINK_OPN_RCVD] = "OPN-RCVD", 435 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD",
436 [PLINK_CNF_RCVD] = "CNF_RCVD", 436 [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD",
437 [PLINK_ESTAB] = "ESTAB", 437 [NL80211_PLINK_ESTAB] = "ESTAB",
438 [PLINK_HOLDING] = "HOLDING", 438 [NL80211_PLINK_HOLDING] = "HOLDING",
439 [PLINK_BLOCKED] = "BLOCKED" 439 [NL80211_PLINK_BLOCKED] = "BLOCKED"
440 }; 440 };
441#endif 441#endif
442 442
@@ -460,7 +460,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
460 mpl_dbg("Mesh plink: missing necessary peer link ie\n"); 460 mpl_dbg("Mesh plink: missing necessary peer link ie\n");
461 return; 461 return;
462 } 462 }
463 if (elems.rsn_len && !sdata->u.mesh.is_secure) { 463 if (elems.rsn_len &&
464 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
464 mpl_dbg("Mesh plink: can't establish link with secure peer\n"); 465 mpl_dbg("Mesh plink: can't establish link with secure peer\n");
465 return; 466 return;
466 } 467 }
@@ -501,7 +502,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
501 return; 502 return;
502 } 503 }
503 504
504 if (sta && sta->plink_state == PLINK_BLOCKED) { 505 if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
505 rcu_read_unlock(); 506 rcu_read_unlock();
506 return; 507 return;
507 } 508 }
@@ -571,7 +572,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
571 event = CNF_ACPT; 572 event = CNF_ACPT;
572 break; 573 break;
573 case PLINK_CLOSE: 574 case PLINK_CLOSE:
574 if (sta->plink_state == PLINK_ESTAB) 575 if (sta->plink_state == NL80211_PLINK_ESTAB)
575 /* Do not check for llid or plid. This does not 576 /* Do not check for llid or plid. This does not
576 * follow the standard but since multiple plinks 577 * follow the standard but since multiple plinks
577 * per sta are not supported, it is necessary in 578 * per sta are not supported, it is necessary in
@@ -606,14 +607,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
606 reason = 0; 607 reason = 0;
607 switch (sta->plink_state) { 608 switch (sta->plink_state) {
608 /* spin_unlock as soon as state is updated at each case */ 609 /* spin_unlock as soon as state is updated at each case */
609 case PLINK_LISTEN: 610 case NL80211_PLINK_LISTEN:
610 switch (event) { 611 switch (event) {
611 case CLS_ACPT: 612 case CLS_ACPT:
612 mesh_plink_fsm_restart(sta); 613 mesh_plink_fsm_restart(sta);
613 spin_unlock_bh(&sta->lock); 614 spin_unlock_bh(&sta->lock);
614 break; 615 break;
615 case OPN_ACPT: 616 case OPN_ACPT:
616 sta->plink_state = PLINK_OPN_RCVD; 617 sta->plink_state = NL80211_PLINK_OPN_RCVD;
617 sta->plid = plid; 618 sta->plid = plid;
618 get_random_bytes(&llid, 2); 619 get_random_bytes(&llid, 2);
619 sta->llid = llid; 620 sta->llid = llid;
@@ -630,7 +631,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
630 } 631 }
631 break; 632 break;
632 633
633 case PLINK_OPN_SNT: 634 case NL80211_PLINK_OPN_SNT:
634 switch (event) { 635 switch (event) {
635 case OPN_RJCT: 636 case OPN_RJCT:
636 case CNF_RJCT: 637 case CNF_RJCT:
@@ -639,7 +640,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
639 if (!reason) 640 if (!reason)
640 reason = cpu_to_le16(MESH_CLOSE_RCVD); 641 reason = cpu_to_le16(MESH_CLOSE_RCVD);
641 sta->reason = reason; 642 sta->reason = reason;
642 sta->plink_state = PLINK_HOLDING; 643 sta->plink_state = NL80211_PLINK_HOLDING;
643 if (!mod_plink_timer(sta, 644 if (!mod_plink_timer(sta,
644 dot11MeshHoldingTimeout(sdata))) 645 dot11MeshHoldingTimeout(sdata)))
645 sta->ignore_plink_timer = true; 646 sta->ignore_plink_timer = true;
@@ -651,7 +652,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
651 break; 652 break;
652 case OPN_ACPT: 653 case OPN_ACPT:
653 /* retry timer is left untouched */ 654 /* retry timer is left untouched */
654 sta->plink_state = PLINK_OPN_RCVD; 655 sta->plink_state = NL80211_PLINK_OPN_RCVD;
655 sta->plid = plid; 656 sta->plid = plid;
656 llid = sta->llid; 657 llid = sta->llid;
657 spin_unlock_bh(&sta->lock); 658 spin_unlock_bh(&sta->lock);
@@ -659,7 +660,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
659 plid, 0); 660 plid, 0);
660 break; 661 break;
661 case CNF_ACPT: 662 case CNF_ACPT:
662 sta->plink_state = PLINK_CNF_RCVD; 663 sta->plink_state = NL80211_PLINK_CNF_RCVD;
663 if (!mod_plink_timer(sta, 664 if (!mod_plink_timer(sta,
664 dot11MeshConfirmTimeout(sdata))) 665 dot11MeshConfirmTimeout(sdata)))
665 sta->ignore_plink_timer = true; 666 sta->ignore_plink_timer = true;
@@ -672,7 +673,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
672 } 673 }
673 break; 674 break;
674 675
675 case PLINK_OPN_RCVD: 676 case NL80211_PLINK_OPN_RCVD:
676 switch (event) { 677 switch (event) {
677 case OPN_RJCT: 678 case OPN_RJCT:
678 case CNF_RJCT: 679 case CNF_RJCT:
@@ -681,7 +682,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
681 if (!reason) 682 if (!reason)
682 reason = cpu_to_le16(MESH_CLOSE_RCVD); 683 reason = cpu_to_le16(MESH_CLOSE_RCVD);
683 sta->reason = reason; 684 sta->reason = reason;
684 sta->plink_state = PLINK_HOLDING; 685 sta->plink_state = NL80211_PLINK_HOLDING;
685 if (!mod_plink_timer(sta, 686 if (!mod_plink_timer(sta,
686 dot11MeshHoldingTimeout(sdata))) 687 dot11MeshHoldingTimeout(sdata)))
687 sta->ignore_plink_timer = true; 688 sta->ignore_plink_timer = true;
@@ -699,7 +700,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
699 break; 700 break;
700 case CNF_ACPT: 701 case CNF_ACPT:
701 del_timer(&sta->plink_timer); 702 del_timer(&sta->plink_timer);
702 sta->plink_state = PLINK_ESTAB; 703 sta->plink_state = NL80211_PLINK_ESTAB;
703 spin_unlock_bh(&sta->lock); 704 spin_unlock_bh(&sta->lock);
704 mesh_plink_inc_estab_count(sdata); 705 mesh_plink_inc_estab_count(sdata);
705 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 706 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
@@ -712,7 +713,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
712 } 713 }
713 break; 714 break;
714 715
715 case PLINK_CNF_RCVD: 716 case NL80211_PLINK_CNF_RCVD:
716 switch (event) { 717 switch (event) {
717 case OPN_RJCT: 718 case OPN_RJCT:
718 case CNF_RJCT: 719 case CNF_RJCT:
@@ -721,7 +722,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
721 if (!reason) 722 if (!reason)
722 reason = cpu_to_le16(MESH_CLOSE_RCVD); 723 reason = cpu_to_le16(MESH_CLOSE_RCVD);
723 sta->reason = reason; 724 sta->reason = reason;
724 sta->plink_state = PLINK_HOLDING; 725 sta->plink_state = NL80211_PLINK_HOLDING;
725 if (!mod_plink_timer(sta, 726 if (!mod_plink_timer(sta,
726 dot11MeshHoldingTimeout(sdata))) 727 dot11MeshHoldingTimeout(sdata)))
727 sta->ignore_plink_timer = true; 728 sta->ignore_plink_timer = true;
@@ -733,7 +734,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
733 break; 734 break;
734 case OPN_ACPT: 735 case OPN_ACPT:
735 del_timer(&sta->plink_timer); 736 del_timer(&sta->plink_timer);
736 sta->plink_state = PLINK_ESTAB; 737 sta->plink_state = NL80211_PLINK_ESTAB;
737 spin_unlock_bh(&sta->lock); 738 spin_unlock_bh(&sta->lock);
738 mesh_plink_inc_estab_count(sdata); 739 mesh_plink_inc_estab_count(sdata);
739 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 740 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
@@ -748,13 +749,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
748 } 749 }
749 break; 750 break;
750 751
751 case PLINK_ESTAB: 752 case NL80211_PLINK_ESTAB:
752 switch (event) { 753 switch (event) {
753 case CLS_ACPT: 754 case CLS_ACPT:
754 reason = cpu_to_le16(MESH_CLOSE_RCVD); 755 reason = cpu_to_le16(MESH_CLOSE_RCVD);
755 sta->reason = reason; 756 sta->reason = reason;
756 deactivated = __mesh_plink_deactivate(sta); 757 deactivated = __mesh_plink_deactivate(sta);
757 sta->plink_state = PLINK_HOLDING; 758 sta->plink_state = NL80211_PLINK_HOLDING;
758 llid = sta->llid; 759 llid = sta->llid;
759 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 760 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
760 spin_unlock_bh(&sta->lock); 761 spin_unlock_bh(&sta->lock);
@@ -774,7 +775,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
774 break; 775 break;
775 } 776 }
776 break; 777 break;
777 case PLINK_HOLDING: 778 case NL80211_PLINK_HOLDING:
778 switch (event) { 779 switch (event) {
779 case CLS_ACPT: 780 case CLS_ACPT:
780 if (del_timer(&sta->plink_timer)) 781 if (del_timer(&sta->plink_timer))
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a41f234bd486..4f6b2675e41d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -750,6 +750,8 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
750 dynamic_ps_enable_work); 750 dynamic_ps_enable_work);
751 struct ieee80211_sub_if_data *sdata = local->ps_sdata; 751 struct ieee80211_sub_if_data *sdata = local->ps_sdata;
752 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 752 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
753 unsigned long flags;
754 int q;
753 755
754 /* can only happen when PS was just disabled anyway */ 756 /* can only happen when PS was just disabled anyway */
755 if (!sdata) 757 if (!sdata)
@@ -758,6 +760,24 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
758 if (local->hw.conf.flags & IEEE80211_CONF_PS) 760 if (local->hw.conf.flags & IEEE80211_CONF_PS)
759 return; 761 return;
760 762
763 /*
764 * transmission can be stopped by others which leads to
765 * dynamic_ps_timer expiry. Postpond the ps timer if it
766 * is not the actual idle state.
767 */
768 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
769 for (q = 0; q < local->hw.queues; q++) {
770 if (local->queue_stop_reasons[q]) {
771 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
772 flags);
773 mod_timer(&local->dynamic_ps_timer, jiffies +
774 msecs_to_jiffies(
775 local->hw.conf.dynamic_ps_timeout));
776 return;
777 }
778 }
779 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
780
761 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && 781 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
762 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) { 782 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) {
763 netif_tx_stop_all_queues(sdata->dev); 783 netif_tx_stop_all_queues(sdata->dev);
@@ -781,7 +801,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
781 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 801 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
782 } 802 }
783 803
784 netif_tx_start_all_queues(sdata->dev); 804 netif_tx_wake_all_queues(sdata->dev);
785} 805}
786 806
787void ieee80211_dynamic_ps_timer(unsigned long data) 807void ieee80211_dynamic_ps_timer(unsigned long data)
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 042461710880..730778a2c90c 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -6,7 +6,7 @@
6#include "driver-ops.h" 6#include "driver-ops.h"
7#include "led.h" 7#include "led.h"
8 8
9int __ieee80211_suspend(struct ieee80211_hw *hw) 9int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
10{ 10{
11 struct ieee80211_local *local = hw_to_local(hw); 11 struct ieee80211_local *local = hw_to_local(hw);
12 struct ieee80211_sub_if_data *sdata; 12 struct ieee80211_sub_if_data *sdata;
@@ -47,6 +47,16 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
47 cancel_work_sync(&local->dynamic_ps_enable_work); 47 cancel_work_sync(&local->dynamic_ps_enable_work);
48 del_timer_sync(&local->dynamic_ps_timer); 48 del_timer_sync(&local->dynamic_ps_timer);
49 49
50 local->wowlan = wowlan && local->open_count;
51 if (local->wowlan) {
52 int err = drv_suspend(local, wowlan);
53 if (err) {
54 local->quiescing = false;
55 return err;
56 }
57 goto suspend;
58 }
59
50 /* disable keys */ 60 /* disable keys */
51 list_for_each_entry(sdata, &local->interfaces, list) 61 list_for_each_entry(sdata, &local->interfaces, list)
52 ieee80211_disable_keys(sdata); 62 ieee80211_disable_keys(sdata);
@@ -104,6 +114,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
104 if (local->open_count) 114 if (local->open_count)
105 ieee80211_stop_device(local); 115 ieee80211_stop_device(local);
106 116
117 suspend:
107 local->suspended = true; 118 local->suspended = true;
108 /* need suspended to be visible before quiescing is false */ 119 /* need suspended to be visible before quiescing is false */
109 barrier(); 120 barrier();
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 778c604d7939..8adac67395f7 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -417,8 +417,8 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
417 tx_time_single = mr->ack_time + mr->perfect_tx_time; 417 tx_time_single = mr->ack_time + mr->perfect_tx_time;
418 418
419 /* contention window */ 419 /* contention window */
420 tx_time_single += t_slot + min(cw, mp->cw_max); 420 tx_time_single += (t_slot * cw) >> 1;
421 cw = (cw << 1) | 1; 421 cw = min((cw << 1) | 1, mp->cw_max);
422 422
423 tx_time += tx_time_single; 423 tx_time += tx_time_single;
424 tx_time_cts += tx_time_single + mi->sp_ack_dur; 424 tx_time_cts += tx_time_single + mi->sp_ack_dur;
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index c06aa3ac6b9d..333b5118be6d 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -464,6 +464,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
464 const struct mcs_group *group; 464 const struct mcs_group *group;
465 unsigned int tx_time, tx_time_rtscts, tx_time_data; 465 unsigned int tx_time, tx_time_rtscts, tx_time_data;
466 unsigned int cw = mp->cw_min; 466 unsigned int cw = mp->cw_min;
467 unsigned int ctime = 0;
467 unsigned int t_slot = 9; /* FIXME */ 468 unsigned int t_slot = 9; /* FIXME */
468 unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len); 469 unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len);
469 470
@@ -480,13 +481,27 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
480 481
481 group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; 482 group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
482 tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len; 483 tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len;
483 tx_time = 2 * (t_slot + mi->overhead + tx_time_data); 484
484 tx_time_rtscts = 2 * (t_slot + mi->overhead_rtscts + tx_time_data); 485 /* Contention time for first 2 tries */
486 ctime = (t_slot * cw) >> 1;
487 cw = min((cw << 1) | 1, mp->cw_max);
488 ctime += (t_slot * cw) >> 1;
489 cw = min((cw << 1) | 1, mp->cw_max);
490
491 /* Total TX time for data and Contention after first 2 tries */
492 tx_time = ctime + 2 * (mi->overhead + tx_time_data);
493 tx_time_rtscts = ctime + 2 * (mi->overhead_rtscts + tx_time_data);
494
495 /* See how many more tries we can fit inside segment size */
485 do { 496 do {
486 cw = (cw << 1) | 1; 497 /* Contention time for this try */
487 cw = min(cw, mp->cw_max); 498 ctime = (t_slot * cw) >> 1;
488 tx_time += cw + t_slot + mi->overhead; 499 cw = min((cw << 1) | 1, mp->cw_max);
489 tx_time_rtscts += cw + t_slot + mi->overhead_rtscts; 500
501 /* Total TX time after this try */
502 tx_time += ctime + mi->overhead + tx_time_data;
503 tx_time_rtscts += ctime + mi->overhead_rtscts + tx_time_data;
504
490 if (tx_time_rtscts < mp->segment_size) 505 if (tx_time_rtscts < mp->segment_size)
491 mr->retry_count_rtscts++; 506 mr->retry_count_rtscts++;
492 } while ((tx_time < mp->segment_size) && 507 } while ((tx_time < mp->segment_size) &&
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 13a6697651ad..7fa8c6be7bf0 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -404,11 +404,13 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
404 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); 404 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
405 struct sk_buff *skb = rx->skb; 405 struct sk_buff *skb = rx->skb;
406 406
407 if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN))) 407 if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN) &&
408 !local->sched_scanning))
408 return RX_CONTINUE; 409 return RX_CONTINUE;
409 410
410 if (test_bit(SCAN_HW_SCANNING, &local->scanning) || 411 if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
411 test_bit(SCAN_SW_SCANNING, &local->scanning)) 412 test_bit(SCAN_SW_SCANNING, &local->scanning) ||
413 local->sched_scanning)
412 return ieee80211_scan_rx(rx->sdata, skb); 414 return ieee80211_scan_rx(rx->sdata, skb);
413 415
414 /* scanning finished during invoking of handlers */ 416 /* scanning finished during invoking of handlers */
@@ -488,15 +490,18 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
488 * establisment frame, beacon or probe, drop the frame. 490 * establisment frame, beacon or probe, drop the frame.
489 */ 491 */
490 492
491 if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) { 493 if (!rx->sta || sta_plink_state(rx->sta) != NL80211_PLINK_ESTAB) {
492 struct ieee80211_mgmt *mgmt; 494 struct ieee80211_mgmt *mgmt;
493 495
494 if (!ieee80211_is_mgmt(hdr->frame_control)) 496 if (!ieee80211_is_mgmt(hdr->frame_control))
495 return RX_DROP_MONITOR; 497 return RX_DROP_MONITOR;
496 498
497 if (ieee80211_is_action(hdr->frame_control)) { 499 if (ieee80211_is_action(hdr->frame_control)) {
500 u8 category;
498 mgmt = (struct ieee80211_mgmt *)hdr; 501 mgmt = (struct ieee80211_mgmt *)hdr;
499 if (mgmt->u.action.category != WLAN_CATEGORY_MESH_PLINK) 502 category = mgmt->u.action.category;
503 if (category != WLAN_CATEGORY_MESH_ACTION &&
504 category != WLAN_CATEGORY_SELF_PROTECTED)
500 return RX_DROP_MONITOR; 505 return RX_DROP_MONITOR;
501 return RX_CONTINUE; 506 return RX_CONTINUE;
502 } 507 }
@@ -1778,7 +1783,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1778 1783
1779 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, 1784 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
1780 rx->sdata->vif.type, 1785 rx->sdata->vif.type,
1781 rx->local->hw.extra_tx_headroom); 1786 rx->local->hw.extra_tx_headroom, true);
1782 1787
1783 while (!skb_queue_empty(&frame_list)) { 1788 while (!skb_queue_empty(&frame_list)) {
1784 rx->skb = __skb_dequeue(&frame_list); 1789 rx->skb = __skb_dequeue(&frame_list);
@@ -2205,7 +2210,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2205 goto handled; 2210 goto handled;
2206 } 2211 }
2207 break; 2212 break;
2208 case WLAN_CATEGORY_MESH_PLINK: 2213 case WLAN_CATEGORY_MESH_ACTION:
2209 if (!ieee80211_vif_is_mesh(&sdata->vif)) 2214 if (!ieee80211_vif_is_mesh(&sdata->vif))
2210 break; 2215 break;
2211 goto queue; 2216 goto queue;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 489b6ad200d4..d20046b5d8f4 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -15,6 +15,7 @@
15#include <linux/if_arp.h> 15#include <linux/if_arp.h>
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <linux/pm_qos_params.h> 17#include <linux/pm_qos_params.h>
18#include <linux/slab.h>
18#include <net/sch_generic.h> 19#include <net/sch_generic.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20#include <net/mac80211.h> 21#include <net/mac80211.h>
@@ -170,7 +171,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
170 return RX_CONTINUE; 171 return RX_CONTINUE;
171 172
172 if (skb->len < 24) 173 if (skb->len < 24)
173 return RX_DROP_MONITOR; 174 return RX_CONTINUE;
174 175
175 presp = ieee80211_is_probe_resp(fc); 176 presp = ieee80211_is_probe_resp(fc);
176 if (presp) { 177 if (presp) {
@@ -850,3 +851,122 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
850 } 851 }
851 mutex_unlock(&local->mtx); 852 mutex_unlock(&local->mtx);
852} 853}
854
855int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
856 struct cfg80211_sched_scan_request *req)
857{
858 struct ieee80211_local *local = sdata->local;
859 int ret, i;
860
861 mutex_lock(&sdata->local->mtx);
862
863 if (local->sched_scanning) {
864 ret = -EBUSY;
865 goto out;
866 }
867
868 if (!local->ops->sched_scan_start) {
869 ret = -ENOTSUPP;
870 goto out;
871 }
872
873 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
874 local->sched_scan_ies.ie[i] = kzalloc(2 +
875 IEEE80211_MAX_SSID_LEN +
876 local->scan_ies_len,
877 GFP_KERNEL);
878 if (!local->sched_scan_ies.ie[i]) {
879 ret = -ENOMEM;
880 goto out_free;
881 }
882
883 local->sched_scan_ies.len[i] =
884 ieee80211_build_preq_ies(local,
885 local->sched_scan_ies.ie[i],
886 req->ie, req->ie_len, i,
887 (u32) -1, 0);
888 }
889
890 ret = drv_sched_scan_start(local, sdata, req,
891 &local->sched_scan_ies);
892 if (ret == 0) {
893 local->sched_scanning = true;
894 goto out;
895 }
896
897out_free:
898 while (i > 0)
899 kfree(local->sched_scan_ies.ie[--i]);
900out:
901 mutex_unlock(&sdata->local->mtx);
902 return ret;
903}
904
905int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
906{
907 struct ieee80211_local *local = sdata->local;
908 int ret = 0, i;
909
910 mutex_lock(&sdata->local->mtx);
911
912 if (!local->ops->sched_scan_stop) {
913 ret = -ENOTSUPP;
914 goto out;
915 }
916
917 if (local->sched_scanning) {
918 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
919 kfree(local->sched_scan_ies.ie[i]);
920
921 drv_sched_scan_stop(local, sdata);
922 local->sched_scanning = false;
923 }
924out:
925 mutex_unlock(&sdata->local->mtx);
926
927 return ret;
928}
929
930void ieee80211_sched_scan_results(struct ieee80211_hw *hw)
931{
932 struct ieee80211_local *local = hw_to_local(hw);
933
934 trace_api_sched_scan_results(local);
935
936 cfg80211_sched_scan_results(hw->wiphy);
937}
938EXPORT_SYMBOL(ieee80211_sched_scan_results);
939
940void ieee80211_sched_scan_stopped_work(struct work_struct *work)
941{
942 struct ieee80211_local *local =
943 container_of(work, struct ieee80211_local,
944 sched_scan_stopped_work);
945 int i;
946
947 mutex_lock(&local->mtx);
948
949 if (!local->sched_scanning) {
950 mutex_unlock(&local->mtx);
951 return;
952 }
953
954 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
955 kfree(local->sched_scan_ies.ie[i]);
956
957 local->sched_scanning = false;
958
959 mutex_unlock(&local->mtx);
960
961 cfg80211_sched_scan_stopped(local->hw.wiphy);
962}
963
964void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
965{
966 struct ieee80211_local *local = hw_to_local(hw);
967
968 trace_api_sched_scan_stopped(local);
969
970 ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work);
971}
972EXPORT_SYMBOL(ieee80211_sched_scan_stopped);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index d9e6e81ff6b2..b83870bf60fa 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -67,7 +67,8 @@ static int sta_info_hash_del(struct ieee80211_local *local,
67{ 67{
68 struct sta_info *s; 68 struct sta_info *s;
69 69
70 s = local->sta_hash[STA_HASH(sta->sta.addr)]; 70 s = rcu_dereference_protected(local->sta_hash[STA_HASH(sta->sta.addr)],
71 lockdep_is_held(&local->sta_lock));
71 if (!s) 72 if (!s)
72 return -ENOENT; 73 return -ENOENT;
73 if (s == sta) { 74 if (s == sta) {
@@ -76,9 +77,11 @@ static int sta_info_hash_del(struct ieee80211_local *local,
76 return 0; 77 return 0;
77 } 78 }
78 79
79 while (s->hnext && s->hnext != sta) 80 while (rcu_access_pointer(s->hnext) &&
80 s = s->hnext; 81 rcu_access_pointer(s->hnext) != sta)
81 if (s->hnext) { 82 s = rcu_dereference_protected(s->hnext,
83 lockdep_is_held(&local->sta_lock));
84 if (rcu_access_pointer(s->hnext)) {
82 rcu_assign_pointer(s->hnext, sta->hnext); 85 rcu_assign_pointer(s->hnext, sta->hnext);
83 return 0; 86 return 0;
84 } 87 }
@@ -274,7 +277,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
274#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 277#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
275 278
276#ifdef CONFIG_MAC80211_MESH 279#ifdef CONFIG_MAC80211_MESH
277 sta->plink_state = PLINK_LISTEN; 280 sta->plink_state = NL80211_PLINK_LISTEN;
278 init_timer(&sta->plink_timer); 281 init_timer(&sta->plink_timer);
279#endif 282#endif
280 283
@@ -652,10 +655,12 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
652 if (ret) 655 if (ret)
653 return ret; 656 return ret;
654 657
658 mutex_lock(&local->key_mtx);
655 for (i = 0; i < NUM_DEFAULT_KEYS; i++) 659 for (i = 0; i < NUM_DEFAULT_KEYS; i++)
656 ieee80211_key_free(local, sta->gtk[i]); 660 __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]));
657 if (sta->ptk) 661 if (sta->ptk)
658 ieee80211_key_free(local, sta->ptk); 662 __ieee80211_key_free(key_mtx_dereference(local, sta->ptk));
663 mutex_unlock(&local->key_mtx);
659 664
660 sta->dead = true; 665 sta->dead = true;
661 666
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index aa0adcbf3a93..c6ae8718bd57 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -152,6 +152,7 @@ struct tid_ampdu_rx {
152 * 152 *
153 * @tid_rx: aggregation info for Rx per TID -- RCU protected 153 * @tid_rx: aggregation info for Rx per TID -- RCU protected
154 * @tid_tx: aggregation info for Tx per TID 154 * @tid_tx: aggregation info for Tx per TID
155 * @tid_start_tx: sessions where start was requested
155 * @addba_req_num: number of times addBA request has been sent. 156 * @addba_req_num: number of times addBA request has been sent.
156 * @dialog_token_allocator: dialog token enumerator for each new session; 157 * @dialog_token_allocator: dialog token enumerator for each new session;
157 * @work: work struct for starting/stopping aggregation 158 * @work: work struct for starting/stopping aggregation
@@ -163,40 +164,18 @@ struct tid_ampdu_rx {
163struct sta_ampdu_mlme { 164struct sta_ampdu_mlme {
164 struct mutex mtx; 165 struct mutex mtx;
165 /* rx */ 166 /* rx */
166 struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; 167 struct tid_ampdu_rx __rcu *tid_rx[STA_TID_NUM];
167 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)]; 168 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)];
168 /* tx */ 169 /* tx */
169 struct work_struct work; 170 struct work_struct work;
170 struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; 171 struct tid_ampdu_tx __rcu *tid_tx[STA_TID_NUM];
172 struct tid_ampdu_tx *tid_start_tx[STA_TID_NUM];
171 u8 addba_req_num[STA_TID_NUM]; 173 u8 addba_req_num[STA_TID_NUM];
172 u8 dialog_token_allocator; 174 u8 dialog_token_allocator;
173}; 175};
174 176
175 177
176/** 178/**
177 * enum plink_state - state of a mesh peer link finite state machine
178 *
179 * @PLINK_LISTEN: initial state, considered the implicit state of non existent
180 * mesh peer links
181 * @PLINK_OPN_SNT: mesh plink open frame has been sent to this mesh peer
182 * @PLINK_OPN_RCVD: mesh plink open frame has been received from this mesh peer
183 * @PLINK_CNF_RCVD: mesh plink confirm frame has been received from this mesh
184 * peer
185 * @PLINK_ESTAB: mesh peer link is established
186 * @PLINK_HOLDING: mesh peer link is being closed or cancelled
187 * @PLINK_BLOCKED: all frames transmitted from this mesh plink are discarded
188 */
189enum plink_state {
190 PLINK_LISTEN,
191 PLINK_OPN_SNT,
192 PLINK_OPN_RCVD,
193 PLINK_CNF_RCVD,
194 PLINK_ESTAB,
195 PLINK_HOLDING,
196 PLINK_BLOCKED
197};
198
199/**
200 * struct sta_info - STA information 179 * struct sta_info - STA information
201 * 180 *
202 * This structure collects information about a station that 181 * This structure collects information about a station that
@@ -264,11 +243,11 @@ enum plink_state {
264struct sta_info { 243struct sta_info {
265 /* General information, mostly static */ 244 /* General information, mostly static */
266 struct list_head list; 245 struct list_head list;
267 struct sta_info *hnext; 246 struct sta_info __rcu *hnext;
268 struct ieee80211_local *local; 247 struct ieee80211_local *local;
269 struct ieee80211_sub_if_data *sdata; 248 struct ieee80211_sub_if_data *sdata;
270 struct ieee80211_key *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 249 struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
271 struct ieee80211_key *ptk; 250 struct ieee80211_key __rcu *ptk;
272 struct rate_control_ref *rate_ctrl; 251 struct rate_control_ref *rate_ctrl;
273 void *rate_ctrl_priv; 252 void *rate_ctrl_priv;
274 spinlock_t lock; 253 spinlock_t lock;
@@ -339,7 +318,7 @@ struct sta_info {
339 u8 plink_retries; 318 u8 plink_retries;
340 bool ignore_plink_timer; 319 bool ignore_plink_timer;
341 bool plink_timer_was_running; 320 bool plink_timer_was_running;
342 enum plink_state plink_state; 321 enum nl80211_plink_state plink_state;
343 u32 plink_timeout; 322 u32 plink_timeout;
344 struct timer_list plink_timer; 323 struct timer_list plink_timer;
345#endif 324#endif
@@ -357,12 +336,12 @@ struct sta_info {
357 struct ieee80211_sta sta; 336 struct ieee80211_sta sta;
358}; 337};
359 338
360static inline enum plink_state sta_plink_state(struct sta_info *sta) 339static inline enum nl80211_plink_state sta_plink_state(struct sta_info *sta)
361{ 340{
362#ifdef CONFIG_MAC80211_MESH 341#ifdef CONFIG_MAC80211_MESH
363 return sta->plink_state; 342 return sta->plink_state;
364#endif 343#endif
365 return PLINK_LISTEN; 344 return NL80211_PLINK_LISTEN;
366} 345}
367 346
368static inline void set_sta_flags(struct sta_info *sta, const u32 flags) 347static inline void set_sta_flags(struct sta_info *sta, const u32 flags)
@@ -421,7 +400,16 @@ static inline u32 get_sta_flags(struct sta_info *sta)
421 return ret; 400 return ret;
422} 401}
423 402
403void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
404 struct tid_ampdu_tx *tid_tx);
424 405
406static inline struct tid_ampdu_tx *
407rcu_dereference_protected_tid_tx(struct sta_info *sta, int tid)
408{
409 return rcu_dereference_protected(sta->ampdu_mlme.tid_tx[tid],
410 lockdep_is_held(&sta->lock) ||
411 lockdep_is_held(&sta->ampdu_mlme.mtx));
412}
425 413
426#define STA_HASH_SIZE 256 414#define STA_HASH_SIZE 256
427#define STA_HASH(sta) (sta[5]) 415#define STA_HASH(sta) (sta[5])
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e3e3aa173af0..6eeaaa2bbafe 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1147,7 +1147,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
1147 * packet pass through because splicing the frames 1147 * packet pass through because splicing the frames
1148 * back is already done. 1148 * back is already done.
1149 */ 1149 */
1150 tid_tx = tx->sta->ampdu_mlme.tid_tx[tid]; 1150 tid_tx = rcu_dereference_protected_tid_tx(tx->sta, tid);
1151 1151
1152 if (!tid_tx) { 1152 if (!tid_tx) {
1153 /* do nothing, let packet pass through */ 1153 /* do nothing, let packet pass through */
@@ -1751,6 +1751,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1751 ret = NETDEV_TX_OK; 1751 ret = NETDEV_TX_OK;
1752 goto fail; 1752 goto fail;
1753 } 1753 }
1754 rcu_read_lock();
1754 if (!is_multicast_ether_addr(skb->data)) 1755 if (!is_multicast_ether_addr(skb->data))
1755 mppath = mpp_path_lookup(skb->data, sdata); 1756 mppath = mpp_path_lookup(skb->data, sdata);
1756 1757
@@ -1765,13 +1766,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1765 !(mppath && compare_ether_addr(mppath->mpp, skb->data))) { 1766 !(mppath && compare_ether_addr(mppath->mpp, skb->data))) {
1766 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, 1767 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
1767 skb->data, skb->data + ETH_ALEN); 1768 skb->data, skb->data + ETH_ALEN);
1769 rcu_read_unlock();
1768 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, 1770 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
1769 sdata, NULL, NULL); 1771 sdata, NULL, NULL);
1770 } else { 1772 } else {
1771 int is_mesh_mcast = 1; 1773 int is_mesh_mcast = 1;
1772 const u8 *mesh_da; 1774 const u8 *mesh_da;
1773 1775
1774 rcu_read_lock();
1775 if (is_multicast_ether_addr(skb->data)) 1776 if (is_multicast_ether_addr(skb->data))
1776 /* DA TA mSA AE:SA */ 1777 /* DA TA mSA AE:SA */
1777 mesh_da = skb->data; 1778 mesh_da = skb->data;
@@ -2534,8 +2535,9 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
2534 skb_set_network_header(skb, 0); 2535 skb_set_network_header(skb, 0);
2535 skb_set_transport_header(skb, 0); 2536 skb_set_transport_header(skb, 0);
2536 2537
2537 /* send all internal mgmt frames on VO */ 2538 /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */
2538 skb_set_queue_mapping(skb, 0); 2539 skb_set_queue_mapping(skb, IEEE80211_AC_VO);
2540 skb->priority = 7;
2539 2541
2540 /* 2542 /*
2541 * The other path calling ieee80211_xmit is from the tasklet, 2543 * The other path calling ieee80211_xmit is from the tasklet,
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ef0560a2346a..d3fe2d237485 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1125,9 +1125,27 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1125 struct sta_info *sta; 1125 struct sta_info *sta;
1126 int res; 1126 int res;
1127 1127
1128#ifdef CONFIG_PM
1128 if (local->suspended) 1129 if (local->suspended)
1129 local->resuming = true; 1130 local->resuming = true;
1130 1131
1132 if (local->wowlan) {
1133 local->wowlan = false;
1134 res = drv_resume(local);
1135 if (res < 0) {
1136 local->resuming = false;
1137 return res;
1138 }
1139 if (res == 0)
1140 goto wake_up;
1141 WARN_ON(res > 1);
1142 /*
1143 * res is 1, which means the driver requested
1144 * to go through a regular reset on wakeup.
1145 */
1146 }
1147#endif
1148
1131 /* restart hardware */ 1149 /* restart hardware */
1132 if (local->open_count) { 1150 if (local->open_count) {
1133 /* 1151 /*
@@ -1258,6 +1276,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1258 if (ieee80211_sdata_running(sdata)) 1276 if (ieee80211_sdata_running(sdata))
1259 ieee80211_enable_keys(sdata); 1277 ieee80211_enable_keys(sdata);
1260 1278
1279 wake_up:
1261 ieee80211_wake_queues_by_reason(hw, 1280 ieee80211_wake_queues_by_reason(hw,
1262 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 1281 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
1263 1282