2 * Copyright (c) 2008 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.
9 #include <linux/kernel.h>
10 #include <linux/random.h>
11 #include "ieee80211_i.h"
12 #include "ieee80211_rate.h"
15 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
16 #define mpl_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args)
18 #define mpl_dbg(fmt, args...) do { (void)(0); } while (0)
21 #define IEEE80211_FC(type, stype) cpu_to_le16(type | stype)
22 #define PLINK_GET_FRAME_SUBTYPE(p) (p)
23 #define PLINK_GET_LLID(p) (p + 1)
24 #define PLINK_GET_PLID(p) (p + 3)
26 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
27 jiffies + HZ * t / 1000))
29 /* Peer link cancel reasons, all subject to ANA approval */
30 #define MESH_LINK_CANCELLED 2
31 #define MESH_MAX_NEIGHBORS 3
32 #define MESH_CAPABILITY_POLICY_VIOLATION 4
33 #define MESH_CLOSE_RCVD 5
34 #define MESH_MAX_RETRIES 6
35 #define MESH_CONFIRM_TIMEOUT 7
36 #define MESH_SECURITY_ROLE_NEGOTIATION_DIFFERS 8
37 #define MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE 9
38 #define MESH_SECURITY_FAILED_VERIFICATION 10
40 #define dot11MeshMaxRetries(s) (s->u.sta.mshcfg.dot11MeshMaxRetries)
41 #define dot11MeshRetryTimeout(s) (s->u.sta.mshcfg.dot11MeshRetryTimeout)
42 #define dot11MeshConfirmTimeout(s) (s->u.sta.mshcfg.dot11MeshConfirmTimeout)
43 #define dot11MeshHoldingTimeout(s) (s->u.sta.mshcfg.dot11MeshHoldingTimeout)
44 #define dot11MeshMaxPeerLinks(s) (s->u.sta.mshcfg.dot11MeshMaxPeerLinks)
46 enum plink_frame_type
{
65 void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data
*sdata
)
67 atomic_inc(&sdata
->u
.sta
.mshstats
.estab_plinks
);
68 mesh_accept_plinks_update(sdata
->dev
);
72 void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data
*sdata
)
74 atomic_dec(&sdata
->u
.sta
.mshstats
.estab_plinks
);
75 mesh_accept_plinks_update(sdata
->dev
);
79 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
81 * @sta: mes peer link to restart
83 * Locking: this function must be called holding sta->plink_lock
85 static inline void mesh_plink_fsm_restart(struct sta_info
*sta
)
87 sta
->plink_state
= LISTEN
;
88 sta
->llid
= sta
->plid
= sta
->reason
= sta
->plink_retries
= 0;
92 * mesh_plink_add - allocate and add a new mesh peer link
94 * @hw_addr: hardware address (ETH_ALEN length)
95 * @rates: rates the mesh peer supports
96 * @dev: local mesh interface
98 * The initial state of the new plink is set to LISTEN
100 * Returns: non-NULL on success, ERR_PTR() on error.
102 struct sta_info
*mesh_plink_add(u8
*hw_addr
, u64 rates
, struct net_device
*dev
)
104 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
105 struct sta_info
*sta
;
107 if (memcmp(hw_addr
, dev
->dev_addr
, ETH_ALEN
) == 0)
108 /* never add ourselves as neighbours */
109 return ERR_PTR(-EINVAL
);
111 if (is_multicast_ether_addr(hw_addr
))
112 return ERR_PTR(-EINVAL
);
114 if (local
->num_sta
>= MESH_MAX_PLINKS
)
115 return ERR_PTR(-ENOSPC
);
117 sta
= sta_info_add(local
, dev
, hw_addr
, GFP_KERNEL
);
121 sta
->plink_state
= LISTEN
;
122 spin_lock_init(&sta
->plink_lock
);
123 init_timer(&sta
->plink_timer
);
124 sta
->flags
|= WLAN_STA_AUTHORIZED
;
125 sta
->supp_rates
[local
->hw
.conf
.channel
->band
] = rates
;
126 rate_control_rate_init(sta
, local
);
128 mesh_accept_plinks_update(dev
);
134 * __mesh_plink_deactivate - deactivate mesh peer link
136 * @sta: mesh peer link to deactivate
138 * All mesh paths with this peer as next hop will be flushed
140 * Locking: the caller must hold sta->plink_lock
142 static void __mesh_plink_deactivate(struct sta_info
*sta
)
144 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(sta
->dev
);
145 if (sta
->plink_state
== ESTAB
)
146 mesh_plink_dec_estab_count(sdata
);
147 sta
->plink_state
= BLOCKED
;
148 mesh_path_flush_by_nexthop(sta
);
152 * __mesh_plink_deactivate - deactivate mesh peer link
154 * @sta: mesh peer link to deactivate
156 * All mesh paths with this peer as next hop will be flushed
158 void mesh_plink_deactivate(struct sta_info
*sta
)
160 spin_lock_bh(&sta
->plink_lock
);
161 __mesh_plink_deactivate(sta
);
162 spin_unlock_bh(&sta
->plink_lock
);
165 static int mesh_plink_frame_tx(struct net_device
*dev
,
166 enum plink_frame_type action
, u8
*da
, __le16 llid
, __le16 plid
,
168 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
169 struct sk_buff
*skb
= dev_alloc_skb(local
->hw
.extra_tx_headroom
+ 400);
170 struct ieee80211_mgmt
*mgmt
;
171 bool include_plid
= false;
177 skb_reserve(skb
, local
->hw
.extra_tx_headroom
);
178 /* 25 is the size of the common mgmt part (24) plus the size of the
179 * common action part (1)
181 mgmt
= (struct ieee80211_mgmt
*)
182 skb_put(skb
, 25 + sizeof(mgmt
->u
.action
.u
.plink_action
));
183 memset(mgmt
, 0, 25 + sizeof(mgmt
->u
.action
.u
.plink_action
));
184 mgmt
->frame_control
= IEEE80211_FC(IEEE80211_FTYPE_MGMT
,
185 IEEE80211_STYPE_ACTION
);
186 memcpy(mgmt
->da
, da
, ETH_ALEN
);
187 memcpy(mgmt
->sa
, dev
->dev_addr
, ETH_ALEN
);
188 /* BSSID is left zeroed, wildcard value */
189 mgmt
->u
.action
.category
= PLINK_CATEGORY
;
190 mgmt
->u
.action
.u
.plink_action
.action_code
= action
;
192 if (action
== PLINK_CLOSE
)
193 mgmt
->u
.action
.u
.plink_action
.aux
= reason
;
195 mgmt
->u
.action
.u
.plink_action
.aux
= cpu_to_le16(0x0);
196 if (action
== PLINK_CONFIRM
) {
197 pos
= skb_put(skb
, 4);
198 /* two-byte status code followed by two-byte AID */
201 mesh_mgmt_ies_add(skb
, dev
);
204 /* Add Peer Link Management element */
224 pos
= skb_put(skb
, 2 + ie_len
);
225 *pos
++ = WLAN_EID_PEER_LINK
;
228 memcpy(pos
, &llid
, 2);
231 memcpy(pos
, &plid
, 2);
233 if (action
== PLINK_CLOSE
) {
235 memcpy(pos
, &reason
, 2);
238 ieee80211_sta_tx(dev
, skb
, 0);
242 void mesh_neighbour_update(u8
*hw_addr
, u64 rates
, struct net_device
*dev
,
243 bool peer_accepting_plinks
)
245 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
246 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
247 struct sta_info
*sta
;
249 sta
= sta_info_get(local
, hw_addr
);
251 sta
= mesh_plink_add(hw_addr
, rates
, dev
);
256 sta
->last_rx
= jiffies
;
257 sta
->supp_rates
[local
->hw
.conf
.channel
->band
] = rates
;
258 if (peer_accepting_plinks
&& sta
->plink_state
== LISTEN
&&
259 sdata
->u
.sta
.accepting_plinks
&&
260 sdata
->u
.sta
.mshcfg
.auto_open_plinks
)
261 mesh_plink_open(sta
);
266 static void mesh_plink_timer(unsigned long data
)
268 struct sta_info
*sta
;
269 __le16 llid
, plid
, reason
;
270 struct net_device
*dev
= NULL
;
271 struct ieee80211_sub_if_data
*sdata
;
272 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
273 DECLARE_MAC_BUF(mac
);
276 sta
= (struct sta_info
*) data
;
278 spin_lock_bh(&sta
->plink_lock
);
279 if (sta
->ignore_plink_timer
) {
280 sta
->ignore_plink_timer
= false;
281 spin_unlock_bh(&sta
->plink_lock
);
284 mpl_dbg("Mesh plink timer for %s fired on state %d\n",
285 print_mac(mac
, sta
->addr
), sta
->plink_state
);
290 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
292 switch (sta
->plink_state
) {
296 if (sta
->plink_retries
< dot11MeshMaxRetries(sdata
)) {
298 mpl_dbg("Mesh plink for %s (retry, timeout): %d %d\n",
299 print_mac(mac
, sta
->addr
),
300 sta
->plink_retries
, sta
->plink_timeout
);
301 get_random_bytes(&rand
, sizeof(u32
));
302 sta
->plink_timeout
= sta
->plink_timeout
+
303 rand
% sta
->plink_timeout
;
304 ++sta
->plink_retries
;
305 if (!mod_plink_timer(sta
, sta
->plink_timeout
))
307 spin_unlock_bh(&sta
->plink_lock
);
308 mesh_plink_frame_tx(dev
, PLINK_OPEN
, sta
->addr
, llid
,
312 reason
= cpu_to_le16(MESH_MAX_RETRIES
);
313 /* fall through on else */
317 reason
= cpu_to_le16(MESH_CONFIRM_TIMEOUT
);
318 sta
->plink_state
= HOLDING
;
319 if (!mod_plink_timer(sta
, dot11MeshHoldingTimeout(sdata
)))
321 spin_unlock_bh(&sta
->plink_lock
);
322 mesh_plink_frame_tx(dev
, PLINK_CLOSE
, sta
->addr
, llid
, plid
,
327 if (del_timer(&sta
->plink_timer
))
329 mesh_plink_fsm_restart(sta
);
330 spin_unlock_bh(&sta
->plink_lock
);
333 spin_unlock_bh(&sta
->plink_lock
);
340 static inline void mesh_plink_timer_set(struct sta_info
*sta
, int timeout
)
342 sta
->plink_timer
.expires
= jiffies
+ (HZ
* timeout
/ 1000);
343 sta
->plink_timer
.data
= (unsigned long) sta
;
344 sta
->plink_timer
.function
= mesh_plink_timer
;
345 sta
->plink_timeout
= timeout
;
347 add_timer(&sta
->plink_timer
);
350 int mesh_plink_open(struct sta_info
*sta
)
353 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(sta
->dev
);
354 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
355 DECLARE_MAC_BUF(mac
);
358 spin_lock_bh(&sta
->plink_lock
);
359 get_random_bytes(&llid
, 2);
361 if (sta
->plink_state
!= LISTEN
) {
362 spin_unlock_bh(&sta
->plink_lock
);
366 sta
->plink_state
= OPN_SNT
;
367 mesh_plink_timer_set(sta
, dot11MeshRetryTimeout(sdata
));
368 spin_unlock_bh(&sta
->plink_lock
);
369 mpl_dbg("Mesh plink: starting establishment with %s\n",
370 print_mac(mac
, sta
->addr
));
372 return mesh_plink_frame_tx(sta
->dev
, PLINK_OPEN
, sta
->addr
, llid
, 0, 0);
375 void mesh_plink_block(struct sta_info
*sta
)
377 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
378 DECLARE_MAC_BUF(mac
);
381 spin_lock_bh(&sta
->plink_lock
);
382 __mesh_plink_deactivate(sta
);
383 sta
->plink_state
= BLOCKED
;
384 spin_unlock_bh(&sta
->plink_lock
);
387 int mesh_plink_close(struct sta_info
*sta
)
389 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(sta
->dev
);
390 int llid
, plid
, reason
;
391 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
392 DECLARE_MAC_BUF(mac
);
395 mpl_dbg("Mesh plink: closing link with %s\n",
396 print_mac(mac
, sta
->addr
));
397 spin_lock_bh(&sta
->plink_lock
);
398 sta
->reason
= cpu_to_le16(MESH_LINK_CANCELLED
);
399 reason
= sta
->reason
;
401 if (sta
->plink_state
== LISTEN
|| sta
->plink_state
== BLOCKED
) {
402 mesh_plink_fsm_restart(sta
);
403 spin_unlock_bh(&sta
->plink_lock
);
406 } else if (sta
->plink_state
== ESTAB
) {
407 __mesh_plink_deactivate(sta
);
408 /* The timer should not be running */
409 if (!mod_plink_timer(sta
, dot11MeshHoldingTimeout(sdata
)))
411 } else if (!mod_plink_timer(sta
, dot11MeshHoldingTimeout(sdata
)))
412 sta
->ignore_plink_timer
= true;
414 sta
->plink_state
= HOLDING
;
417 spin_unlock_bh(&sta
->plink_lock
);
418 mesh_plink_frame_tx(sta
->dev
, PLINK_CLOSE
, sta
->addr
, llid
, plid
,
423 void mesh_rx_plink_frame(struct net_device
*dev
, struct ieee80211_mgmt
*mgmt
,
424 size_t len
, struct ieee80211_rx_status
*rx_status
)
426 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
427 struct ieee802_11_elems elems
;
428 struct sta_info
*sta
;
429 enum plink_event event
;
430 enum plink_frame_type ftype
;
434 __le16 plid
, llid
, reason
;
435 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
436 DECLARE_MAC_BUF(mac
);
438 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
440 if (is_multicast_ether_addr(mgmt
->da
)) {
441 mpl_dbg("Mesh plink: ignore frame from multicast address");
445 baseaddr
= mgmt
->u
.action
.u
.plink_action
.variable
;
446 baselen
= (u8
*) mgmt
->u
.action
.u
.plink_action
.variable
- (u8
*) mgmt
;
447 if (mgmt
->u
.action
.u
.plink_action
.action_code
== PLINK_CONFIRM
) {
451 ieee802_11_parse_elems(baseaddr
, len
- baselen
, &elems
);
452 if (!elems
.peer_link
) {
453 mpl_dbg("Mesh plink: missing necessary peer link ie\n");
457 ftype
= *((u8
*)PLINK_GET_FRAME_SUBTYPE(elems
.peer_link
));
458 ie_len
= elems
.peer_link_len
;
459 if ((ftype
== PLINK_OPEN
&& ie_len
!= 3) ||
460 (ftype
== PLINK_CONFIRM
&& ie_len
!= 5) ||
461 (ftype
== PLINK_CLOSE
&& ie_len
!= 5 && ie_len
!= 7)) {
462 mpl_dbg("Mesh plink: incorrect plink ie length\n");
466 if (ftype
!= PLINK_CLOSE
&& (!elems
.mesh_id
|| !elems
.mesh_config
)) {
467 mpl_dbg("Mesh plink: missing necessary ie\n");
470 /* Note the lines below are correct, the llid in the frame is the plid
471 * from the point of view of this host.
473 memcpy(&plid
, PLINK_GET_LLID(elems
.peer_link
), 2);
474 if (ftype
== PLINK_CONFIRM
|| (ftype
== PLINK_CLOSE
&& ie_len
== 7))
475 memcpy(&llid
, PLINK_GET_PLID(elems
.peer_link
), 2);
477 sta
= sta_info_get(local
, mgmt
->sa
);
478 if (!sta
&& ftype
!= PLINK_OPEN
) {
479 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
483 if (sta
&& sta
->plink_state
== BLOCKED
) {
488 /* Now we will figure out the appropriate event... */
489 event
= PLINK_UNDEFINED
;
490 if (ftype
!= PLINK_CLOSE
&& (!mesh_matches_local(&elems
, dev
))) {
502 spin_lock_bh(&sta
->plink_lock
);
504 /* ftype == PLINK_OPEN */
506 if (!mesh_plink_free_count(sdata
)) {
507 mpl_dbg("Mesh plink error: no more free plinks\n");
511 rates
= ieee80211_sta_get_rates(local
, &elems
, rx_status
->band
);
512 sta
= mesh_plink_add(mgmt
->sa
, rates
, dev
);
514 mpl_dbg("Mesh plink error: plink table full\n");
518 spin_lock_bh(&sta
->plink_lock
);
520 spin_lock_bh(&sta
->plink_lock
);
523 if (!mesh_plink_free_count(sdata
) ||
524 (sta
->plid
&& sta
->plid
!= plid
))
530 if (!mesh_plink_free_count(sdata
) ||
531 (sta
->llid
!= llid
|| sta
->plid
!= plid
))
537 if (sta
->plink_state
== ESTAB
)
538 /* Do not check for llid or plid. This does not
539 * follow the standard but since multiple plinks
540 * per sta are not supported, it is necessary in
541 * order to avoid a livelock when MP A sees an
542 * establish peer link to MP B but MP B does not
543 * see it. This can be caused by a timeout in
544 * B's peer link establishment or B beign
548 else if (sta
->plid
!= plid
)
550 else if (ie_len
== 7 && sta
->llid
!= llid
)
556 mpl_dbg("Mesh plink: unknown frame subtype\n");
557 spin_unlock_bh(&sta
->plink_lock
);
563 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %s %d %d %d %d\n",
564 print_mac(mac
, mgmt
->sa
), sta
->plink_state
,
565 __le16_to_cpu(sta
->llid
), __le16_to_cpu(sta
->plid
),
568 switch (sta
->plink_state
) {
569 /* spin_unlock as soon as state is updated at each case */
573 mesh_plink_fsm_restart(sta
);
574 spin_unlock_bh(&sta
->plink_lock
);
577 sta
->plink_state
= OPN_RCVD
;
579 get_random_bytes(&llid
, 2);
581 mesh_plink_timer_set(sta
, dot11MeshRetryTimeout(sdata
));
582 spin_unlock_bh(&sta
->plink_lock
);
583 mesh_plink_frame_tx(dev
, PLINK_OPEN
, sta
->addr
, llid
,
585 mesh_plink_frame_tx(dev
, PLINK_CONFIRM
, sta
->addr
,
589 spin_unlock_bh(&sta
->plink_lock
);
598 reason
= cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION
);
601 reason
= cpu_to_le16(MESH_CLOSE_RCVD
);
602 sta
->reason
= reason
;
603 sta
->plink_state
= HOLDING
;
604 if (!mod_plink_timer(sta
,
605 dot11MeshHoldingTimeout(sdata
)))
606 sta
->ignore_plink_timer
= true;
609 spin_unlock_bh(&sta
->plink_lock
);
610 mesh_plink_frame_tx(dev
, PLINK_CLOSE
, sta
->addr
, llid
,
614 /* retry timer is left untouched */
615 sta
->plink_state
= OPN_RCVD
;
618 spin_unlock_bh(&sta
->plink_lock
);
619 mesh_plink_frame_tx(dev
, PLINK_CONFIRM
, sta
->addr
, llid
,
623 sta
->plink_state
= CNF_RCVD
;
624 if (!mod_plink_timer(sta
,
625 dot11MeshConfirmTimeout(sdata
)))
626 sta
->ignore_plink_timer
= true;
628 spin_unlock_bh(&sta
->plink_lock
);
631 spin_unlock_bh(&sta
->plink_lock
);
640 reason
= cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION
);
643 reason
= cpu_to_le16(MESH_CLOSE_RCVD
);
644 sta
->reason
= reason
;
645 sta
->plink_state
= HOLDING
;
646 if (!mod_plink_timer(sta
,
647 dot11MeshHoldingTimeout(sdata
)))
648 sta
->ignore_plink_timer
= true;
651 spin_unlock_bh(&sta
->plink_lock
);
652 mesh_plink_frame_tx(dev
, PLINK_CLOSE
, sta
->addr
, llid
,
657 spin_unlock_bh(&sta
->plink_lock
);
658 mesh_plink_frame_tx(dev
, PLINK_CONFIRM
, sta
->addr
, llid
,
662 if (del_timer(&sta
->plink_timer
))
664 sta
->plink_state
= ESTAB
;
665 mesh_plink_inc_estab_count(sdata
);
666 spin_unlock_bh(&sta
->plink_lock
);
667 mpl_dbg("Mesh plink with %s ESTABLISHED\n",
668 print_mac(mac
, sta
->addr
));
671 spin_unlock_bh(&sta
->plink_lock
);
680 reason
= cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION
);
683 reason
= cpu_to_le16(MESH_CLOSE_RCVD
);
684 sta
->reason
= reason
;
685 sta
->plink_state
= HOLDING
;
686 if (!mod_plink_timer(sta
,
687 dot11MeshHoldingTimeout(sdata
)))
688 sta
->ignore_plink_timer
= true;
691 spin_unlock_bh(&sta
->plink_lock
);
692 mesh_plink_frame_tx(dev
, PLINK_CLOSE
, sta
->addr
, llid
,
695 if (del_timer(&sta
->plink_timer
))
697 sta
->plink_state
= ESTAB
;
698 mesh_plink_inc_estab_count(sdata
);
699 spin_unlock_bh(&sta
->plink_lock
);
700 mpl_dbg("Mesh plink with %s ESTABLISHED\n",
701 print_mac(mac
, sta
->addr
));
702 mesh_plink_frame_tx(dev
, PLINK_CONFIRM
, sta
->addr
, llid
,
706 spin_unlock_bh(&sta
->plink_lock
);
714 reason
= cpu_to_le16(MESH_CLOSE_RCVD
);
715 sta
->reason
= reason
;
716 __mesh_plink_deactivate(sta
);
717 sta
->plink_state
= HOLDING
;
719 if (!mod_plink_timer(sta
,
720 dot11MeshHoldingTimeout(sdata
)))
722 spin_unlock_bh(&sta
->plink_lock
);
723 mesh_plink_frame_tx(dev
, PLINK_CLOSE
, sta
->addr
, llid
,
728 spin_unlock_bh(&sta
->plink_lock
);
729 mesh_plink_frame_tx(dev
, PLINK_CONFIRM
, sta
->addr
, llid
,
733 spin_unlock_bh(&sta
->plink_lock
);
740 if (del_timer(&sta
->plink_timer
)) {
741 sta
->ignore_plink_timer
= 1;
744 mesh_plink_fsm_restart(sta
);
745 spin_unlock_bh(&sta
->plink_lock
);
752 reason
= sta
->reason
;
753 spin_unlock_bh(&sta
->plink_lock
);
754 mesh_plink_frame_tx(dev
, PLINK_CLOSE
, sta
->addr
, llid
,
758 spin_unlock_bh(&sta
->plink_lock
);
762 /* should not get here, BLOCKED is dealt with at the beggining
765 spin_unlock_bh(&sta
->plink_lock
);