diff options
author | Bob Copeland <me@bobcopeland.com> | 2015-07-14 08:31:58 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2015-07-17 09:47:11 -0400 |
commit | a69bd8e60b02946896c097439b94eb77c0c2c9e4 (patch) | |
tree | b5081e7acefb264b2b1272f26dcdc47df6fe9133 | |
parent | fa87a6566ca8f17a92ba81980bd47c456262907c (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.c | 29 | ||||
-rw-r--r-- | net/mac80211/mesh_ps.c | 2 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 5 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 2 |
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 | ||
202 | static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | 203 | static 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 | ||