aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-04-26 15:03:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-26 15:03:48 -0400
commitd9b8ae6bd8c3304569a25079fcdbebaa28a48ee4 (patch)
tree9ce3e4eb355685f970dd7333a0a935109aff0583 /net/mac80211
parent872f24dbc604ef585ea7eec73020dcdfaffd1956 (diff)
parent94c514fe240fc0dd02187b78facefde8b6744634 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/iwlwifi/iwl-testmode.c
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c19
-rw-r--r--net/mac80211/debugfs_netdev.c4
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/iface.c19
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/mac80211/mesh.c19
-rw-r--r--net/mac80211/mesh.h14
-rw-r--r--net/mac80211/mesh_plink.c138
-rw-r--r--net/mac80211/mesh_sync.c2
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/scan.c95
-rw-r--r--net/mac80211/sta_info.c12
-rw-r--r--net/mac80211/tx.c2
-rw-r--r--net/mac80211/util.c9
14 files changed, 226 insertions, 118 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 510a745c310..70b2af2315a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1005,6 +1005,9 @@ static int ieee80211_change_station(struct wiphy *wiphy,
1005 } 1005 }
1006 1006
1007 if (params->vlan && params->vlan != sta->sdata->dev) { 1007 if (params->vlan && params->vlan != sta->sdata->dev) {
1008 bool prev_4addr = false;
1009 bool new_4addr = false;
1010
1008 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 1011 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
1009 1012
1010 if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN && 1013 if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
@@ -1020,9 +1023,25 @@ static int ieee80211_change_station(struct wiphy *wiphy,
1020 } 1023 }
1021 1024
1022 rcu_assign_pointer(vlansdata->u.vlan.sta, sta); 1025 rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
1026 new_4addr = true;
1027 }
1028
1029 if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
1030 sta->sdata->u.vlan.sta) {
1031 rcu_assign_pointer(sta->sdata->u.vlan.sta, NULL);
1032 prev_4addr = true;
1023 } 1033 }
1024 1034
1025 sta->sdata = vlansdata; 1035 sta->sdata = vlansdata;
1036
1037 if (sta->sta_state == IEEE80211_STA_AUTHORIZED &&
1038 prev_4addr != new_4addr) {
1039 if (new_4addr)
1040 atomic_dec(&sta->sdata->bss->num_mcast_sta);
1041 else
1042 atomic_inc(&sta->sdata->bss->num_mcast_sta);
1043 }
1044
1026 ieee80211_send_layer2_update(sta); 1045 ieee80211_send_layer2_update(sta);
1027 } 1046 }
1028 1047
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index e7af5227e32..ea0122dbd2b 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -394,7 +394,7 @@ static ssize_t ieee80211_if_parse_uapsd_max_sp_len(
394__IEEE80211_IF_FILE_W(uapsd_max_sp_len); 394__IEEE80211_IF_FILE_W(uapsd_max_sp_len);
395 395
396/* AP attributes */ 396/* AP attributes */
397IEEE80211_IF_FILE(num_sta_authorized, u.ap.num_sta_authorized, ATOMIC); 397IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC);
398IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); 398IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
399IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); 399IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC);
400 400
@@ -540,7 +540,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
540 540
541static void add_ap_files(struct ieee80211_sub_if_data *sdata) 541static void add_ap_files(struct ieee80211_sub_if_data *sdata)
542{ 542{
543 DEBUGFS_ADD(num_sta_authorized); 543 DEBUGFS_ADD(num_mcast_sta);
544 DEBUGFS_ADD(num_sta_ps); 544 DEBUGFS_ADD(num_sta_ps);
545 DEBUGFS_ADD(dtim_count); 545 DEBUGFS_ADD(dtim_count);
546 DEBUGFS_ADD(num_buffered_multicast); 546 DEBUGFS_ADD(num_buffered_multicast);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index bd7a451b084..851fb7dc893 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -282,7 +282,7 @@ struct ieee80211_if_ap {
282 u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; 282 u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)];
283 struct sk_buff_head ps_bc_buf; 283 struct sk_buff_head ps_bc_buf;
284 atomic_t num_sta_ps; /* number of stations in PS mode */ 284 atomic_t num_sta_ps; /* number of stations in PS mode */
285 atomic_t num_sta_authorized; /* number of authorized stations */ 285 atomic_t num_mcast_sta; /* number of stations receiving multicast */
286 int dtim_count; 286 int dtim_count;
287 bool dtim_bc_mc; 287 bool dtim_bc_mc;
288}; 288};
@@ -803,6 +803,8 @@ struct tpt_led_trigger {
803 * well be on the operating channel 803 * well be on the operating channel
804 * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to 804 * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to
805 * determine if we are on the operating channel or not 805 * determine if we are on the operating channel or not
806 * @SCAN_ONCHANNEL_SCANNING: Do a software scan on only the current operating
807 * channel. This should not interrupt normal traffic.
806 * @SCAN_COMPLETED: Set for our scan work function when the driver reported 808 * @SCAN_COMPLETED: Set for our scan work function when the driver reported
807 * that the scan completed. 809 * that the scan completed.
808 * @SCAN_ABORTED: Set for our scan work function when the driver reported 810 * @SCAN_ABORTED: Set for our scan work function when the driver reported
@@ -811,6 +813,7 @@ struct tpt_led_trigger {
811enum { 813enum {
812 SCAN_SW_SCANNING, 814 SCAN_SW_SCANNING,
813 SCAN_HW_SCANNING, 815 SCAN_HW_SCANNING,
816 SCAN_ONCHANNEL_SCANNING,
814 SCAN_COMPLETED, 817 SCAN_COMPLETED,
815 SCAN_ABORTED, 818 SCAN_ABORTED,
816}; 819};
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 23d1da376eb..ba86978dd56 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1031,6 +1031,18 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1031 ieee80211_debugfs_add_netdev(sdata); 1031 ieee80211_debugfs_add_netdev(sdata);
1032} 1032}
1033 1033
1034static void ieee80211_clean_sdata(struct ieee80211_sub_if_data *sdata)
1035{
1036 switch (sdata->vif.type) {
1037 case NL80211_IFTYPE_MESH_POINT:
1038 mesh_path_flush_by_iface(sdata);
1039 break;
1040
1041 default:
1042 break;
1043 }
1044}
1045
1034static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, 1046static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
1035 enum nl80211_iftype type) 1047 enum nl80211_iftype type)
1036{ 1048{
@@ -1364,8 +1376,8 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata)
1364 list_del_rcu(&sdata->list); 1376 list_del_rcu(&sdata->list);
1365 mutex_unlock(&sdata->local->iflist_mtx); 1377 mutex_unlock(&sdata->local->iflist_mtx);
1366 1378
1367 if (ieee80211_vif_is_mesh(&sdata->vif)) 1379 /* clean up type-dependent data */
1368 mesh_path_flush_by_iface(sdata); 1380 ieee80211_clean_sdata(sdata);
1369 1381
1370 synchronize_rcu(); 1382 synchronize_rcu();
1371 unregister_netdevice(sdata->dev); 1383 unregister_netdevice(sdata->dev);
@@ -1386,8 +1398,7 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
1386 list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { 1398 list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
1387 list_del(&sdata->list); 1399 list_del(&sdata->list);
1388 1400
1389 if (ieee80211_vif_is_mesh(&sdata->vif)) 1401 ieee80211_clean_sdata(sdata);
1390 mesh_path_flush_by_iface(sdata);
1391 1402
1392 unregister_netdevice_queue(sdata->dev, &unreg_list); 1403 unregister_netdevice_queue(sdata->dev, &unreg_list);
1393 } 1404 }
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index ac79d5e8e0d..b70f7f09da6 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -47,7 +47,8 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
47 if (atomic_read(&local->iff_allmultis)) 47 if (atomic_read(&local->iff_allmultis))
48 new_flags |= FIF_ALLMULTI; 48 new_flags |= FIF_ALLMULTI;
49 49
50 if (local->monitors || test_bit(SCAN_SW_SCANNING, &local->scanning)) 50 if (local->monitors || test_bit(SCAN_SW_SCANNING, &local->scanning) ||
51 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning))
51 new_flags |= FIF_BCN_PRBRESP_PROMISC; 52 new_flags |= FIF_BCN_PRBRESP_PROMISC;
52 53
53 if (local->fif_probe_req || local->probe_req_reg) 54 if (local->fif_probe_req || local->probe_req_reg)
@@ -148,6 +149,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
148 } 149 }
149 150
150 if (test_bit(SCAN_SW_SCANNING, &local->scanning) || 151 if (test_bit(SCAN_SW_SCANNING, &local->scanning) ||
152 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
151 test_bit(SCAN_HW_SCANNING, &local->scanning)) 153 test_bit(SCAN_HW_SCANNING, &local->scanning))
152 power = chan->max_power; 154 power = chan->max_power;
153 else 155 else
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 133c118526f..598a96a3a05 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -64,18 +64,18 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data)
64/** 64/**
65 * mesh_matches_local - check if the config of a mesh point matches ours 65 * mesh_matches_local - check if the config of a mesh point matches ours
66 * 66 *
67 * @ie: information elements of a management frame from the mesh peer
68 * @sdata: local mesh subif 67 * @sdata: local mesh subif
69 * @basic_rates: BSSBasicRateSet of the peer candidate 68 * @ie: information elements of a management frame from the mesh peer
70 * 69 *
71 * This function checks if the mesh configuration of a mesh point matches the 70 * This function checks if the mesh configuration of a mesh point matches the
72 * local mesh configuration, i.e. if both nodes belong to the same mesh network. 71 * local mesh configuration, i.e. if both nodes belong to the same mesh network.
73 */ 72 */
74bool mesh_matches_local(struct ieee802_11_elems *ie, 73bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
75 struct ieee80211_sub_if_data *sdata, u32 basic_rates) 74 struct ieee802_11_elems *ie)
76{ 75{
77 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 76 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
78 struct ieee80211_local *local = sdata->local; 77 struct ieee80211_local *local = sdata->local;
78 u32 basic_rates = 0;
79 79
80 /* 80 /*
81 * As support for each feature is added, check for matching 81 * As support for each feature is added, check for matching
@@ -96,6 +96,9 @@ bool mesh_matches_local(struct ieee802_11_elems *ie,
96 (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth))) 96 (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)))
97 goto mismatch; 97 goto mismatch;
98 98
99 ieee80211_sta_get_rates(local, ie, local->oper_channel->band,
100 &basic_rates);
101
99 if (sdata->vif.bss_conf.basic_rates != basic_rates) 102 if (sdata->vif.bss_conf.basic_rates != basic_rates)
100 goto mismatch; 103 goto mismatch;
101 104
@@ -630,7 +633,6 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
630 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 633 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
631 struct ieee802_11_elems elems; 634 struct ieee802_11_elems elems;
632 struct ieee80211_channel *channel; 635 struct ieee80211_channel *channel;
633 u32 supp_rates = 0, basic_rates = 0;
634 size_t baselen; 636 size_t baselen;
635 int freq; 637 int freq;
636 enum ieee80211_band band = rx_status->band; 638 enum ieee80211_band band = rx_status->band;
@@ -661,12 +663,9 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
661 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) 663 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
662 return; 664 return;
663 665
664 supp_rates = ieee80211_sta_get_rates(local, &elems,
665 band, &basic_rates);
666
667 if (elems.mesh_id && elems.mesh_config && 666 if (elems.mesh_id && elems.mesh_config &&
668 mesh_matches_local(&elems, sdata, basic_rates)) 667 mesh_matches_local(sdata, &elems))
669 mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems); 668 mesh_neighbour_update(sdata, mgmt->sa, &elems);
670 669
671 if (ifmsh->sync_ops) 670 if (ifmsh->sync_ops)
672 ifmsh->sync_ops->rx_bcn_presp(sdata, 671 ifmsh->sync_ops->rx_bcn_presp(sdata,
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 4ad73898880..e3642756f8f 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -222,8 +222,8 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
222 char *addr6); 222 char *addr6);
223int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr, 223int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
224 struct ieee80211_sub_if_data *sdata); 224 struct ieee80211_sub_if_data *sdata);
225bool mesh_matches_local(struct ieee802_11_elems *ie, 225bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
226 struct ieee80211_sub_if_data *sdata, u32 basic_rates); 226 struct ieee802_11_elems *ie);
227void mesh_ids_set_default(struct ieee80211_if_mesh *mesh); 227void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
228void mesh_mgmt_ies_add(struct sk_buff *skb, 228void mesh_mgmt_ies_add(struct sk_buff *skb,
229 struct ieee80211_sub_if_data *sdata); 229 struct ieee80211_sub_if_data *sdata);
@@ -276,9 +276,9 @@ int mesh_path_add_gate(struct mesh_path *mpath);
276int mesh_path_send_to_gates(struct mesh_path *mpath); 276int mesh_path_send_to_gates(struct mesh_path *mpath);
277int mesh_gate_num(struct ieee80211_sub_if_data *sdata); 277int mesh_gate_num(struct ieee80211_sub_if_data *sdata);
278/* Mesh plinks */ 278/* Mesh plinks */
279void mesh_neighbour_update(u8 *hw_addr, u32 rates, 279void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
280 struct ieee80211_sub_if_data *sdata, 280 u8 *hw_addr,
281 struct ieee802_11_elems *ie); 281 struct ieee802_11_elems *ie);
282bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 282bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
283void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 283void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
284void mesh_plink_broken(struct sta_info *sta); 284void mesh_plink_broken(struct sta_info *sta);
@@ -304,7 +304,6 @@ void mesh_pathtbl_unregister(void);
304int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata); 304int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata);
305void mesh_path_timer(unsigned long data); 305void mesh_path_timer(unsigned long data);
306void mesh_path_flush_by_nexthop(struct sta_info *sta); 306void mesh_path_flush_by_nexthop(struct sta_info *sta);
307void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
308void mesh_path_discard_frame(struct sk_buff *skb, 307void mesh_path_discard_frame(struct sk_buff *skb,
309 struct ieee80211_sub_if_data *sdata); 308 struct ieee80211_sub_if_data *sdata);
310void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata); 309void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
@@ -345,6 +344,7 @@ void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata);
345void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata); 344void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata);
346void mesh_plink_quiesce(struct sta_info *sta); 345void mesh_plink_quiesce(struct sta_info *sta);
347void mesh_plink_restart(struct sta_info *sta); 346void mesh_plink_restart(struct sta_info *sta);
347void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
348void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata); 348void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
349#else 349#else
350#define mesh_allocated 0 350#define mesh_allocated 0
@@ -358,6 +358,8 @@ static inline void mesh_plink_quiesce(struct sta_info *sta) {}
358static inline void mesh_plink_restart(struct sta_info *sta) {} 358static inline void mesh_plink_restart(struct sta_info *sta) {}
359static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata) 359static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
360{ return false; } 360{ return false; }
361static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
362{}
361#endif 363#endif
362 364
363#endif /* IEEE80211S_H */ 365#endif /* IEEE80211S_H */
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 9c836e774fb..1ff2a5c63e4 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -82,20 +82,14 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta)
82} 82}
83 83
84/* 84/*
85 * NOTE: This is just an alias for sta_info_alloc(), see notes 85 * Allocate mesh sta entry and insert into station table
86 * on it in the lifecycle management section!
87 */ 86 */
88static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, 87static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
89 u8 *hw_addr, u32 rates, 88 u8 *hw_addr)
90 struct ieee802_11_elems *elems)
91{ 89{
92 struct ieee80211_local *local = sdata->local;
93 struct ieee80211_supported_band *sband;
94 struct sta_info *sta; 90 struct sta_info *sta;
95 91
96 sband = local->hw.wiphy->bands[local->oper_channel->band]; 92 if (sdata->local->num_sta >= MESH_MAX_PLINKS)
97
98 if (local->num_sta >= MESH_MAX_PLINKS)
99 return NULL; 93 return NULL;
100 94
101 sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL); 95 sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL);
@@ -108,12 +102,8 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
108 102
109 set_sta_flag(sta, WLAN_STA_WME); 103 set_sta_flag(sta, WLAN_STA_WME);
110 104
111 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 105 if (sta_info_insert(sta))
112 if (elems->ht_cap_elem) 106 return NULL;
113 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
114 elems->ht_cap_elem,
115 &sta->sta.ht_cap);
116 rate_control_rate_init(sta);
117 107
118 return sta; 108 return sta;
119} 109}
@@ -274,43 +264,79 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
274 return 0; 264 return 0;
275} 265}
276 266
277void mesh_neighbour_update(u8 *hw_addr, u32 rates, 267/* mesh_peer_init - initialize new mesh peer and return resulting sta_info
278 struct ieee80211_sub_if_data *sdata, 268 *
279 struct ieee802_11_elems *elems) 269 * @sdata: local meshif
270 * @addr: peer's address
271 * @elems: IEs from beacon or mesh peering frame
272 *
273 * call under RCU
274 */
275static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
276 u8 *addr,
277 struct ieee802_11_elems *elems)
280{ 278{
281 struct ieee80211_local *local = sdata->local; 279 struct ieee80211_local *local = sdata->local;
280 enum ieee80211_band band = local->oper_channel->band;
281 struct ieee80211_supported_band *sband;
282 u32 rates, basic_rates = 0;
282 struct sta_info *sta; 283 struct sta_info *sta;
283 284
284 rcu_read_lock(); 285 sband = local->hw.wiphy->bands[band];
286 rates = ieee80211_sta_get_rates(local, elems, band, &basic_rates);
285 287
286 sta = sta_info_get(sdata, hw_addr); 288 sta = sta_info_get(sdata, addr);
287 if (!sta) { 289 if (!sta) {
288 rcu_read_unlock(); 290 sta = mesh_plink_alloc(sdata, addr);
289 /* Userspace handles peer allocation when security is enabled
290 * */
291 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
292 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr,
293 elems->ie_start, elems->total_len,
294 GFP_KERNEL);
295 else
296 sta = mesh_plink_alloc(sdata, hw_addr, rates, elems);
297 if (!sta) 291 if (!sta)
298 return; 292 return NULL;
299 if (sta_info_insert_rcu(sta)) {
300 rcu_read_unlock();
301 return;
302 }
303 } 293 }
304 294
295 spin_lock_bh(&sta->lock);
305 sta->last_rx = jiffies; 296 sta->last_rx = jiffies;
306 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 297 sta->sta.supp_rates[band] = rates;
298 if (elems->ht_cap_elem &&
299 sdata->local->_oper_channel_type != NL80211_CHAN_NO_HT)
300 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
301 elems->ht_cap_elem,
302 &sta->sta.ht_cap);
303 else
304 memset(&sta->sta.ht_cap, 0, sizeof(sta->sta.ht_cap));
305
306 rate_control_rate_init(sta);
307 spin_unlock_bh(&sta->lock);
308
309 return sta;
310}
311
312void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
313 u8 *hw_addr,
314 struct ieee802_11_elems *elems)
315{
316 struct sta_info *sta;
317
318 /* Userspace handles peer allocation when security is enabled */
319 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) {
320 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr,
321 elems->ie_start,
322 elems->total_len,
323 GFP_KERNEL);
324 return;
325 }
326
327 rcu_read_lock();
328 sta = mesh_peer_init(sdata, hw_addr, elems);
329 if (!sta)
330 goto out;
331
307 if (mesh_peer_accepts_plinks(elems) && 332 if (mesh_peer_accepts_plinks(elems) &&
308 sta->plink_state == NL80211_PLINK_LISTEN && 333 sta->plink_state == NL80211_PLINK_LISTEN &&
309 sdata->u.mesh.accepting_plinks && 334 sdata->u.mesh.accepting_plinks &&
310 sdata->u.mesh.mshcfg.auto_open_plinks && 335 sdata->u.mesh.mshcfg.auto_open_plinks &&
311 rssi_threshold_check(sta, sdata)) 336 rssi_threshold_check(sta, sdata))
312 mesh_plink_open(sta); 337 mesh_plink_open(sta);
313 338
339out:
314 rcu_read_unlock(); 340 rcu_read_unlock();
315} 341}
316 342
@@ -456,7 +482,6 @@ void mesh_plink_block(struct sta_info *sta)
456void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, 482void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt,
457 size_t len, struct ieee80211_rx_status *rx_status) 483 size_t len, struct ieee80211_rx_status *rx_status)
458{ 484{
459 struct ieee80211_local *local = sdata->local;
460 struct ieee802_11_elems elems; 485 struct ieee802_11_elems elems;
461 struct sta_info *sta; 486 struct sta_info *sta;
462 enum plink_event event; 487 enum plink_event event;
@@ -465,7 +490,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
465 bool deactivated, matches_local = true; 490 bool deactivated, matches_local = true;
466 u8 ie_len; 491 u8 ie_len;
467 u8 *baseaddr; 492 u8 *baseaddr;
468 u32 rates, basic_rates = 0;
469 __le16 plid, llid, reason; 493 __le16 plid, llid, reason;
470#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG 494#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
471 static const char *mplstates[] = { 495 static const char *mplstates[] = {
@@ -560,11 +584,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
560 584
561 /* Now we will figure out the appropriate event... */ 585 /* Now we will figure out the appropriate event... */
562 event = PLINK_UNDEFINED; 586 event = PLINK_UNDEFINED;
563 rates = ieee80211_sta_get_rates(local, &elems,
564 rx_status->band, &basic_rates);
565
566 if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 587 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
567 (!mesh_matches_local(&elems, sdata, basic_rates))) { 588 !mesh_matches_local(sdata, &elems)) {
568 matches_local = false; 589 matches_local = false;
569 switch (ftype) { 590 switch (ftype) {
570 case WLAN_SP_MESH_PEERING_OPEN: 591 case WLAN_SP_MESH_PEERING_OPEN:
@@ -587,26 +608,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
587 return; 608 return;
588 } else if (!sta) { 609 } else if (!sta) {
589 /* ftype == WLAN_SP_MESH_PEERING_OPEN */ 610 /* ftype == WLAN_SP_MESH_PEERING_OPEN */
590
591 rcu_read_unlock();
592
593 if (!mesh_plink_free_count(sdata)) { 611 if (!mesh_plink_free_count(sdata)) {
594 mpl_dbg("Mesh plink error: no more free plinks\n"); 612 mpl_dbg("Mesh plink error: no more free plinks\n");
595 return;
596 }
597 sta = mesh_plink_alloc(sdata, mgmt->sa, rates, &elems);
598 if (!sta) {
599 mpl_dbg("Mesh plink error: plink table full\n");
600 return;
601 }
602 if (sta_info_insert_rcu(sta)) {
603 rcu_read_unlock(); 613 rcu_read_unlock();
604 return; 614 return;
605 } 615 }
606 event = OPN_ACPT; 616 event = OPN_ACPT;
607 spin_lock_bh(&sta->lock);
608 } else if (matches_local) { 617 } else if (matches_local) {
609 spin_lock_bh(&sta->lock);
610 switch (ftype) { 618 switch (ftype) {
611 case WLAN_SP_MESH_PEERING_OPEN: 619 case WLAN_SP_MESH_PEERING_OPEN:
612 if (!mesh_plink_free_count(sdata) || 620 if (!mesh_plink_free_count(sdata) ||
@@ -643,12 +651,19 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
643 break; 651 break;
644 default: 652 default:
645 mpl_dbg("Mesh plink: unknown frame subtype\n"); 653 mpl_dbg("Mesh plink: unknown frame subtype\n");
646 spin_unlock_bh(&sta->lock);
647 rcu_read_unlock(); 654 rcu_read_unlock();
648 return; 655 return;
649 } 656 }
650 } else { 657 }
651 spin_lock_bh(&sta->lock); 658
659 if (event == OPN_ACPT) {
660 /* allocate sta entry if necessary and update info */
661 sta = mesh_peer_init(sdata, mgmt->sa, &elems);
662 if (!sta) {
663 mpl_dbg("Mesh plink: failed to init peer!\n");
664 rcu_read_unlock();
665 return;
666 }
652 } 667 }
653 668
654 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", 669 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
@@ -656,6 +671,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
656 le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), 671 le16_to_cpu(sta->llid), le16_to_cpu(sta->plid),
657 event); 672 event);
658 reason = 0; 673 reason = 0;
674 spin_lock_bh(&sta->lock);
659 switch (sta->plink_state) { 675 switch (sta->plink_state) {
660 /* spin_unlock as soon as state is updated at each case */ 676 /* spin_unlock as soon as state is updated at each case */
661 case NL80211_PLINK_LISTEN: 677 case NL80211_PLINK_LISTEN:
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index ff60d6bcc63..38d30e8ce6d 100644
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -195,7 +195,7 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
195 spin_unlock_bh(&ifmsh->sync_offset_lock); 195 spin_unlock_bh(&ifmsh->sync_offset_lock);
196 196
197 } else { 197 } else {
198 sta->t_offset_setpoint = sta->t_offset; 198 sta->t_offset_setpoint = sta->t_offset - TOFFSET_SET_MARGIN;
199 set_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); 199 set_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN);
200 msync_dbg("STA %pM : offset was invalid, " 200 msync_dbg("STA %pM : offset was invalid, "
201 " sta->t_offset=%lld", 201 " sta->t_offset=%lld",
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 7cbb4aad057..d5ac02fe37f 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -426,6 +426,7 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
426 426
427 if (test_bit(SCAN_HW_SCANNING, &local->scanning) || 427 if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
428 test_bit(SCAN_SW_SCANNING, &local->scanning) || 428 test_bit(SCAN_SW_SCANNING, &local->scanning) ||
429 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
429 local->sched_scanning) 430 local->sched_scanning)
430 return ieee80211_scan_rx(rx->sdata, skb); 431 return ieee80211_scan_rx(rx->sdata, skb);
431 432
@@ -2917,6 +2918,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2917 local->dot11ReceivedFragmentCount++; 2918 local->dot11ReceivedFragmentCount++;
2918 2919
2919 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || 2920 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
2921 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
2920 test_bit(SCAN_SW_SCANNING, &local->scanning))) 2922 test_bit(SCAN_SW_SCANNING, &local->scanning)))
2921 status->rx_flags |= IEEE80211_RX_IN_SCAN; 2923 status->rx_flags |= IEEE80211_RX_IN_SCAN;
2922 2924
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 45f5aa229ef..8282284f835 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -401,6 +401,30 @@ void ieee80211_run_deferred_scan(struct ieee80211_local *local)
401 round_jiffies_relative(0)); 401 round_jiffies_relative(0));
402} 402}
403 403
404static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
405 unsigned long *next_delay)
406{
407 int i;
408 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
409 enum ieee80211_band band = local->hw.conf.channel->band;
410
411 for (i = 0; i < local->scan_req->n_ssids; i++)
412 ieee80211_send_probe_req(
413 sdata, NULL,
414 local->scan_req->ssids[i].ssid,
415 local->scan_req->ssids[i].ssid_len,
416 local->scan_req->ie, local->scan_req->ie_len,
417 local->scan_req->rates[band], false,
418 local->scan_req->no_cck);
419
420 /*
421 * After sending probe requests, wait for probe responses
422 * on the channel.
423 */
424 *next_delay = IEEE80211_CHANNEL_TIME;
425 local->next_scan_state = SCAN_DECISION;
426}
427
404static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, 428static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
405 struct cfg80211_scan_request *req) 429 struct cfg80211_scan_request *req)
406{ 430{
@@ -451,10 +475,47 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
451 local->scan_req = req; 475 local->scan_req = req;
452 local->scan_sdata = sdata; 476 local->scan_sdata = sdata;
453 477
454 if (local->ops->hw_scan) 478 if (local->ops->hw_scan) {
455 __set_bit(SCAN_HW_SCANNING, &local->scanning); 479 __set_bit(SCAN_HW_SCANNING, &local->scanning);
456 else 480 } else if ((req->n_channels == 1) &&
481 (req->channels[0]->center_freq ==
482 local->hw.conf.channel->center_freq)) {
483
484 /* If we are scanning only on the current channel, then
485 * we do not need to stop normal activities
486 */
487 unsigned long next_delay;
488
489 __set_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning);
490
491 ieee80211_recalc_idle(local);
492
493 /* Notify driver scan is starting, keep order of operations
494 * same as normal software scan, in case that matters. */
495 drv_sw_scan_start(local);
496
497 ieee80211_configure_filter(local); /* accept probe-responses */
498
499 /* We need to ensure power level is at max for scanning. */
500 ieee80211_hw_config(local, 0);
501
502 if ((req->channels[0]->flags &
503 IEEE80211_CHAN_PASSIVE_SCAN) ||
504 !local->scan_req->n_ssids) {
505 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
506 } else {
507 ieee80211_scan_state_send_probe(local, &next_delay);
508 next_delay = IEEE80211_CHANNEL_TIME;
509 }
510
511 /* Now, just wait a bit and we are all done! */
512 ieee80211_queue_delayed_work(&local->hw, &local->scan_work,
513 next_delay);
514 return 0;
515 } else {
516 /* Do normal software scan */
457 __set_bit(SCAN_SW_SCANNING, &local->scanning); 517 __set_bit(SCAN_SW_SCANNING, &local->scanning);
518 }
458 519
459 ieee80211_recalc_idle(local); 520 ieee80211_recalc_idle(local);
460 521
@@ -611,30 +672,6 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
611 local->next_scan_state = SCAN_SEND_PROBE; 672 local->next_scan_state = SCAN_SEND_PROBE;
612} 673}
613 674
614static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
615 unsigned long *next_delay)
616{
617 int i;
618 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
619 enum ieee80211_band band = local->hw.conf.channel->band;
620
621 for (i = 0; i < local->scan_req->n_ssids; i++)
622 ieee80211_send_probe_req(
623 sdata, NULL,
624 local->scan_req->ssids[i].ssid,
625 local->scan_req->ssids[i].ssid_len,
626 local->scan_req->ie, local->scan_req->ie_len,
627 local->scan_req->rates[band], false,
628 local->scan_req->no_cck);
629
630 /*
631 * After sending probe requests, wait for probe responses
632 * on the channel.
633 */
634 *next_delay = IEEE80211_CHANNEL_TIME;
635 local->next_scan_state = SCAN_DECISION;
636}
637
638static void ieee80211_scan_state_suspend(struct ieee80211_local *local, 675static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
639 unsigned long *next_delay) 676 unsigned long *next_delay)
640{ 677{
@@ -685,6 +722,12 @@ void ieee80211_scan_work(struct work_struct *work)
685 722
686 sdata = local->scan_sdata; 723 sdata = local->scan_sdata;
687 724
725 /* When scanning on-channel, the first-callback means completed. */
726 if (test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning)) {
727 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
728 goto out_complete;
729 }
730
688 if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) { 731 if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
689 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning); 732 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
690 goto out_complete; 733 goto out_complete;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 7fd7ac48f89..97a9d6639fb 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1417,15 +1417,19 @@ int sta_info_move_state(struct sta_info *sta,
1417 if (sta->sta_state == IEEE80211_STA_AUTH) { 1417 if (sta->sta_state == IEEE80211_STA_AUTH) {
1418 set_bit(WLAN_STA_ASSOC, &sta->_flags); 1418 set_bit(WLAN_STA_ASSOC, &sta->_flags);
1419 } else if (sta->sta_state == IEEE80211_STA_AUTHORIZED) { 1419 } else if (sta->sta_state == IEEE80211_STA_AUTHORIZED) {
1420 if (sta->sdata->vif.type == NL80211_IFTYPE_AP) 1420 if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
1421 atomic_dec(&sta->sdata->u.ap.num_sta_authorized); 1421 (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
1422 !sta->sdata->u.vlan.sta))
1423 atomic_dec(&sta->sdata->bss->num_mcast_sta);
1422 clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags); 1424 clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
1423 } 1425 }
1424 break; 1426 break;
1425 case IEEE80211_STA_AUTHORIZED: 1427 case IEEE80211_STA_AUTHORIZED:
1426 if (sta->sta_state == IEEE80211_STA_ASSOC) { 1428 if (sta->sta_state == IEEE80211_STA_ASSOC) {
1427 if (sta->sdata->vif.type == NL80211_IFTYPE_AP) 1429 if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
1428 atomic_inc(&sta->sdata->u.ap.num_sta_authorized); 1430 (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
1431 !sta->sdata->u.vlan.sta))
1432 atomic_inc(&sta->sdata->bss->num_mcast_sta);
1429 set_bit(WLAN_STA_AUTHORIZED, &sta->_flags); 1433 set_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
1430 } 1434 }
1431 break; 1435 break;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 0abbef952c1..44001c7e0e5 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -306,7 +306,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
306 } 306 }
307 } else if (unlikely(tx->sdata->vif.type == NL80211_IFTYPE_AP && 307 } else if (unlikely(tx->sdata->vif.type == NL80211_IFTYPE_AP &&
308 ieee80211_is_data(hdr->frame_control) && 308 ieee80211_is_data(hdr->frame_control) &&
309 !atomic_read(&tx->sdata->u.ap.num_sta_authorized))) { 309 !atomic_read(&tx->sdata->u.ap.num_mcast_sta))) {
310 /* 310 /*
311 * No associated STAs - no need to send multicast 311 * No associated STAs - no need to send multicast
312 * frames. 312 * frames.
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 89c1e5b9ba9..d9a747d387f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1684,7 +1684,9 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1684 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; 1684 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
1685 break; 1685 break;
1686 } 1686 }
1687 if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) 1687 if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
1688 channel_type != NL80211_CHAN_NO_HT &&
1689 channel_type != NL80211_CHAN_HT20)
1688 ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; 1690 ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
1689 1691
1690 /* 1692 /*
@@ -1799,5 +1801,10 @@ int ieee80211_ave_rssi(struct ieee80211_vif *vif)
1799 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 1801 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1800 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1802 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1801 1803
1804 if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION)) {
1805 /* non-managed type inferfaces */
1806 return 0;
1807 }
1802 return ifmgd->ave_beacon_signal; 1808 return ifmgd->ave_beacon_signal;
1803} 1809}
1810EXPORT_SYMBOL_GPL(ieee80211_ave_rssi);