aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Copeland <me@bobcopeland.com>2015-07-14 08:31:58 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-07-17 09:47:11 -0400
commita69bd8e60b02946896c097439b94eb77c0c2c9e4 (patch)
treeb5081e7acefb264b2b1272f26dcdc47df6fe9133
parentfa87a6566ca8f17a92ba81980bd47c456262907c (diff)
mac80211: mesh: separate plid and aid concepts
According to 802.11-2012 13.3.1, a mesh STA should assign an AID upon receipt of a mesh peering open frame rather than using the link id of the peer. Using the peer link id has two potential issues: it may not be unique among the peers, and by its nature it is random, so the TIM may not compress well. In preparation for allocating it properly, use sta->sta.aid, but keep the existing behavior of using the plid in the aid we send. Signed-off-by: Bob Copeland <me@bobcopeland.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/mesh_plink.c29
-rw-r--r--net/mac80211/mesh_ps.c2
-rw-r--r--net/mac80211/sta_info.c5
-rw-r--r--net/mac80211/sta_info.h2
4 files changed, 23 insertions, 15 deletions
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index a5aa0345dd7e..3323413acb77 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -13,6 +13,7 @@
13#include "rate.h" 13#include "rate.h"
14#include "mesh.h" 14#include "mesh.h"
15 15
16#define PLINK_CNF_AID(mgmt) ((mgmt)->u.action.u.self_prot.variable + 2)
16#define PLINK_GET_LLID(p) (p + 2) 17#define PLINK_GET_LLID(p) (p + 2)
17#define PLINK_GET_PLID(p) (p + 4) 18#define PLINK_GET_PLID(p) (p + 4)
18 19
@@ -200,6 +201,7 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
200} 201}
201 202
202static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 203static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
204 struct sta_info *sta,
203 enum ieee80211_self_protected_actioncode action, 205 enum ieee80211_self_protected_actioncode action,
204 u8 *da, u16 llid, u16 plid, u16 reason) 206 u8 *da, u16 llid, u16 plid, u16 reason)
205{ 207{
@@ -249,7 +251,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
249 if (action == WLAN_SP_MESH_PEERING_CONFIRM) { 251 if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
250 /* AID */ 252 /* AID */
251 pos = skb_put(skb, 2); 253 pos = skb_put(skb, 2);
252 put_unaligned_le16(plid, pos); 254 put_unaligned_le16(sta->sta.aid, pos);
253 } 255 }
254 if (ieee80211_add_srates_ie(sdata, skb, true, band) || 256 if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
255 ieee80211_add_ext_srates_ie(sdata, skb, true, band) || 257 ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
@@ -362,7 +364,7 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
362 spin_lock_bh(&sta->mesh->plink_lock); 364 spin_lock_bh(&sta->mesh->plink_lock);
363 changed = __mesh_plink_deactivate(sta); 365 changed = __mesh_plink_deactivate(sta);
364 sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED; 366 sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED;
365 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 367 mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE,
366 sta->sta.addr, sta->mesh->llid, sta->mesh->plid, 368 sta->sta.addr, sta->mesh->llid, sta->mesh->plid,
367 sta->mesh->reason); 369 sta->mesh->reason);
368 spin_unlock_bh(&sta->mesh->plink_lock); 370 spin_unlock_bh(&sta->mesh->plink_lock);
@@ -619,7 +621,7 @@ static void mesh_plink_timer(unsigned long data)
619 } 621 }
620 spin_unlock_bh(&sta->mesh->plink_lock); 622 spin_unlock_bh(&sta->mesh->plink_lock);
621 if (action) 623 if (action)
622 mesh_plink_frame_tx(sdata, action, sta->sta.addr, 624 mesh_plink_frame_tx(sdata, sta, action, sta->sta.addr,
623 sta->mesh->llid, sta->mesh->plid, reason); 625 sta->mesh->llid, sta->mesh->plid, reason);
624} 626}
625 627
@@ -689,7 +691,7 @@ u32 mesh_plink_open(struct sta_info *sta)
689 /* set the non-peer mode to active during peering */ 691 /* set the non-peer mode to active during peering */
690 changed = ieee80211_mps_local_status_update(sdata); 692 changed = ieee80211_mps_local_status_update(sdata);
691 693
692 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, 694 mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_OPEN,
693 sta->sta.addr, sta->mesh->llid, 0, 0); 695 sta->sta.addr, sta->mesh->llid, 0, 0);
694 return changed; 696 return changed;
695} 697}
@@ -871,13 +873,13 @@ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
871 } 873 }
872 spin_unlock_bh(&sta->mesh->plink_lock); 874 spin_unlock_bh(&sta->mesh->plink_lock);
873 if (action) { 875 if (action) {
874 mesh_plink_frame_tx(sdata, action, sta->sta.addr, 876 mesh_plink_frame_tx(sdata, sta, action, sta->sta.addr,
875 sta->mesh->llid, sta->mesh->plid, 877 sta->mesh->llid, sta->mesh->plid,
876 sta->mesh->reason); 878 sta->mesh->reason);
877 879
878 /* also send confirm in open case */ 880 /* also send confirm in open case */
879 if (action == WLAN_SP_MESH_PEERING_OPEN) { 881 if (action == WLAN_SP_MESH_PEERING_OPEN) {
880 mesh_plink_frame_tx(sdata, 882 mesh_plink_frame_tx(sdata, sta,
881 WLAN_SP_MESH_PEERING_CONFIRM, 883 WLAN_SP_MESH_PEERING_CONFIRM,
882 sta->sta.addr, sta->mesh->llid, 884 sta->sta.addr, sta->mesh->llid,
883 sta->mesh->plid, 0); 885 sta->mesh->plid, 0);
@@ -1067,8 +1069,9 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
1067 goto unlock_rcu; 1069 goto unlock_rcu;
1068 } 1070 }
1069 sta->mesh->plid = plid; 1071 sta->mesh->plid = plid;
1072 sta->sta.aid = plid;
1070 } else if (!sta && event == OPN_RJCT) { 1073 } else if (!sta && event == OPN_RJCT) {
1071 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 1074 mesh_plink_frame_tx(sdata, NULL, WLAN_SP_MESH_PEERING_CLOSE,
1072 mgmt->sa, 0, plid, 1075 mgmt->sa, 0, plid,
1073 WLAN_REASON_MESH_CONFIG); 1076 WLAN_REASON_MESH_CONFIG);
1074 goto unlock_rcu; 1077 goto unlock_rcu;
@@ -1077,9 +1080,15 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
1077 goto unlock_rcu; 1080 goto unlock_rcu;
1078 } 1081 }
1079 1082
1080 /* 802.11-2012 13.3.7.2 - update plid on CNF if not set */ 1083 if (event == CNF_ACPT) {
1081 if (!sta->mesh->plid && event == CNF_ACPT) 1084 /* 802.11-2012 13.3.7.2 - update plid on CNF if not set */
1082 sta->mesh->plid = plid; 1085 if (!sta->mesh->plid) {
1086 sta->mesh->plid = plid;
1087 sta->sta.aid = sta->mesh->plid;
1088 }
1089
1090 sta->mesh->aid = get_unaligned_le16(PLINK_CNF_AID(mgmt));
1091 }
1083 1092
1084 changed |= mesh_plink_fsm(sdata, sta, event); 1093 changed |= mesh_plink_fsm(sdata, sta, event);
1085 1094
diff --git a/net/mac80211/mesh_ps.c b/net/mac80211/mesh_ps.c
index 29747f92b9b0..90a268abea17 100644
--- a/net/mac80211/mesh_ps.c
+++ b/net/mac80211/mesh_ps.c
@@ -579,7 +579,7 @@ void ieee80211_mps_frame_release(struct sta_info *sta,
579 579
580 if (sta->mesh->plink_state == NL80211_PLINK_ESTAB) 580 if (sta->mesh->plink_state == NL80211_PLINK_ESTAB)
581 has_buffered = ieee80211_check_tim(elems->tim, elems->tim_len, 581 has_buffered = ieee80211_check_tim(elems->tim, elems->tim_len,
582 sta->mesh->llid); 582 sta->mesh->aid);
583 583
584 if (has_buffered) 584 if (has_buffered)
585 mps_dbg(sta->sdata, "%pM indicates buffered frames\n", 585 mps_dbg(sta->sdata, "%pM indicates buffered frames\n",
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 9da7d2bc271a..70cd9fa57424 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -635,7 +635,7 @@ static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending)
635 bool indicate_tim = false; 635 bool indicate_tim = false;
636 u8 ignore_for_tim = sta->sta.uapsd_queues; 636 u8 ignore_for_tim = sta->sta.uapsd_queues;
637 int ac; 637 int ac;
638 u16 id; 638 u16 id = sta->sta.aid;
639 639
640 if (sta->sdata->vif.type == NL80211_IFTYPE_AP || 640 if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
641 sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { 641 sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
@@ -643,12 +643,9 @@ static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending)
643 return; 643 return;
644 644
645 ps = &sta->sdata->bss->ps; 645 ps = &sta->sdata->bss->ps;
646 id = sta->sta.aid;
647#ifdef CONFIG_MAC80211_MESH 646#ifdef CONFIG_MAC80211_MESH
648 } else if (ieee80211_vif_is_mesh(&sta->sdata->vif)) { 647 } else if (ieee80211_vif_is_mesh(&sta->sdata->vif)) {
649 ps = &sta->sdata->u.mesh.ps; 648 ps = &sta->sdata->u.mesh.ps;
650 /* TIM map only for 1 <= PLID <= IEEE80211_MAX_AID */
651 id = sta->mesh->plid % (IEEE80211_MAX_AID + 1);
652#endif 649#endif
653 } else { 650 } else {
654 return; 651 return;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 6dcb33484eac..1d2805c598c0 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -277,6 +277,7 @@ struct ieee80211_fast_tx {
277 * @plink_lock: serialize access to plink fields 277 * @plink_lock: serialize access to plink fields
278 * @llid: Local link ID 278 * @llid: Local link ID
279 * @plid: Peer link ID 279 * @plid: Peer link ID
280 * @aid: local aid supplied by peer
280 * @reason: Cancel reason on PLINK_HOLDING state 281 * @reason: Cancel reason on PLINK_HOLDING state
281 * @plink_retries: Retries in establishment 282 * @plink_retries: Retries in establishment
282 * @plink_state: peer link state 283 * @plink_state: peer link state
@@ -301,6 +302,7 @@ struct mesh_sta {
301 spinlock_t plink_lock; 302 spinlock_t plink_lock;
302 u16 llid; 303 u16 llid;
303 u16 plid; 304 u16 plid;
305 u16 aid;
304 u16 reason; 306 u16 reason;
305 u8 plink_retries; 307 u8 plink_retries;
306 308