Lines Matching +full:tf +full:- +full:a
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
8 * Copyright 2015 - 2016 Intel Deutschland GmbH
9 * Copyright (C) 2019, 2021-2023 Intel Corporation
17 #include "driver-ops.h"
31 local = sdata->local; in ieee80211_tdls_peer_del_work()
33 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_tdls_peer_del_work()
35 if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer)) { in ieee80211_tdls_peer_del_work()
36 tdls_dbg(sdata, "TDLS del peer %pM\n", sdata->u.mgd.tdls_peer); in ieee80211_tdls_peer_del_work()
37 sta_info_destroy_addr(sdata, sdata->u.mgd.tdls_peer); in ieee80211_tdls_peer_del_work()
38 eth_zero_addr(sdata->u.mgd.tdls_peer); in ieee80211_tdls_peer_del_work()
45 struct ieee80211_sub_if_data *sdata = link->sdata; in ieee80211_tdls_add_ext_capab()
46 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_add_ext_capab()
47 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; in ieee80211_tdls_add_ext_capab()
48 bool chan_switch = local->hw.wiphy->features & in ieee80211_tdls_add_ext_capab()
50 bool wider_band = ieee80211_hw_check(&local->hw, TDLS_WIDER_BW) && in ieee80211_tdls_add_ext_capab()
51 !ifmgd->tdls_wider_bw_prohibited; in ieee80211_tdls_add_ext_capab()
52 bool buffer_sta = ieee80211_hw_check(&local->hw, in ieee80211_tdls_add_ext_capab()
55 bool vht = sband && sband->vht_cap.vht_supported; in ieee80211_tdls_add_ext_capab()
80 struct wiphy *wiphy = sdata->local->hw.wiphy; in ieee80211_tdls_add_subband()
86 ch = ieee80211_get_channel(sdata->local->hw.wiphy, i); in ieee80211_tdls_add_subband()
92 sdata->wdev.iftype)) { in ieee80211_tdls_add_subband()
103 * we've reached the end of a range, with allowed channels in ieee80211_tdls_add_subband()
116 /* all channels in the requested range are allowed - add them here */ in ieee80211_tdls_add_subband()
162 if (!ieee80211_chandef_to_operating_class(&link->conf->chandef, in ieee80211_tdls_add_oper_classes()
189 /* The capability will be 0 when sending a failure code */ in ieee80211_get_tdls_sta_capab()
195 if (sband && sband->band == NL80211_BAND_2GHZ) { in ieee80211_get_tdls_sta_capab()
207 struct ieee80211_sub_if_data *sdata = link->sdata; in ieee80211_tdls_add_link_ie()
212 init_addr = sdata->vif.addr; in ieee80211_tdls_add_link_ie()
216 rsp_addr = sdata->vif.addr; in ieee80211_tdls_add_link_ie()
221 lnkid->ie_type = WLAN_EID_LINK_ID; in ieee80211_tdls_add_link_ie()
222 lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2; in ieee80211_tdls_add_link_ie()
224 memcpy(lnkid->bssid, link->u.mgd.bssid, ETH_ALEN); in ieee80211_tdls_add_link_ie()
225 memcpy(lnkid->init_sta, init_addr, ETH_ALEN); in ieee80211_tdls_add_link_ie()
226 memcpy(lnkid->resp_sta, rsp_addr, ETH_ALEN); in ieee80211_tdls_add_link_ie()
236 put_unaligned_le16(sdata->vif.cfg.aid, pos); in ieee80211_tdls_add_aid()
283 wmm->element_id = WLAN_EID_VENDOR_SPECIFIC; in ieee80211_tdls_add_wmm_param_ie()
284 wmm->len = sizeof(*wmm) - 2; in ieee80211_tdls_add_wmm_param_ie()
286 wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */ in ieee80211_tdls_add_wmm_param_ie()
287 wmm->oui[1] = 0x50; in ieee80211_tdls_add_wmm_param_ie()
288 wmm->oui[2] = 0xf2; in ieee80211_tdls_add_wmm_param_ie()
289 wmm->oui_type = 2; /* WME */ in ieee80211_tdls_add_wmm_param_ie()
290 wmm->oui_subtype = 1; /* WME param */ in ieee80211_tdls_add_wmm_param_ie()
291 wmm->version = 1; /* WME ver */ in ieee80211_tdls_add_wmm_param_ie()
292 wmm->qos_info = 0; /* U-APSD not in use */ in ieee80211_tdls_add_wmm_param_ie()
296 * doesn't support it, as mandated by 802.11-2012 section 10.22.4 in ieee80211_tdls_add_wmm_param_ie()
299 txq = &sdata->deflink.tx_conf[ieee80211_ac_from_wmm(i)]; in ieee80211_tdls_add_wmm_param_ie()
300 wmm->ac[i].aci_aifsn = ieee80211_wmm_aci_aifsn(txq->aifs, in ieee80211_tdls_add_wmm_param_ie()
301 txq->acm, i); in ieee80211_tdls_add_wmm_param_ie()
302 wmm->ac[i].cw = ieee80211_wmm_ecw(txq->cw_min, txq->cw_max); in ieee80211_tdls_add_wmm_param_ie()
303 wmm->ac[i].txop_limit = cpu_to_le16(txq->txop); in ieee80211_tdls_add_wmm_param_ie()
311 /* IEEE802.11ac-2013 Table E-4 */ in ieee80211_tdls_chandef_vht_upgrade()
313 struct cfg80211_chan_def uc = sta->tdls_chandef; in ieee80211_tdls_chandef_vht_upgrade()
315 ieee80211_sta_cap_chan_bw(&sta->deflink); in ieee80211_tdls_chandef_vht_upgrade()
318 /* only support upgrading non-narrow channels up to 80Mhz */ in ieee80211_tdls_chandef_vht_upgrade()
329 * Channel usage constrains in the IEEE802.11ac-2013 specification only in ieee80211_tdls_chandef_vht_upgrade()
330 * allow expanding a 20MHz channel to 80MHz in a single way. In in ieee80211_tdls_chandef_vht_upgrade()
335 if (abs(uc.chan->center_freq - centers_80mhz[i]) <= 30) { in ieee80211_tdls_chandef_vht_upgrade()
347 (uc.width > sta->tdls_chandef.width && in ieee80211_tdls_chandef_vht_upgrade()
348 !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc, in ieee80211_tdls_chandef_vht_upgrade()
349 sdata->wdev.iftype))) in ieee80211_tdls_chandef_vht_upgrade()
352 if (!cfg80211_chandef_identical(&uc, &sta->tdls_chandef)) { in ieee80211_tdls_chandef_vht_upgrade()
353 tdls_dbg(sdata, "TDLS ch width upgraded %d -> %d\n", in ieee80211_tdls_chandef_vht_upgrade()
354 sta->tdls_chandef.width, uc.width); in ieee80211_tdls_chandef_vht_upgrade()
360 sta->tdls_chandef = uc; in ieee80211_tdls_chandef_vht_upgrade()
370 struct ieee80211_sub_if_data *sdata = link->sdata; in ieee80211_tdls_add_setup_start_ies()
372 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_add_setup_start_ies()
385 ieee80211_add_srates_ie(sdata, skb, false, sband->band); in ieee80211_tdls_add_setup_start_ies()
386 ieee80211_add_ext_srates_ie(sdata, skb, false, sband->band); in ieee80211_tdls_add_setup_start_ies()
402 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_start_ies()
409 if (local->hw.queues >= IEEE80211_NUM_ACS && in ieee80211_tdls_add_setup_start_ies()
411 ieee80211_add_wmm_info_ie(skb_put(skb, 9), 0); /* no U-APSD */ in ieee80211_tdls_add_setup_start_ies()
431 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_start_ies()
441 sta->tdls_chandef = link->conf->chandef; in ieee80211_tdls_add_setup_start_ies()
447 * with TDLS we can switch channels, and HT-caps are not necessarily in ieee80211_tdls_add_setup_start_ies()
448 * the same on all bands. The specification limits the setup to a in ieee80211_tdls_add_setup_start_ies()
449 * single HT-cap, so use the current band for now. in ieee80211_tdls_add_setup_start_ies()
451 memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); in ieee80211_tdls_add_setup_start_ies()
465 ht_cap.ht_supported && sta->sta.deflink.ht_cap.ht_supported) { in ieee80211_tdls_add_setup_start_ies()
467 memcpy(&ht_cap, &sta->sta.deflink.ht_cap, sizeof(ht_cap)); in ieee80211_tdls_add_setup_start_ies()
498 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_start_ies()
503 memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap)); in ieee80211_tdls_add_setup_start_ies()
504 he_cap = ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif); in ieee80211_tdls_add_setup_start_ies()
505 eht_cap = ieee80211_get_eht_iftype_cap_vif(sband, &sdata->vif); in ieee80211_tdls_add_setup_start_ies()
511 /* build the VHT-cap similarly to the HT-cap */ in ieee80211_tdls_add_setup_start_ies()
520 vht_cap.vht_supported && sta->sta.deflink.vht_cap.vht_supported) { in ieee80211_tdls_add_setup_start_ies()
522 memcpy(&vht_cap, &sta->sta.deflink.vht_cap, sizeof(vht_cap)); in ieee80211_tdls_add_setup_start_ies()
529 * a wider compatible one, up to 80MHz in ieee80211_tdls_add_setup_start_ies()
546 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_start_ies()
550 /* build the HE-cap from sband */ in ieee80211_tdls_add_setup_start_ies()
559 2 + 1 + sizeof(he_cap->he_cap_elem) + in ieee80211_tdls_add_setup_start_ies()
560 ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem) + in ieee80211_tdls_add_setup_start_ies()
561 ieee80211_he_ppe_size(he_cap->ppe_thres[0], in ieee80211_tdls_add_setup_start_ies()
562 he_cap->he_cap_elem.phy_cap_info); in ieee80211_tdls_add_setup_start_ies()
567 if (sband->band == NL80211_BAND_6GHZ) { in ieee80211_tdls_add_setup_start_ies()
571 ieee80211_get_he_6ghz_capa_vif(sband, &sdata->vif); in ieee80211_tdls_add_setup_start_ies()
589 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_start_ies()
593 /* build the EHT-cap from sband */ in ieee80211_tdls_add_setup_start_ies()
601 2 + 1 + sizeof(eht_cap->eht_cap_elem) + in ieee80211_tdls_add_setup_start_ies()
602 ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem, in ieee80211_tdls_add_setup_start_ies()
603 &eht_cap->eht_cap_elem, false) + in ieee80211_tdls_add_setup_start_ies()
604 ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0], in ieee80211_tdls_add_setup_start_ies()
605 eht_cap->eht_cap_elem.phy_cap_info); in ieee80211_tdls_add_setup_start_ies()
613 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_start_ies()
624 struct ieee80211_sub_if_data *sdata = link->sdata; in ieee80211_tdls_add_setup_cfm_ies()
625 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_add_setup_cfm_ies()
636 ap_sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr); in ieee80211_tdls_add_setup_cfm_ies()
641 sta->tdls_chandef = link->conf->chandef; in ieee80211_tdls_add_setup_cfm_ies()
652 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_cfm_ies()
657 if (local->hw.queues >= IEEE80211_NUM_ACS && sta->sta.wme) in ieee80211_tdls_add_setup_cfm_ies()
672 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_cfm_ies()
677 * if HT support is only added in TDLS, we need an HT-operation IE. in ieee80211_tdls_add_setup_cfm_ies()
678 * add the IE as required by IEEE802.11-2012 9.23.3.2. in ieee80211_tdls_add_setup_cfm_ies()
680 if (!ap_sta->sta.deflink.ht_cap.ht_supported && sta->sta.deflink.ht_cap.ht_supported) { in ieee80211_tdls_add_setup_cfm_ies()
686 ieee80211_ie_build_ht_oper(pos, &sta->sta.deflink.ht_cap, in ieee80211_tdls_add_setup_cfm_ies()
687 &link->conf->chandef, prot, in ieee80211_tdls_add_setup_cfm_ies()
693 /* only include VHT-operation if not on the 2.4GHz band */ in ieee80211_tdls_add_setup_cfm_ies()
694 if (sband->band != NL80211_BAND_2GHZ && in ieee80211_tdls_add_setup_cfm_ies()
695 sta->sta.deflink.vht_cap.vht_supported) { in ieee80211_tdls_add_setup_cfm_ies()
698 * a wider compatible one, up to 80MHz in ieee80211_tdls_add_setup_cfm_ies()
704 ieee80211_ie_build_vht_oper(pos, &sta->sta.deflink.vht_cap, in ieee80211_tdls_add_setup_cfm_ies()
705 &sta->tdls_chandef); in ieee80211_tdls_add_setup_cfm_ies()
711 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_cfm_ies()
722 struct ieee80211_tdls_data *tf; in ieee80211_tdls_add_chan_switch_req_ies() local
728 tf = (void *)skb->data; in ieee80211_tdls_add_chan_switch_req_ies()
729 tf->u.chan_switch_req.target_channel = in ieee80211_tdls_add_chan_switch_req_ies()
730 ieee80211_frequency_to_channel(chandef->chan->center_freq); in ieee80211_tdls_add_chan_switch_req_ies()
731 tf->u.chan_switch_req.oper_class = oper_class; in ieee80211_tdls_add_chan_switch_req_ies()
741 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_chan_switch_req_ies()
750 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_chan_switch_req_ies()
824 struct ieee80211_tdls_data *tf; in ieee80211_prep_tdls_encap_data() local
826 tf = skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); in ieee80211_prep_tdls_encap_data()
828 memcpy(tf->da, peer, ETH_ALEN); in ieee80211_prep_tdls_encap_data()
829 memcpy(tf->sa, sdata->vif.addr, ETH_ALEN); in ieee80211_prep_tdls_encap_data()
830 tf->ether_type = cpu_to_be16(ETH_P_TDLS); in ieee80211_prep_tdls_encap_data()
831 tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; in ieee80211_prep_tdls_encap_data()
838 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
839 tf->action_code = WLAN_TDLS_SETUP_REQUEST; in ieee80211_prep_tdls_encap_data()
841 skb_put(skb, sizeof(tf->u.setup_req)); in ieee80211_prep_tdls_encap_data()
842 tf->u.setup_req.dialog_token = dialog_token; in ieee80211_prep_tdls_encap_data()
843 tf->u.setup_req.capability = in ieee80211_prep_tdls_encap_data()
848 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
849 tf->action_code = WLAN_TDLS_SETUP_RESPONSE; in ieee80211_prep_tdls_encap_data()
851 skb_put(skb, sizeof(tf->u.setup_resp)); in ieee80211_prep_tdls_encap_data()
852 tf->u.setup_resp.status_code = cpu_to_le16(status_code); in ieee80211_prep_tdls_encap_data()
853 tf->u.setup_resp.dialog_token = dialog_token; in ieee80211_prep_tdls_encap_data()
854 tf->u.setup_resp.capability = in ieee80211_prep_tdls_encap_data()
859 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
860 tf->action_code = WLAN_TDLS_SETUP_CONFIRM; in ieee80211_prep_tdls_encap_data()
862 skb_put(skb, sizeof(tf->u.setup_cfm)); in ieee80211_prep_tdls_encap_data()
863 tf->u.setup_cfm.status_code = cpu_to_le16(status_code); in ieee80211_prep_tdls_encap_data()
864 tf->u.setup_cfm.dialog_token = dialog_token; in ieee80211_prep_tdls_encap_data()
867 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
868 tf->action_code = WLAN_TDLS_TEARDOWN; in ieee80211_prep_tdls_encap_data()
870 skb_put(skb, sizeof(tf->u.teardown)); in ieee80211_prep_tdls_encap_data()
871 tf->u.teardown.reason_code = cpu_to_le16(status_code); in ieee80211_prep_tdls_encap_data()
874 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
875 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST; in ieee80211_prep_tdls_encap_data()
877 skb_put(skb, sizeof(tf->u.discover_req)); in ieee80211_prep_tdls_encap_data()
878 tf->u.discover_req.dialog_token = dialog_token; in ieee80211_prep_tdls_encap_data()
881 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
882 tf->action_code = WLAN_TDLS_CHANNEL_SWITCH_REQUEST; in ieee80211_prep_tdls_encap_data()
884 skb_put(skb, sizeof(tf->u.chan_switch_req)); in ieee80211_prep_tdls_encap_data()
887 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
888 tf->action_code = WLAN_TDLS_CHANNEL_SWITCH_RESPONSE; in ieee80211_prep_tdls_encap_data()
890 skb_put(skb, sizeof(tf->u.chan_switch_resp)); in ieee80211_prep_tdls_encap_data()
891 tf->u.chan_switch_resp.status_code = cpu_to_le16(status_code); in ieee80211_prep_tdls_encap_data()
894 return -EINVAL; in ieee80211_prep_tdls_encap_data()
910 memcpy(mgmt->da, peer, ETH_ALEN); in ieee80211_prep_tdls_direct()
911 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); in ieee80211_prep_tdls_direct()
912 memcpy(mgmt->bssid, link->u.mgd.bssid, ETH_ALEN); in ieee80211_prep_tdls_direct()
913 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | in ieee80211_prep_tdls_direct()
918 skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp)); in ieee80211_prep_tdls_direct()
919 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; in ieee80211_prep_tdls_direct()
920 mgmt->u.action.u.tdls_discover_resp.action_code = in ieee80211_prep_tdls_direct()
922 mgmt->u.action.u.tdls_discover_resp.dialog_token = in ieee80211_prep_tdls_direct()
924 mgmt->u.action.u.tdls_discover_resp.capability = in ieee80211_prep_tdls_direct()
929 return -EINVAL; in ieee80211_prep_tdls_direct()
944 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_build_mgmt_packet_data()
951 link = rcu_dereference(sdata->link[link_id]); in ieee80211_tdls_build_mgmt_packet_data()
955 skb = netdev_alloc_skb(sdata->dev, in ieee80211_tdls_build_mgmt_packet_data()
956 local->hw.extra_tx_headroom + in ieee80211_tdls_build_mgmt_packet_data()
961 26 + /* max(WMM-info, WMM-param) */ in ieee80211_tdls_build_mgmt_packet_data()
982 skb_reserve(skb, local->hw.extra_tx_headroom); in ieee80211_tdls_build_mgmt_packet_data()
992 ret = ieee80211_prep_tdls_encap_data(local->hw.wiphy, in ieee80211_tdls_build_mgmt_packet_data()
993 sdata->dev, link, peer, in ieee80211_tdls_build_mgmt_packet_data()
998 ret = ieee80211_prep_tdls_direct(local->hw.wiphy, sdata->dev, in ieee80211_tdls_build_mgmt_packet_data()
1004 ret = -EOPNOTSUPP; in ieee80211_tdls_build_mgmt_packet_data()
1047 sta->sta.tdls_initiator = false; in ieee80211_tdls_prep_mgmt_packet()
1056 * In some testing scenarios, we send a request and response. in ieee80211_tdls_prep_mgmt_packet()
1062 sta->sta.tdls_initiator = true; in ieee80211_tdls_prep_mgmt_packet()
1074 ret = -EOPNOTSUPP; in ieee80211_tdls_prep_mgmt_packet()
1092 ret = -EINVAL; in ieee80211_tdls_prep_mgmt_packet()
1108 skb->priority = 256 + 2; in ieee80211_tdls_prep_mgmt_packet()
1111 skb->priority = 256 + 5; in ieee80211_tdls_prep_mgmt_packet()
1116 * Set the WLAN_TDLS_TEARDOWN flag to indicate a teardown in progress. in ieee80211_tdls_prep_mgmt_packet()
1117 * Later, if no ACK is returned from peer, we will re-send the teardown in ieee80211_tdls_prep_mgmt_packet()
1121 ieee80211_hw_check(&sdata->local->hw, REPORTS_TX_ACK_STATUS)) { in ieee80211_tdls_prep_mgmt_packet()
1124 /* If not sending directly to peer - no point in keeping skb */ in ieee80211_tdls_prep_mgmt_packet()
1130 spin_lock_bh(&sdata->u.mgd.teardown_lock); in ieee80211_tdls_prep_mgmt_packet()
1131 if (try_resend && !sdata->u.mgd.teardown_skb) { in ieee80211_tdls_prep_mgmt_packet()
1143 sdata->u.mgd.teardown_skb = skb_copy(skb, GFP_ATOMIC); in ieee80211_tdls_prep_mgmt_packet()
1144 sdata->u.mgd.orig_teardown_skb = skb; in ieee80211_tdls_prep_mgmt_packet()
1146 spin_unlock_bh(&sdata->u.mgd.teardown_lock); in ieee80211_tdls_prep_mgmt_packet()
1170 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_mgmt_setup()
1172 sdata->deflink.u.mgd.driver_smps_mode; in ieee80211_tdls_mgmt_setup()
1180 return -EOPNOTSUPP; in ieee80211_tdls_mgmt_setup()
1183 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_tdls_mgmt_setup()
1186 if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer) && in ieee80211_tdls_mgmt_setup()
1187 !ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) { in ieee80211_tdls_mgmt_setup()
1188 ret = -EBUSY; in ieee80211_tdls_mgmt_setup()
1193 * make sure we have a STA representing the peer so we drop or buffer in ieee80211_tdls_mgmt_setup()
1194 * non-TDLS-setup frames to the peer. We can't send other packets in ieee80211_tdls_mgmt_setup()
1196 * Allow error packets to be sent - sometimes we don't even add a STA in ieee80211_tdls_mgmt_setup()
1203 ret = -ENOLINK; in ieee80211_tdls_mgmt_setup()
1210 memcpy(sdata->u.mgd.tdls_peer, peer, ETH_ALEN); in ieee80211_tdls_mgmt_setup()
1220 eth_zero_addr(sdata->u.mgd.tdls_peer); in ieee80211_tdls_mgmt_setup()
1224 wiphy_delayed_work_queue(sdata->local->hw.wiphy, in ieee80211_tdls_mgmt_setup()
1225 &sdata->u.mgd.tdls_peer_del_work, in ieee80211_tdls_mgmt_setup()
1242 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_mgmt_teardown()
1247 * No packets can be transmitted to the peer via the AP during setup - in ieee80211_tdls_mgmt_teardown()
1248 * the STA is set as a TDLS peer, but is not authorized. in ieee80211_tdls_mgmt_teardown()
1291 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) in ieee80211_tdls_mgmt()
1292 return -EOPNOTSUPP; in ieee80211_tdls_mgmt()
1295 if (sdata->vif.type != NL80211_IFTYPE_STATION || in ieee80211_tdls_mgmt()
1296 !sdata->u.mgd.associated) in ieee80211_tdls_mgmt()
1297 return -EINVAL; in ieee80211_tdls_mgmt()
1321 drv_mgd_protect_tdls_discover(sdata->local, sdata, link_id); in ieee80211_tdls_mgmt()
1335 ret = -EOPNOTSUPP; in ieee80211_tdls_mgmt()
1347 struct ieee80211_local *local = sdata->local; in iee80211_tdls_recalc_chanctx()
1353 lockdep_assert_wiphy(local->hw.wiphy); in iee80211_tdls_recalc_chanctx()
1355 conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, in iee80211_tdls_recalc_chanctx()
1356 lockdep_is_held(&local->hw.wiphy->mtx)); in iee80211_tdls_recalc_chanctx()
1358 width = conf->def.width; in iee80211_tdls_recalc_chanctx()
1359 sband = local->hw.wiphy->bands[conf->def.chan->band]; in iee80211_tdls_recalc_chanctx()
1363 /* if width changed and a peer is given, update its BW */ in iee80211_tdls_recalc_chanctx()
1364 if (width != conf->def.width && sta && in iee80211_tdls_recalc_chanctx()
1368 bw = ieee80211_chan_width_to_rx_bw(conf->def.width); in iee80211_tdls_recalc_chanctx()
1369 bw = min(bw, ieee80211_sta_cap_rx_bw(&sta->deflink)); in iee80211_tdls_recalc_chanctx()
1370 if (bw != sta->sta.deflink.bandwidth) { in iee80211_tdls_recalc_chanctx()
1371 sta->sta.deflink.bandwidth = bw; in iee80211_tdls_recalc_chanctx()
1375 * if a TDLS peer BW was updated, we need to in iee80211_tdls_recalc_chanctx()
1392 list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { in iee80211_tdls_have_ht_peers()
1393 if (!sta->sta.tdls || sta->sdata != sdata || !sta->uploaded || in iee80211_tdls_have_ht_peers()
1396 !sta->sta.deflink.ht_cap.ht_supported) in iee80211_tdls_have_ht_peers()
1417 if (!(sdata->deflink.u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HT)) in iee80211_tdls_recalc_ht_protection()
1420 tdls_ht = (sta && sta->sta.deflink.ht_cap.ht_supported) || in iee80211_tdls_recalc_ht_protection()
1423 opmode = sdata->vif.bss_conf.ht_operation_mode; in iee80211_tdls_recalc_ht_protection()
1430 if (opmode == sdata->vif.bss_conf.ht_operation_mode) in iee80211_tdls_recalc_ht_protection()
1433 sdata->vif.bss_conf.ht_operation_mode = opmode; in iee80211_tdls_recalc_ht_protection()
1434 ieee80211_link_info_change_notify(sdata, &sdata->deflink, in iee80211_tdls_recalc_ht_protection()
1443 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_oper()
1446 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_tdls_oper()
1448 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) in ieee80211_tdls_oper()
1449 return -EOPNOTSUPP; in ieee80211_tdls_oper()
1451 if (sdata->vif.type != NL80211_IFTYPE_STATION) in ieee80211_tdls_oper()
1452 return -EINVAL; in ieee80211_tdls_oper()
1461 /* We don't support in-driver setup/teardown/discovery */ in ieee80211_tdls_oper()
1462 return -EOPNOTSUPP; in ieee80211_tdls_oper()
1472 if (sdata->vif.bss_conf.csa_active) { in ieee80211_tdls_oper()
1474 return -EBUSY; in ieee80211_tdls_oper()
1479 return -ENOLINK; in ieee80211_tdls_oper()
1486 WARN_ON_ONCE(is_zero_ether_addr(sdata->u.mgd.tdls_peer) || in ieee80211_tdls_oper()
1487 !ether_addr_equal(sdata->u.mgd.tdls_peer, peer)); in ieee80211_tdls_oper()
1497 * Note that this only forces the tasklet to flush pendings - in ieee80211_tdls_oper()
1500 tasklet_kill(&local->tx_pending_tasklet); in ieee80211_tdls_oper()
1501 /* flush a potentially queued teardown packet */ in ieee80211_tdls_oper()
1513 return -EOPNOTSUPP; in ieee80211_tdls_oper()
1516 if (ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) { in ieee80211_tdls_oper()
1517 wiphy_delayed_work_cancel(sdata->local->hw.wiphy, in ieee80211_tdls_oper()
1518 &sdata->u.mgd.tdls_peer_del_work); in ieee80211_tdls_oper()
1519 eth_zero_addr(sdata->u.mgd.tdls_peer); in ieee80211_tdls_oper()
1522 wiphy_work_queue(sdata->local->hw.wiphy, in ieee80211_tdls_oper()
1523 &sdata->deflink.u.mgd.request_smps_work); in ieee80211_tdls_oper()
1534 if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc) { in ieee80211_tdls_oper_request()
1535 sdata_err(sdata, "Discarding TDLS oper %d - not STA or disconnected\n", in ieee80211_tdls_oper_request()
1540 cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp); in ieee80211_tdls_oper_request()
1553 ch_sw->switch_time = cpu_to_le16(switch_time); in iee80211_tdls_add_ch_switch_timing()
1554 ch_sw->switch_timeout = cpu_to_le16(switch_timeout); in iee80211_tdls_add_ch_switch_timing()
1560 struct ieee80211_tdls_data *tf; in ieee80211_tdls_find_sw_timing_ie() local
1568 tf = container_of(skb->data + skb_network_offset(skb), in ieee80211_tdls_find_sw_timing_ie()
1570 ie_start = tf->u.chan_switch_req.variable; in ieee80211_tdls_find_sw_timing_ie()
1572 skb->len - (ie_start - skb->data)); in ieee80211_tdls_find_sw_timing_ie()
1580 struct ieee80211_sub_if_data *sdata = sta->sdata; in ieee80211_tdls_ch_sw_tmpl_get()
1586 int link_id = sta->sta.valid_links ? ffs(sta->sta.valid_links) - 1 : 0; in ieee80211_tdls_ch_sw_tmpl_get()
1589 * if chandef points to a wide channel add a Secondary-Channel in ieee80211_tdls_ch_sw_tmpl_get()
1592 if (chandef->width == NL80211_CHAN_WIDTH_40) { in ieee80211_tdls_ch_sw_tmpl_get()
1602 sec_chan_ie->sec_chan_offs = ht40plus ? in ieee80211_tdls_ch_sw_tmpl_get()
1610 /* just set the values to 0, this is a template */ in ieee80211_tdls_ch_sw_tmpl_get()
1613 skb = ieee80211_tdls_build_mgmt_packet_data(sdata, sta->sta.addr, in ieee80211_tdls_ch_sw_tmpl_get()
1616 0, 0, !sta->sta.tdls_initiator, in ieee80211_tdls_ch_sw_tmpl_get()
1637 *ch_sw_tm_ie_offset = tm_ie - skb->data; in ieee80211_tdls_ch_sw_tmpl_get()
1642 sta->sta.addr, chandef->chan->center_freq, chandef->width); in ieee80211_tdls_ch_sw_tmpl_get()
1652 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_channel_switch()
1658 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_tdls_channel_switch()
1660 if (chandef->chan->freq_offset) in ieee80211_tdls_channel_switch()
1662 return -EOPNOTSUPP; in ieee80211_tdls_channel_switch()
1669 ret = -ENOENT; in ieee80211_tdls_channel_switch()
1676 ret = -EOPNOTSUPP; in ieee80211_tdls_channel_switch()
1683 ret = -ENOENT; in ieee80211_tdls_channel_switch()
1687 ret = drv_tdls_channel_switch(local, sdata, &sta->sta, oper_class, in ieee80211_tdls_channel_switch()
1703 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_cancel_channel_switch()
1706 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_tdls_cancel_channel_switch()
1722 drv_tdls_cancel_channel_switch(local, sdata, &sta->sta); in ieee80211_tdls_cancel_channel_switch()
1730 struct ieee80211_sub_if_data *sdata = sta->sdata; in ieee80211_tdls_ch_sw_resp_tmpl_get()
1733 int link_id = sta->sta.valid_links ? ffs(sta->sta.valid_links) - 1 : 0; in ieee80211_tdls_ch_sw_resp_tmpl_get()
1738 skb = ieee80211_tdls_build_mgmt_packet_data(sdata, sta->sta.addr, in ieee80211_tdls_ch_sw_resp_tmpl_get()
1741 0, 0, !sta->sta.tdls_initiator, in ieee80211_tdls_ch_sw_resp_tmpl_get()
1763 *ch_sw_tm_ie_offset = tm_ie - skb->data; in ieee80211_tdls_ch_sw_resp_tmpl_get()
1767 sta->sta.addr); in ieee80211_tdls_ch_sw_resp_tmpl_get()
1775 struct ieee80211_local *local = sdata->local; in ieee80211_process_tdls_channel_switch_resp()
1778 struct ieee80211_tdls_data *tf = (void *)skb->data; in ieee80211_process_tdls_channel_switch_resp() local
1781 int baselen = offsetof(typeof(*tf), u.chan_switch_resp.variable); in ieee80211_process_tdls_channel_switch_resp()
1785 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_process_tdls_channel_switch_resp()
1788 params.timestamp = rx_status->device_timestamp; in ieee80211_process_tdls_channel_switch_resp()
1790 if (skb->len < baselen) { in ieee80211_process_tdls_channel_switch_resp()
1792 skb->len); in ieee80211_process_tdls_channel_switch_resp()
1793 return -EINVAL; in ieee80211_process_tdls_channel_switch_resp()
1796 sta = sta_info_get(sdata, tf->sa); in ieee80211_process_tdls_channel_switch_resp()
1798 tdls_dbg(sdata, "TDLS chan switch from non-peer sta %pM\n", in ieee80211_process_tdls_channel_switch_resp()
1799 tf->sa); in ieee80211_process_tdls_channel_switch_resp()
1800 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_resp()
1804 params.sta = &sta->sta; in ieee80211_process_tdls_channel_switch_resp()
1805 params.status = le16_to_cpu(tf->u.chan_switch_resp.status_code); in ieee80211_process_tdls_channel_switch_resp()
1811 elems = ieee802_11_parse_elems(tf->u.chan_switch_resp.variable, in ieee80211_process_tdls_channel_switch_resp()
1812 skb->len - baselen, false, NULL); in ieee80211_process_tdls_channel_switch_resp()
1814 ret = -ENOMEM; in ieee80211_process_tdls_channel_switch_resp()
1818 if (elems->parse_error) { in ieee80211_process_tdls_channel_switch_resp()
1820 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_resp()
1824 if (!elems->ch_sw_timing || !elems->lnk_id) { in ieee80211_process_tdls_channel_switch_resp()
1825 tdls_dbg(sdata, "TDLS channel switch resp - missing IEs\n"); in ieee80211_process_tdls_channel_switch_resp()
1826 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_resp()
1832 !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); in ieee80211_process_tdls_channel_switch_resp()
1833 if (local_initiator == sta->sta.tdls_initiator) { in ieee80211_process_tdls_channel_switch_resp()
1834 tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); in ieee80211_process_tdls_channel_switch_resp()
1835 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_resp()
1839 params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time); in ieee80211_process_tdls_channel_switch_resp()
1840 params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout); in ieee80211_process_tdls_channel_switch_resp()
1845 ret = -ENOENT; in ieee80211_process_tdls_channel_switch_resp()
1851 drv_tdls_recv_channel_switch(sdata->local, sdata, ¶ms); in ieee80211_process_tdls_channel_switch_resp()
1855 tf->sa, params.status); in ieee80211_process_tdls_channel_switch_resp()
1867 struct ieee80211_local *local = sdata->local; in ieee80211_process_tdls_channel_switch_req()
1877 struct ieee80211_tdls_data *tf = (void *)skb->data; in ieee80211_process_tdls_channel_switch_req() local
1879 int baselen = offsetof(typeof(*tf), u.chan_switch_req.variable); in ieee80211_process_tdls_channel_switch_req()
1883 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_process_tdls_channel_switch_req()
1886 params.timestamp = rx_status->device_timestamp; in ieee80211_process_tdls_channel_switch_req()
1888 if (skb->len < baselen) { in ieee80211_process_tdls_channel_switch_req()
1890 skb->len); in ieee80211_process_tdls_channel_switch_req()
1891 return -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1894 target_channel = tf->u.chan_switch_req.target_channel; in ieee80211_process_tdls_channel_switch_req()
1895 oper_class = tf->u.chan_switch_req.oper_class; in ieee80211_process_tdls_channel_switch_req()
1899 * ambiguous - there are multiple tables (US/Europe/JP/Global). The in ieee80211_process_tdls_channel_switch_req()
1903 * IEEE802.11-2012. in ieee80211_process_tdls_channel_switch_req()
1919 return -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1922 chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq); in ieee80211_process_tdls_channel_switch_req()
1927 return -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1930 elems = ieee802_11_parse_elems(tf->u.chan_switch_req.variable, in ieee80211_process_tdls_channel_switch_req()
1931 skb->len - baselen, false, NULL); in ieee80211_process_tdls_channel_switch_req()
1933 return -ENOMEM; in ieee80211_process_tdls_channel_switch_req()
1935 if (elems->parse_error) { in ieee80211_process_tdls_channel_switch_req()
1937 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1941 if (!elems->ch_sw_timing || !elems->lnk_id) { in ieee80211_process_tdls_channel_switch_req()
1942 tdls_dbg(sdata, "TDLS channel switch req - missing IEs\n"); in ieee80211_process_tdls_channel_switch_req()
1943 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1947 if (!elems->sec_chan_offs) { in ieee80211_process_tdls_channel_switch_req()
1950 switch (elems->sec_chan_offs->sec_chan_offs) { in ieee80211_process_tdls_channel_switch_req()
1966 if (!cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &chandef, in ieee80211_process_tdls_channel_switch_req()
1967 sdata->wdev.iftype)) { in ieee80211_process_tdls_channel_switch_req()
1969 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1973 sta = sta_info_get(sdata, tf->sa); in ieee80211_process_tdls_channel_switch_req()
1975 tdls_dbg(sdata, "TDLS chan switch from non-peer sta %pM\n", in ieee80211_process_tdls_channel_switch_req()
1976 tf->sa); in ieee80211_process_tdls_channel_switch_req()
1977 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1981 params.sta = &sta->sta; in ieee80211_process_tdls_channel_switch_req()
1985 !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); in ieee80211_process_tdls_channel_switch_req()
1986 if (local_initiator == sta->sta.tdls_initiator) { in ieee80211_process_tdls_channel_switch_req()
1987 tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); in ieee80211_process_tdls_channel_switch_req()
1988 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1993 if (!sta->sta.deflink.ht_cap.ht_supported && elems->sec_chan_offs && in ieee80211_process_tdls_channel_switch_req()
1994 elems->sec_chan_offs->sec_chan_offs) { in ieee80211_process_tdls_channel_switch_req()
1995 tdls_dbg(sdata, "TDLS chan switch - wide chan unsupported\n"); in ieee80211_process_tdls_channel_switch_req()
1996 ret = -EOPNOTSUPP; in ieee80211_process_tdls_channel_switch_req()
2001 params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time); in ieee80211_process_tdls_channel_switch_req()
2002 params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout); in ieee80211_process_tdls_channel_switch_req()
2008 ret = -ENOENT; in ieee80211_process_tdls_channel_switch_req()
2012 drv_tdls_recv_channel_switch(sdata->local, sdata, ¶ms); in ieee80211_process_tdls_channel_switch_req()
2016 tf->sa, params.chandef->chan->center_freq, in ieee80211_process_tdls_channel_switch_req()
2017 params.chandef->width); in ieee80211_process_tdls_channel_switch_req()
2029 struct ieee80211_tdls_data *tf = (void *)skb->data; in ieee80211_process_tdls_channel_switch() local
2030 struct wiphy *wiphy = sdata->local->hw.wiphy; in ieee80211_process_tdls_channel_switch()
2035 if (!(wiphy->features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH)) in ieee80211_process_tdls_channel_switch()
2045 switch (tf->action_code) { in ieee80211_process_tdls_channel_switch()
2064 list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { in ieee80211_teardown_tdls_peers()
2065 if (!sta->sta.tdls || sta->sdata != sdata || !sta->uploaded || in ieee80211_teardown_tdls_peers()
2069 ieee80211_tdls_oper_request(&sdata->vif, sta->sta.addr, in ieee80211_teardown_tdls_peers()
2082 sta = ieee80211_find_sta(&sdata->vif, peer); in ieee80211_tdls_handle_disconnect()
2083 if (!sta || !sta->tdls) { in ieee80211_tdls_handle_disconnect()
2093 ieee80211_tdls_oper_request(&sdata->vif, peer, in ieee80211_tdls_handle_disconnect()