aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-12-03 15:56:22 -0500
committerDavid S. Miller <davem@davemloft.net>2015-12-03 15:56:22 -0500
commite3c9b1ef78eb111f925dd04992a3de1f383e8f49 (patch)
tree9370880eb39c25c86eb3a44ea6aa0b0f56f3eb8f /net
parentcf18b7788fe1bf99e9c2ab580b065bf2d3cb1a34 (diff)
parentc1df932c0574c13ab3ce72e969c9647ff3aaad68 (diff)
Merge tag 'mac80211-for-davem-2015-12-02' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says: ==================== A small set of fixes for 4.4: * fix scanning in mac80211 to not actively scan radar channels (from Antonio) * fix uninitialized variable in remain-on-channel that could lead to treating frame TX as remain-on-channel and not sending the frame at all * remove NL80211_FEATURE_FULL_AP_CLIENT_STATE again, it was broken and needs more work, we'll enable it later * fix call_rcu() induced use-after-reset/free in mesh (that was suddenly causing issues in certain tests) * always request block-ack window size 64 as we found some APs will otherwise crash (really ...) * fix P2P-Device teardown sequence to avoid restarting with uninitialized data ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/agg-tx.c3
-rw-r--r--net/mac80211/cfg.c8
-rw-r--r--net/mac80211/iface.c5
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh_pathtbl.c8
-rw-r--r--net/mac80211/scan.c9
6 files changed, 21 insertions, 15 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index a758eb84e8f0..ff757181b0a8 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -500,7 +500,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
500 /* send AddBA request */ 500 /* send AddBA request */
501 ieee80211_send_addba_request(sdata, sta->sta.addr, tid, 501 ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
502 tid_tx->dialog_token, start_seq_num, 502 tid_tx->dialog_token, start_seq_num,
503 local->hw.max_tx_aggregation_subframes, 503 IEEE80211_MAX_AMPDU_BUF,
504 tid_tx->timeout); 504 tid_tx->timeout);
505} 505}
506 506
@@ -926,6 +926,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
926 amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK; 926 amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK;
927 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 927 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
928 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6; 928 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
929 buf_size = min(buf_size, local->hw.max_tx_aggregation_subframes);
929 930
930 mutex_lock(&sta->ampdu_mlme.mtx); 931 mutex_lock(&sta->ampdu_mlme.mtx);
931 932
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c2bd1b6a6922..da471eef07bb 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3454,8 +3454,12 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3454 goto out_unlock; 3454 goto out_unlock;
3455 } 3455 }
3456 } else { 3456 } else {
3457 /* for cookie below */ 3457 /* Assign a dummy non-zero cookie, it's not sent to
3458 ack_skb = skb; 3458 * userspace in this case but we rely on its value
3459 * internally in the need_offchan case to distinguish
3460 * mgmt-tx from remain-on-channel.
3461 */
3462 *cookie = 0xffffffff;
3459 } 3463 }
3460 3464
3461 if (!need_offchan) { 3465 if (!need_offchan) {
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index d0dc1bfaeec2..c9e325d2e120 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -76,7 +76,8 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
76void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata, 76void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
77 bool update_bss) 77 bool update_bss)
78{ 78{
79 if (__ieee80211_recalc_txpower(sdata) || update_bss) 79 if (__ieee80211_recalc_txpower(sdata) ||
80 (update_bss && ieee80211_sdata_running(sdata)))
80 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); 81 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
81} 82}
82 83
@@ -1861,6 +1862,7 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata)
1861 unregister_netdevice(sdata->dev); 1862 unregister_netdevice(sdata->dev);
1862 } else { 1863 } else {
1863 cfg80211_unregister_wdev(&sdata->wdev); 1864 cfg80211_unregister_wdev(&sdata->wdev);
1865 ieee80211_teardown_sdata(sdata);
1864 kfree(sdata); 1866 kfree(sdata);
1865 } 1867 }
1866} 1868}
@@ -1870,7 +1872,6 @@ void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata)
1870 if (WARN_ON_ONCE(!test_bit(SDATA_STATE_RUNNING, &sdata->state))) 1872 if (WARN_ON_ONCE(!test_bit(SDATA_STATE_RUNNING, &sdata->state)))
1871 return; 1873 return;
1872 ieee80211_do_stop(sdata, true); 1874 ieee80211_do_stop(sdata, true);
1873 ieee80211_teardown_sdata(sdata);
1874} 1875}
1875 1876
1876void ieee80211_remove_interfaces(struct ieee80211_local *local) 1877void ieee80211_remove_interfaces(struct ieee80211_local *local)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 858f6b1cb149..175ffcf7fb06 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -541,8 +541,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
541 NL80211_FEATURE_HT_IBSS | 541 NL80211_FEATURE_HT_IBSS |
542 NL80211_FEATURE_VIF_TXPOWER | 542 NL80211_FEATURE_VIF_TXPOWER |
543 NL80211_FEATURE_MAC_ON_CREATE | 543 NL80211_FEATURE_MAC_ON_CREATE |
544 NL80211_FEATURE_USERSPACE_MPM | 544 NL80211_FEATURE_USERSPACE_MPM;
545 NL80211_FEATURE_FULL_AP_CLIENT_STATE;
546 545
547 if (!ops->hw_scan) 546 if (!ops->hw_scan)
548 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | 547 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index b890e225a8f1..b3b44a5dd375 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -779,10 +779,8 @@ void mesh_plink_broken(struct sta_info *sta)
779static void mesh_path_node_reclaim(struct rcu_head *rp) 779static void mesh_path_node_reclaim(struct rcu_head *rp)
780{ 780{
781 struct mpath_node *node = container_of(rp, struct mpath_node, rcu); 781 struct mpath_node *node = container_of(rp, struct mpath_node, rcu);
782 struct ieee80211_sub_if_data *sdata = node->mpath->sdata;
783 782
784 del_timer_sync(&node->mpath->timer); 783 del_timer_sync(&node->mpath->timer);
785 atomic_dec(&sdata->u.mesh.mpaths);
786 kfree(node->mpath); 784 kfree(node->mpath);
787 kfree(node); 785 kfree(node);
788} 786}
@@ -790,8 +788,9 @@ static void mesh_path_node_reclaim(struct rcu_head *rp)
790/* needs to be called with the corresponding hashwlock taken */ 788/* needs to be called with the corresponding hashwlock taken */
791static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node) 789static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node)
792{ 790{
793 struct mesh_path *mpath; 791 struct mesh_path *mpath = node->mpath;
794 mpath = node->mpath; 792 struct ieee80211_sub_if_data *sdata = node->mpath->sdata;
793
795 spin_lock(&mpath->state_lock); 794 spin_lock(&mpath->state_lock);
796 mpath->flags |= MESH_PATH_RESOLVING; 795 mpath->flags |= MESH_PATH_RESOLVING;
797 if (mpath->is_gate) 796 if (mpath->is_gate)
@@ -799,6 +798,7 @@ static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node)
799 hlist_del_rcu(&node->list); 798 hlist_del_rcu(&node->list);
800 call_rcu(&node->rcu, mesh_path_node_reclaim); 799 call_rcu(&node->rcu, mesh_path_node_reclaim);
801 spin_unlock(&mpath->state_lock); 800 spin_unlock(&mpath->state_lock);
801 atomic_dec(&sdata->u.mesh.mpaths);
802 atomic_dec(&tbl->entries); 802 atomic_dec(&tbl->entries);
803} 803}
804 804
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 4aeca4b0c3cb..a413e52f7691 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -597,8 +597,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
597 /* We need to ensure power level is at max for scanning. */ 597 /* We need to ensure power level is at max for scanning. */
598 ieee80211_hw_config(local, 0); 598 ieee80211_hw_config(local, 0);
599 599
600 if ((req->channels[0]->flags & 600 if ((req->channels[0]->flags & (IEEE80211_CHAN_NO_IR |
601 IEEE80211_CHAN_NO_IR) || 601 IEEE80211_CHAN_RADAR)) ||
602 !req->n_ssids) { 602 !req->n_ssids) {
603 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; 603 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
604 } else { 604 } else {
@@ -645,7 +645,7 @@ ieee80211_scan_get_channel_time(struct ieee80211_channel *chan)
645 * TODO: channel switching also consumes quite some time, 645 * TODO: channel switching also consumes quite some time,
646 * add that delay as well to get a better estimation 646 * add that delay as well to get a better estimation
647 */ 647 */
648 if (chan->flags & IEEE80211_CHAN_NO_IR) 648 if (chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR))
649 return IEEE80211_PASSIVE_CHANNEL_TIME; 649 return IEEE80211_PASSIVE_CHANNEL_TIME;
650 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; 650 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME;
651} 651}
@@ -777,7 +777,8 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
777 * 777 *
778 * In any case, it is not necessary for a passive scan. 778 * In any case, it is not necessary for a passive scan.
779 */ 779 */
780 if (chan->flags & IEEE80211_CHAN_NO_IR || !scan_req->n_ssids) { 780 if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR)) ||
781 !scan_req->n_ssids) {
781 *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; 782 *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
782 local->next_scan_state = SCAN_DECISION; 783 local->next_scan_state = SCAN_DECISION;
783 return; 784 return;