blob: c59b8f460eb935dbd803b5fdba838f24eadd7dce [file] [log] [blame]
Arik Nemtsov95224fe2014-05-01 10:17:28 +03001/*
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>
Arik Nemtsov6f7eaa42014-07-17 17:14:24 +030011#include <linux/log2.h>
Arik Nemtsovc887f0d32014-06-11 17:18:25 +030012#include <net/cfg80211.h>
Arik Nemtsov95224fe2014-05-01 10:17:28 +030013#include "ieee80211_i.h"
Arik Nemtsovee10f2c2014-06-11 17:18:27 +030014#include "driver-ops.h"
Arik Nemtsov95224fe2014-05-01 10:17:28 +030015
Arik Nemtsov17e6a592014-06-11 17:18:20 +030016/* give usermode some time for retries in setting up the TDLS session */
17#define TDLS_PEER_SETUP_TIMEOUT (15 * HZ)
18
19void 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,
Arik Nemtsov81dd2b82014-07-17 17:14:25 +030025 u.mgd.tdls_peer_del_work.work);
Arik Nemtsov17e6a592014-06-11 17:18:20 +030026 local = sdata->local;
27
28 mutex_lock(&local->mtx);
Arik Nemtsov81dd2b82014-07-17 17:14:25 +030029 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);
Arik Nemtsov17e6a592014-06-11 17:18:20 +030033 }
34 mutex_unlock(&local->mtx);
35}
36
Arik Nemtsov95224fe2014-05-01 10:17:28 +030037static 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
Arik Nemtsovdd8c0b02014-07-17 17:14:22 +030050static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata,
51 u16 status_code)
Arik Nemtsov95224fe2014-05-01 10:17:28 +030052{
53 struct ieee80211_local *local = sdata->local;
54 u16 capab;
55
Arik Nemtsovdd8c0b02014-07-17 17:14:22 +030056 /* The capability will be 0 when sending a failure code */
57 if (status_code != 0)
58 return 0;
59
Arik Nemtsov95224fe2014-05-01 10:17:28 +030060 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
Arik Nemtsov1606ef42014-07-17 17:14:21 +030072static void ieee80211_tdls_add_link_ie(struct ieee80211_sub_if_data *sdata,
73 struct sk_buff *skb, const u8 *peer,
74 bool initiator)
Arik Nemtsov95224fe2014-05-01 10:17:28 +030075{
76 struct ieee80211_tdls_lnkie *lnkid;
Arik Nemtsov1606ef42014-07-17 17:14:21 +030077 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 }
Arik Nemtsov95224fe2014-05-01 10:17:28 +030086
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
Arik Nemtsov1606ef42014-07-17 17:14:21 +030092 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);
Arik Nemtsov95224fe2014-05-01 10:17:28 +030095}
96
Arik Nemtsov6f7eaa42014-07-17 17:14:24 +030097/* translate numbering in the WMM parameter IE to the mac80211 notation */
98static 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
114static 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
125static 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
131static 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
Arik Nemtsovf09a87d2014-07-17 17:14:20 +0300165static void
166ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata,
167 struct sk_buff *skb, const u8 *peer,
Arik Nemtsov1606ef42014-07-17 17:14:21 +0300168 u8 action_code, bool initiator,
169 const u8 *extra_ies, size_t extra_ies_len)
Arik Nemtsovf09a87d2014-07-17 17:14:20 +0300170{
171 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
Arik Nemtsov40b861a2014-07-17 17:14:23 +0300172 struct ieee80211_local *local = sdata->local;
Arik Nemtsovf09a87d2014-07-17 17:14:20 +0300173 size_t offset = 0, noffset;
174 u8 *pos;
175
176 ieee80211_add_srates_ie(sdata, skb, false, band);
177 ieee80211_add_ext_srates_ie(sdata, skb, false, band);
178
179 /* add any custom IEs that go before Extended Capabilities */
180 if (extra_ies_len) {
181 static const u8 before_ext_cap[] = {
182 WLAN_EID_SUPP_RATES,
183 WLAN_EID_COUNTRY,
184 WLAN_EID_EXT_SUPP_RATES,
185 WLAN_EID_SUPPORTED_CHANNELS,
186 WLAN_EID_RSN,
187 };
188 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
189 before_ext_cap,
190 ARRAY_SIZE(before_ext_cap),
191 offset);
192 pos = skb_put(skb, noffset - offset);
193 memcpy(pos, extra_ies + offset, noffset - offset);
194 offset = noffset;
195 }
196
197 ieee80211_tdls_add_ext_capab(skb);
198
Arik Nemtsov40b861a2014-07-17 17:14:23 +0300199 /* add the QoS element if we support it */
200 if (local->hw.queues >= IEEE80211_NUM_ACS &&
201 action_code != WLAN_PUB_ACTION_TDLS_DISCOVER_RES)
202 ieee80211_add_wmm_info_ie(skb_put(skb, 9), 0); /* no U-APSD */
203
Arik Nemtsovf09a87d2014-07-17 17:14:20 +0300204 /* add any custom IEs that go before HT capabilities */
205 if (extra_ies_len) {
206 static const u8 before_ht_cap[] = {
207 WLAN_EID_SUPP_RATES,
208 WLAN_EID_COUNTRY,
209 WLAN_EID_EXT_SUPP_RATES,
210 WLAN_EID_SUPPORTED_CHANNELS,
211 WLAN_EID_RSN,
212 WLAN_EID_EXT_CAPABILITY,
213 WLAN_EID_QOS_CAPA,
214 WLAN_EID_FAST_BSS_TRANSITION,
215 WLAN_EID_TIMEOUT_INTERVAL,
216 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
217 };
218 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
219 before_ht_cap,
220 ARRAY_SIZE(before_ht_cap),
221 offset);
222 pos = skb_put(skb, noffset - offset);
223 memcpy(pos, extra_ies + offset, noffset - offset);
224 offset = noffset;
225 }
226
227 /* add any remaining IEs */
228 if (extra_ies_len) {
229 noffset = extra_ies_len;
230 pos = skb_put(skb, noffset - offset);
231 memcpy(pos, extra_ies + offset, noffset - offset);
232 }
Arik Nemtsov1606ef42014-07-17 17:14:21 +0300233
234 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
Arik Nemtsovf09a87d2014-07-17 17:14:20 +0300235}
236
Arik Nemtsov6f7eaa42014-07-17 17:14:24 +0300237static void
238ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata,
239 struct sk_buff *skb, const u8 *peer,
240 bool initiator, const u8 *extra_ies,
241 size_t extra_ies_len)
242{
243 struct ieee80211_local *local = sdata->local;
244 size_t offset = 0, noffset;
245 struct sta_info *sta;
246 u8 *pos;
247
248 rcu_read_lock();
249
250 sta = sta_info_get(sdata, peer);
251 if (WARN_ON_ONCE(!sta)) {
252 rcu_read_unlock();
253 return;
254 }
255
256 /* add any custom IEs that go before the QoS IE */
257 if (extra_ies_len) {
258 static const u8 before_qos[] = {
259 WLAN_EID_RSN,
260 };
261 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
262 before_qos,
263 ARRAY_SIZE(before_qos),
264 offset);
265 pos = skb_put(skb, noffset - offset);
266 memcpy(pos, extra_ies + offset, noffset - offset);
267 offset = noffset;
268 }
269
270 /* add the QoS param IE if both the peer and we support it */
271 if (local->hw.queues >= IEEE80211_NUM_ACS &&
272 test_sta_flag(sta, WLAN_STA_WME))
273 ieee80211_tdls_add_wmm_param_ie(sdata, skb);
274
275 /* add any remaining IEs */
276 if (extra_ies_len) {
277 noffset = extra_ies_len;
278 pos = skb_put(skb, noffset - offset);
279 memcpy(pos, extra_ies + offset, noffset - offset);
280 }
281
282 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
283
284 rcu_read_unlock();
285}
286
Arik Nemtsov46792a22014-07-17 17:14:19 +0300287static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata,
288 struct sk_buff *skb, const u8 *peer,
Arik Nemtsov1606ef42014-07-17 17:14:21 +0300289 u8 action_code, u16 status_code,
290 bool initiator, const u8 *extra_ies,
291 size_t extra_ies_len)
Arik Nemtsov46792a22014-07-17 17:14:19 +0300292{
Arik Nemtsov46792a22014-07-17 17:14:19 +0300293 switch (action_code) {
294 case WLAN_TDLS_SETUP_REQUEST:
295 case WLAN_TDLS_SETUP_RESPONSE:
296 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
Arik Nemtsov1606ef42014-07-17 17:14:21 +0300297 if (status_code == 0)
298 ieee80211_tdls_add_setup_start_ies(sdata, skb, peer,
299 action_code,
300 initiator,
301 extra_ies,
302 extra_ies_len);
Arik Nemtsov46792a22014-07-17 17:14:19 +0300303 break;
304 case WLAN_TDLS_SETUP_CONFIRM:
Arik Nemtsov6f7eaa42014-07-17 17:14:24 +0300305 if (status_code == 0)
306 ieee80211_tdls_add_setup_cfm_ies(sdata, skb, peer,
307 initiator, extra_ies,
308 extra_ies_len);
309 break;
Arik Nemtsov46792a22014-07-17 17:14:19 +0300310 case WLAN_TDLS_TEARDOWN:
311 case WLAN_TDLS_DISCOVERY_REQUEST:
Arik Nemtsovf09a87d2014-07-17 17:14:20 +0300312 if (extra_ies_len)
313 memcpy(skb_put(skb, extra_ies_len), extra_ies,
314 extra_ies_len);
Arik Nemtsov1606ef42014-07-17 17:14:21 +0300315 if (status_code == 0 || action_code == WLAN_TDLS_TEARDOWN)
316 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
Arik Nemtsov46792a22014-07-17 17:14:19 +0300317 break;
318 }
319
Arik Nemtsov46792a22014-07-17 17:14:19 +0300320}
321
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300322static int
323ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
Johannes Berg3b3a0162014-05-19 17:19:31 +0200324 const u8 *peer, u8 action_code, u8 dialog_token,
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300325 u16 status_code, struct sk_buff *skb)
326{
327 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300328 struct ieee80211_tdls_data *tf;
329
330 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
331
332 memcpy(tf->da, peer, ETH_ALEN);
333 memcpy(tf->sa, sdata->vif.addr, ETH_ALEN);
334 tf->ether_type = cpu_to_be16(ETH_P_TDLS);
335 tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
336
337 switch (action_code) {
338 case WLAN_TDLS_SETUP_REQUEST:
339 tf->category = WLAN_CATEGORY_TDLS;
340 tf->action_code = WLAN_TDLS_SETUP_REQUEST;
341
342 skb_put(skb, sizeof(tf->u.setup_req));
343 tf->u.setup_req.dialog_token = dialog_token;
344 tf->u.setup_req.capability =
Arik Nemtsovdd8c0b02014-07-17 17:14:22 +0300345 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
346 status_code));
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300347 break;
348 case WLAN_TDLS_SETUP_RESPONSE:
349 tf->category = WLAN_CATEGORY_TDLS;
350 tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
351
352 skb_put(skb, sizeof(tf->u.setup_resp));
353 tf->u.setup_resp.status_code = cpu_to_le16(status_code);
354 tf->u.setup_resp.dialog_token = dialog_token;
355 tf->u.setup_resp.capability =
Arik Nemtsovdd8c0b02014-07-17 17:14:22 +0300356 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
357 status_code));
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300358 break;
359 case WLAN_TDLS_SETUP_CONFIRM:
360 tf->category = WLAN_CATEGORY_TDLS;
361 tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
362
363 skb_put(skb, sizeof(tf->u.setup_cfm));
364 tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
365 tf->u.setup_cfm.dialog_token = dialog_token;
366 break;
367 case WLAN_TDLS_TEARDOWN:
368 tf->category = WLAN_CATEGORY_TDLS;
369 tf->action_code = WLAN_TDLS_TEARDOWN;
370
371 skb_put(skb, sizeof(tf->u.teardown));
372 tf->u.teardown.reason_code = cpu_to_le16(status_code);
373 break;
374 case WLAN_TDLS_DISCOVERY_REQUEST:
375 tf->category = WLAN_CATEGORY_TDLS;
376 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
377
378 skb_put(skb, sizeof(tf->u.discover_req));
379 tf->u.discover_req.dialog_token = dialog_token;
380 break;
381 default:
382 return -EINVAL;
383 }
384
385 return 0;
386}
387
388static int
389ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
Johannes Berg3b3a0162014-05-19 17:19:31 +0200390 const u8 *peer, u8 action_code, u8 dialog_token,
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300391 u16 status_code, struct sk_buff *skb)
392{
393 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300394 struct ieee80211_mgmt *mgmt;
395
396 mgmt = (void *)skb_put(skb, 24);
397 memset(mgmt, 0, 24);
398 memcpy(mgmt->da, peer, ETH_ALEN);
399 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
400 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
401
402 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
403 IEEE80211_STYPE_ACTION);
404
405 switch (action_code) {
406 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
407 skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
408 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
409 mgmt->u.action.u.tdls_discover_resp.action_code =
410 WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
411 mgmt->u.action.u.tdls_discover_resp.dialog_token =
412 dialog_token;
413 mgmt->u.action.u.tdls_discover_resp.capability =
Arik Nemtsovdd8c0b02014-07-17 17:14:22 +0300414 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
415 status_code));
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300416 break;
417 default:
418 return -EINVAL;
419 }
420
421 return 0;
422}
423
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300424static int
425ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
426 const u8 *peer, u8 action_code,
427 u8 dialog_token, u16 status_code,
Arik Nemtsov2fb6b9b2014-06-11 17:18:22 +0300428 u32 peer_capability, bool initiator,
429 const u8 *extra_ies, size_t extra_ies_len)
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300430{
431 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
432 struct ieee80211_local *local = sdata->local;
433 struct sk_buff *skb = NULL;
434 bool send_direct;
Arik Nemtsov626911c2014-07-17 17:14:17 +0300435 struct sta_info *sta;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300436 int ret;
437
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300438 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
439 max(sizeof(struct ieee80211_mgmt),
440 sizeof(struct ieee80211_tdls_data)) +
441 50 + /* supported rates */
442 7 + /* ext capab */
Arik Nemtsov40b861a2014-07-17 17:14:23 +0300443 26 + /* max(WMM-info, WMM-param) */
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300444 extra_ies_len +
445 sizeof(struct ieee80211_tdls_lnkie));
446 if (!skb)
447 return -ENOMEM;
448
449 skb_reserve(skb, local->hw.extra_tx_headroom);
450
451 switch (action_code) {
452 case WLAN_TDLS_SETUP_REQUEST:
453 case WLAN_TDLS_SETUP_RESPONSE:
454 case WLAN_TDLS_SETUP_CONFIRM:
455 case WLAN_TDLS_TEARDOWN:
456 case WLAN_TDLS_DISCOVERY_REQUEST:
457 ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer,
458 action_code, dialog_token,
459 status_code, skb);
460 send_direct = false;
461 break;
462 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
463 ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code,
464 dialog_token, status_code,
465 skb);
466 send_direct = true;
467 break;
468 default:
469 ret = -ENOTSUPP;
470 break;
471 }
472
473 if (ret < 0)
474 goto fail;
475
Arik Nemtsov626911c2014-07-17 17:14:17 +0300476 rcu_read_lock();
477 sta = sta_info_get(sdata, peer);
478
479 /* infer the initiator if we can, to support old userspace */
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300480 switch (action_code) {
481 case WLAN_TDLS_SETUP_REQUEST:
Arik Nemtsov626911c2014-07-17 17:14:17 +0300482 if (sta)
483 set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
484 /* fall-through */
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300485 case WLAN_TDLS_SETUP_CONFIRM:
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300486 case WLAN_TDLS_DISCOVERY_REQUEST:
Arik Nemtsov626911c2014-07-17 17:14:17 +0300487 initiator = true;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300488 break;
489 case WLAN_TDLS_SETUP_RESPONSE:
Arik Nemtsov626911c2014-07-17 17:14:17 +0300490 /*
491 * In some testing scenarios, we send a request and response.
492 * Make the last packet sent take effect for the initiator
493 * value.
494 */
495 if (sta)
496 clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
497 /* fall-through */
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300498 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
Arik Nemtsov626911c2014-07-17 17:14:17 +0300499 initiator = false;
Arik Nemtsov2fb6b9b2014-06-11 17:18:22 +0300500 break;
501 case WLAN_TDLS_TEARDOWN:
502 /* any value is ok */
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300503 break;
504 default:
505 ret = -ENOTSUPP;
Arik Nemtsov626911c2014-07-17 17:14:17 +0300506 break;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300507 }
508
Arik Nemtsov46792a22014-07-17 17:14:19 +0300509 if (sta && test_sta_flag(sta, WLAN_STA_TDLS_INITIATOR))
510 initiator = true;
Arik Nemtsov2fb6b9b2014-06-11 17:18:22 +0300511
Arik Nemtsov626911c2014-07-17 17:14:17 +0300512 rcu_read_unlock();
513 if (ret < 0)
514 goto fail;
515
Arik Nemtsov1606ef42014-07-17 17:14:21 +0300516 ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code,
517 initiator, extra_ies, extra_ies_len);
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300518 if (send_direct) {
519 ieee80211_tx_skb(sdata, skb);
520 return 0;
521 }
522
523 /*
524 * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise
525 * we should default to AC_VI.
526 */
527 switch (action_code) {
528 case WLAN_TDLS_SETUP_REQUEST:
529 case WLAN_TDLS_SETUP_RESPONSE:
530 skb_set_queue_mapping(skb, IEEE80211_AC_BK);
531 skb->priority = 2;
532 break;
533 default:
534 skb_set_queue_mapping(skb, IEEE80211_AC_VI);
535 skb->priority = 5;
536 break;
537 }
538
539 /* disable bottom halves when entering the Tx path */
540 local_bh_disable();
541 ret = ieee80211_subif_start_xmit(skb, dev);
542 local_bh_enable();
543
544 return ret;
545
546fail:
547 dev_kfree_skb(skb);
548 return ret;
549}
550
Arik Nemtsov191dd462014-06-11 17:18:23 +0300551static int
552ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev,
553 const u8 *peer, u8 action_code, u8 dialog_token,
554 u16 status_code, u32 peer_capability, bool initiator,
555 const u8 *extra_ies, size_t extra_ies_len)
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300556{
557 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
558 struct ieee80211_local *local = sdata->local;
559 int ret;
560
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300561 mutex_lock(&local->mtx);
562
563 /* we don't support concurrent TDLS peer setups */
Arik Nemtsov81dd2b82014-07-17 17:14:25 +0300564 if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer) &&
565 !ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) {
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300566 ret = -EBUSY;
567 goto exit;
568 }
569
Arik Nemtsov7adc3e42014-06-11 17:18:26 +0300570 /*
571 * make sure we have a STA representing the peer so we drop or buffer
572 * non-TDLS-setup frames to the peer. We can't send other packets
Arik Nemtsov6ae32e52014-07-17 17:14:18 +0300573 * during setup through the AP path.
574 * Allow error packets to be sent - sometimes we don't even add a STA
575 * before failing the setup.
Arik Nemtsov7adc3e42014-06-11 17:18:26 +0300576 */
Arik Nemtsov6ae32e52014-07-17 17:14:18 +0300577 if (status_code == 0) {
578 rcu_read_lock();
579 if (!sta_info_get(sdata, peer)) {
580 rcu_read_unlock();
581 ret = -ENOLINK;
582 goto exit;
583 }
Arik Nemtsov7adc3e42014-06-11 17:18:26 +0300584 rcu_read_unlock();
Arik Nemtsov7adc3e42014-06-11 17:18:26 +0300585 }
Arik Nemtsov7adc3e42014-06-11 17:18:26 +0300586
Arik Nemtsovdb67d662014-06-11 17:18:24 +0300587 ieee80211_flush_queues(local, sdata);
588
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300589 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
590 dialog_token, status_code,
Arik Nemtsov2fb6b9b2014-06-11 17:18:22 +0300591 peer_capability, initiator,
592 extra_ies, extra_ies_len);
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300593 if (ret < 0)
594 goto exit;
595
Arik Nemtsov81dd2b82014-07-17 17:14:25 +0300596 memcpy(sdata->u.mgd.tdls_peer, peer, ETH_ALEN);
Arik Nemtsov191dd462014-06-11 17:18:23 +0300597 ieee80211_queue_delayed_work(&sdata->local->hw,
Arik Nemtsov81dd2b82014-07-17 17:14:25 +0300598 &sdata->u.mgd.tdls_peer_del_work,
Arik Nemtsov191dd462014-06-11 17:18:23 +0300599 TDLS_PEER_SETUP_TIMEOUT);
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300600
601exit:
602 mutex_unlock(&local->mtx);
Arik Nemtsov191dd462014-06-11 17:18:23 +0300603 return ret;
604}
605
Arik Nemtsovdb67d662014-06-11 17:18:24 +0300606static int
607ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev,
608 const u8 *peer, u8 action_code, u8 dialog_token,
609 u16 status_code, u32 peer_capability,
610 bool initiator, const u8 *extra_ies,
611 size_t extra_ies_len)
612{
613 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
614 struct ieee80211_local *local = sdata->local;
615 struct sta_info *sta;
616 int ret;
617
618 /*
619 * No packets can be transmitted to the peer via the AP during setup -
620 * the STA is set as a TDLS peer, but is not authorized.
621 * During teardown, we prevent direct transmissions by stopping the
622 * queues and flushing all direct packets.
623 */
624 ieee80211_stop_vif_queues(local, sdata,
625 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
626 ieee80211_flush_queues(local, sdata);
627
628 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
629 dialog_token, status_code,
630 peer_capability, initiator,
631 extra_ies, extra_ies_len);
632 if (ret < 0)
633 sdata_err(sdata, "Failed sending TDLS teardown packet %d\n",
634 ret);
635
636 /*
637 * Remove the STA AUTH flag to force further traffic through the AP. If
638 * the STA was unreachable, it was already removed.
639 */
640 rcu_read_lock();
641 sta = sta_info_get(sdata, peer);
642 if (sta)
643 clear_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
644 rcu_read_unlock();
645
646 ieee80211_wake_vif_queues(local, sdata,
647 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
648
649 return 0;
650}
651
Arik Nemtsov191dd462014-06-11 17:18:23 +0300652int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
653 const u8 *peer, u8 action_code, u8 dialog_token,
654 u16 status_code, u32 peer_capability,
655 bool initiator, const u8 *extra_ies,
656 size_t extra_ies_len)
657{
658 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
659 int ret;
660
661 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
662 return -ENOTSUPP;
663
664 /* make sure we are in managed mode, and associated */
665 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
666 !sdata->u.mgd.associated)
667 return -EINVAL;
668
669 switch (action_code) {
670 case WLAN_TDLS_SETUP_REQUEST:
671 case WLAN_TDLS_SETUP_RESPONSE:
672 ret = ieee80211_tdls_mgmt_setup(wiphy, dev, peer, action_code,
673 dialog_token, status_code,
674 peer_capability, initiator,
675 extra_ies, extra_ies_len);
676 break;
677 case WLAN_TDLS_TEARDOWN:
Arik Nemtsovdb67d662014-06-11 17:18:24 +0300678 ret = ieee80211_tdls_mgmt_teardown(wiphy, dev, peer,
679 action_code, dialog_token,
680 status_code,
681 peer_capability, initiator,
682 extra_ies, extra_ies_len);
683 break;
Arik Nemtsov191dd462014-06-11 17:18:23 +0300684 case WLAN_TDLS_DISCOVERY_REQUEST:
Arik Nemtsovee10f2c2014-06-11 17:18:27 +0300685 /*
686 * Protect the discovery so we can hear the TDLS discovery
687 * response frame. It is transmitted directly and not buffered
688 * by the AP.
689 */
690 drv_mgd_protect_tdls_discover(sdata->local, sdata);
691 /* fall-through */
692 case WLAN_TDLS_SETUP_CONFIRM:
Arik Nemtsov191dd462014-06-11 17:18:23 +0300693 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
694 /* no special handling */
695 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
696 action_code,
697 dialog_token,
698 status_code,
699 peer_capability,
700 initiator, extra_ies,
701 extra_ies_len);
702 break;
703 default:
704 ret = -EOPNOTSUPP;
705 break;
706 }
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300707
708 tdls_dbg(sdata, "TDLS mgmt action %d peer %pM status %d\n",
709 action_code, peer, ret);
710 return ret;
711}
712
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300713int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Johannes Berg3b3a0162014-05-19 17:19:31 +0200714 const u8 *peer, enum nl80211_tdls_operation oper)
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300715{
716 struct sta_info *sta;
717 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300718 struct ieee80211_local *local = sdata->local;
719 int ret;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300720
721 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
722 return -ENOTSUPP;
723
724 if (sdata->vif.type != NL80211_IFTYPE_STATION)
725 return -EINVAL;
726
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300727 switch (oper) {
728 case NL80211_TDLS_ENABLE_LINK:
729 case NL80211_TDLS_DISABLE_LINK:
730 break;
731 case NL80211_TDLS_TEARDOWN:
732 case NL80211_TDLS_SETUP:
733 case NL80211_TDLS_DISCOVERY_REQ:
734 /* We don't support in-driver setup/teardown/discovery */
735 return -ENOTSUPP;
736 }
737
738 mutex_lock(&local->mtx);
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300739 tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer);
740
741 switch (oper) {
742 case NL80211_TDLS_ENABLE_LINK:
743 rcu_read_lock();
744 sta = sta_info_get(sdata, peer);
745 if (!sta) {
746 rcu_read_unlock();
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300747 ret = -ENOLINK;
748 break;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300749 }
750
751 set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
752 rcu_read_unlock();
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300753
Arik Nemtsov81dd2b82014-07-17 17:14:25 +0300754 WARN_ON_ONCE(is_zero_ether_addr(sdata->u.mgd.tdls_peer) ||
755 !ether_addr_equal(sdata->u.mgd.tdls_peer, peer));
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300756 ret = 0;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300757 break;
758 case NL80211_TDLS_DISABLE_LINK:
Arik Nemtsovdb67d662014-06-11 17:18:24 +0300759 /* flush a potentially queued teardown packet */
760 ieee80211_flush_queues(local, sdata);
761
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300762 ret = sta_info_destroy_addr(sdata, peer);
763 break;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300764 default:
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300765 ret = -ENOTSUPP;
766 break;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300767 }
768
Arik Nemtsov81dd2b82014-07-17 17:14:25 +0300769 if (ret == 0 && ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) {
770 cancel_delayed_work(&sdata->u.mgd.tdls_peer_del_work);
771 eth_zero_addr(sdata->u.mgd.tdls_peer);
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300772 }
773
774 mutex_unlock(&local->mtx);
775 return ret;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300776}
Arik Nemtsovc887f0d32014-06-11 17:18:25 +0300777
778void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
779 enum nl80211_tdls_operation oper,
780 u16 reason_code, gfp_t gfp)
781{
782 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
783
784 if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) {
785 sdata_err(sdata, "Discarding TDLS oper %d - not STA or disconnected\n",
786 oper);
787 return;
788 }
789
790 cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp);
791}
792EXPORT_SYMBOL(ieee80211_tdls_oper_request);