mac80211: automatically free sta struct when insertion fails
[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);
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);
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 = PLINK_LISTEN;
88         sta->llid = sta->plid = sta->reason = 0;
89         sta->plink_retries = 0;
90 }
91
92 /*
93  * NOTE: This is just an alias for sta_info_alloc(), see notes
94  *       on it in the lifecycle management section!
95  */
96 static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
97                                          u8 *hw_addr, u64 rates)
98 {
99         struct ieee80211_local *local = sdata->local;
100         struct sta_info *sta;
101
102         if (local->num_sta >= MESH_MAX_PLINKS)
103                 return NULL;
104
105         sta = sta_info_alloc(sdata, hw_addr, GFP_ATOMIC);
106         if (!sta)
107                 return NULL;
108
109         sta->flags |= WLAN_STA_AUTHORIZED;
110         sta->supp_rates[local->hw.conf.channel->band] = rates;
111
112         return sta;
113 }
114
115 /**
116  * mesh_plink_deactivate - deactivate mesh peer link
117  *
118  * @sta: mesh peer link to deactivate
119  *
120  * All mesh paths with this peer as next hop will be flushed
121  *
122  * Locking: the caller must hold sta->plink_lock
123  */
124 static void __mesh_plink_deactivate(struct sta_info *sta)
125 {
126         struct ieee80211_sub_if_data *sdata = sta->sdata;
127
128         if (sta->plink_state == PLINK_ESTAB)
129                 mesh_plink_dec_estab_count(sdata);
130         sta->plink_state = PLINK_BLOCKED;
131         mesh_path_flush_by_nexthop(sta);
132 }
133
134 /**
135  * __mesh_plink_deactivate - deactivate mesh peer link
136  *
137  * @sta: mesh peer link to deactivate
138  *
139  * All mesh paths with this peer as next hop will be flushed
140  */
141 void mesh_plink_deactivate(struct sta_info *sta)
142 {
143         spin_lock_bh(&sta->plink_lock);
144         __mesh_plink_deactivate(sta);
145         spin_unlock_bh(&sta->plink_lock);
146 }
147
148 static int mesh_plink_frame_tx(struct net_device *dev,
149                 enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid,
150                 __le16 reason) {
151         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
152         struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
153         struct ieee80211_mgmt *mgmt;
154         bool include_plid = false;
155         u8 *pos;
156         int ie_len;
157
158         if (!skb)
159                 return -1;
160         skb_reserve(skb, local->hw.extra_tx_headroom);
161         /* 25 is the size of the common mgmt part (24) plus the size of the
162          * common action part (1)
163          */
164         mgmt = (struct ieee80211_mgmt *)
165                 skb_put(skb, 25 + sizeof(mgmt->u.action.u.plink_action));
166         memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.plink_action));
167         mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
168                                            IEEE80211_STYPE_ACTION);
169         memcpy(mgmt->da, da, ETH_ALEN);
170         memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
171         /* BSSID is left zeroed, wildcard value */
172         mgmt->u.action.category = PLINK_CATEGORY;
173         mgmt->u.action.u.plink_action.action_code = action;
174
175         if (action == PLINK_CLOSE)
176                 mgmt->u.action.u.plink_action.aux = reason;
177         else {
178                 mgmt->u.action.u.plink_action.aux = cpu_to_le16(0x0);
179                 if (action == PLINK_CONFIRM) {
180                         pos = skb_put(skb, 4);
181                         /* two-byte status code followed by two-byte AID */
182                         memset(pos, 0, 4);
183                 }
184                 mesh_mgmt_ies_add(skb, dev);
185         }
186
187         /* Add Peer Link Management element */
188         switch (action) {
189         case PLINK_OPEN:
190                 ie_len = 3;
191                 break;
192         case PLINK_CONFIRM:
193                 ie_len = 5;
194                 include_plid = true;
195                 break;
196         case PLINK_CLOSE:
197         default:
198                 if (!plid)
199                         ie_len = 5;
200                 else {
201                         ie_len = 7;
202                         include_plid = true;
203                 }
204                 break;
205         }
206
207         pos = skb_put(skb, 2 + ie_len);
208         *pos++ = WLAN_EID_PEER_LINK;
209         *pos++ = ie_len;
210         *pos++ = action;
211         memcpy(pos, &llid, 2);
212         if (include_plid) {
213                 pos += 2;
214                 memcpy(pos, &plid, 2);
215         }
216         if (action == PLINK_CLOSE) {
217                 pos += 2;
218                 memcpy(pos, &reason, 2);
219         }
220
221         ieee80211_sta_tx(dev, skb, 0);
222         return 0;
223 }
224
225 void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev,
226                            bool peer_accepting_plinks)
227 {
228         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
229         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
230         struct sta_info *sta;
231
232         rcu_read_lock();
233
234         sta = sta_info_get(local, hw_addr);
235         if (!sta) {
236                 sta = mesh_plink_alloc(sdata, hw_addr, rates);
237                 if (!sta) {
238                         rcu_read_unlock();
239                         return;
240                 }
241                 if (sta_info_insert(sta)) {
242                         rcu_read_unlock();
243                         return;
244                 }
245         }
246
247         sta->last_rx = jiffies;
248         sta->supp_rates[local->hw.conf.channel->band] = rates;
249         if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN &&
250                         sdata->u.sta.accepting_plinks &&
251                         sdata->u.sta.mshcfg.auto_open_plinks)
252                 mesh_plink_open(sta);
253
254         rcu_read_unlock();
255 }
256
257 static void mesh_plink_timer(unsigned long data)
258 {
259         struct sta_info *sta;
260         __le16 llid, plid, reason;
261         struct net_device *dev = NULL;
262         struct ieee80211_sub_if_data *sdata;
263 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
264         DECLARE_MAC_BUF(mac);
265 #endif
266
267         /*
268          * This STA is valid because sta_info_destroy() will
269          * del_timer_sync() this timer after having made sure
270          * it cannot be readded (by deleting the plink.)
271          */
272         sta = (struct sta_info *) data;
273
274         spin_lock_bh(&sta->plink_lock);
275         if (sta->ignore_plink_timer) {
276                 sta->ignore_plink_timer = false;
277                 spin_unlock_bh(&sta->plink_lock);
278                 return;
279         }
280         mpl_dbg("Mesh plink timer for %s fired on state %d\n",
281                         print_mac(mac, sta->addr), sta->plink_state);
282         reason = 0;
283         llid = sta->llid;
284         plid = sta->plid;
285         sdata = sta->sdata;
286         dev = sdata->dev;
287
288         switch (sta->plink_state) {
289         case PLINK_OPN_RCVD:
290         case PLINK_OPN_SNT:
291                 /* retry timer */
292                 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
293                         u32 rand;
294                         mpl_dbg("Mesh plink for %s (retry, timeout): %d %d\n",
295                                         print_mac(mac, sta->addr),
296                                         sta->plink_retries, sta->plink_timeout);
297                         get_random_bytes(&rand, sizeof(u32));
298                         sta->plink_timeout = sta->plink_timeout +
299                                              rand % sta->plink_timeout;
300                         ++sta->plink_retries;
301                         mod_plink_timer(sta, sta->plink_timeout);
302                         spin_unlock_bh(&sta->plink_lock);
303                         mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
304                                             0, 0);
305                         break;
306                 }
307                 reason = cpu_to_le16(MESH_MAX_RETRIES);
308                 /* fall through on else */
309         case PLINK_CNF_RCVD:
310                 /* confirm timer */
311                 if (!reason)
312                         reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
313                 sta->plink_state = PLINK_HOLDING;
314                 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
315                 spin_unlock_bh(&sta->plink_lock);
316                 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid,
317                                     reason);
318                 break;
319         case PLINK_HOLDING:
320                 /* holding timer */
321                 del_timer(&sta->plink_timer);
322                 mesh_plink_fsm_restart(sta);
323                 spin_unlock_bh(&sta->plink_lock);
324                 break;
325         default:
326                 spin_unlock_bh(&sta->plink_lock);
327                 break;
328         }
329 }
330
331 static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
332 {
333         sta->plink_timer.expires = jiffies + (HZ * timeout / 1000);
334         sta->plink_timer.data = (unsigned long) sta;
335         sta->plink_timer.function = mesh_plink_timer;
336         sta->plink_timeout = timeout;
337         add_timer(&sta->plink_timer);
338 }
339
340 int mesh_plink_open(struct sta_info *sta)
341 {
342         __le16 llid;
343         struct ieee80211_sub_if_data *sdata = sta->sdata;
344 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
345         DECLARE_MAC_BUF(mac);
346 #endif
347
348         spin_lock_bh(&sta->plink_lock);
349         get_random_bytes(&llid, 2);
350         sta->llid = llid;
351         if (sta->plink_state != PLINK_LISTEN) {
352                 spin_unlock_bh(&sta->plink_lock);
353                 return -EBUSY;
354         }
355         sta->plink_state = PLINK_OPN_SNT;
356         mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
357         spin_unlock_bh(&sta->plink_lock);
358         mpl_dbg("Mesh plink: starting establishment with %s\n",
359                 print_mac(mac, sta->addr));
360
361         return mesh_plink_frame_tx(sdata->dev, PLINK_OPEN,
362                                    sta->addr, llid, 0, 0);
363 }
364
365 void mesh_plink_block(struct sta_info *sta)
366 {
367 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
368         DECLARE_MAC_BUF(mac);
369 #endif
370
371         spin_lock_bh(&sta->plink_lock);
372         __mesh_plink_deactivate(sta);
373         sta->plink_state = PLINK_BLOCKED;
374         spin_unlock_bh(&sta->plink_lock);
375 }
376
377 int mesh_plink_close(struct sta_info *sta)
378 {
379         struct ieee80211_sub_if_data *sdata = sta->sdata;
380         __le16 llid, plid, reason;
381 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
382         DECLARE_MAC_BUF(mac);
383 #endif
384
385         mpl_dbg("Mesh plink: closing link with %s\n",
386                         print_mac(mac, sta->addr));
387         spin_lock_bh(&sta->plink_lock);
388         sta->reason = cpu_to_le16(MESH_LINK_CANCELLED);
389         reason = sta->reason;
390
391         if (sta->plink_state == PLINK_LISTEN ||
392             sta->plink_state == PLINK_BLOCKED) {
393                 mesh_plink_fsm_restart(sta);
394                 spin_unlock_bh(&sta->plink_lock);
395                 return 0;
396         } else if (sta->plink_state == PLINK_ESTAB) {
397                 __mesh_plink_deactivate(sta);
398                 /* The timer should not be running */
399                 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
400         } else if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)))
401                 sta->ignore_plink_timer = true;
402
403         sta->plink_state = PLINK_HOLDING;
404         llid = sta->llid;
405         plid = sta->plid;
406         spin_unlock_bh(&sta->plink_lock);
407         mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid,
408                             plid, reason);
409         return 0;
410 }
411
412 void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
413                          size_t len, struct ieee80211_rx_status *rx_status)
414 {
415         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
416         struct ieee80211_local *local = sdata->local;
417         struct ieee802_11_elems elems;
418         struct sta_info *sta;
419         enum plink_event event;
420         enum plink_frame_type ftype;
421         size_t baselen;
422         u8 ie_len;
423         u8 *baseaddr;
424         __le16 plid, llid, reason;
425 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
426         DECLARE_MAC_BUF(mac);
427 #endif
428
429         if (is_multicast_ether_addr(mgmt->da)) {
430                 mpl_dbg("Mesh plink: ignore frame from multicast address");
431                 return;
432         }
433
434         baseaddr = mgmt->u.action.u.plink_action.variable;
435         baselen = (u8 *) mgmt->u.action.u.plink_action.variable - (u8 *) mgmt;
436         if (mgmt->u.action.u.plink_action.action_code == PLINK_CONFIRM) {
437                 baseaddr += 4;
438                 baselen -= 4;
439         }
440         ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
441         if (!elems.peer_link) {
442                 mpl_dbg("Mesh plink: missing necessary peer link ie\n");
443                 return;
444         }
445
446         ftype = *((u8 *)PLINK_GET_FRAME_SUBTYPE(elems.peer_link));
447         ie_len = elems.peer_link_len;
448         if ((ftype == PLINK_OPEN && ie_len != 3) ||
449             (ftype == PLINK_CONFIRM && ie_len != 5) ||
450             (ftype == PLINK_CLOSE && ie_len != 5 && ie_len != 7)) {
451                 mpl_dbg("Mesh plink: incorrect plink ie length\n");
452                 return;
453         }
454
455         if (ftype != PLINK_CLOSE && (!elems.mesh_id || !elems.mesh_config)) {
456                 mpl_dbg("Mesh plink: missing necessary ie\n");
457                 return;
458         }
459         /* Note the lines below are correct, the llid in the frame is the plid
460          * from the point of view of this host.
461          */
462         memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2);
463         if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 7))
464                 memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2);
465
466         rcu_read_lock();
467
468         sta = sta_info_get(local, mgmt->sa);
469         if (!sta && ftype != PLINK_OPEN) {
470                 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
471                 rcu_read_unlock();
472                 return;
473         }
474
475         if (sta && sta->plink_state == PLINK_BLOCKED) {
476                 rcu_read_unlock();
477                 return;
478         }
479
480         /* Now we will figure out the appropriate event... */
481         event = PLINK_UNDEFINED;
482         if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, dev))) {
483                 switch (ftype) {
484                 case PLINK_OPEN:
485                         event = OPN_RJCT;
486                         break;
487                 case PLINK_CONFIRM:
488                         event = CNF_RJCT;
489                         break;
490                 case PLINK_CLOSE:
491                         /* avoid warning */
492                         break;
493                 }
494                 spin_lock_bh(&sta->plink_lock);
495         } else if (!sta) {
496                 /* ftype == PLINK_OPEN */
497                 u64 rates;
498                 if (!mesh_plink_free_count(sdata)) {
499                         mpl_dbg("Mesh plink error: no more free plinks\n");
500                         rcu_read_unlock();
501                         return;
502                 }
503
504                 rates = ieee80211_sta_get_rates(local, &elems, rx_status->band);
505                 sta = mesh_plink_alloc(sdata, mgmt->sa, rates);
506                 if (!sta) {
507                         mpl_dbg("Mesh plink error: plink table full\n");
508                         rcu_read_unlock();
509                         return;
510                 }
511                 if (sta_info_insert(sta)) {
512                         rcu_read_unlock();
513                         return;
514                 }
515                 event = OPN_ACPT;
516                 spin_lock_bh(&sta->plink_lock);
517         } else {
518                 spin_lock_bh(&sta->plink_lock);
519                 switch (ftype) {
520                 case PLINK_OPEN:
521                         if (!mesh_plink_free_count(sdata) ||
522                             (sta->plid && sta->plid != plid))
523                                 event = OPN_IGNR;
524                         else
525                                 event = OPN_ACPT;
526                         break;
527                 case PLINK_CONFIRM:
528                         if (!mesh_plink_free_count(sdata) ||
529                             (sta->llid != llid || sta->plid != plid))
530                                 event = CNF_IGNR;
531                         else
532                                 event = CNF_ACPT;
533                         break;
534                 case PLINK_CLOSE:
535                         if (sta->plink_state == PLINK_ESTAB)
536                                 /* Do not check for llid or plid. This does not
537                                  * follow the standard but since multiple plinks
538                                  * per sta are not supported, it is necessary in
539                                  * order to avoid a livelock when MP A sees an
540                                  * establish peer link to MP B but MP B does not
541                                  * see it. This can be caused by a timeout in
542                                  * B's peer link establishment or B beign
543                                  * restarted.
544                                  */
545                                 event = CLS_ACPT;
546                         else if (sta->plid != plid)
547                                 event = CLS_IGNR;
548                         else if (ie_len == 7 && sta->llid != llid)
549                                 event = CLS_IGNR;
550                         else
551                                 event = CLS_ACPT;
552                         break;
553                 default:
554                         mpl_dbg("Mesh plink: unknown frame subtype\n");
555                         spin_unlock_bh(&sta->plink_lock);
556                         rcu_read_unlock();
557                         return;
558                 }
559         }
560
561         mpl_dbg("Mesh plink (peer, state, llid, plid, event): %s %d %d %d %d\n",
562                         print_mac(mac, mgmt->sa), sta->plink_state,
563                         le16_to_cpu(sta->llid), le16_to_cpu(sta->plid),
564                         event);
565         reason = 0;
566         switch (sta->plink_state) {
567                 /* spin_unlock as soon as state is updated at each case */
568         case PLINK_LISTEN:
569                 switch (event) {
570                 case CLS_ACPT:
571                         mesh_plink_fsm_restart(sta);
572                         spin_unlock_bh(&sta->plink_lock);
573                         break;
574                 case OPN_ACPT:
575                         sta->plink_state = PLINK_OPN_RCVD;
576                         sta->plid = plid;
577                         get_random_bytes(&llid, 2);
578                         sta->llid = llid;
579                         mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
580                         spin_unlock_bh(&sta->plink_lock);
581                         mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
582                                             0, 0);
583                         mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr,
584                                             llid, plid, 0);
585                         break;
586                 default:
587                         spin_unlock_bh(&sta->plink_lock);
588                         break;
589                 }
590                 break;
591
592         case PLINK_OPN_SNT:
593                 switch (event) {
594                 case OPN_RJCT:
595                 case CNF_RJCT:
596                         reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
597                 case CLS_ACPT:
598                         if (!reason)
599                                 reason = cpu_to_le16(MESH_CLOSE_RCVD);
600                         sta->reason = reason;
601                         sta->plink_state = PLINK_HOLDING;
602                         if (!mod_plink_timer(sta,
603                                              dot11MeshHoldingTimeout(sdata)))
604                                 sta->ignore_plink_timer = true;
605
606                         llid = sta->llid;
607                         spin_unlock_bh(&sta->plink_lock);
608                         mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
609                                             plid, reason);
610                         break;
611                 case OPN_ACPT:
612                         /* retry timer is left untouched */
613                         sta->plink_state = PLINK_OPN_RCVD;
614                         sta->plid = plid;
615                         llid = sta->llid;
616                         spin_unlock_bh(&sta->plink_lock);
617                         mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
618                                             plid, 0);
619                         break;
620                 case CNF_ACPT:
621                         sta->plink_state = PLINK_CNF_RCVD;
622                         if (!mod_plink_timer(sta,
623                                              dot11MeshConfirmTimeout(sdata)))
624                                 sta->ignore_plink_timer = true;
625
626                         spin_unlock_bh(&sta->plink_lock);
627                         break;
628                 default:
629                         spin_unlock_bh(&sta->plink_lock);
630                         break;
631                 }
632                 break;
633
634         case PLINK_OPN_RCVD:
635                 switch (event) {
636                 case OPN_RJCT:
637                 case CNF_RJCT:
638                         reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
639                 case CLS_ACPT:
640                         if (!reason)
641                                 reason = cpu_to_le16(MESH_CLOSE_RCVD);
642                         sta->reason = reason;
643                         sta->plink_state = PLINK_HOLDING;
644                         if (!mod_plink_timer(sta,
645                                              dot11MeshHoldingTimeout(sdata)))
646                                 sta->ignore_plink_timer = true;
647
648                         llid = sta->llid;
649                         spin_unlock_bh(&sta->plink_lock);
650                         mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
651                                             plid, reason);
652                         break;
653                 case OPN_ACPT:
654                         llid = sta->llid;
655                         spin_unlock_bh(&sta->plink_lock);
656                         mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
657                                             plid, 0);
658                         break;
659                 case CNF_ACPT:
660                         del_timer(&sta->plink_timer);
661                         sta->plink_state = PLINK_ESTAB;
662                         mesh_plink_inc_estab_count(sdata);
663                         spin_unlock_bh(&sta->plink_lock);
664                         mpl_dbg("Mesh plink with %s ESTABLISHED\n",
665                                         print_mac(mac, sta->addr));
666                         break;
667                 default:
668                         spin_unlock_bh(&sta->plink_lock);
669                         break;
670                 }
671                 break;
672
673         case PLINK_CNF_RCVD:
674                 switch (event) {
675                 case OPN_RJCT:
676                 case CNF_RJCT:
677                         reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
678                 case CLS_ACPT:
679                         if (!reason)
680                                 reason = cpu_to_le16(MESH_CLOSE_RCVD);
681                         sta->reason = reason;
682                         sta->plink_state = PLINK_HOLDING;
683                         if (!mod_plink_timer(sta,
684                                              dot11MeshHoldingTimeout(sdata)))
685                                 sta->ignore_plink_timer = true;
686
687                         llid = sta->llid;
688                         spin_unlock_bh(&sta->plink_lock);
689                         mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
690                                             plid, reason);
691                         break;
692                 case OPN_ACPT:
693                         del_timer(&sta->plink_timer);
694                         sta->plink_state = PLINK_ESTAB;
695                         mesh_plink_inc_estab_count(sdata);
696                         spin_unlock_bh(&sta->plink_lock);
697                         mpl_dbg("Mesh plink with %s ESTABLISHED\n",
698                                         print_mac(mac, sta->addr));
699                         mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
700                                             plid, 0);
701                         break;
702                 default:
703                         spin_unlock_bh(&sta->plink_lock);
704                         break;
705                 }
706                 break;
707
708         case PLINK_ESTAB:
709                 switch (event) {
710                 case CLS_ACPT:
711                         reason = cpu_to_le16(MESH_CLOSE_RCVD);
712                         sta->reason = reason;
713                         __mesh_plink_deactivate(sta);
714                         sta->plink_state = PLINK_HOLDING;
715                         llid = sta->llid;
716                         mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
717                         spin_unlock_bh(&sta->plink_lock);
718                         mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
719                                             plid, reason);
720                         break;
721                 case OPN_ACPT:
722                         llid = sta->llid;
723                         spin_unlock_bh(&sta->plink_lock);
724                         mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
725                                             plid, 0);
726                         break;
727                 default:
728                         spin_unlock_bh(&sta->plink_lock);
729                         break;
730                 }
731                 break;
732         case PLINK_HOLDING:
733                 switch (event) {
734                 case CLS_ACPT:
735                         if (del_timer(&sta->plink_timer))
736                                 sta->ignore_plink_timer = 1;
737                         mesh_plink_fsm_restart(sta);
738                         spin_unlock_bh(&sta->plink_lock);
739                         break;
740                 case OPN_ACPT:
741                 case CNF_ACPT:
742                 case OPN_RJCT:
743                 case CNF_RJCT:
744                         llid = sta->llid;
745                         reason = sta->reason;
746                         spin_unlock_bh(&sta->plink_lock);
747                         mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
748                                             plid, reason);
749                         break;
750                 default:
751                         spin_unlock_bh(&sta->plink_lock);
752                 }
753                 break;
754         default:
755                 /* should not get here, PLINK_BLOCKED is dealt with at the
756                  * beggining of the function
757                  */
758                 spin_unlock_bh(&sta->plink_lock);
759                 break;
760         }
761
762         rcu_read_unlock();
763 }