50d0e0660cc44cbcf498359c2ea48038babd1d21
[pandora-kernel.git] / net / mac80211 / tdls.c
1 /*
2  * mac80211 TDLS handling code
3  *
4  * Copyright 2006-2010  Johannes Berg <johannes@sipsolutions.net>
5  * Copyright 2014, Intel Corporation
6  *
7  * This file is GPLv2 as found in COPYING.
8  */
9
10 #include <linux/ieee80211.h>
11 #include <linux/log2.h>
12 #include <net/cfg80211.h>
13 #include "ieee80211_i.h"
14 #include "driver-ops.h"
15
16 /* give usermode some time for retries in setting up the TDLS session */
17 #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ)
18
19 void ieee80211_tdls_peer_del_work(struct work_struct *wk)
20 {
21         struct ieee80211_sub_if_data *sdata;
22         struct ieee80211_local *local;
23
24         sdata = container_of(wk, struct ieee80211_sub_if_data,
25                              u.mgd.tdls_peer_del_work.work);
26         local = sdata->local;
27
28         mutex_lock(&local->mtx);
29         if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer)) {
30                 tdls_dbg(sdata, "TDLS del peer %pM\n", sdata->u.mgd.tdls_peer);
31                 sta_info_destroy_addr(sdata, sdata->u.mgd.tdls_peer);
32                 eth_zero_addr(sdata->u.mgd.tdls_peer);
33         }
34         mutex_unlock(&local->mtx);
35 }
36
37 static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb)
38 {
39         u8 *pos = (void *)skb_put(skb, 7);
40
41         *pos++ = WLAN_EID_EXT_CAPABILITY;
42         *pos++ = 5; /* len */
43         *pos++ = 0x0;
44         *pos++ = 0x0;
45         *pos++ = 0x0;
46         *pos++ = 0x0;
47         *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED;
48 }
49
50 static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata,
51                                         u16 status_code)
52 {
53         struct ieee80211_local *local = sdata->local;
54         u16 capab;
55
56         /* The capability will be 0 when sending a failure code */
57         if (status_code != 0)
58                 return 0;
59
60         capab = 0;
61         if (ieee80211_get_sdata_band(sdata) != IEEE80211_BAND_2GHZ)
62                 return capab;
63
64         if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
65                 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
66         if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
67                 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
68
69         return capab;
70 }
71
72 static void ieee80211_tdls_add_link_ie(struct ieee80211_sub_if_data *sdata,
73                                        struct sk_buff *skb, const u8 *peer,
74                                        bool initiator)
75 {
76         struct ieee80211_tdls_lnkie *lnkid;
77         const u8 *init_addr, *rsp_addr;
78
79         if (initiator) {
80                 init_addr = sdata->vif.addr;
81                 rsp_addr = peer;
82         } else {
83                 init_addr = peer;
84                 rsp_addr = sdata->vif.addr;
85         }
86
87         lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
88
89         lnkid->ie_type = WLAN_EID_LINK_ID;
90         lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2;
91
92         memcpy(lnkid->bssid, sdata->u.mgd.bssid, ETH_ALEN);
93         memcpy(lnkid->init_sta, init_addr, ETH_ALEN);
94         memcpy(lnkid->resp_sta, rsp_addr, ETH_ALEN);
95 }
96
97 /* translate numbering in the WMM parameter IE to the mac80211 notation */
98 static enum ieee80211_ac_numbers ieee80211_ac_from_wmm(int ac)
99 {
100         switch (ac) {
101         default:
102                 WARN_ON_ONCE(1);
103         case 0:
104                 return IEEE80211_AC_BE;
105         case 1:
106                 return IEEE80211_AC_BK;
107         case 2:
108                 return IEEE80211_AC_VI;
109         case 3:
110                 return IEEE80211_AC_VO;
111         }
112 }
113
114 static u8 ieee80211_wmm_aci_aifsn(int aifsn, bool acm, int aci)
115 {
116         u8 ret;
117
118         ret = aifsn & 0x0f;
119         if (acm)
120                 ret |= 0x10;
121         ret |= (aci << 5) & 0x60;
122         return ret;
123 }
124
125 static u8 ieee80211_wmm_ecw(u16 cw_min, u16 cw_max)
126 {
127         return ((ilog2(cw_min + 1) << 0x0) & 0x0f) |
128                ((ilog2(cw_max + 1) << 0x4) & 0xf0);
129 }
130
131 static void ieee80211_tdls_add_wmm_param_ie(struct ieee80211_sub_if_data *sdata,
132                                             struct sk_buff *skb)
133 {
134         struct ieee80211_wmm_param_ie *wmm;
135         struct ieee80211_tx_queue_params *txq;
136         int i;
137
138         wmm = (void *)skb_put(skb, sizeof(*wmm));
139         memset(wmm, 0, sizeof(*wmm));
140
141         wmm->element_id = WLAN_EID_VENDOR_SPECIFIC;
142         wmm->len = sizeof(*wmm) - 2;
143
144         wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */
145         wmm->oui[1] = 0x50;
146         wmm->oui[2] = 0xf2;
147         wmm->oui_type = 2; /* WME */
148         wmm->oui_subtype = 1; /* WME param */
149         wmm->version = 1; /* WME ver */
150         wmm->qos_info = 0; /* U-APSD not in use */
151
152         /*
153          * Use the EDCA parameters defined for the BSS, or default if the AP
154          * doesn't support it, as mandated by 802.11-2012 section 10.22.4
155          */
156         for (i = 0; i < IEEE80211_NUM_ACS; i++) {
157                 txq = &sdata->tx_conf[ieee80211_ac_from_wmm(i)];
158                 wmm->ac[i].aci_aifsn = ieee80211_wmm_aci_aifsn(txq->aifs,
159                                                                txq->acm, i);
160                 wmm->ac[i].cw = ieee80211_wmm_ecw(txq->cw_min, txq->cw_max);
161                 wmm->ac[i].txop_limit = cpu_to_le16(txq->txop);
162         }
163 }
164
165 static void
166 ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata,
167                                    struct sk_buff *skb, const u8 *peer,
168                                    u8 action_code, bool initiator,
169                                    const u8 *extra_ies, size_t extra_ies_len)
170 {
171         enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
172         struct ieee80211_local *local = sdata->local;
173         struct ieee80211_supported_band *sband;
174         struct ieee80211_sta_ht_cap ht_cap;
175         struct sta_info *sta = NULL;
176         size_t offset = 0, noffset;
177         u8 *pos;
178
179         rcu_read_lock();
180
181         /* we should have the peer STA if we're already responding */
182         if (action_code == WLAN_TDLS_SETUP_RESPONSE) {
183                 sta = sta_info_get(sdata, peer);
184                 if (WARN_ON_ONCE(!sta)) {
185                         rcu_read_unlock();
186                         return;
187                 }
188         }
189
190         ieee80211_add_srates_ie(sdata, skb, false, band);
191         ieee80211_add_ext_srates_ie(sdata, skb, false, band);
192
193         /* add any custom IEs that go before Extended Capabilities */
194         if (extra_ies_len) {
195                 static const u8 before_ext_cap[] = {
196                         WLAN_EID_SUPP_RATES,
197                         WLAN_EID_COUNTRY,
198                         WLAN_EID_EXT_SUPP_RATES,
199                         WLAN_EID_SUPPORTED_CHANNELS,
200                         WLAN_EID_RSN,
201                 };
202                 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
203                                              before_ext_cap,
204                                              ARRAY_SIZE(before_ext_cap),
205                                              offset);
206                 pos = skb_put(skb, noffset - offset);
207                 memcpy(pos, extra_ies + offset, noffset - offset);
208                 offset = noffset;
209         }
210
211         ieee80211_tdls_add_ext_capab(skb);
212
213         /* add the QoS element if we support it */
214         if (local->hw.queues >= IEEE80211_NUM_ACS &&
215             action_code != WLAN_PUB_ACTION_TDLS_DISCOVER_RES)
216                 ieee80211_add_wmm_info_ie(skb_put(skb, 9), 0); /* no U-APSD */
217
218         /* add any custom IEs that go before HT capabilities */
219         if (extra_ies_len) {
220                 static const u8 before_ht_cap[] = {
221                         WLAN_EID_SUPP_RATES,
222                         WLAN_EID_COUNTRY,
223                         WLAN_EID_EXT_SUPP_RATES,
224                         WLAN_EID_SUPPORTED_CHANNELS,
225                         WLAN_EID_RSN,
226                         WLAN_EID_EXT_CAPABILITY,
227                         WLAN_EID_QOS_CAPA,
228                         WLAN_EID_FAST_BSS_TRANSITION,
229                         WLAN_EID_TIMEOUT_INTERVAL,
230                         WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
231                 };
232                 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
233                                              before_ht_cap,
234                                              ARRAY_SIZE(before_ht_cap),
235                                              offset);
236                 pos = skb_put(skb, noffset - offset);
237                 memcpy(pos, extra_ies + offset, noffset - offset);
238                 offset = noffset;
239         }
240
241         /*
242          * with TDLS we can switch channels, and HT-caps are not necessarily
243          * the same on all bands. The specification limits the setup to a
244          * single HT-cap, so use the current band for now.
245          */
246         sband = local->hw.wiphy->bands[band];
247         memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
248         if ((action_code == WLAN_TDLS_SETUP_REQUEST ||
249              action_code == WLAN_TDLS_SETUP_RESPONSE) &&
250             ht_cap.ht_supported && (!sta || sta->sta.ht_cap.ht_supported)) {
251                 if (action_code == WLAN_TDLS_SETUP_REQUEST) {
252                         ieee80211_apply_htcap_overrides(sdata, &ht_cap);
253
254                         /* disable SMPS in TDLS initiator */
255                         ht_cap.cap |= (WLAN_HT_CAP_SM_PS_DISABLED
256                                        << IEEE80211_HT_CAP_SM_PS_SHIFT);
257                 } else {
258                         /* disable SMPS in TDLS responder */
259                         sta->sta.ht_cap.cap |=
260                                 (WLAN_HT_CAP_SM_PS_DISABLED
261                                  << IEEE80211_HT_CAP_SM_PS_SHIFT);
262
263                         /* the peer caps are already intersected with our own */
264                         memcpy(&ht_cap, &sta->sta.ht_cap, sizeof(ht_cap));
265                 }
266
267                 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
268                 ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap);
269         }
270
271         rcu_read_unlock();
272
273         /* add any remaining IEs */
274         if (extra_ies_len) {
275                 noffset = extra_ies_len;
276                 pos = skb_put(skb, noffset - offset);
277                 memcpy(pos, extra_ies + offset, noffset - offset);
278         }
279
280         ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
281 }
282
283 static void
284 ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata,
285                                  struct sk_buff *skb, const u8 *peer,
286                                  bool initiator, const u8 *extra_ies,
287                                  size_t extra_ies_len)
288 {
289         struct ieee80211_local *local = sdata->local;
290         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
291         size_t offset = 0, noffset;
292         struct sta_info *sta, *ap_sta;
293         u8 *pos;
294
295         rcu_read_lock();
296
297         sta = sta_info_get(sdata, peer);
298         ap_sta = sta_info_get(sdata, ifmgd->bssid);
299         if (WARN_ON_ONCE(!sta || !ap_sta)) {
300                 rcu_read_unlock();
301                 return;
302         }
303
304         /* add any custom IEs that go before the QoS IE */
305         if (extra_ies_len) {
306                 static const u8 before_qos[] = {
307                         WLAN_EID_RSN,
308                 };
309                 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
310                                              before_qos,
311                                              ARRAY_SIZE(before_qos),
312                                              offset);
313                 pos = skb_put(skb, noffset - offset);
314                 memcpy(pos, extra_ies + offset, noffset - offset);
315                 offset = noffset;
316         }
317
318         /* add the QoS param IE if both the peer and we support it */
319         if (local->hw.queues >= IEEE80211_NUM_ACS &&
320             test_sta_flag(sta, WLAN_STA_WME))
321                 ieee80211_tdls_add_wmm_param_ie(sdata, skb);
322
323         /* add any custom IEs that go before HT operation */
324         if (extra_ies_len) {
325                 static const u8 before_ht_op[] = {
326                         WLAN_EID_RSN,
327                         WLAN_EID_QOS_CAPA,
328                         WLAN_EID_FAST_BSS_TRANSITION,
329                         WLAN_EID_TIMEOUT_INTERVAL,
330                 };
331                 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
332                                              before_ht_op,
333                                              ARRAY_SIZE(before_ht_op),
334                                              offset);
335                 pos = skb_put(skb, noffset - offset);
336                 memcpy(pos, extra_ies + offset, noffset - offset);
337                 offset = noffset;
338         }
339
340         /* if HT support is only added in TDLS, we need an HT-operation IE */
341         if (!ap_sta->sta.ht_cap.ht_supported && sta->sta.ht_cap.ht_supported) {
342                 struct ieee80211_chanctx_conf *chanctx_conf =
343                                 rcu_dereference(sdata->vif.chanctx_conf);
344                 if (!WARN_ON(!chanctx_conf)) {
345                         pos = skb_put(skb, 2 +
346                                       sizeof(struct ieee80211_ht_operation));
347                         /* send an empty HT operation IE */
348                         ieee80211_ie_build_ht_oper(pos, &sta->sta.ht_cap,
349                                                    &chanctx_conf->def, 0);
350                 }
351         }
352
353         rcu_read_unlock();
354
355         /* add any remaining IEs */
356         if (extra_ies_len) {
357                 noffset = extra_ies_len;
358                 pos = skb_put(skb, noffset - offset);
359                 memcpy(pos, extra_ies + offset, noffset - offset);
360         }
361
362         ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
363 }
364
365 static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata,
366                                    struct sk_buff *skb, const u8 *peer,
367                                    u8 action_code, u16 status_code,
368                                    bool initiator, const u8 *extra_ies,
369                                    size_t extra_ies_len)
370 {
371         switch (action_code) {
372         case WLAN_TDLS_SETUP_REQUEST:
373         case WLAN_TDLS_SETUP_RESPONSE:
374         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
375                 if (status_code == 0)
376                         ieee80211_tdls_add_setup_start_ies(sdata, skb, peer,
377                                                            action_code,
378                                                            initiator,
379                                                            extra_ies,
380                                                            extra_ies_len);
381                 break;
382         case WLAN_TDLS_SETUP_CONFIRM:
383                 if (status_code == 0)
384                         ieee80211_tdls_add_setup_cfm_ies(sdata, skb, peer,
385                                                          initiator, extra_ies,
386                                                          extra_ies_len);
387                 break;
388         case WLAN_TDLS_TEARDOWN:
389         case WLAN_TDLS_DISCOVERY_REQUEST:
390                 if (extra_ies_len)
391                         memcpy(skb_put(skb, extra_ies_len), extra_ies,
392                                extra_ies_len);
393                 if (status_code == 0 || action_code == WLAN_TDLS_TEARDOWN)
394                         ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
395                 break;
396         }
397
398 }
399
400 static int
401 ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
402                                const u8 *peer, u8 action_code, u8 dialog_token,
403                                u16 status_code, struct sk_buff *skb)
404 {
405         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
406         struct ieee80211_tdls_data *tf;
407
408         tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
409
410         memcpy(tf->da, peer, ETH_ALEN);
411         memcpy(tf->sa, sdata->vif.addr, ETH_ALEN);
412         tf->ether_type = cpu_to_be16(ETH_P_TDLS);
413         tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
414
415         switch (action_code) {
416         case WLAN_TDLS_SETUP_REQUEST:
417                 tf->category = WLAN_CATEGORY_TDLS;
418                 tf->action_code = WLAN_TDLS_SETUP_REQUEST;
419
420                 skb_put(skb, sizeof(tf->u.setup_req));
421                 tf->u.setup_req.dialog_token = dialog_token;
422                 tf->u.setup_req.capability =
423                         cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
424                                                                  status_code));
425                 break;
426         case WLAN_TDLS_SETUP_RESPONSE:
427                 tf->category = WLAN_CATEGORY_TDLS;
428                 tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
429
430                 skb_put(skb, sizeof(tf->u.setup_resp));
431                 tf->u.setup_resp.status_code = cpu_to_le16(status_code);
432                 tf->u.setup_resp.dialog_token = dialog_token;
433                 tf->u.setup_resp.capability =
434                         cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
435                                                                  status_code));
436                 break;
437         case WLAN_TDLS_SETUP_CONFIRM:
438                 tf->category = WLAN_CATEGORY_TDLS;
439                 tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
440
441                 skb_put(skb, sizeof(tf->u.setup_cfm));
442                 tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
443                 tf->u.setup_cfm.dialog_token = dialog_token;
444                 break;
445         case WLAN_TDLS_TEARDOWN:
446                 tf->category = WLAN_CATEGORY_TDLS;
447                 tf->action_code = WLAN_TDLS_TEARDOWN;
448
449                 skb_put(skb, sizeof(tf->u.teardown));
450                 tf->u.teardown.reason_code = cpu_to_le16(status_code);
451                 break;
452         case WLAN_TDLS_DISCOVERY_REQUEST:
453                 tf->category = WLAN_CATEGORY_TDLS;
454                 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
455
456                 skb_put(skb, sizeof(tf->u.discover_req));
457                 tf->u.discover_req.dialog_token = dialog_token;
458                 break;
459         default:
460                 return -EINVAL;
461         }
462
463         return 0;
464 }
465
466 static int
467 ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
468                            const u8 *peer, u8 action_code, u8 dialog_token,
469                            u16 status_code, struct sk_buff *skb)
470 {
471         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
472         struct ieee80211_mgmt *mgmt;
473
474         mgmt = (void *)skb_put(skb, 24);
475         memset(mgmt, 0, 24);
476         memcpy(mgmt->da, peer, ETH_ALEN);
477         memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
478         memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
479
480         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
481                                           IEEE80211_STYPE_ACTION);
482
483         switch (action_code) {
484         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
485                 skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
486                 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
487                 mgmt->u.action.u.tdls_discover_resp.action_code =
488                         WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
489                 mgmt->u.action.u.tdls_discover_resp.dialog_token =
490                         dialog_token;
491                 mgmt->u.action.u.tdls_discover_resp.capability =
492                         cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
493                                                                  status_code));
494                 break;
495         default:
496                 return -EINVAL;
497         }
498
499         return 0;
500 }
501
502 static int
503 ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
504                                 const u8 *peer, u8 action_code,
505                                 u8 dialog_token, u16 status_code,
506                                 u32 peer_capability, bool initiator,
507                                 const u8 *extra_ies, size_t extra_ies_len)
508 {
509         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
510         struct ieee80211_local *local = sdata->local;
511         struct sk_buff *skb = NULL;
512         bool send_direct;
513         struct sta_info *sta;
514         int ret;
515
516         skb = dev_alloc_skb(local->hw.extra_tx_headroom +
517                             max(sizeof(struct ieee80211_mgmt),
518                                 sizeof(struct ieee80211_tdls_data)) +
519                             50 + /* supported rates */
520                             7 + /* ext capab */
521                             26 + /* max(WMM-info, WMM-param) */
522                             2 + max(sizeof(struct ieee80211_ht_cap),
523                                     sizeof(struct ieee80211_ht_operation)) +
524                             extra_ies_len +
525                             sizeof(struct ieee80211_tdls_lnkie));
526         if (!skb)
527                 return -ENOMEM;
528
529         skb_reserve(skb, local->hw.extra_tx_headroom);
530
531         switch (action_code) {
532         case WLAN_TDLS_SETUP_REQUEST:
533         case WLAN_TDLS_SETUP_RESPONSE:
534         case WLAN_TDLS_SETUP_CONFIRM:
535         case WLAN_TDLS_TEARDOWN:
536         case WLAN_TDLS_DISCOVERY_REQUEST:
537                 ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer,
538                                                      action_code, dialog_token,
539                                                      status_code, skb);
540                 send_direct = false;
541                 break;
542         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
543                 ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code,
544                                                  dialog_token, status_code,
545                                                  skb);
546                 send_direct = true;
547                 break;
548         default:
549                 ret = -ENOTSUPP;
550                 break;
551         }
552
553         if (ret < 0)
554                 goto fail;
555
556         rcu_read_lock();
557         sta = sta_info_get(sdata, peer);
558
559         /* infer the initiator if we can, to support old userspace */
560         switch (action_code) {
561         case WLAN_TDLS_SETUP_REQUEST:
562                 if (sta)
563                         set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
564                 /* fall-through */
565         case WLAN_TDLS_SETUP_CONFIRM:
566         case WLAN_TDLS_DISCOVERY_REQUEST:
567                 initiator = true;
568                 break;
569         case WLAN_TDLS_SETUP_RESPONSE:
570                 /*
571                  * In some testing scenarios, we send a request and response.
572                  * Make the last packet sent take effect for the initiator
573                  * value.
574                  */
575                 if (sta)
576                         clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
577                 /* fall-through */
578         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
579                 initiator = false;
580                 break;
581         case WLAN_TDLS_TEARDOWN:
582                 /* any value is ok */
583                 break;
584         default:
585                 ret = -ENOTSUPP;
586                 break;
587         }
588
589         if (sta && test_sta_flag(sta, WLAN_STA_TDLS_INITIATOR))
590                 initiator = true;
591
592         rcu_read_unlock();
593         if (ret < 0)
594                 goto fail;
595
596         ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code,
597                                initiator, extra_ies, extra_ies_len);
598         if (send_direct) {
599                 ieee80211_tx_skb(sdata, skb);
600                 return 0;
601         }
602
603         /*
604          * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise
605          * we should default to AC_VI.
606          */
607         switch (action_code) {
608         case WLAN_TDLS_SETUP_REQUEST:
609         case WLAN_TDLS_SETUP_RESPONSE:
610                 skb_set_queue_mapping(skb, IEEE80211_AC_BK);
611                 skb->priority = 2;
612                 break;
613         default:
614                 skb_set_queue_mapping(skb, IEEE80211_AC_VI);
615                 skb->priority = 5;
616                 break;
617         }
618
619         /* disable bottom halves when entering the Tx path */
620         local_bh_disable();
621         ret = ieee80211_subif_start_xmit(skb, dev);
622         local_bh_enable();
623
624         return ret;
625
626 fail:
627         dev_kfree_skb(skb);
628         return ret;
629 }
630
631 static int
632 ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev,
633                           const u8 *peer, u8 action_code, u8 dialog_token,
634                           u16 status_code, u32 peer_capability, bool initiator,
635                           const u8 *extra_ies, size_t extra_ies_len)
636 {
637         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
638         struct ieee80211_local *local = sdata->local;
639         int ret;
640
641         mutex_lock(&local->mtx);
642
643         /* we don't support concurrent TDLS peer setups */
644         if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer) &&
645             !ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) {
646                 ret = -EBUSY;
647                 goto exit;
648         }
649
650         /*
651          * make sure we have a STA representing the peer so we drop or buffer
652          * non-TDLS-setup frames to the peer. We can't send other packets
653          * during setup through the AP path.
654          * Allow error packets to be sent - sometimes we don't even add a STA
655          * before failing the setup.
656          */
657         if (status_code == 0) {
658                 rcu_read_lock();
659                 if (!sta_info_get(sdata, peer)) {
660                         rcu_read_unlock();
661                         ret = -ENOLINK;
662                         goto exit;
663                 }
664                 rcu_read_unlock();
665         }
666
667         ieee80211_flush_queues(local, sdata);
668
669         ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
670                                               dialog_token, status_code,
671                                               peer_capability, initiator,
672                                               extra_ies, extra_ies_len);
673         if (ret < 0)
674                 goto exit;
675
676         memcpy(sdata->u.mgd.tdls_peer, peer, ETH_ALEN);
677         ieee80211_queue_delayed_work(&sdata->local->hw,
678                                      &sdata->u.mgd.tdls_peer_del_work,
679                                      TDLS_PEER_SETUP_TIMEOUT);
680
681 exit:
682         mutex_unlock(&local->mtx);
683         return ret;
684 }
685
686 static int
687 ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev,
688                              const u8 *peer, u8 action_code, u8 dialog_token,
689                              u16 status_code, u32 peer_capability,
690                              bool initiator, const u8 *extra_ies,
691                              size_t extra_ies_len)
692 {
693         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
694         struct ieee80211_local *local = sdata->local;
695         struct sta_info *sta;
696         int ret;
697
698         /*
699          * No packets can be transmitted to the peer via the AP during setup -
700          * the STA is set as a TDLS peer, but is not authorized.
701          * During teardown, we prevent direct transmissions by stopping the
702          * queues and flushing all direct packets.
703          */
704         ieee80211_stop_vif_queues(local, sdata,
705                                   IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
706         ieee80211_flush_queues(local, sdata);
707
708         ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
709                                               dialog_token, status_code,
710                                               peer_capability, initiator,
711                                               extra_ies, extra_ies_len);
712         if (ret < 0)
713                 sdata_err(sdata, "Failed sending TDLS teardown packet %d\n",
714                           ret);
715
716         /*
717          * Remove the STA AUTH flag to force further traffic through the AP. If
718          * the STA was unreachable, it was already removed.
719          */
720         rcu_read_lock();
721         sta = sta_info_get(sdata, peer);
722         if (sta)
723                 clear_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
724         rcu_read_unlock();
725
726         ieee80211_wake_vif_queues(local, sdata,
727                                   IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
728
729         return 0;
730 }
731
732 int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
733                         const u8 *peer, u8 action_code, u8 dialog_token,
734                         u16 status_code, u32 peer_capability,
735                         bool initiator, const u8 *extra_ies,
736                         size_t extra_ies_len)
737 {
738         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
739         int ret;
740
741         if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
742                 return -ENOTSUPP;
743
744         /* make sure we are in managed mode, and associated */
745         if (sdata->vif.type != NL80211_IFTYPE_STATION ||
746             !sdata->u.mgd.associated)
747                 return -EINVAL;
748
749         switch (action_code) {
750         case WLAN_TDLS_SETUP_REQUEST:
751         case WLAN_TDLS_SETUP_RESPONSE:
752                 ret = ieee80211_tdls_mgmt_setup(wiphy, dev, peer, action_code,
753                                                 dialog_token, status_code,
754                                                 peer_capability, initiator,
755                                                 extra_ies, extra_ies_len);
756                 break;
757         case WLAN_TDLS_TEARDOWN:
758                 ret = ieee80211_tdls_mgmt_teardown(wiphy, dev, peer,
759                                                    action_code, dialog_token,
760                                                    status_code,
761                                                    peer_capability, initiator,
762                                                    extra_ies, extra_ies_len);
763                 break;
764         case WLAN_TDLS_DISCOVERY_REQUEST:
765                 /*
766                  * Protect the discovery so we can hear the TDLS discovery
767                  * response frame. It is transmitted directly and not buffered
768                  * by the AP.
769                  */
770                 drv_mgd_protect_tdls_discover(sdata->local, sdata);
771                 /* fall-through */
772         case WLAN_TDLS_SETUP_CONFIRM:
773         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
774                 /* no special handling */
775                 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
776                                                       action_code,
777                                                       dialog_token,
778                                                       status_code,
779                                                       peer_capability,
780                                                       initiator, extra_ies,
781                                                       extra_ies_len);
782                 break;
783         default:
784                 ret = -EOPNOTSUPP;
785                 break;
786         }
787
788         tdls_dbg(sdata, "TDLS mgmt action %d peer %pM status %d\n",
789                  action_code, peer, ret);
790         return ret;
791 }
792
793 int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
794                         const u8 *peer, enum nl80211_tdls_operation oper)
795 {
796         struct sta_info *sta;
797         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
798         struct ieee80211_local *local = sdata->local;
799         int ret;
800
801         if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
802                 return -ENOTSUPP;
803
804         if (sdata->vif.type != NL80211_IFTYPE_STATION)
805                 return -EINVAL;
806
807         switch (oper) {
808         case NL80211_TDLS_ENABLE_LINK:
809         case NL80211_TDLS_DISABLE_LINK:
810                 break;
811         case NL80211_TDLS_TEARDOWN:
812         case NL80211_TDLS_SETUP:
813         case NL80211_TDLS_DISCOVERY_REQ:
814                 /* We don't support in-driver setup/teardown/discovery */
815                 return -ENOTSUPP;
816         }
817
818         mutex_lock(&local->mtx);
819         tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer);
820
821         switch (oper) {
822         case NL80211_TDLS_ENABLE_LINK:
823                 rcu_read_lock();
824                 sta = sta_info_get(sdata, peer);
825                 if (!sta) {
826                         rcu_read_unlock();
827                         ret = -ENOLINK;
828                         break;
829                 }
830
831                 set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
832                 rcu_read_unlock();
833
834                 WARN_ON_ONCE(is_zero_ether_addr(sdata->u.mgd.tdls_peer) ||
835                              !ether_addr_equal(sdata->u.mgd.tdls_peer, peer));
836                 ret = 0;
837                 break;
838         case NL80211_TDLS_DISABLE_LINK:
839                 /* flush a potentially queued teardown packet */
840                 ieee80211_flush_queues(local, sdata);
841
842                 ret = sta_info_destroy_addr(sdata, peer);
843                 break;
844         default:
845                 ret = -ENOTSUPP;
846                 break;
847         }
848
849         if (ret == 0 && ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) {
850                 cancel_delayed_work(&sdata->u.mgd.tdls_peer_del_work);
851                 eth_zero_addr(sdata->u.mgd.tdls_peer);
852         }
853
854         mutex_unlock(&local->mtx);
855         return ret;
856 }
857
858 void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
859                                  enum nl80211_tdls_operation oper,
860                                  u16 reason_code, gfp_t gfp)
861 {
862         struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
863
864         if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) {
865                 sdata_err(sdata, "Discarding TDLS oper %d - not STA or disconnected\n",
866                           oper);
867                 return;
868         }
869
870         cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp);
871 }
872 EXPORT_SYMBOL(ieee80211_tdls_oper_request);