2 * Copyright (c) 2008, 2009 open80211s Ltd.
3 * Author: Luis Carlos Cobo <luisca@cozybit.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 #include <linux/kernel.h>
11 #include <linux/random.h>
12 #include "ieee80211_i.h"
16 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
17 #define mpl_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args)
19 #define mpl_dbg(fmt, args...) do { (void)(0); } while (0)
22 #define PLINK_GET_LLID(p) (p + 2)
23 #define PLINK_GET_PLID(p) (p + 4)
25 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
26 jiffies + HZ * t / 1000))
28 #define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries)
29 #define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout)
30 #define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout)
31 #define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
32 #define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
34 #define sta_meets_rssi_threshold(sta, sdata) \
35 (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
36 (s8) -ewma_read(&sta->avg_signal) > \
37 sdata->u.mesh.mshcfg.rssi_threshold)
51 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data
*sdata
,
52 enum ieee80211_self_protected_actioncode action
,
53 u8
*da
, __le16 llid
, __le16 plid
, __le16 reason
);
56 void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data
*sdata
)
58 atomic_inc(&sdata
->u
.mesh
.mshstats
.estab_plinks
);
59 mesh_accept_plinks_update(sdata
);
63 void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data
*sdata
)
65 atomic_dec(&sdata
->u
.mesh
.mshstats
.estab_plinks
);
66 mesh_accept_plinks_update(sdata
);
70 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
72 * @sta: mesh peer link to restart
74 * Locking: this function must be called holding sta->lock
76 static inline void mesh_plink_fsm_restart(struct sta_info
*sta
)
78 sta
->plink_state
= NL80211_PLINK_LISTEN
;
79 sta
->llid
= sta
->plid
= sta
->reason
= 0;
80 sta
->plink_retries
= 0;
84 * NOTE: This is just an alias for sta_info_alloc(), see notes
85 * on it in the lifecycle management section!
87 static struct sta_info
*mesh_plink_alloc(struct ieee80211_sub_if_data
*sdata
,
88 u8
*hw_addr
, u32 rates
,
89 struct ieee802_11_elems
*elems
)
91 struct ieee80211_local
*local
= sdata
->local
;
92 struct ieee80211_supported_band
*sband
;
95 sband
= local
->hw
.wiphy
->bands
[local
->oper_channel
->band
];
97 if (local
->num_sta
>= MESH_MAX_PLINKS
)
100 sta
= sta_info_alloc(sdata
, hw_addr
, GFP_KERNEL
);
104 sta_info_pre_move_state(sta
, IEEE80211_STA_AUTH
);
105 sta_info_pre_move_state(sta
, IEEE80211_STA_ASSOC
);
106 sta_info_pre_move_state(sta
, IEEE80211_STA_AUTHORIZED
);
108 set_sta_flag(sta
, WLAN_STA_WME
);
110 sta
->sta
.supp_rates
[local
->hw
.conf
.channel
->band
] = rates
;
111 if (elems
->ht_cap_elem
)
112 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata
, sband
,
115 rate_control_rate_init(sta
);
121 * __mesh_plink_deactivate - deactivate mesh peer link
123 * @sta: mesh peer link to deactivate
125 * All mesh paths with this peer as next hop will be flushed
127 * Locking: the caller must hold sta->lock
129 static bool __mesh_plink_deactivate(struct sta_info
*sta
)
131 struct ieee80211_sub_if_data
*sdata
= sta
->sdata
;
132 bool deactivated
= false;
134 if (sta
->plink_state
== NL80211_PLINK_ESTAB
) {
135 mesh_plink_dec_estab_count(sdata
);
138 sta
->plink_state
= NL80211_PLINK_BLOCKED
;
139 mesh_path_flush_by_nexthop(sta
);
145 * mesh_plink_deactivate - deactivate mesh peer link
147 * @sta: mesh peer link to deactivate
149 * All mesh paths with this peer as next hop will be flushed
151 void mesh_plink_deactivate(struct sta_info
*sta
)
153 struct ieee80211_sub_if_data
*sdata
= sta
->sdata
;
156 spin_lock_bh(&sta
->lock
);
157 deactivated
= __mesh_plink_deactivate(sta
);
158 sta
->reason
= cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED
);
159 mesh_plink_frame_tx(sdata
, WLAN_SP_MESH_PEERING_CLOSE
,
160 sta
->sta
.addr
, sta
->llid
, sta
->plid
,
162 spin_unlock_bh(&sta
->lock
);
165 ieee80211_bss_info_change_notify(sdata
, BSS_CHANGED_BEACON
);
168 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data
*sdata
,
169 enum ieee80211_self_protected_actioncode action
,
170 u8
*da
, __le16 llid
, __le16 plid
, __le16 reason
) {
171 struct ieee80211_local
*local
= sdata
->local
;
173 struct ieee80211_mgmt
*mgmt
;
174 bool include_plid
= false;
175 u16 peering_proto
= 0;
177 int hdr_len
= offsetof(struct ieee80211_mgmt
, u
.action
.u
.self_prot
) +
178 sizeof(mgmt
->u
.action
.u
.self_prot
);
180 skb
= dev_alloc_skb(local
->tx_headroom
+
182 2 + /* capability info */
184 2 + 8 + /* supported rates */
185 2 + (IEEE80211_MAX_SUPP_RATES
- 8) +
186 2 + sdata
->u
.mesh
.mesh_id_len
+
187 2 + sizeof(struct ieee80211_meshconf_ie
) +
188 2 + sizeof(struct ieee80211_ht_cap
) +
189 2 + sizeof(struct ieee80211_ht_info
) +
190 2 + 8 + /* peering IE */
191 sdata
->u
.mesh
.ie_len
);
194 skb_reserve(skb
, local
->tx_headroom
);
195 mgmt
= (struct ieee80211_mgmt
*) skb_put(skb
, hdr_len
);
196 memset(mgmt
, 0, hdr_len
);
197 mgmt
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
|
198 IEEE80211_STYPE_ACTION
);
199 memcpy(mgmt
->da
, da
, ETH_ALEN
);
200 memcpy(mgmt
->sa
, sdata
->vif
.addr
, ETH_ALEN
);
201 memcpy(mgmt
->bssid
, sdata
->vif
.addr
, ETH_ALEN
);
202 mgmt
->u
.action
.category
= WLAN_CATEGORY_SELF_PROTECTED
;
203 mgmt
->u
.action
.u
.self_prot
.action_code
= action
;
205 if (action
!= WLAN_SP_MESH_PEERING_CLOSE
) {
206 /* capability info */
207 pos
= skb_put(skb
, 2);
209 if (action
== WLAN_SP_MESH_PEERING_CONFIRM
) {
211 pos
= skb_put(skb
, 2);
212 memcpy(pos
+ 2, &plid
, 2);
214 if (ieee80211_add_srates_ie(&sdata
->vif
, skb
) ||
215 ieee80211_add_ext_srates_ie(&sdata
->vif
, skb
) ||
216 mesh_add_rsn_ie(skb
, sdata
) ||
217 mesh_add_meshid_ie(skb
, sdata
) ||
218 mesh_add_meshconf_ie(skb
, sdata
))
220 } else { /* WLAN_SP_MESH_PEERING_CLOSE */
221 if (mesh_add_meshid_ie(skb
, sdata
))
225 /* Add Mesh Peering Management element */
227 case WLAN_SP_MESH_PEERING_OPEN
:
229 case WLAN_SP_MESH_PEERING_CONFIRM
:
233 case WLAN_SP_MESH_PEERING_CLOSE
:
238 ie_len
+= 2; /* reason code */
244 if (WARN_ON(skb_tailroom(skb
) < 2 + ie_len
))
247 pos
= skb_put(skb
, 2 + ie_len
);
248 *pos
++ = WLAN_EID_PEER_MGMT
;
250 memcpy(pos
, &peering_proto
, 2);
252 memcpy(pos
, &llid
, 2);
255 memcpy(pos
, &plid
, 2);
258 if (action
== WLAN_SP_MESH_PEERING_CLOSE
) {
259 memcpy(pos
, &reason
, 2);
263 if (action
!= WLAN_SP_MESH_PEERING_CLOSE
) {
264 if (mesh_add_ht_cap_ie(skb
, sdata
) ||
265 mesh_add_ht_info_ie(skb
, sdata
))
269 if (mesh_add_vendor_ies(skb
, sdata
))
272 ieee80211_tx_skb(sdata
, skb
);
276 void mesh_neighbour_update(u8
*hw_addr
, u32 rates
,
277 struct ieee80211_sub_if_data
*sdata
,
278 struct ieee802_11_elems
*elems
)
280 struct ieee80211_local
*local
= sdata
->local
;
281 struct sta_info
*sta
;
285 sta
= sta_info_get(sdata
, hw_addr
);
288 /* Userspace handles peer allocation when security is enabled
290 if (sdata
->u
.mesh
.security
& IEEE80211_MESH_SEC_AUTHED
)
291 cfg80211_notify_new_peer_candidate(sdata
->dev
, hw_addr
,
292 elems
->ie_start
, elems
->total_len
,
295 sta
= mesh_plink_alloc(sdata
, hw_addr
, rates
, elems
);
298 if (sta_info_insert_rcu(sta
)) {
304 sta
->last_rx
= jiffies
;
305 sta
->sta
.supp_rates
[local
->hw
.conf
.channel
->band
] = rates
;
306 if (mesh_peer_accepts_plinks(elems
) &&
307 sta
->plink_state
== NL80211_PLINK_LISTEN
&&
308 sdata
->u
.mesh
.accepting_plinks
&&
309 sdata
->u
.mesh
.mshcfg
.auto_open_plinks
&&
310 sta_meets_rssi_threshold(sta
, sdata
))
311 mesh_plink_open(sta
);
316 static void mesh_plink_timer(unsigned long data
)
318 struct sta_info
*sta
;
319 __le16 llid
, plid
, reason
;
320 struct ieee80211_sub_if_data
*sdata
;
323 * This STA is valid because sta_info_destroy() will
324 * del_timer_sync() this timer after having made sure
325 * it cannot be readded (by deleting the plink.)
327 sta
= (struct sta_info
*) data
;
329 if (sta
->sdata
->local
->quiescing
) {
330 sta
->plink_timer_was_running
= true;
334 spin_lock_bh(&sta
->lock
);
335 if (sta
->ignore_plink_timer
) {
336 sta
->ignore_plink_timer
= false;
337 spin_unlock_bh(&sta
->lock
);
340 mpl_dbg("Mesh plink timer for %pM fired on state %d\n",
341 sta
->sta
.addr
, sta
->plink_state
);
347 switch (sta
->plink_state
) {
348 case NL80211_PLINK_OPN_RCVD
:
349 case NL80211_PLINK_OPN_SNT
:
351 if (sta
->plink_retries
< dot11MeshMaxRetries(sdata
)) {
353 mpl_dbg("Mesh plink for %pM (retry, timeout): %d %d\n",
354 sta
->sta
.addr
, sta
->plink_retries
,
356 get_random_bytes(&rand
, sizeof(u32
));
357 sta
->plink_timeout
= sta
->plink_timeout
+
358 rand
% sta
->plink_timeout
;
359 ++sta
->plink_retries
;
360 mod_plink_timer(sta
, sta
->plink_timeout
);
361 spin_unlock_bh(&sta
->lock
);
362 mesh_plink_frame_tx(sdata
, WLAN_SP_MESH_PEERING_OPEN
,
363 sta
->sta
.addr
, llid
, 0, 0);
366 reason
= cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES
);
367 /* fall through on else */
368 case NL80211_PLINK_CNF_RCVD
:
371 reason
= cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT
);
372 sta
->plink_state
= NL80211_PLINK_HOLDING
;
373 mod_plink_timer(sta
, dot11MeshHoldingTimeout(sdata
));
374 spin_unlock_bh(&sta
->lock
);
375 mesh_plink_frame_tx(sdata
, WLAN_SP_MESH_PEERING_CLOSE
,
376 sta
->sta
.addr
, llid
, plid
, reason
);
378 case NL80211_PLINK_HOLDING
:
380 del_timer(&sta
->plink_timer
);
381 mesh_plink_fsm_restart(sta
);
382 spin_unlock_bh(&sta
->lock
);
385 spin_unlock_bh(&sta
->lock
);
391 void mesh_plink_quiesce(struct sta_info
*sta
)
393 if (del_timer_sync(&sta
->plink_timer
))
394 sta
->plink_timer_was_running
= true;
397 void mesh_plink_restart(struct sta_info
*sta
)
399 if (sta
->plink_timer_was_running
) {
400 add_timer(&sta
->plink_timer
);
401 sta
->plink_timer_was_running
= false;
406 static inline void mesh_plink_timer_set(struct sta_info
*sta
, int timeout
)
408 sta
->plink_timer
.expires
= jiffies
+ (HZ
* timeout
/ 1000);
409 sta
->plink_timer
.data
= (unsigned long) sta
;
410 sta
->plink_timer
.function
= mesh_plink_timer
;
411 sta
->plink_timeout
= timeout
;
412 add_timer(&sta
->plink_timer
);
415 int mesh_plink_open(struct sta_info
*sta
)
418 struct ieee80211_sub_if_data
*sdata
= sta
->sdata
;
420 if (!test_sta_flag(sta
, WLAN_STA_AUTH
))
423 spin_lock_bh(&sta
->lock
);
424 get_random_bytes(&llid
, 2);
426 if (sta
->plink_state
!= NL80211_PLINK_LISTEN
) {
427 spin_unlock_bh(&sta
->lock
);
430 sta
->plink_state
= NL80211_PLINK_OPN_SNT
;
431 mesh_plink_timer_set(sta
, dot11MeshRetryTimeout(sdata
));
432 spin_unlock_bh(&sta
->lock
);
433 mpl_dbg("Mesh plink: starting establishment with %pM\n",
436 return mesh_plink_frame_tx(sdata
, WLAN_SP_MESH_PEERING_OPEN
,
437 sta
->sta
.addr
, llid
, 0, 0);
440 void mesh_plink_block(struct sta_info
*sta
)
442 struct ieee80211_sub_if_data
*sdata
= sta
->sdata
;
445 spin_lock_bh(&sta
->lock
);
446 deactivated
= __mesh_plink_deactivate(sta
);
447 sta
->plink_state
= NL80211_PLINK_BLOCKED
;
448 spin_unlock_bh(&sta
->lock
);
451 ieee80211_bss_info_change_notify(sdata
, BSS_CHANGED_BEACON
);
455 void mesh_rx_plink_frame(struct ieee80211_sub_if_data
*sdata
, struct ieee80211_mgmt
*mgmt
,
456 size_t len
, struct ieee80211_rx_status
*rx_status
)
458 struct ieee80211_local
*local
= sdata
->local
;
459 struct ieee802_11_elems elems
;
460 struct sta_info
*sta
;
461 enum plink_event event
;
462 enum ieee80211_self_protected_actioncode ftype
;
464 bool deactivated
, matches_local
= true;
467 __le16 plid
, llid
, reason
;
468 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
469 static const char *mplstates
[] = {
470 [NL80211_PLINK_LISTEN
] = "LISTEN",
471 [NL80211_PLINK_OPN_SNT
] = "OPN-SNT",
472 [NL80211_PLINK_OPN_RCVD
] = "OPN-RCVD",
473 [NL80211_PLINK_CNF_RCVD
] = "CNF_RCVD",
474 [NL80211_PLINK_ESTAB
] = "ESTAB",
475 [NL80211_PLINK_HOLDING
] = "HOLDING",
476 [NL80211_PLINK_BLOCKED
] = "BLOCKED"
480 /* need action_code, aux */
481 if (len
< IEEE80211_MIN_ACTION_SIZE
+ 3)
484 if (is_multicast_ether_addr(mgmt
->da
)) {
485 mpl_dbg("Mesh plink: ignore frame from multicast address");
489 baseaddr
= mgmt
->u
.action
.u
.self_prot
.variable
;
490 baselen
= (u8
*) mgmt
->u
.action
.u
.self_prot
.variable
- (u8
*) mgmt
;
491 if (mgmt
->u
.action
.u
.self_prot
.action_code
==
492 WLAN_SP_MESH_PEERING_CONFIRM
) {
496 ieee802_11_parse_elems(baseaddr
, len
- baselen
, &elems
);
497 if (!elems
.peering
) {
498 mpl_dbg("Mesh plink: missing necessary peer link ie\n");
502 sdata
->u
.mesh
.security
== IEEE80211_MESH_SEC_NONE
) {
503 mpl_dbg("Mesh plink: can't establish link with secure peer\n");
507 ftype
= mgmt
->u
.action
.u
.self_prot
.action_code
;
508 ie_len
= elems
.peering_len
;
509 if ((ftype
== WLAN_SP_MESH_PEERING_OPEN
&& ie_len
!= 4) ||
510 (ftype
== WLAN_SP_MESH_PEERING_CONFIRM
&& ie_len
!= 6) ||
511 (ftype
== WLAN_SP_MESH_PEERING_CLOSE
&& ie_len
!= 6
513 mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n",
518 if (ftype
!= WLAN_SP_MESH_PEERING_CLOSE
&&
519 (!elems
.mesh_id
|| !elems
.mesh_config
)) {
520 mpl_dbg("Mesh plink: missing necessary ie\n");
523 /* Note the lines below are correct, the llid in the frame is the plid
524 * from the point of view of this host.
526 memcpy(&plid
, PLINK_GET_LLID(elems
.peering
), 2);
527 if (ftype
== WLAN_SP_MESH_PEERING_CONFIRM
||
528 (ftype
== WLAN_SP_MESH_PEERING_CLOSE
&& ie_len
== 8))
529 memcpy(&llid
, PLINK_GET_PLID(elems
.peering
), 2);
533 sta
= sta_info_get(sdata
, mgmt
->sa
);
534 if (!sta
&& ftype
!= WLAN_SP_MESH_PEERING_OPEN
) {
535 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
540 if (ftype
== WLAN_SP_MESH_PEERING_OPEN
&&
541 !sta_meets_rssi_threshold(sta
, sdata
)) {
542 mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n",
548 if (sta
&& !test_sta_flag(sta
, WLAN_STA_AUTH
)) {
549 mpl_dbg("Mesh plink: Action frame from non-authed peer\n");
554 if (sta
&& sta
->plink_state
== NL80211_PLINK_BLOCKED
) {
559 /* Now we will figure out the appropriate event... */
560 event
= PLINK_UNDEFINED
;
561 if (ftype
!= WLAN_SP_MESH_PEERING_CLOSE
&&
562 (!mesh_matches_local(&elems
, sdata
))) {
563 matches_local
= false;
565 case WLAN_SP_MESH_PEERING_OPEN
:
568 case WLAN_SP_MESH_PEERING_CONFIRM
:
576 if (!sta
&& !matches_local
) {
578 reason
= cpu_to_le16(WLAN_REASON_MESH_CONFIG
);
580 mesh_plink_frame_tx(sdata
, WLAN_SP_MESH_PEERING_CLOSE
,
581 mgmt
->sa
, llid
, plid
, reason
);
584 /* ftype == WLAN_SP_MESH_PEERING_OPEN */
589 if (!mesh_plink_free_count(sdata
)) {
590 mpl_dbg("Mesh plink error: no more free plinks\n");
594 rates
= ieee80211_sta_get_rates(local
, &elems
, rx_status
->band
);
595 sta
= mesh_plink_alloc(sdata
, mgmt
->sa
, rates
, &elems
);
597 mpl_dbg("Mesh plink error: plink table full\n");
600 if (sta_info_insert_rcu(sta
)) {
605 spin_lock_bh(&sta
->lock
);
606 } else if (matches_local
) {
607 spin_lock_bh(&sta
->lock
);
609 case WLAN_SP_MESH_PEERING_OPEN
:
610 if (!mesh_plink_free_count(sdata
) ||
611 (sta
->plid
&& sta
->plid
!= plid
))
616 case WLAN_SP_MESH_PEERING_CONFIRM
:
617 if (!mesh_plink_free_count(sdata
) ||
618 (sta
->llid
!= llid
|| sta
->plid
!= plid
))
623 case WLAN_SP_MESH_PEERING_CLOSE
:
624 if (sta
->plink_state
== NL80211_PLINK_ESTAB
)
625 /* Do not check for llid or plid. This does not
626 * follow the standard but since multiple plinks
627 * per sta are not supported, it is necessary in
628 * order to avoid a livelock when MP A sees an
629 * establish peer link to MP B but MP B does not
630 * see it. This can be caused by a timeout in
631 * B's peer link establishment or B beign
635 else if (sta
->plid
!= plid
)
637 else if (ie_len
== 7 && sta
->llid
!= llid
)
643 mpl_dbg("Mesh plink: unknown frame subtype\n");
644 spin_unlock_bh(&sta
->lock
);
649 spin_lock_bh(&sta
->lock
);
652 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
653 mgmt
->sa
, mplstates
[sta
->plink_state
],
654 le16_to_cpu(sta
->llid
), le16_to_cpu(sta
->plid
),
657 switch (sta
->plink_state
) {
658 /* spin_unlock as soon as state is updated at each case */
659 case NL80211_PLINK_LISTEN
:
662 mesh_plink_fsm_restart(sta
);
663 spin_unlock_bh(&sta
->lock
);
666 sta
->plink_state
= NL80211_PLINK_OPN_RCVD
;
668 get_random_bytes(&llid
, 2);
670 mesh_plink_timer_set(sta
, dot11MeshRetryTimeout(sdata
));
671 spin_unlock_bh(&sta
->lock
);
672 mesh_plink_frame_tx(sdata
,
673 WLAN_SP_MESH_PEERING_OPEN
,
674 sta
->sta
.addr
, llid
, 0, 0);
675 mesh_plink_frame_tx(sdata
,
676 WLAN_SP_MESH_PEERING_CONFIRM
,
677 sta
->sta
.addr
, llid
, plid
, 0);
680 spin_unlock_bh(&sta
->lock
);
685 case NL80211_PLINK_OPN_SNT
:
689 reason
= cpu_to_le16(WLAN_REASON_MESH_CONFIG
);
692 reason
= cpu_to_le16(WLAN_REASON_MESH_CLOSE
);
693 sta
->reason
= reason
;
694 sta
->plink_state
= NL80211_PLINK_HOLDING
;
695 if (!mod_plink_timer(sta
,
696 dot11MeshHoldingTimeout(sdata
)))
697 sta
->ignore_plink_timer
= true;
700 spin_unlock_bh(&sta
->lock
);
701 mesh_plink_frame_tx(sdata
,
702 WLAN_SP_MESH_PEERING_CLOSE
,
703 sta
->sta
.addr
, llid
, plid
, reason
);
706 /* retry timer is left untouched */
707 sta
->plink_state
= NL80211_PLINK_OPN_RCVD
;
710 spin_unlock_bh(&sta
->lock
);
711 mesh_plink_frame_tx(sdata
,
712 WLAN_SP_MESH_PEERING_CONFIRM
,
713 sta
->sta
.addr
, llid
, plid
, 0);
716 sta
->plink_state
= NL80211_PLINK_CNF_RCVD
;
717 if (!mod_plink_timer(sta
,
718 dot11MeshConfirmTimeout(sdata
)))
719 sta
->ignore_plink_timer
= true;
721 spin_unlock_bh(&sta
->lock
);
724 spin_unlock_bh(&sta
->lock
);
729 case NL80211_PLINK_OPN_RCVD
:
733 reason
= cpu_to_le16(WLAN_REASON_MESH_CONFIG
);
736 reason
= cpu_to_le16(WLAN_REASON_MESH_CLOSE
);
737 sta
->reason
= reason
;
738 sta
->plink_state
= NL80211_PLINK_HOLDING
;
739 if (!mod_plink_timer(sta
,
740 dot11MeshHoldingTimeout(sdata
)))
741 sta
->ignore_plink_timer
= true;
744 spin_unlock_bh(&sta
->lock
);
745 mesh_plink_frame_tx(sdata
, WLAN_SP_MESH_PEERING_CLOSE
,
746 sta
->sta
.addr
, llid
, plid
, reason
);
750 spin_unlock_bh(&sta
->lock
);
751 mesh_plink_frame_tx(sdata
,
752 WLAN_SP_MESH_PEERING_CONFIRM
,
753 sta
->sta
.addr
, llid
, plid
, 0);
756 del_timer(&sta
->plink_timer
);
757 sta
->plink_state
= NL80211_PLINK_ESTAB
;
758 spin_unlock_bh(&sta
->lock
);
759 mesh_plink_inc_estab_count(sdata
);
760 ieee80211_bss_info_change_notify(sdata
, BSS_CHANGED_BEACON
);
761 mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
765 spin_unlock_bh(&sta
->lock
);
770 case NL80211_PLINK_CNF_RCVD
:
774 reason
= cpu_to_le16(WLAN_REASON_MESH_CONFIG
);
777 reason
= cpu_to_le16(WLAN_REASON_MESH_CLOSE
);
778 sta
->reason
= reason
;
779 sta
->plink_state
= NL80211_PLINK_HOLDING
;
780 if (!mod_plink_timer(sta
,
781 dot11MeshHoldingTimeout(sdata
)))
782 sta
->ignore_plink_timer
= true;
785 spin_unlock_bh(&sta
->lock
);
786 mesh_plink_frame_tx(sdata
,
787 WLAN_SP_MESH_PEERING_CLOSE
,
788 sta
->sta
.addr
, llid
, plid
, reason
);
791 del_timer(&sta
->plink_timer
);
792 sta
->plink_state
= NL80211_PLINK_ESTAB
;
793 spin_unlock_bh(&sta
->lock
);
794 mesh_plink_inc_estab_count(sdata
);
795 ieee80211_bss_info_change_notify(sdata
, BSS_CHANGED_BEACON
);
796 mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
798 mesh_plink_frame_tx(sdata
,
799 WLAN_SP_MESH_PEERING_CONFIRM
,
800 sta
->sta
.addr
, llid
, plid
, 0);
803 spin_unlock_bh(&sta
->lock
);
808 case NL80211_PLINK_ESTAB
:
811 reason
= cpu_to_le16(WLAN_REASON_MESH_CLOSE
);
812 sta
->reason
= reason
;
813 deactivated
= __mesh_plink_deactivate(sta
);
814 sta
->plink_state
= NL80211_PLINK_HOLDING
;
816 mod_plink_timer(sta
, dot11MeshHoldingTimeout(sdata
));
817 spin_unlock_bh(&sta
->lock
);
819 ieee80211_bss_info_change_notify(sdata
, BSS_CHANGED_BEACON
);
820 mesh_plink_frame_tx(sdata
, WLAN_SP_MESH_PEERING_CLOSE
,
821 sta
->sta
.addr
, llid
, plid
, reason
);
825 spin_unlock_bh(&sta
->lock
);
826 mesh_plink_frame_tx(sdata
,
827 WLAN_SP_MESH_PEERING_CONFIRM
,
828 sta
->sta
.addr
, llid
, plid
, 0);
831 spin_unlock_bh(&sta
->lock
);
835 case NL80211_PLINK_HOLDING
:
838 if (del_timer(&sta
->plink_timer
))
839 sta
->ignore_plink_timer
= 1;
840 mesh_plink_fsm_restart(sta
);
841 spin_unlock_bh(&sta
->lock
);
848 reason
= sta
->reason
;
849 spin_unlock_bh(&sta
->lock
);
850 mesh_plink_frame_tx(sdata
, WLAN_SP_MESH_PEERING_CLOSE
,
851 sta
->sta
.addr
, llid
, plid
, reason
);
854 spin_unlock_bh(&sta
->lock
);
858 /* should not get here, PLINK_BLOCKED is dealt with at the
859 * beginning of the function
861 spin_unlock_bh(&sta
->lock
);