mac80211: fix kernel-doc comment for mesh_plink_deactivate
[safe/jmp/linux-2.6] / net / mac80211 / mesh_plink.c
1 /*
2  * Copyright (c) 2008 open80211s Ltd.
3  * Author:     Luis Carlos Cobo <luisca@cozybit.com>
4  *
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.
8  */
9 #include <linux/kernel.h>
10 #include <linux/random.h>
11 #include "ieee80211_i.h"
12 #include "ieee80211_rate.h"
13 #include "mesh.h"
14
15 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
16 #define mpl_dbg(fmt, args...)   printk(KERN_DEBUG fmt, ##args)
17 #else
18 #define mpl_dbg(fmt, args...)   do { (void)(0); } while (0)
19 #endif
20
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)
25
26 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
27                                 jiffies + HZ * t / 1000))
28
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
39
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)
45
46 enum plink_frame_type {
47         PLINK_OPEN = 0,
48         PLINK_CONFIRM,
49         PLINK_CLOSE
50 };
51
52 enum plink_event {
53         PLINK_UNDEFINED,
54         OPN_ACPT,
55         OPN_RJCT,
56         OPN_IGNR,
57         CNF_ACPT,
58         CNF_RJCT,
59         CNF_IGNR,
60         CLS_ACPT,
61         CLS_IGNR
62 };
63
64 static inline
65 void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
66 {
67         atomic_inc(&sdata->u.sta.mshstats.estab_plinks);
68         mesh_accept_plinks_update(sdata->dev);
69 }
70
71 static inline
72 void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
73 {
74         atomic_dec(&sdata->u.sta.mshstats.estab_plinks);
75         mesh_accept_plinks_update(sdata->dev);
76 }
77
78 /**
79  * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
80  *
81  * @sta: mes peer link to restart
82  *
83  * Locking: this function must be called holding sta->plink_lock
84  */
85 static inline void mesh_plink_fsm_restart(struct sta_info *sta)
86 {
87         sta->plink_state = LISTEN;
88         sta->llid = sta->plid = sta->reason = sta->plink_retries = 0;
89 }
90
91 /**
92  * mesh_plink_add - allocate and add a new mesh peer link
93  *
94  * @hw_addr: hardware address (ETH_ALEN length)
95  * @rates: rates the mesh peer supports
96  * @dev: local mesh interface
97  *
98  * The initial state of the new plink is set to LISTEN
99  *
100  * Returns: non-NULL on success, ERR_PTR() on error.
101  */
102 struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates, struct net_device *dev)
103 {
104         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
105         struct sta_info *sta;
106
107         if (memcmp(hw_addr, dev->dev_addr, ETH_ALEN) == 0)
108                 /* never add ourselves as neighbours */
109                 return ERR_PTR(-EINVAL);
110
111         if (is_multicast_ether_addr(hw_addr))
112                 return ERR_PTR(-EINVAL);
113
114         if (local->num_sta >= MESH_MAX_PLINKS)
115                 return ERR_PTR(-ENOSPC);
116
117         sta = sta_info_add(local, dev, hw_addr, GFP_KERNEL);
118         if (IS_ERR(sta))
119                 return sta;
120
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);
127
128         mesh_accept_plinks_update(dev);
129
130         return sta;
131 }
132
133 /**
134  * mesh_plink_deactivate - deactivate mesh peer link
135  *
136  * @sta: mesh peer link to deactivate
137  *
138  * All mesh paths with this peer as next hop will be flushed
139  *
140  * Locking: the caller must hold sta->plink_lock
141  */
142 static void __mesh_plink_deactivate(struct sta_info *sta)
143 {
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);
149 }
150
151 /**
152  * __mesh_plink_deactivate - deactivate mesh peer link
153  *
154  * @sta: mesh peer link to deactivate
155  *
156  * All mesh paths with this peer as next hop will be flushed
157  */
158 void mesh_plink_deactivate(struct sta_info *sta)
159 {
160         spin_lock_bh(&sta->plink_lock);
161         __mesh_plink_deactivate(sta);
162         spin_unlock_bh(&sta->plink_lock);
163 }
164
165 static int mesh_plink_frame_tx(struct net_device *dev,
166                 enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid,
167                 __le16 reason) {
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;
172         u8 *pos;
173         int ie_len;
174
175         if (!skb)
176                 return -1;
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)
180          */
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;
191
192         if (action == PLINK_CLOSE)
193                 mgmt->u.action.u.plink_action.aux = reason;
194         else {
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 */
199                         memset(pos, 0, 4);
200                 }
201                 mesh_mgmt_ies_add(skb, dev);
202         }
203
204         /* Add Peer Link Management element */
205         switch (action) {
206         case PLINK_OPEN:
207                 ie_len = 3;
208                 break;
209         case PLINK_CONFIRM:
210                 ie_len = 5;
211                 include_plid = true;
212                 break;
213         case PLINK_CLOSE:
214         default:
215                 if (!plid)
216                         ie_len = 5;
217                 else {
218                         ie_len = 7;
219                         include_plid = true;
220                 }
221                 break;
222         }
223
224         pos = skb_put(skb, 2 + ie_len);
225         *pos++ = WLAN_EID_PEER_LINK;
226         *pos++ = ie_len;
227         *pos++ = action;
228         memcpy(pos, &llid, 2);
229         if (include_plid) {
230                 pos += 2;
231                 memcpy(pos, &plid, 2);
232         }
233         if (action == PLINK_CLOSE) {
234                 pos += 2;
235                 memcpy(pos, &reason, 2);
236         }
237
238         ieee80211_sta_tx(dev, skb, 0);
239         return 0;
240 }
241
242 void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev,
243                            bool peer_accepting_plinks)
244 {
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;
248
249         sta = sta_info_get(local, hw_addr);
250         if (!sta) {
251                 sta = mesh_plink_add(hw_addr, rates, dev);
252                 if (IS_ERR(sta))
253                         return;
254         }
255
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);
262
263         sta_info_put(sta);
264 }
265
266 static void mesh_plink_timer(unsigned long data)
267 {
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);
274 #endif
275
276         sta = (struct sta_info *) data;
277
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);
282                 return;
283         }
284         mpl_dbg("Mesh plink timer for %s fired on state %d\n",
285                         print_mac(mac, sta->addr), sta->plink_state);
286         reason = 0;
287         llid = sta->llid;
288         plid = sta->plid;
289         dev = sta->dev;
290         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
291
292         switch (sta->plink_state) {
293         case OPN_RCVD:
294         case OPN_SNT:
295                 /* retry timer */
296                 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
297                         u32 rand;
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))
306                                 __sta_info_get(sta);
307                         spin_unlock_bh(&sta->plink_lock);
308                         mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
309                                             0, 0);
310                         break;
311                 }
312                 reason = cpu_to_le16(MESH_MAX_RETRIES);
313                 /* fall through on else */
314         case CNF_RCVD:
315                 /* confirm timer */
316                 if (!reason)
317                         reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
318                 sta->plink_state = HOLDING;
319                 if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)))
320                         __sta_info_get(sta);
321                 spin_unlock_bh(&sta->plink_lock);
322                 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid,
323                                     reason);
324                 break;
325         case HOLDING:
326                 /* holding timer */
327                 if (del_timer(&sta->plink_timer))
328                         sta_info_put(sta);
329                 mesh_plink_fsm_restart(sta);
330                 spin_unlock_bh(&sta->plink_lock);
331                 break;
332         default:
333                 spin_unlock_bh(&sta->plink_lock);
334                 break;
335         }
336
337         sta_info_put(sta);
338 }
339
340 static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
341 {
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;
346         __sta_info_get(sta);
347         add_timer(&sta->plink_timer);
348 }
349
350 int mesh_plink_open(struct sta_info *sta)
351 {
352         __le16 llid;
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);
356 #endif
357
358         spin_lock_bh(&sta->plink_lock);
359         get_random_bytes(&llid, 2);
360         sta->llid = llid;
361         if (sta->plink_state != LISTEN) {
362                 spin_unlock_bh(&sta->plink_lock);
363                 sta_info_put(sta);
364                 return -EBUSY;
365         }
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));
371
372         return mesh_plink_frame_tx(sta->dev, PLINK_OPEN, sta->addr, llid, 0, 0);
373 }
374
375 void mesh_plink_block(struct sta_info *sta)
376 {
377 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
378         DECLARE_MAC_BUF(mac);
379 #endif
380
381         spin_lock_bh(&sta->plink_lock);
382         __mesh_plink_deactivate(sta);
383         sta->plink_state = BLOCKED;
384         spin_unlock_bh(&sta->plink_lock);
385 }
386
387 int mesh_plink_close(struct sta_info *sta)
388 {
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);
393 #endif
394
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;
400
401         if (sta->plink_state == LISTEN || sta->plink_state == BLOCKED) {
402                 mesh_plink_fsm_restart(sta);
403                 spin_unlock_bh(&sta->plink_lock);
404                 sta_info_put(sta);
405                 return 0;
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)))
410                         __sta_info_get(sta);
411         } else if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)))
412                 sta->ignore_plink_timer = true;
413
414         sta->plink_state = HOLDING;
415         llid = sta->llid;
416         plid = sta->plid;
417         spin_unlock_bh(&sta->plink_lock);
418         mesh_plink_frame_tx(sta->dev, PLINK_CLOSE, sta->addr, llid, plid,
419                             reason);
420         return 0;
421 }
422
423 void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
424                          size_t len, struct ieee80211_rx_status *rx_status)
425 {
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;
431         size_t baselen;
432         u8 ie_len;
433         u8 *baseaddr;
434         __le16 plid, llid, reason;
435 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
436         DECLARE_MAC_BUF(mac);
437 #endif
438         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
439
440         if (is_multicast_ether_addr(mgmt->da)) {
441                 mpl_dbg("Mesh plink: ignore frame from multicast address");
442                 return;
443         }
444
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) {
448                 baseaddr += 4;
449                 baselen -= 4;
450         }
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");
454                 return;
455         }
456
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");
463                 return;
464         }
465
466         if (ftype != PLINK_CLOSE && (!elems.mesh_id || !elems.mesh_config)) {
467                 mpl_dbg("Mesh plink: missing necessary ie\n");
468                 return;
469         }
470         /* Note the lines below are correct, the llid in the frame is the plid
471          * from the point of view of this host.
472          */
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);
476
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");
480                 return;
481         }
482
483         if (sta && sta->plink_state == BLOCKED) {
484                 sta_info_put(sta);
485                 return;
486         }
487
488         /* Now we will figure out the appropriate event... */
489         event = PLINK_UNDEFINED;
490         if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, dev))) {
491                 switch (ftype) {
492                 case PLINK_OPEN:
493                         event = OPN_RJCT;
494                         break;
495                 case PLINK_CONFIRM:
496                         event = CNF_RJCT;
497                         break;
498                 case PLINK_CLOSE:
499                         /* avoid warning */
500                         break;
501                 }
502                 spin_lock_bh(&sta->plink_lock);
503         } else if (!sta) {
504                 /* ftype == PLINK_OPEN */
505                 u64 rates;
506                 if (!mesh_plink_free_count(sdata)) {
507                         mpl_dbg("Mesh plink error: no more free plinks\n");
508                         return;
509                 }
510
511                 rates = ieee80211_sta_get_rates(local, &elems, rx_status->band);
512                 sta = mesh_plink_add(mgmt->sa, rates, dev);
513                 if (IS_ERR(sta)) {
514                         mpl_dbg("Mesh plink error: plink table full\n");
515                         return;
516                 }
517                 event = OPN_ACPT;
518                 spin_lock_bh(&sta->plink_lock);
519         } else {
520                 spin_lock_bh(&sta->plink_lock);
521                 switch (ftype) {
522                 case PLINK_OPEN:
523                         if (!mesh_plink_free_count(sdata) ||
524                                         (sta->plid && sta->plid != plid))
525                                 event = OPN_IGNR;
526                         else
527                                 event = OPN_ACPT;
528                         break;
529                 case PLINK_CONFIRM:
530                         if (!mesh_plink_free_count(sdata) ||
531                                 (sta->llid != llid || sta->plid != plid))
532                                 event = CNF_IGNR;
533                         else
534                                 event = CNF_ACPT;
535                         break;
536                 case PLINK_CLOSE:
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
545                                  * restarted.
546                                  */
547                                 event = CLS_ACPT;
548                         else if (sta->plid != plid)
549                                 event = CLS_IGNR;
550                         else if (ie_len == 7 && sta->llid != llid)
551                                 event = CLS_IGNR;
552                         else
553                                 event = CLS_ACPT;
554                         break;
555                 default:
556                         mpl_dbg("Mesh plink: unknown frame subtype\n");
557                         spin_unlock_bh(&sta->plink_lock);
558                         sta_info_put(sta);
559                         return;
560                 }
561         }
562
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),
566                         event);
567         reason = 0;
568         switch (sta->plink_state) {
569                 /* spin_unlock as soon as state is updated at each case */
570         case LISTEN:
571                 switch (event) {
572                 case CLS_ACPT:
573                         mesh_plink_fsm_restart(sta);
574                         spin_unlock_bh(&sta->plink_lock);
575                         break;
576                 case OPN_ACPT:
577                         sta->plink_state = OPN_RCVD;
578                         sta->plid = plid;
579                         get_random_bytes(&llid, 2);
580                         sta->llid = llid;
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,
584                                             0, 0);
585                         mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr,
586                                             llid, plid, 0);
587                         break;
588                 default:
589                         spin_unlock_bh(&sta->plink_lock);
590                         break;
591                 }
592                 break;
593
594         case OPN_SNT:
595                 switch (event) {
596                 case OPN_RJCT:
597                 case CNF_RJCT:
598                         reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
599                 case CLS_ACPT:
600                         if (!reason)
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;
607
608                         llid = sta->llid;
609                         spin_unlock_bh(&sta->plink_lock);
610                         mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
611                                             plid, reason);
612                         break;
613                 case OPN_ACPT:
614                         /* retry timer is left untouched */
615                         sta->plink_state = OPN_RCVD;
616                         sta->plid = plid;
617                         llid = sta->llid;
618                         spin_unlock_bh(&sta->plink_lock);
619                         mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
620                                             plid, 0);
621                         break;
622                 case CNF_ACPT:
623                         sta->plink_state = CNF_RCVD;
624                         if (!mod_plink_timer(sta,
625                                              dot11MeshConfirmTimeout(sdata)))
626                                 sta->ignore_plink_timer = true;
627
628                         spin_unlock_bh(&sta->plink_lock);
629                         break;
630                 default:
631                         spin_unlock_bh(&sta->plink_lock);
632                         break;
633                 }
634                 break;
635
636         case OPN_RCVD:
637                 switch (event) {
638                 case OPN_RJCT:
639                 case CNF_RJCT:
640                         reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
641                 case CLS_ACPT:
642                         if (!reason)
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;
649
650                         llid = sta->llid;
651                         spin_unlock_bh(&sta->plink_lock);
652                         mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
653                                             plid, reason);
654                         break;
655                 case OPN_ACPT:
656                         llid = sta->llid;
657                         spin_unlock_bh(&sta->plink_lock);
658                         mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
659                                             plid, 0);
660                         break;
661                 case CNF_ACPT:
662                         if (del_timer(&sta->plink_timer))
663                                 sta_info_put(sta);
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));
669                         break;
670                 default:
671                         spin_unlock_bh(&sta->plink_lock);
672                         break;
673                 }
674                 break;
675
676         case CNF_RCVD:
677                 switch (event) {
678                 case OPN_RJCT:
679                 case CNF_RJCT:
680                         reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
681                 case CLS_ACPT:
682                         if (!reason)
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;
689
690                         llid = sta->llid;
691                         spin_unlock_bh(&sta->plink_lock);
692                         mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
693                                             plid, reason);
694                         break;
695                 case OPN_ACPT:
696                         if (del_timer(&sta->plink_timer))
697                                 sta_info_put(sta);
698                         sta->plink_state = ESTAB;
699                         mesh_plink_inc_estab_count(sdata);
700                         spin_unlock_bh(&sta->plink_lock);
701                         mpl_dbg("Mesh plink with %s ESTABLISHED\n",
702                                         print_mac(mac, sta->addr));
703                         mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
704                                             plid, 0);
705                         break;
706                 default:
707                         spin_unlock_bh(&sta->plink_lock);
708                         break;
709                 }
710                 break;
711
712         case ESTAB:
713                 switch (event) {
714                 case CLS_ACPT:
715                         reason = cpu_to_le16(MESH_CLOSE_RCVD);
716                         sta->reason = reason;
717                         __mesh_plink_deactivate(sta);
718                         sta->plink_state = HOLDING;
719                         llid = sta->llid;
720                         if (!mod_plink_timer(sta,
721                                         dot11MeshHoldingTimeout(sdata)))
722                                 __sta_info_get(sta);
723                         spin_unlock_bh(&sta->plink_lock);
724                         mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
725                                             plid, reason);
726                         break;
727                 case OPN_ACPT:
728                         llid = sta->llid;
729                         spin_unlock_bh(&sta->plink_lock);
730                         mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
731                                             plid, 0);
732                         break;
733                 default:
734                         spin_unlock_bh(&sta->plink_lock);
735                         break;
736                 }
737                 break;
738         case HOLDING:
739                 switch (event) {
740                 case CLS_ACPT:
741                         if (del_timer(&sta->plink_timer)) {
742                                 sta->ignore_plink_timer = 1;
743                                 sta_info_put(sta);
744                         }
745                         mesh_plink_fsm_restart(sta);
746                         spin_unlock_bh(&sta->plink_lock);
747                         break;
748                 case OPN_ACPT:
749                 case CNF_ACPT:
750                 case OPN_RJCT:
751                 case CNF_RJCT:
752                         llid = sta->llid;
753                         reason = sta->reason;
754                         spin_unlock_bh(&sta->plink_lock);
755                         mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
756                                             plid, reason);
757                         break;
758                 default:
759                         spin_unlock_bh(&sta->plink_lock);
760                 }
761                 break;
762         default:
763                 /* should not get here, BLOCKED is dealt with at the beggining
764                  * of the function
765                  */
766                 spin_unlock_bh(&sta->plink_lock);
767                 break;
768         }
769         sta_info_put(sta);
770 }