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