blob: 99d5ed3aa474eb6b989a48fe8671aa59f84b2222 [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 Nemtsovc887f0d32014-06-11 17:18:25 +030011#include <net/cfg80211.h>
Arik Nemtsov95224fe2014-05-01 10:17:28 +030012#include "ieee80211_i.h"
Arik Nemtsovee10f2c2014-06-11 17:18:27 +030013#include "driver-ops.h"
Arik Nemtsov95224fe2014-05-01 10:17:28 +030014
Arik Nemtsov17e6a592014-06-11 17:18:20 +030015/* give usermode some time for retries in setting up the TDLS session */
16#define TDLS_PEER_SETUP_TIMEOUT (15 * HZ)
17
18void ieee80211_tdls_peer_del_work(struct work_struct *wk)
19{
20 struct ieee80211_sub_if_data *sdata;
21 struct ieee80211_local *local;
22
23 sdata = container_of(wk, struct ieee80211_sub_if_data,
24 tdls_peer_del_work.work);
25 local = sdata->local;
26
27 mutex_lock(&local->mtx);
28 if (!is_zero_ether_addr(sdata->tdls_peer)) {
29 tdls_dbg(sdata, "TDLS del peer %pM\n", sdata->tdls_peer);
30 sta_info_destroy_addr(sdata, sdata->tdls_peer);
31 eth_zero_addr(sdata->tdls_peer);
32 }
33 mutex_unlock(&local->mtx);
34}
35
Arik Nemtsov95224fe2014-05-01 10:17:28 +030036static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb)
37{
38 u8 *pos = (void *)skb_put(skb, 7);
39
40 *pos++ = WLAN_EID_EXT_CAPABILITY;
41 *pos++ = 5; /* len */
42 *pos++ = 0x0;
43 *pos++ = 0x0;
44 *pos++ = 0x0;
45 *pos++ = 0x0;
46 *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED;
47}
48
49static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata)
50{
51 struct ieee80211_local *local = sdata->local;
52 u16 capab;
53
54 capab = 0;
55 if (ieee80211_get_sdata_band(sdata) != IEEE80211_BAND_2GHZ)
56 return capab;
57
58 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
59 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
60 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
61 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
62
63 return capab;
64}
65
Arik Nemtsov1606ef42014-07-17 17:14:21 +030066static void ieee80211_tdls_add_link_ie(struct ieee80211_sub_if_data *sdata,
67 struct sk_buff *skb, const u8 *peer,
68 bool initiator)
Arik Nemtsov95224fe2014-05-01 10:17:28 +030069{
70 struct ieee80211_tdls_lnkie *lnkid;
Arik Nemtsov1606ef42014-07-17 17:14:21 +030071 const u8 *init_addr, *rsp_addr;
72
73 if (initiator) {
74 init_addr = sdata->vif.addr;
75 rsp_addr = peer;
76 } else {
77 init_addr = peer;
78 rsp_addr = sdata->vif.addr;
79 }
Arik Nemtsov95224fe2014-05-01 10:17:28 +030080
81 lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
82
83 lnkid->ie_type = WLAN_EID_LINK_ID;
84 lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2;
85
Arik Nemtsov1606ef42014-07-17 17:14:21 +030086 memcpy(lnkid->bssid, sdata->u.mgd.bssid, ETH_ALEN);
87 memcpy(lnkid->init_sta, init_addr, ETH_ALEN);
88 memcpy(lnkid->resp_sta, rsp_addr, ETH_ALEN);
Arik Nemtsov95224fe2014-05-01 10:17:28 +030089}
90
Arik Nemtsovf09a87d2014-07-17 17:14:20 +030091static void
92ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata,
93 struct sk_buff *skb, const u8 *peer,
Arik Nemtsov1606ef42014-07-17 17:14:21 +030094 u8 action_code, bool initiator,
95 const u8 *extra_ies, size_t extra_ies_len)
Arik Nemtsovf09a87d2014-07-17 17:14:20 +030096{
97 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
98 size_t offset = 0, noffset;
99 u8 *pos;
100
101 ieee80211_add_srates_ie(sdata, skb, false, band);
102 ieee80211_add_ext_srates_ie(sdata, skb, false, band);
103
104 /* add any custom IEs that go before Extended Capabilities */
105 if (extra_ies_len) {
106 static const u8 before_ext_cap[] = {
107 WLAN_EID_SUPP_RATES,
108 WLAN_EID_COUNTRY,
109 WLAN_EID_EXT_SUPP_RATES,
110 WLAN_EID_SUPPORTED_CHANNELS,
111 WLAN_EID_RSN,
112 };
113 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
114 before_ext_cap,
115 ARRAY_SIZE(before_ext_cap),
116 offset);
117 pos = skb_put(skb, noffset - offset);
118 memcpy(pos, extra_ies + offset, noffset - offset);
119 offset = noffset;
120 }
121
122 ieee80211_tdls_add_ext_capab(skb);
123
124 /* add any custom IEs that go before HT capabilities */
125 if (extra_ies_len) {
126 static const u8 before_ht_cap[] = {
127 WLAN_EID_SUPP_RATES,
128 WLAN_EID_COUNTRY,
129 WLAN_EID_EXT_SUPP_RATES,
130 WLAN_EID_SUPPORTED_CHANNELS,
131 WLAN_EID_RSN,
132 WLAN_EID_EXT_CAPABILITY,
133 WLAN_EID_QOS_CAPA,
134 WLAN_EID_FAST_BSS_TRANSITION,
135 WLAN_EID_TIMEOUT_INTERVAL,
136 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
137 };
138 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
139 before_ht_cap,
140 ARRAY_SIZE(before_ht_cap),
141 offset);
142 pos = skb_put(skb, noffset - offset);
143 memcpy(pos, extra_ies + offset, noffset - offset);
144 offset = noffset;
145 }
146
147 /* add any remaining IEs */
148 if (extra_ies_len) {
149 noffset = extra_ies_len;
150 pos = skb_put(skb, noffset - offset);
151 memcpy(pos, extra_ies + offset, noffset - offset);
152 }
Arik Nemtsov1606ef42014-07-17 17:14:21 +0300153
154 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
Arik Nemtsovf09a87d2014-07-17 17:14:20 +0300155}
156
Arik Nemtsov46792a22014-07-17 17:14:19 +0300157static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata,
158 struct sk_buff *skb, const u8 *peer,
Arik Nemtsov1606ef42014-07-17 17:14:21 +0300159 u8 action_code, u16 status_code,
160 bool initiator, const u8 *extra_ies,
161 size_t extra_ies_len)
Arik Nemtsov46792a22014-07-17 17:14:19 +0300162{
Arik Nemtsov46792a22014-07-17 17:14:19 +0300163 switch (action_code) {
164 case WLAN_TDLS_SETUP_REQUEST:
165 case WLAN_TDLS_SETUP_RESPONSE:
166 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
Arik Nemtsov1606ef42014-07-17 17:14:21 +0300167 if (status_code == 0)
168 ieee80211_tdls_add_setup_start_ies(sdata, skb, peer,
169 action_code,
170 initiator,
171 extra_ies,
172 extra_ies_len);
Arik Nemtsov46792a22014-07-17 17:14:19 +0300173 break;
174 case WLAN_TDLS_SETUP_CONFIRM:
175 case WLAN_TDLS_TEARDOWN:
176 case WLAN_TDLS_DISCOVERY_REQUEST:
Arik Nemtsovf09a87d2014-07-17 17:14:20 +0300177 if (extra_ies_len)
178 memcpy(skb_put(skb, extra_ies_len), extra_ies,
179 extra_ies_len);
Arik Nemtsov1606ef42014-07-17 17:14:21 +0300180 if (status_code == 0 || action_code == WLAN_TDLS_TEARDOWN)
181 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
Arik Nemtsov46792a22014-07-17 17:14:19 +0300182 break;
183 }
184
Arik Nemtsov46792a22014-07-17 17:14:19 +0300185}
186
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300187static int
188ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
Johannes Berg3b3a0162014-05-19 17:19:31 +0200189 const u8 *peer, u8 action_code, u8 dialog_token,
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300190 u16 status_code, struct sk_buff *skb)
191{
192 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300193 struct ieee80211_tdls_data *tf;
194
195 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
196
197 memcpy(tf->da, peer, ETH_ALEN);
198 memcpy(tf->sa, sdata->vif.addr, ETH_ALEN);
199 tf->ether_type = cpu_to_be16(ETH_P_TDLS);
200 tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
201
202 switch (action_code) {
203 case WLAN_TDLS_SETUP_REQUEST:
204 tf->category = WLAN_CATEGORY_TDLS;
205 tf->action_code = WLAN_TDLS_SETUP_REQUEST;
206
207 skb_put(skb, sizeof(tf->u.setup_req));
208 tf->u.setup_req.dialog_token = dialog_token;
209 tf->u.setup_req.capability =
210 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300211 break;
212 case WLAN_TDLS_SETUP_RESPONSE:
213 tf->category = WLAN_CATEGORY_TDLS;
214 tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
215
216 skb_put(skb, sizeof(tf->u.setup_resp));
217 tf->u.setup_resp.status_code = cpu_to_le16(status_code);
218 tf->u.setup_resp.dialog_token = dialog_token;
219 tf->u.setup_resp.capability =
220 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300221 break;
222 case WLAN_TDLS_SETUP_CONFIRM:
223 tf->category = WLAN_CATEGORY_TDLS;
224 tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
225
226 skb_put(skb, sizeof(tf->u.setup_cfm));
227 tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
228 tf->u.setup_cfm.dialog_token = dialog_token;
229 break;
230 case WLAN_TDLS_TEARDOWN:
231 tf->category = WLAN_CATEGORY_TDLS;
232 tf->action_code = WLAN_TDLS_TEARDOWN;
233
234 skb_put(skb, sizeof(tf->u.teardown));
235 tf->u.teardown.reason_code = cpu_to_le16(status_code);
236 break;
237 case WLAN_TDLS_DISCOVERY_REQUEST:
238 tf->category = WLAN_CATEGORY_TDLS;
239 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
240
241 skb_put(skb, sizeof(tf->u.discover_req));
242 tf->u.discover_req.dialog_token = dialog_token;
243 break;
244 default:
245 return -EINVAL;
246 }
247
248 return 0;
249}
250
251static int
252ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
Johannes Berg3b3a0162014-05-19 17:19:31 +0200253 const u8 *peer, u8 action_code, u8 dialog_token,
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300254 u16 status_code, struct sk_buff *skb)
255{
256 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300257 struct ieee80211_mgmt *mgmt;
258
259 mgmt = (void *)skb_put(skb, 24);
260 memset(mgmt, 0, 24);
261 memcpy(mgmt->da, peer, ETH_ALEN);
262 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
263 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
264
265 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
266 IEEE80211_STYPE_ACTION);
267
268 switch (action_code) {
269 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
270 skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
271 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
272 mgmt->u.action.u.tdls_discover_resp.action_code =
273 WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
274 mgmt->u.action.u.tdls_discover_resp.dialog_token =
275 dialog_token;
276 mgmt->u.action.u.tdls_discover_resp.capability =
277 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300278 break;
279 default:
280 return -EINVAL;
281 }
282
283 return 0;
284}
285
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300286static int
287ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
288 const u8 *peer, u8 action_code,
289 u8 dialog_token, u16 status_code,
Arik Nemtsov2fb6b9b2014-06-11 17:18:22 +0300290 u32 peer_capability, bool initiator,
291 const u8 *extra_ies, size_t extra_ies_len)
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300292{
293 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
294 struct ieee80211_local *local = sdata->local;
295 struct sk_buff *skb = NULL;
296 bool send_direct;
Arik Nemtsov626911c2014-07-17 17:14:17 +0300297 struct sta_info *sta;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300298 int ret;
299
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300300 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
301 max(sizeof(struct ieee80211_mgmt),
302 sizeof(struct ieee80211_tdls_data)) +
303 50 + /* supported rates */
304 7 + /* ext capab */
305 extra_ies_len +
306 sizeof(struct ieee80211_tdls_lnkie));
307 if (!skb)
308 return -ENOMEM;
309
310 skb_reserve(skb, local->hw.extra_tx_headroom);
311
312 switch (action_code) {
313 case WLAN_TDLS_SETUP_REQUEST:
314 case WLAN_TDLS_SETUP_RESPONSE:
315 case WLAN_TDLS_SETUP_CONFIRM:
316 case WLAN_TDLS_TEARDOWN:
317 case WLAN_TDLS_DISCOVERY_REQUEST:
318 ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer,
319 action_code, dialog_token,
320 status_code, skb);
321 send_direct = false;
322 break;
323 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
324 ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code,
325 dialog_token, status_code,
326 skb);
327 send_direct = true;
328 break;
329 default:
330 ret = -ENOTSUPP;
331 break;
332 }
333
334 if (ret < 0)
335 goto fail;
336
Arik Nemtsov626911c2014-07-17 17:14:17 +0300337 rcu_read_lock();
338 sta = sta_info_get(sdata, peer);
339
340 /* infer the initiator if we can, to support old userspace */
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300341 switch (action_code) {
342 case WLAN_TDLS_SETUP_REQUEST:
Arik Nemtsov626911c2014-07-17 17:14:17 +0300343 if (sta)
344 set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
345 /* fall-through */
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300346 case WLAN_TDLS_SETUP_CONFIRM:
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300347 case WLAN_TDLS_DISCOVERY_REQUEST:
Arik Nemtsov626911c2014-07-17 17:14:17 +0300348 initiator = true;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300349 break;
350 case WLAN_TDLS_SETUP_RESPONSE:
Arik Nemtsov626911c2014-07-17 17:14:17 +0300351 /*
352 * In some testing scenarios, we send a request and response.
353 * Make the last packet sent take effect for the initiator
354 * value.
355 */
356 if (sta)
357 clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
358 /* fall-through */
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300359 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
Arik Nemtsov626911c2014-07-17 17:14:17 +0300360 initiator = false;
Arik Nemtsov2fb6b9b2014-06-11 17:18:22 +0300361 break;
362 case WLAN_TDLS_TEARDOWN:
363 /* any value is ok */
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300364 break;
365 default:
366 ret = -ENOTSUPP;
Arik Nemtsov626911c2014-07-17 17:14:17 +0300367 break;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300368 }
369
Arik Nemtsov46792a22014-07-17 17:14:19 +0300370 if (sta && test_sta_flag(sta, WLAN_STA_TDLS_INITIATOR))
371 initiator = true;
Arik Nemtsov2fb6b9b2014-06-11 17:18:22 +0300372
Arik Nemtsov626911c2014-07-17 17:14:17 +0300373 rcu_read_unlock();
374 if (ret < 0)
375 goto fail;
376
Arik Nemtsov1606ef42014-07-17 17:14:21 +0300377 ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code,
378 initiator, extra_ies, extra_ies_len);
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300379 if (send_direct) {
380 ieee80211_tx_skb(sdata, skb);
381 return 0;
382 }
383
384 /*
385 * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise
386 * we should default to AC_VI.
387 */
388 switch (action_code) {
389 case WLAN_TDLS_SETUP_REQUEST:
390 case WLAN_TDLS_SETUP_RESPONSE:
391 skb_set_queue_mapping(skb, IEEE80211_AC_BK);
392 skb->priority = 2;
393 break;
394 default:
395 skb_set_queue_mapping(skb, IEEE80211_AC_VI);
396 skb->priority = 5;
397 break;
398 }
399
400 /* disable bottom halves when entering the Tx path */
401 local_bh_disable();
402 ret = ieee80211_subif_start_xmit(skb, dev);
403 local_bh_enable();
404
405 return ret;
406
407fail:
408 dev_kfree_skb(skb);
409 return ret;
410}
411
Arik Nemtsov191dd462014-06-11 17:18:23 +0300412static int
413ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev,
414 const u8 *peer, u8 action_code, u8 dialog_token,
415 u16 status_code, u32 peer_capability, bool initiator,
416 const u8 *extra_ies, size_t extra_ies_len)
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300417{
418 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
419 struct ieee80211_local *local = sdata->local;
420 int ret;
421
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300422 mutex_lock(&local->mtx);
423
424 /* we don't support concurrent TDLS peer setups */
425 if (!is_zero_ether_addr(sdata->tdls_peer) &&
Arik Nemtsov191dd462014-06-11 17:18:23 +0300426 !ether_addr_equal(sdata->tdls_peer, peer)) {
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300427 ret = -EBUSY;
428 goto exit;
429 }
430
Arik Nemtsov7adc3e42014-06-11 17:18:26 +0300431 /*
432 * make sure we have a STA representing the peer so we drop or buffer
433 * non-TDLS-setup frames to the peer. We can't send other packets
Arik Nemtsov6ae32e52014-07-17 17:14:18 +0300434 * during setup through the AP path.
435 * Allow error packets to be sent - sometimes we don't even add a STA
436 * before failing the setup.
Arik Nemtsov7adc3e42014-06-11 17:18:26 +0300437 */
Arik Nemtsov6ae32e52014-07-17 17:14:18 +0300438 if (status_code == 0) {
439 rcu_read_lock();
440 if (!sta_info_get(sdata, peer)) {
441 rcu_read_unlock();
442 ret = -ENOLINK;
443 goto exit;
444 }
Arik Nemtsov7adc3e42014-06-11 17:18:26 +0300445 rcu_read_unlock();
Arik Nemtsov7adc3e42014-06-11 17:18:26 +0300446 }
Arik Nemtsov7adc3e42014-06-11 17:18:26 +0300447
Arik Nemtsovdb67d662014-06-11 17:18:24 +0300448 ieee80211_flush_queues(local, sdata);
449
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300450 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
451 dialog_token, status_code,
Arik Nemtsov2fb6b9b2014-06-11 17:18:22 +0300452 peer_capability, initiator,
453 extra_ies, extra_ies_len);
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300454 if (ret < 0)
455 goto exit;
456
Arik Nemtsov191dd462014-06-11 17:18:23 +0300457 memcpy(sdata->tdls_peer, peer, ETH_ALEN);
458 ieee80211_queue_delayed_work(&sdata->local->hw,
459 &sdata->tdls_peer_del_work,
460 TDLS_PEER_SETUP_TIMEOUT);
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300461
462exit:
463 mutex_unlock(&local->mtx);
Arik Nemtsov191dd462014-06-11 17:18:23 +0300464 return ret;
465}
466
Arik Nemtsovdb67d662014-06-11 17:18:24 +0300467static int
468ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev,
469 const u8 *peer, u8 action_code, u8 dialog_token,
470 u16 status_code, u32 peer_capability,
471 bool initiator, const u8 *extra_ies,
472 size_t extra_ies_len)
473{
474 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
475 struct ieee80211_local *local = sdata->local;
476 struct sta_info *sta;
477 int ret;
478
479 /*
480 * No packets can be transmitted to the peer via the AP during setup -
481 * the STA is set as a TDLS peer, but is not authorized.
482 * During teardown, we prevent direct transmissions by stopping the
483 * queues and flushing all direct packets.
484 */
485 ieee80211_stop_vif_queues(local, sdata,
486 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
487 ieee80211_flush_queues(local, sdata);
488
489 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
490 dialog_token, status_code,
491 peer_capability, initiator,
492 extra_ies, extra_ies_len);
493 if (ret < 0)
494 sdata_err(sdata, "Failed sending TDLS teardown packet %d\n",
495 ret);
496
497 /*
498 * Remove the STA AUTH flag to force further traffic through the AP. If
499 * the STA was unreachable, it was already removed.
500 */
501 rcu_read_lock();
502 sta = sta_info_get(sdata, peer);
503 if (sta)
504 clear_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
505 rcu_read_unlock();
506
507 ieee80211_wake_vif_queues(local, sdata,
508 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
509
510 return 0;
511}
512
Arik Nemtsov191dd462014-06-11 17:18:23 +0300513int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
514 const u8 *peer, u8 action_code, u8 dialog_token,
515 u16 status_code, u32 peer_capability,
516 bool initiator, const u8 *extra_ies,
517 size_t extra_ies_len)
518{
519 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
520 int ret;
521
522 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
523 return -ENOTSUPP;
524
525 /* make sure we are in managed mode, and associated */
526 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
527 !sdata->u.mgd.associated)
528 return -EINVAL;
529
530 switch (action_code) {
531 case WLAN_TDLS_SETUP_REQUEST:
532 case WLAN_TDLS_SETUP_RESPONSE:
533 ret = ieee80211_tdls_mgmt_setup(wiphy, dev, peer, action_code,
534 dialog_token, status_code,
535 peer_capability, initiator,
536 extra_ies, extra_ies_len);
537 break;
538 case WLAN_TDLS_TEARDOWN:
Arik Nemtsovdb67d662014-06-11 17:18:24 +0300539 ret = ieee80211_tdls_mgmt_teardown(wiphy, dev, peer,
540 action_code, dialog_token,
541 status_code,
542 peer_capability, initiator,
543 extra_ies, extra_ies_len);
544 break;
Arik Nemtsov191dd462014-06-11 17:18:23 +0300545 case WLAN_TDLS_DISCOVERY_REQUEST:
Arik Nemtsovee10f2c2014-06-11 17:18:27 +0300546 /*
547 * Protect the discovery so we can hear the TDLS discovery
548 * response frame. It is transmitted directly and not buffered
549 * by the AP.
550 */
551 drv_mgd_protect_tdls_discover(sdata->local, sdata);
552 /* fall-through */
553 case WLAN_TDLS_SETUP_CONFIRM:
Arik Nemtsov191dd462014-06-11 17:18:23 +0300554 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
555 /* no special handling */
556 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
557 action_code,
558 dialog_token,
559 status_code,
560 peer_capability,
561 initiator, extra_ies,
562 extra_ies_len);
563 break;
564 default:
565 ret = -EOPNOTSUPP;
566 break;
567 }
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300568
569 tdls_dbg(sdata, "TDLS mgmt action %d peer %pM status %d\n",
570 action_code, peer, ret);
571 return ret;
572}
573
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300574int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Johannes Berg3b3a0162014-05-19 17:19:31 +0200575 const u8 *peer, enum nl80211_tdls_operation oper)
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300576{
577 struct sta_info *sta;
578 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300579 struct ieee80211_local *local = sdata->local;
580 int ret;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300581
582 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
583 return -ENOTSUPP;
584
585 if (sdata->vif.type != NL80211_IFTYPE_STATION)
586 return -EINVAL;
587
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300588 switch (oper) {
589 case NL80211_TDLS_ENABLE_LINK:
590 case NL80211_TDLS_DISABLE_LINK:
591 break;
592 case NL80211_TDLS_TEARDOWN:
593 case NL80211_TDLS_SETUP:
594 case NL80211_TDLS_DISCOVERY_REQ:
595 /* We don't support in-driver setup/teardown/discovery */
596 return -ENOTSUPP;
597 }
598
599 mutex_lock(&local->mtx);
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300600 tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer);
601
602 switch (oper) {
603 case NL80211_TDLS_ENABLE_LINK:
604 rcu_read_lock();
605 sta = sta_info_get(sdata, peer);
606 if (!sta) {
607 rcu_read_unlock();
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300608 ret = -ENOLINK;
609 break;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300610 }
611
612 set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
613 rcu_read_unlock();
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300614
615 WARN_ON_ONCE(is_zero_ether_addr(sdata->tdls_peer) ||
616 !ether_addr_equal(sdata->tdls_peer, peer));
617 ret = 0;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300618 break;
619 case NL80211_TDLS_DISABLE_LINK:
Arik Nemtsovdb67d662014-06-11 17:18:24 +0300620 /* flush a potentially queued teardown packet */
621 ieee80211_flush_queues(local, sdata);
622
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300623 ret = sta_info_destroy_addr(sdata, peer);
624 break;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300625 default:
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300626 ret = -ENOTSUPP;
627 break;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300628 }
629
Arik Nemtsov17e6a592014-06-11 17:18:20 +0300630 if (ret == 0 && ether_addr_equal(sdata->tdls_peer, peer)) {
631 cancel_delayed_work(&sdata->tdls_peer_del_work);
632 eth_zero_addr(sdata->tdls_peer);
633 }
634
635 mutex_unlock(&local->mtx);
636 return ret;
Arik Nemtsov95224fe2014-05-01 10:17:28 +0300637}
Arik Nemtsovc887f0d32014-06-11 17:18:25 +0300638
639void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
640 enum nl80211_tdls_operation oper,
641 u16 reason_code, gfp_t gfp)
642{
643 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
644
645 if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) {
646 sdata_err(sdata, "Discarding TDLS oper %d - not STA or disconnected\n",
647 oper);
648 return;
649 }
650
651 cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp);
652}
653EXPORT_SYMBOL(ieee80211_tdls_oper_request);