2 * mac80211 TDLS handling code
4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright 2014, Intel Corporation
7 * This file is GPLv2 as found in COPYING.
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"
16 /* give usermode some time for retries in setting up the TDLS session */
17 #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ)
19 void ieee80211_tdls_peer_del_work(struct work_struct *wk)
21 struct ieee80211_sub_if_data *sdata;
22 struct ieee80211_local *local;
24 sdata = container_of(wk, struct ieee80211_sub_if_data,
25 tdls_peer_del_work.work);
28 mutex_lock(&local->mtx);
29 if (!is_zero_ether_addr(sdata->tdls_peer)) {
30 tdls_dbg(sdata, "TDLS del peer %pM\n", sdata->tdls_peer);
31 sta_info_destroy_addr(sdata, sdata->tdls_peer);
32 eth_zero_addr(sdata->tdls_peer);
34 mutex_unlock(&local->mtx);
37 static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb)
39 u8 *pos = (void *)skb_put(skb, 7);
41 *pos++ = WLAN_EID_EXT_CAPABILITY;
47 *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED;
50 static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata,
53 struct ieee80211_local *local = sdata->local;
56 /* The capability will be 0 when sending a failure code */
61 if (ieee80211_get_sdata_band(sdata) != IEEE80211_BAND_2GHZ)
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;
72 static void ieee80211_tdls_add_link_ie(struct ieee80211_sub_if_data *sdata,
73 struct sk_buff *skb, const u8 *peer,
76 struct ieee80211_tdls_lnkie *lnkid;
77 const u8 *init_addr, *rsp_addr;
80 init_addr = sdata->vif.addr;
84 rsp_addr = sdata->vif.addr;
87 lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
89 lnkid->ie_type = WLAN_EID_LINK_ID;
90 lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2;
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);
97 /* translate numbering in the WMM parameter IE to the mac80211 notation */
98 static enum ieee80211_ac_numbers ieee80211_ac_from_wmm(int ac)
104 return IEEE80211_AC_BE;
106 return IEEE80211_AC_BK;
108 return IEEE80211_AC_VI;
110 return IEEE80211_AC_VO;
114 static u8 ieee80211_wmm_aci_aifsn(int aifsn, bool acm, int aci)
121 ret |= (aci << 5) & 0x60;
125 static u8 ieee80211_wmm_ecw(u16 cw_min, u16 cw_max)
127 return ((ilog2(cw_min + 1) << 0x0) & 0x0f) |
128 ((ilog2(cw_max + 1) << 0x4) & 0xf0);
131 static void ieee80211_tdls_add_wmm_param_ie(struct ieee80211_sub_if_data *sdata,
134 struct ieee80211_wmm_param_ie *wmm;
135 struct ieee80211_tx_queue_params *txq;
138 wmm = (void *)skb_put(skb, sizeof(*wmm));
139 memset(wmm, 0, sizeof(*wmm));
141 wmm->element_id = WLAN_EID_VENDOR_SPECIFIC;
142 wmm->len = sizeof(*wmm) - 2;
144 wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */
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 */
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
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,
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);
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)
171 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
172 struct ieee80211_local *local = sdata->local;
173 size_t offset = 0, noffset;
176 ieee80211_add_srates_ie(sdata, skb, false, band);
177 ieee80211_add_ext_srates_ie(sdata, skb, false, band);
179 /* add any custom IEs that go before Extended Capabilities */
181 static const u8 before_ext_cap[] = {
184 WLAN_EID_EXT_SUPP_RATES,
185 WLAN_EID_SUPPORTED_CHANNELS,
188 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
190 ARRAY_SIZE(before_ext_cap),
192 pos = skb_put(skb, noffset - offset);
193 memcpy(pos, extra_ies + offset, noffset - offset);
197 ieee80211_tdls_add_ext_capab(skb);
199 /* 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 */
204 /* add any custom IEs that go before HT capabilities */
206 static const u8 before_ht_cap[] = {
209 WLAN_EID_EXT_SUPP_RATES,
210 WLAN_EID_SUPPORTED_CHANNELS,
212 WLAN_EID_EXT_CAPABILITY,
214 WLAN_EID_FAST_BSS_TRANSITION,
215 WLAN_EID_TIMEOUT_INTERVAL,
216 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
218 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
220 ARRAY_SIZE(before_ht_cap),
222 pos = skb_put(skb, noffset - offset);
223 memcpy(pos, extra_ies + offset, noffset - offset);
227 /* add any remaining IEs */
229 noffset = extra_ies_len;
230 pos = skb_put(skb, noffset - offset);
231 memcpy(pos, extra_ies + offset, noffset - offset);
234 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
238 ieee80211_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)
243 struct ieee80211_local *local = sdata->local;
244 size_t offset = 0, noffset;
245 struct sta_info *sta;
250 sta = sta_info_get(sdata, peer);
251 if (WARN_ON_ONCE(!sta)) {
256 /* add any custom IEs that go before the QoS IE */
258 static const u8 before_qos[] = {
261 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
263 ARRAY_SIZE(before_qos),
265 pos = skb_put(skb, noffset - offset);
266 memcpy(pos, extra_ies + offset, noffset - offset);
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);
275 /* add any remaining IEs */
277 noffset = extra_ies_len;
278 pos = skb_put(skb, noffset - offset);
279 memcpy(pos, extra_ies + offset, noffset - offset);
282 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
287 static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata,
288 struct sk_buff *skb, const u8 *peer,
289 u8 action_code, u16 status_code,
290 bool initiator, const u8 *extra_ies,
291 size_t extra_ies_len)
293 switch (action_code) {
294 case WLAN_TDLS_SETUP_REQUEST:
295 case WLAN_TDLS_SETUP_RESPONSE:
296 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
297 if (status_code == 0)
298 ieee80211_tdls_add_setup_start_ies(sdata, skb, peer,
304 case WLAN_TDLS_SETUP_CONFIRM:
305 if (status_code == 0)
306 ieee80211_tdls_add_setup_cfm_ies(sdata, skb, peer,
307 initiator, extra_ies,
310 case WLAN_TDLS_TEARDOWN:
311 case WLAN_TDLS_DISCOVERY_REQUEST:
313 memcpy(skb_put(skb, extra_ies_len), extra_ies,
315 if (status_code == 0 || action_code == WLAN_TDLS_TEARDOWN)
316 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
323 ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
324 const u8 *peer, u8 action_code, u8 dialog_token,
325 u16 status_code, struct sk_buff *skb)
327 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
328 struct ieee80211_tdls_data *tf;
330 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
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;
337 switch (action_code) {
338 case WLAN_TDLS_SETUP_REQUEST:
339 tf->category = WLAN_CATEGORY_TDLS;
340 tf->action_code = WLAN_TDLS_SETUP_REQUEST;
342 skb_put(skb, sizeof(tf->u.setup_req));
343 tf->u.setup_req.dialog_token = dialog_token;
344 tf->u.setup_req.capability =
345 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
348 case WLAN_TDLS_SETUP_RESPONSE:
349 tf->category = WLAN_CATEGORY_TDLS;
350 tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
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 =
356 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
359 case WLAN_TDLS_SETUP_CONFIRM:
360 tf->category = WLAN_CATEGORY_TDLS;
361 tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
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;
367 case WLAN_TDLS_TEARDOWN:
368 tf->category = WLAN_CATEGORY_TDLS;
369 tf->action_code = WLAN_TDLS_TEARDOWN;
371 skb_put(skb, sizeof(tf->u.teardown));
372 tf->u.teardown.reason_code = cpu_to_le16(status_code);
374 case WLAN_TDLS_DISCOVERY_REQUEST:
375 tf->category = WLAN_CATEGORY_TDLS;
376 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
378 skb_put(skb, sizeof(tf->u.discover_req));
379 tf->u.discover_req.dialog_token = dialog_token;
389 ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
390 const u8 *peer, u8 action_code, u8 dialog_token,
391 u16 status_code, struct sk_buff *skb)
393 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
394 struct ieee80211_mgmt *mgmt;
396 mgmt = (void *)skb_put(skb, 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);
402 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
403 IEEE80211_STYPE_ACTION);
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 =
413 mgmt->u.action.u.tdls_discover_resp.capability =
414 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
425 ieee80211_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,
428 u32 peer_capability, bool initiator,
429 const u8 *extra_ies, size_t extra_ies_len)
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;
435 struct sta_info *sta;
438 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 */
443 26 + /* max(WMM-info, WMM-param) */
445 sizeof(struct ieee80211_tdls_lnkie));
449 skb_reserve(skb, local->hw.extra_tx_headroom);
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,
462 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
463 ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code,
464 dialog_token, status_code,
477 sta = sta_info_get(sdata, peer);
479 /* infer the initiator if we can, to support old userspace */
480 switch (action_code) {
481 case WLAN_TDLS_SETUP_REQUEST:
483 set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
485 case WLAN_TDLS_SETUP_CONFIRM:
486 case WLAN_TDLS_DISCOVERY_REQUEST:
489 case WLAN_TDLS_SETUP_RESPONSE:
491 * In some testing scenarios, we send a request and response.
492 * Make the last packet sent take effect for the initiator
496 clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
498 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
501 case WLAN_TDLS_TEARDOWN:
502 /* any value is ok */
509 if (sta && test_sta_flag(sta, WLAN_STA_TDLS_INITIATOR))
516 ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code,
517 initiator, extra_ies, extra_ies_len);
519 ieee80211_tx_skb(sdata, skb);
524 * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise
525 * we should default to AC_VI.
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);
534 skb_set_queue_mapping(skb, IEEE80211_AC_VI);
539 /* disable bottom halves when entering the Tx path */
541 ret = ieee80211_subif_start_xmit(skb, dev);
552 ieee80211_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)
557 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
558 struct ieee80211_local *local = sdata->local;
561 mutex_lock(&local->mtx);
563 /* we don't support concurrent TDLS peer setups */
564 if (!is_zero_ether_addr(sdata->tdls_peer) &&
565 !ether_addr_equal(sdata->tdls_peer, peer)) {
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
573 * 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.
577 if (status_code == 0) {
579 if (!sta_info_get(sdata, peer)) {
587 ieee80211_flush_queues(local, sdata);
589 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
590 dialog_token, status_code,
591 peer_capability, initiator,
592 extra_ies, extra_ies_len);
596 memcpy(sdata->tdls_peer, peer, ETH_ALEN);
597 ieee80211_queue_delayed_work(&sdata->local->hw,
598 &sdata->tdls_peer_del_work,
599 TDLS_PEER_SETUP_TIMEOUT);
602 mutex_unlock(&local->mtx);
607 ieee80211_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)
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;
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.
624 ieee80211_stop_vif_queues(local, sdata,
625 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
626 ieee80211_flush_queues(local, sdata);
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);
633 sdata_err(sdata, "Failed sending TDLS teardown packet %d\n",
637 * Remove the STA AUTH flag to force further traffic through the AP. If
638 * the STA was unreachable, it was already removed.
641 sta = sta_info_get(sdata, peer);
643 clear_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
646 ieee80211_wake_vif_queues(local, sdata,
647 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
652 int 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)
658 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
661 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
664 /* make sure we are in managed mode, and associated */
665 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
666 !sdata->u.mgd.associated)
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);
677 case WLAN_TDLS_TEARDOWN:
678 ret = ieee80211_tdls_mgmt_teardown(wiphy, dev, peer,
679 action_code, dialog_token,
681 peer_capability, initiator,
682 extra_ies, extra_ies_len);
684 case WLAN_TDLS_DISCOVERY_REQUEST:
686 * Protect the discovery so we can hear the TDLS discovery
687 * response frame. It is transmitted directly and not buffered
690 drv_mgd_protect_tdls_discover(sdata->local, sdata);
692 case WLAN_TDLS_SETUP_CONFIRM:
693 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
694 /* no special handling */
695 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
700 initiator, extra_ies,
708 tdls_dbg(sdata, "TDLS mgmt action %d peer %pM status %d\n",
709 action_code, peer, ret);
713 int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
714 const u8 *peer, enum nl80211_tdls_operation oper)
716 struct sta_info *sta;
717 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
718 struct ieee80211_local *local = sdata->local;
721 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
724 if (sdata->vif.type != NL80211_IFTYPE_STATION)
728 case NL80211_TDLS_ENABLE_LINK:
729 case NL80211_TDLS_DISABLE_LINK:
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 */
738 mutex_lock(&local->mtx);
739 tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer);
742 case NL80211_TDLS_ENABLE_LINK:
744 sta = sta_info_get(sdata, peer);
751 set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
754 WARN_ON_ONCE(is_zero_ether_addr(sdata->tdls_peer) ||
755 !ether_addr_equal(sdata->tdls_peer, peer));
758 case NL80211_TDLS_DISABLE_LINK:
759 /* flush a potentially queued teardown packet */
760 ieee80211_flush_queues(local, sdata);
762 ret = sta_info_destroy_addr(sdata, peer);
769 if (ret == 0 && ether_addr_equal(sdata->tdls_peer, peer)) {
770 cancel_delayed_work(&sdata->tdls_peer_del_work);
771 eth_zero_addr(sdata->tdls_peer);
774 mutex_unlock(&local->mtx);
778 void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
779 enum nl80211_tdls_operation oper,
780 u16 reason_code, gfp_t gfp)
782 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
784 if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) {
785 sdata_err(sdata, "Discarding TDLS oper %d - not STA or disconnected\n",
790 cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp);
792 EXPORT_SYMBOL(ieee80211_tdls_oper_request);