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