Lines Matching +full:local +full:- +full:cap +full:- +full:size
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-2024 Intel Corporation
17 #include "driver-ops.h"
27 struct ieee80211_local *local; in ieee80211_tdls_peer_del_work() local
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() local
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()
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->chanreq.oper, in ieee80211_tdls_add_oper_classes()
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()
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() local
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->chanreq.oper; 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()
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()
459 ht_cap.cap |= WLAN_HT_CAP_SM_PS_DISABLED in ieee80211_tdls_add_setup_start_ies()
463 ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.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()
470 ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap); in ieee80211_tdls_add_setup_start_ies()
474 (ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) 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()
518 ieee80211_ie_build_vht_cap(pos, &vht_cap, vht_cap.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()
525 ieee80211_ie_build_vht_cap(pos, &vht_cap, vht_cap.cap); 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()
557 if (sband->band == NL80211_BAND_6GHZ) in ieee80211_tdls_add_setup_start_ies()
558 ieee80211_put_he_6ghz_cap(skb, sdata, link->smps_mode); in ieee80211_tdls_add_setup_start_ies()
573 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_start_ies()
577 /* build the EHT-cap from sband */ in ieee80211_tdls_add_setup_start_ies()
586 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_start_ies()
597 struct ieee80211_sub_if_data *sdata = link->sdata; in ieee80211_tdls_add_setup_cfm_ies()
598 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_add_setup_cfm_ies() local
609 ap_sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr); in ieee80211_tdls_add_setup_cfm_ies()
614 sta->tdls_chandef = link->conf->chanreq.oper; in ieee80211_tdls_add_setup_cfm_ies()
625 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_cfm_ies()
630 if (local->hw.queues >= IEEE80211_NUM_ACS && sta->sta.wme) in ieee80211_tdls_add_setup_cfm_ies()
645 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_cfm_ies()
650 * if HT support is only added in TDLS, we need an HT-operation IE. in ieee80211_tdls_add_setup_cfm_ies()
651 * add the IE as required by IEEE802.11-2012 9.23.3.2. in ieee80211_tdls_add_setup_cfm_ies()
653 if (!ap_sta->sta.deflink.ht_cap.ht_supported && sta->sta.deflink.ht_cap.ht_supported) { in ieee80211_tdls_add_setup_cfm_ies()
659 ieee80211_ie_build_ht_oper(pos, &sta->sta.deflink.ht_cap, in ieee80211_tdls_add_setup_cfm_ies()
660 &link->conf->chanreq.oper, prot, in ieee80211_tdls_add_setup_cfm_ies()
666 /* only include VHT-operation if not on the 2.4GHz band */ in ieee80211_tdls_add_setup_cfm_ies()
667 if (sband->band != NL80211_BAND_2GHZ && in ieee80211_tdls_add_setup_cfm_ies()
668 sta->sta.deflink.vht_cap.vht_supported) { in ieee80211_tdls_add_setup_cfm_ies()
677 ieee80211_ie_build_vht_oper(pos, &sta->sta.deflink.vht_cap, in ieee80211_tdls_add_setup_cfm_ies()
678 &sta->tdls_chandef); in ieee80211_tdls_add_setup_cfm_ies()
684 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_setup_cfm_ies()
701 tf = (void *)skb->data; in ieee80211_tdls_add_chan_switch_req_ies()
702 tf->u.chan_switch_req.target_channel = in ieee80211_tdls_add_chan_switch_req_ies()
703 ieee80211_frequency_to_channel(chandef->chan->center_freq); in ieee80211_tdls_add_chan_switch_req_ies()
704 tf->u.chan_switch_req.oper_class = oper_class; in ieee80211_tdls_add_chan_switch_req_ies()
714 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_chan_switch_req_ies()
723 skb_put_data(skb, extra_ies + offset, noffset - offset); in ieee80211_tdls_add_chan_switch_req_ies()
801 memcpy(tf->da, peer, ETH_ALEN); in ieee80211_prep_tdls_encap_data()
802 memcpy(tf->sa, sdata->vif.addr, ETH_ALEN); in ieee80211_prep_tdls_encap_data()
803 tf->ether_type = cpu_to_be16(ETH_P_TDLS); in ieee80211_prep_tdls_encap_data()
804 tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; in ieee80211_prep_tdls_encap_data()
811 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
812 tf->action_code = WLAN_TDLS_SETUP_REQUEST; in ieee80211_prep_tdls_encap_data()
814 skb_put(skb, sizeof(tf->u.setup_req)); in ieee80211_prep_tdls_encap_data()
815 tf->u.setup_req.dialog_token = dialog_token; in ieee80211_prep_tdls_encap_data()
816 tf->u.setup_req.capability = in ieee80211_prep_tdls_encap_data()
821 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
822 tf->action_code = WLAN_TDLS_SETUP_RESPONSE; in ieee80211_prep_tdls_encap_data()
824 skb_put(skb, sizeof(tf->u.setup_resp)); in ieee80211_prep_tdls_encap_data()
825 tf->u.setup_resp.status_code = cpu_to_le16(status_code); in ieee80211_prep_tdls_encap_data()
826 tf->u.setup_resp.dialog_token = dialog_token; in ieee80211_prep_tdls_encap_data()
827 tf->u.setup_resp.capability = in ieee80211_prep_tdls_encap_data()
832 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
833 tf->action_code = WLAN_TDLS_SETUP_CONFIRM; in ieee80211_prep_tdls_encap_data()
835 skb_put(skb, sizeof(tf->u.setup_cfm)); in ieee80211_prep_tdls_encap_data()
836 tf->u.setup_cfm.status_code = cpu_to_le16(status_code); in ieee80211_prep_tdls_encap_data()
837 tf->u.setup_cfm.dialog_token = dialog_token; in ieee80211_prep_tdls_encap_data()
840 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
841 tf->action_code = WLAN_TDLS_TEARDOWN; in ieee80211_prep_tdls_encap_data()
843 skb_put(skb, sizeof(tf->u.teardown)); in ieee80211_prep_tdls_encap_data()
844 tf->u.teardown.reason_code = cpu_to_le16(status_code); in ieee80211_prep_tdls_encap_data()
847 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
848 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST; in ieee80211_prep_tdls_encap_data()
850 skb_put(skb, sizeof(tf->u.discover_req)); in ieee80211_prep_tdls_encap_data()
851 tf->u.discover_req.dialog_token = dialog_token; in ieee80211_prep_tdls_encap_data()
854 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
855 tf->action_code = WLAN_TDLS_CHANNEL_SWITCH_REQUEST; in ieee80211_prep_tdls_encap_data()
857 skb_put(skb, sizeof(tf->u.chan_switch_req)); in ieee80211_prep_tdls_encap_data()
860 tf->category = WLAN_CATEGORY_TDLS; in ieee80211_prep_tdls_encap_data()
861 tf->action_code = WLAN_TDLS_CHANNEL_SWITCH_RESPONSE; in ieee80211_prep_tdls_encap_data()
863 skb_put(skb, sizeof(tf->u.chan_switch_resp)); in ieee80211_prep_tdls_encap_data()
864 tf->u.chan_switch_resp.status_code = cpu_to_le16(status_code); in ieee80211_prep_tdls_encap_data()
867 return -EINVAL; in ieee80211_prep_tdls_encap_data()
883 memcpy(mgmt->da, peer, ETH_ALEN); in ieee80211_prep_tdls_direct()
884 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); in ieee80211_prep_tdls_direct()
885 memcpy(mgmt->bssid, link->u.mgd.bssid, ETH_ALEN); in ieee80211_prep_tdls_direct()
886 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | in ieee80211_prep_tdls_direct()
891 skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp)); in ieee80211_prep_tdls_direct()
892 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; in ieee80211_prep_tdls_direct()
893 mgmt->u.action.u.tdls_discover_resp.action_code = in ieee80211_prep_tdls_direct()
895 mgmt->u.action.u.tdls_discover_resp.dialog_token = in ieee80211_prep_tdls_direct()
897 mgmt->u.action.u.tdls_discover_resp.capability = in ieee80211_prep_tdls_direct()
902 return -EINVAL; in ieee80211_prep_tdls_direct()
917 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_build_mgmt_packet_data() local
924 link = rcu_dereference(sdata->link[link_id]); in ieee80211_tdls_build_mgmt_packet_data()
928 skb = netdev_alloc_skb(sdata->dev, in ieee80211_tdls_build_mgmt_packet_data()
929 local->hw.extra_tx_headroom + in ieee80211_tdls_build_mgmt_packet_data()
934 26 + /* max(WMM-info, WMM-param) */ in ieee80211_tdls_build_mgmt_packet_data()
955 skb_reserve(skb, local->hw.extra_tx_headroom); in ieee80211_tdls_build_mgmt_packet_data()
965 ret = ieee80211_prep_tdls_encap_data(local->hw.wiphy, in ieee80211_tdls_build_mgmt_packet_data()
966 sdata->dev, link, peer, in ieee80211_tdls_build_mgmt_packet_data()
971 ret = ieee80211_prep_tdls_direct(local->hw.wiphy, sdata->dev, in ieee80211_tdls_build_mgmt_packet_data()
977 ret = -EOPNOTSUPP; in ieee80211_tdls_build_mgmt_packet_data()
1020 sta->sta.tdls_initiator = false; in ieee80211_tdls_prep_mgmt_packet()
1035 sta->sta.tdls_initiator = true; in ieee80211_tdls_prep_mgmt_packet()
1047 ret = -EOPNOTSUPP; in ieee80211_tdls_prep_mgmt_packet()
1065 ret = -EINVAL; in ieee80211_tdls_prep_mgmt_packet()
1081 skb->priority = 256 + 2; in ieee80211_tdls_prep_mgmt_packet()
1084 skb->priority = 256 + 5; in ieee80211_tdls_prep_mgmt_packet()
1090 * Later, if no ACK is returned from peer, we will re-send the teardown in ieee80211_tdls_prep_mgmt_packet()
1094 ieee80211_hw_check(&sdata->local->hw, REPORTS_TX_ACK_STATUS)) { in ieee80211_tdls_prep_mgmt_packet()
1097 /* If not sending directly to peer - no point in keeping skb */ in ieee80211_tdls_prep_mgmt_packet()
1103 spin_lock_bh(&sdata->u.mgd.teardown_lock); in ieee80211_tdls_prep_mgmt_packet()
1104 if (try_resend && !sdata->u.mgd.teardown_skb) { in ieee80211_tdls_prep_mgmt_packet()
1116 sdata->u.mgd.teardown_skb = skb_copy(skb, GFP_ATOMIC); in ieee80211_tdls_prep_mgmt_packet()
1117 sdata->u.mgd.orig_teardown_skb = skb; in ieee80211_tdls_prep_mgmt_packet()
1119 spin_unlock_bh(&sdata->u.mgd.teardown_lock); in ieee80211_tdls_prep_mgmt_packet()
1143 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_mgmt_setup() local
1145 sdata->deflink.u.mgd.driver_smps_mode; in ieee80211_tdls_mgmt_setup()
1153 return -EOPNOTSUPP; in ieee80211_tdls_mgmt_setup()
1156 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_tdls_mgmt_setup()
1159 if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer) && in ieee80211_tdls_mgmt_setup()
1160 !ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) { in ieee80211_tdls_mgmt_setup()
1161 ret = -EBUSY; in ieee80211_tdls_mgmt_setup()
1167 * non-TDLS-setup frames to the peer. We can't send other packets in ieee80211_tdls_mgmt_setup()
1169 * Allow error packets to be sent - sometimes we don't even add a STA in ieee80211_tdls_mgmt_setup()
1176 ret = -ENOLINK; in ieee80211_tdls_mgmt_setup()
1182 ieee80211_flush_queues(local, sdata, false); in ieee80211_tdls_mgmt_setup()
1183 memcpy(sdata->u.mgd.tdls_peer, peer, ETH_ALEN); in ieee80211_tdls_mgmt_setup()
1193 eth_zero_addr(sdata->u.mgd.tdls_peer); in ieee80211_tdls_mgmt_setup()
1197 wiphy_delayed_work_queue(sdata->local->hw.wiphy, in ieee80211_tdls_mgmt_setup()
1198 &sdata->u.mgd.tdls_peer_del_work, in ieee80211_tdls_mgmt_setup()
1215 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_mgmt_teardown() local
1220 * No packets can be transmitted to the peer via the AP during setup - in ieee80211_tdls_mgmt_teardown()
1225 ieee80211_stop_vif_queues(local, sdata, in ieee80211_tdls_mgmt_teardown()
1227 ieee80211_flush_queues(local, sdata, false); in ieee80211_tdls_mgmt_teardown()
1249 ieee80211_wake_vif_queues(local, sdata, in ieee80211_tdls_mgmt_teardown()
1264 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) in ieee80211_tdls_mgmt()
1265 return -EOPNOTSUPP; in ieee80211_tdls_mgmt()
1268 if (sdata->vif.type != NL80211_IFTYPE_STATION || in ieee80211_tdls_mgmt()
1269 !sdata->u.mgd.associated) in ieee80211_tdls_mgmt()
1270 return -EINVAL; in ieee80211_tdls_mgmt()
1294 drv_mgd_protect_tdls_discover(sdata->local, sdata, link_id); in ieee80211_tdls_mgmt()
1308 ret = -EOPNOTSUPP; in ieee80211_tdls_mgmt()
1320 struct ieee80211_local *local = sdata->local; in iee80211_tdls_recalc_chanctx() local
1326 lockdep_assert_wiphy(local->hw.wiphy); in iee80211_tdls_recalc_chanctx()
1328 conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, in iee80211_tdls_recalc_chanctx()
1329 lockdep_is_held(&local->hw.wiphy->mtx)); in iee80211_tdls_recalc_chanctx()
1331 width = conf->def.width; in iee80211_tdls_recalc_chanctx()
1332 sband = local->hw.wiphy->bands[conf->def.chan->band]; in iee80211_tdls_recalc_chanctx()
1334 ieee80211_recalc_chanctx_chantype(local, ctx); in iee80211_tdls_recalc_chanctx()
1337 if (width != conf->def.width && sta && in iee80211_tdls_recalc_chanctx()
1341 bw = ieee80211_chan_width_to_rx_bw(conf->def.width); in iee80211_tdls_recalc_chanctx()
1342 bw = min(bw, ieee80211_sta_cap_rx_bw(&sta->deflink)); in iee80211_tdls_recalc_chanctx()
1343 if (bw != sta->sta.deflink.bandwidth) { in iee80211_tdls_recalc_chanctx()
1344 sta->sta.deflink.bandwidth = bw; in iee80211_tdls_recalc_chanctx()
1345 rate_control_rate_update(local, sband, sta, 0, in iee80211_tdls_recalc_chanctx()
1352 ieee80211_recalc_chanctx_chantype(local, ctx); in iee80211_tdls_recalc_chanctx()
1365 list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { in iee80211_tdls_have_ht_peers()
1366 if (!sta->sta.tdls || sta->sdata != sdata || !sta->uploaded || in iee80211_tdls_have_ht_peers()
1369 !sta->sta.deflink.ht_cap.ht_supported) in iee80211_tdls_have_ht_peers()
1390 if (sdata->deflink.u.mgd.conn.mode >= IEEE80211_CONN_MODE_HT) in iee80211_tdls_recalc_ht_protection()
1393 tdls_ht = (sta && sta->sta.deflink.ht_cap.ht_supported) || in iee80211_tdls_recalc_ht_protection()
1396 opmode = sdata->vif.bss_conf.ht_operation_mode; in iee80211_tdls_recalc_ht_protection()
1403 if (opmode == sdata->vif.bss_conf.ht_operation_mode) in iee80211_tdls_recalc_ht_protection()
1406 sdata->vif.bss_conf.ht_operation_mode = opmode; in iee80211_tdls_recalc_ht_protection()
1407 ieee80211_link_info_change_notify(sdata, &sdata->deflink, in iee80211_tdls_recalc_ht_protection()
1416 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_oper() local
1419 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_tdls_oper()
1421 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) in ieee80211_tdls_oper()
1422 return -EOPNOTSUPP; in ieee80211_tdls_oper()
1424 if (sdata->vif.type != NL80211_IFTYPE_STATION) in ieee80211_tdls_oper()
1425 return -EINVAL; in ieee80211_tdls_oper()
1434 /* We don't support in-driver setup/teardown/discovery */ in ieee80211_tdls_oper()
1435 return -EOPNOTSUPP; in ieee80211_tdls_oper()
1445 if (sdata->vif.bss_conf.csa_active) { in ieee80211_tdls_oper()
1447 return -EBUSY; in ieee80211_tdls_oper()
1452 return -ENOLINK; in ieee80211_tdls_oper()
1459 WARN_ON_ONCE(is_zero_ether_addr(sdata->u.mgd.tdls_peer) || in ieee80211_tdls_oper()
1460 !ether_addr_equal(sdata->u.mgd.tdls_peer, peer)); in ieee80211_tdls_oper()
1470 * Note that this only forces the tasklet to flush pendings - in ieee80211_tdls_oper()
1473 tasklet_kill(&local->tx_pending_tasklet); in ieee80211_tdls_oper()
1475 ieee80211_flush_queues(local, sdata, false); in ieee80211_tdls_oper()
1486 return -EOPNOTSUPP; in ieee80211_tdls_oper()
1489 if (ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) { in ieee80211_tdls_oper()
1490 wiphy_delayed_work_cancel(sdata->local->hw.wiphy, in ieee80211_tdls_oper()
1491 &sdata->u.mgd.tdls_peer_del_work); in ieee80211_tdls_oper()
1492 eth_zero_addr(sdata->u.mgd.tdls_peer); in ieee80211_tdls_oper()
1495 wiphy_work_queue(sdata->local->hw.wiphy, in ieee80211_tdls_oper()
1496 &sdata->deflink.u.mgd.request_smps_work); in ieee80211_tdls_oper()
1507 if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc) { in ieee80211_tdls_oper_request()
1508 sdata_err(sdata, "Discarding TDLS oper %d - not STA or disconnected\n", in ieee80211_tdls_oper_request()
1513 cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp); in ieee80211_tdls_oper_request()
1526 ch_sw->switch_time = cpu_to_le16(switch_time); in iee80211_tdls_add_ch_switch_timing()
1527 ch_sw->switch_timeout = cpu_to_le16(switch_timeout); in iee80211_tdls_add_ch_switch_timing()
1541 tf = container_of(skb->data + skb_network_offset(skb), in ieee80211_tdls_find_sw_timing_ie()
1543 ie_start = tf->u.chan_switch_req.variable; in ieee80211_tdls_find_sw_timing_ie()
1545 skb->len - (ie_start - skb->data)); in ieee80211_tdls_find_sw_timing_ie()
1553 struct ieee80211_sub_if_data *sdata = sta->sdata; in ieee80211_tdls_ch_sw_tmpl_get()
1559 int link_id = sta->sta.valid_links ? ffs(sta->sta.valid_links) - 1 : 0; in ieee80211_tdls_ch_sw_tmpl_get()
1562 * if chandef points to a wide channel add a Secondary-Channel in ieee80211_tdls_ch_sw_tmpl_get()
1565 if (chandef->width == NL80211_CHAN_WIDTH_40) { in ieee80211_tdls_ch_sw_tmpl_get()
1575 sec_chan_ie->sec_chan_offs = ht40plus ? in ieee80211_tdls_ch_sw_tmpl_get()
1586 skb = ieee80211_tdls_build_mgmt_packet_data(sdata, sta->sta.addr, in ieee80211_tdls_ch_sw_tmpl_get()
1589 0, 0, !sta->sta.tdls_initiator, in ieee80211_tdls_ch_sw_tmpl_get()
1610 *ch_sw_tm_ie_offset = tm_ie - skb->data; in ieee80211_tdls_ch_sw_tmpl_get()
1615 sta->sta.addr, chandef->chan->center_freq, chandef->width); in ieee80211_tdls_ch_sw_tmpl_get()
1625 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_channel_switch() local
1631 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_tdls_channel_switch()
1633 if (chandef->chan->freq_offset) in ieee80211_tdls_channel_switch()
1635 return -EOPNOTSUPP; in ieee80211_tdls_channel_switch()
1642 ret = -ENOENT; in ieee80211_tdls_channel_switch()
1649 ret = -EOPNOTSUPP; in ieee80211_tdls_channel_switch()
1656 ret = -ENOENT; in ieee80211_tdls_channel_switch()
1660 ret = drv_tdls_channel_switch(local, sdata, &sta->sta, oper_class, in ieee80211_tdls_channel_switch()
1676 struct ieee80211_local *local = sdata->local; in ieee80211_tdls_cancel_channel_switch() local
1679 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_tdls_cancel_channel_switch()
1695 drv_tdls_cancel_channel_switch(local, sdata, &sta->sta); in ieee80211_tdls_cancel_channel_switch()
1703 struct ieee80211_sub_if_data *sdata = sta->sdata; in ieee80211_tdls_ch_sw_resp_tmpl_get()
1706 int link_id = sta->sta.valid_links ? ffs(sta->sta.valid_links) - 1 : 0; in ieee80211_tdls_ch_sw_resp_tmpl_get()
1711 skb = ieee80211_tdls_build_mgmt_packet_data(sdata, sta->sta.addr, in ieee80211_tdls_ch_sw_resp_tmpl_get()
1714 0, 0, !sta->sta.tdls_initiator, in ieee80211_tdls_ch_sw_resp_tmpl_get()
1736 *ch_sw_tm_ie_offset = tm_ie - skb->data; in ieee80211_tdls_ch_sw_resp_tmpl_get()
1740 sta->sta.addr); in ieee80211_tdls_ch_sw_resp_tmpl_get()
1748 struct ieee80211_local *local = sdata->local; in ieee80211_process_tdls_channel_switch_resp() local
1751 struct ieee80211_tdls_data *tf = (void *)skb->data; in ieee80211_process_tdls_channel_switch_resp()
1758 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_process_tdls_channel_switch_resp()
1761 params.timestamp = rx_status->device_timestamp; in ieee80211_process_tdls_channel_switch_resp()
1763 if (skb->len < baselen) { in ieee80211_process_tdls_channel_switch_resp()
1765 skb->len); in ieee80211_process_tdls_channel_switch_resp()
1766 return -EINVAL; in ieee80211_process_tdls_channel_switch_resp()
1769 sta = sta_info_get(sdata, tf->sa); in ieee80211_process_tdls_channel_switch_resp()
1771 tdls_dbg(sdata, "TDLS chan switch from non-peer sta %pM\n", in ieee80211_process_tdls_channel_switch_resp()
1772 tf->sa); in ieee80211_process_tdls_channel_switch_resp()
1773 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_resp()
1777 params.sta = &sta->sta; in ieee80211_process_tdls_channel_switch_resp()
1778 params.status = le16_to_cpu(tf->u.chan_switch_resp.status_code); in ieee80211_process_tdls_channel_switch_resp()
1784 elems = ieee802_11_parse_elems(tf->u.chan_switch_resp.variable, in ieee80211_process_tdls_channel_switch_resp()
1785 skb->len - baselen, false, NULL); in ieee80211_process_tdls_channel_switch_resp()
1787 ret = -ENOMEM; in ieee80211_process_tdls_channel_switch_resp()
1791 if (elems->parse_error) { in ieee80211_process_tdls_channel_switch_resp()
1793 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_resp()
1797 if (!elems->ch_sw_timing || !elems->lnk_id) { in ieee80211_process_tdls_channel_switch_resp()
1798 tdls_dbg(sdata, "TDLS channel switch resp - missing IEs\n"); in ieee80211_process_tdls_channel_switch_resp()
1799 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_resp()
1805 !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); in ieee80211_process_tdls_channel_switch_resp()
1806 if (local_initiator == sta->sta.tdls_initiator) { in ieee80211_process_tdls_channel_switch_resp()
1807 tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); in ieee80211_process_tdls_channel_switch_resp()
1808 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_resp()
1812 params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time); in ieee80211_process_tdls_channel_switch_resp()
1813 params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout); in ieee80211_process_tdls_channel_switch_resp()
1818 ret = -ENOENT; in ieee80211_process_tdls_channel_switch_resp()
1824 drv_tdls_recv_channel_switch(sdata->local, sdata, ¶ms); in ieee80211_process_tdls_channel_switch_resp()
1828 tf->sa, params.status); in ieee80211_process_tdls_channel_switch_resp()
1840 struct ieee80211_local *local = sdata->local; in ieee80211_process_tdls_channel_switch_req() local
1850 struct ieee80211_tdls_data *tf = (void *)skb->data; in ieee80211_process_tdls_channel_switch_req()
1856 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_process_tdls_channel_switch_req()
1859 params.timestamp = rx_status->device_timestamp; in ieee80211_process_tdls_channel_switch_req()
1861 if (skb->len < baselen) { in ieee80211_process_tdls_channel_switch_req()
1863 skb->len); in ieee80211_process_tdls_channel_switch_req()
1864 return -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1867 target_channel = tf->u.chan_switch_req.target_channel; in ieee80211_process_tdls_channel_switch_req()
1868 oper_class = tf->u.chan_switch_req.oper_class; in ieee80211_process_tdls_channel_switch_req()
1872 * ambiguous - there are multiple tables (US/Europe/JP/Global). The in ieee80211_process_tdls_channel_switch_req()
1876 * IEEE802.11-2012. in ieee80211_process_tdls_channel_switch_req()
1892 return -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1895 chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq); in ieee80211_process_tdls_channel_switch_req()
1900 return -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1903 elems = ieee802_11_parse_elems(tf->u.chan_switch_req.variable, in ieee80211_process_tdls_channel_switch_req()
1904 skb->len - baselen, false, NULL); in ieee80211_process_tdls_channel_switch_req()
1906 return -ENOMEM; in ieee80211_process_tdls_channel_switch_req()
1908 if (elems->parse_error) { in ieee80211_process_tdls_channel_switch_req()
1910 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1914 if (!elems->ch_sw_timing || !elems->lnk_id) { in ieee80211_process_tdls_channel_switch_req()
1915 tdls_dbg(sdata, "TDLS channel switch req - missing IEs\n"); in ieee80211_process_tdls_channel_switch_req()
1916 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1920 if (!elems->sec_chan_offs) { in ieee80211_process_tdls_channel_switch_req()
1923 switch (elems->sec_chan_offs->sec_chan_offs) { in ieee80211_process_tdls_channel_switch_req()
1939 if (!cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &chandef, in ieee80211_process_tdls_channel_switch_req()
1940 sdata->wdev.iftype)) { in ieee80211_process_tdls_channel_switch_req()
1942 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1946 sta = sta_info_get(sdata, tf->sa); in ieee80211_process_tdls_channel_switch_req()
1948 tdls_dbg(sdata, "TDLS chan switch from non-peer sta %pM\n", in ieee80211_process_tdls_channel_switch_req()
1949 tf->sa); in ieee80211_process_tdls_channel_switch_req()
1950 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1954 params.sta = &sta->sta; in ieee80211_process_tdls_channel_switch_req()
1958 !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); in ieee80211_process_tdls_channel_switch_req()
1959 if (local_initiator == sta->sta.tdls_initiator) { in ieee80211_process_tdls_channel_switch_req()
1960 tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); in ieee80211_process_tdls_channel_switch_req()
1961 ret = -EINVAL; in ieee80211_process_tdls_channel_switch_req()
1966 if (!sta->sta.deflink.ht_cap.ht_supported && elems->sec_chan_offs && in ieee80211_process_tdls_channel_switch_req()
1967 elems->sec_chan_offs->sec_chan_offs) { in ieee80211_process_tdls_channel_switch_req()
1968 tdls_dbg(sdata, "TDLS chan switch - wide chan unsupported\n"); in ieee80211_process_tdls_channel_switch_req()
1969 ret = -EOPNOTSUPP; in ieee80211_process_tdls_channel_switch_req()
1974 params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time); in ieee80211_process_tdls_channel_switch_req()
1975 params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout); in ieee80211_process_tdls_channel_switch_req()
1981 ret = -ENOENT; in ieee80211_process_tdls_channel_switch_req()
1985 drv_tdls_recv_channel_switch(sdata->local, sdata, ¶ms); in ieee80211_process_tdls_channel_switch_req()
1989 tf->sa, params.chandef->chan->center_freq, in ieee80211_process_tdls_channel_switch_req()
1990 params.chandef->width); in ieee80211_process_tdls_channel_switch_req()
2002 struct ieee80211_tdls_data *tf = (void *)skb->data; in ieee80211_process_tdls_channel_switch()
2003 struct wiphy *wiphy = sdata->local->hw.wiphy; in ieee80211_process_tdls_channel_switch()
2008 if (!(wiphy->features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH)) in ieee80211_process_tdls_channel_switch()
2015 * The packet/size was already validated by mac80211 Rx path, only look in ieee80211_process_tdls_channel_switch()
2018 switch (tf->action_code) { in ieee80211_process_tdls_channel_switch()
2033 struct ieee80211_sub_if_data *sdata = link->sdata; in ieee80211_teardown_tdls_peers()
2038 list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { in ieee80211_teardown_tdls_peers()
2039 if (!sta->sta.tdls || sta->sdata != sdata || !sta->uploaded || in ieee80211_teardown_tdls_peers()
2043 if (sta->deflink.link_id != link->link_id) in ieee80211_teardown_tdls_peers()
2046 ieee80211_tdls_oper_request(&sdata->vif, sta->sta.addr, in ieee80211_teardown_tdls_peers()
2059 sta = ieee80211_find_sta(&sdata->vif, peer); in ieee80211_tdls_handle_disconnect()
2060 if (!sta || !sta->tdls) { in ieee80211_tdls_handle_disconnect()
2070 ieee80211_tdls_oper_request(&sdata->vif, peer, in ieee80211_tdls_handle_disconnect()