Path: blob/main/sys/contrib/dev/athk/ath11k/mac.c
105882 views
// SPDX-License-Identifier: BSD-3-Clause-Clear1/*2* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.3* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.4*/56#include <net/mac80211.h>7#include <net/cfg80211.h>8#include <linux/etherdevice.h>9#include <linux/bitfield.h>10#include <linux/inetdevice.h>11#include <net/if_inet6.h>12#include <net/ipv6.h>1314#include "mac.h"15#include "core.h"16#include "debug.h"17#include "wmi.h"18#include "hw.h"19#include "dp_tx.h"20#include "dp_rx.h"21#include "testmode.h"22#include "peer.h"23#include "debugfs_sta.h"24#include "hif.h"25#include "wow.h"2627#define CHAN2G(_channel, _freq, _flags) { \28.band = NL80211_BAND_2GHZ, \29.hw_value = (_channel), \30.center_freq = (_freq), \31.flags = (_flags), \32.max_antenna_gain = 0, \33.max_power = 30, \34}3536#define CHAN5G(_channel, _freq, _flags) { \37.band = NL80211_BAND_5GHZ, \38.hw_value = (_channel), \39.center_freq = (_freq), \40.flags = (_flags), \41.max_antenna_gain = 0, \42.max_power = 30, \43}4445#define CHAN6G(_channel, _freq, _flags) { \46.band = NL80211_BAND_6GHZ, \47.hw_value = (_channel), \48.center_freq = (_freq), \49.flags = (_flags), \50.max_antenna_gain = 0, \51.max_power = 30, \52}5354static const struct ieee80211_channel ath11k_2ghz_channels[] = {55CHAN2G(1, 2412, 0),56CHAN2G(2, 2417, 0),57CHAN2G(3, 2422, 0),58CHAN2G(4, 2427, 0),59CHAN2G(5, 2432, 0),60CHAN2G(6, 2437, 0),61CHAN2G(7, 2442, 0),62CHAN2G(8, 2447, 0),63CHAN2G(9, 2452, 0),64CHAN2G(10, 2457, 0),65CHAN2G(11, 2462, 0),66CHAN2G(12, 2467, 0),67CHAN2G(13, 2472, 0),68CHAN2G(14, 2484, 0),69};7071static const struct ieee80211_channel ath11k_5ghz_channels[] = {72CHAN5G(36, 5180, 0),73CHAN5G(40, 5200, 0),74CHAN5G(44, 5220, 0),75CHAN5G(48, 5240, 0),76CHAN5G(52, 5260, 0),77CHAN5G(56, 5280, 0),78CHAN5G(60, 5300, 0),79CHAN5G(64, 5320, 0),80CHAN5G(100, 5500, 0),81CHAN5G(104, 5520, 0),82CHAN5G(108, 5540, 0),83CHAN5G(112, 5560, 0),84CHAN5G(116, 5580, 0),85CHAN5G(120, 5600, 0),86CHAN5G(124, 5620, 0),87CHAN5G(128, 5640, 0),88CHAN5G(132, 5660, 0),89CHAN5G(136, 5680, 0),90CHAN5G(140, 5700, 0),91CHAN5G(144, 5720, 0),92CHAN5G(149, 5745, 0),93CHAN5G(153, 5765, 0),94CHAN5G(157, 5785, 0),95CHAN5G(161, 5805, 0),96CHAN5G(165, 5825, 0),97CHAN5G(169, 5845, 0),98CHAN5G(173, 5865, 0),99CHAN5G(177, 5885, 0),100};101102static const struct ieee80211_channel ath11k_6ghz_channels[] = {103CHAN6G(1, 5955, 0),104CHAN6G(5, 5975, 0),105CHAN6G(9, 5995, 0),106CHAN6G(13, 6015, 0),107CHAN6G(17, 6035, 0),108CHAN6G(21, 6055, 0),109CHAN6G(25, 6075, 0),110CHAN6G(29, 6095, 0),111CHAN6G(33, 6115, 0),112CHAN6G(37, 6135, 0),113CHAN6G(41, 6155, 0),114CHAN6G(45, 6175, 0),115CHAN6G(49, 6195, 0),116CHAN6G(53, 6215, 0),117CHAN6G(57, 6235, 0),118CHAN6G(61, 6255, 0),119CHAN6G(65, 6275, 0),120CHAN6G(69, 6295, 0),121CHAN6G(73, 6315, 0),122CHAN6G(77, 6335, 0),123CHAN6G(81, 6355, 0),124CHAN6G(85, 6375, 0),125CHAN6G(89, 6395, 0),126CHAN6G(93, 6415, 0),127CHAN6G(97, 6435, 0),128CHAN6G(101, 6455, 0),129CHAN6G(105, 6475, 0),130CHAN6G(109, 6495, 0),131CHAN6G(113, 6515, 0),132CHAN6G(117, 6535, 0),133CHAN6G(121, 6555, 0),134CHAN6G(125, 6575, 0),135CHAN6G(129, 6595, 0),136CHAN6G(133, 6615, 0),137CHAN6G(137, 6635, 0),138CHAN6G(141, 6655, 0),139CHAN6G(145, 6675, 0),140CHAN6G(149, 6695, 0),141CHAN6G(153, 6715, 0),142CHAN6G(157, 6735, 0),143CHAN6G(161, 6755, 0),144CHAN6G(165, 6775, 0),145CHAN6G(169, 6795, 0),146CHAN6G(173, 6815, 0),147CHAN6G(177, 6835, 0),148CHAN6G(181, 6855, 0),149CHAN6G(185, 6875, 0),150CHAN6G(189, 6895, 0),151CHAN6G(193, 6915, 0),152CHAN6G(197, 6935, 0),153CHAN6G(201, 6955, 0),154CHAN6G(205, 6975, 0),155CHAN6G(209, 6995, 0),156CHAN6G(213, 7015, 0),157CHAN6G(217, 7035, 0),158CHAN6G(221, 7055, 0),159CHAN6G(225, 7075, 0),160CHAN6G(229, 7095, 0),161CHAN6G(233, 7115, 0),162163/* new addition in IEEE Std 802.11ax-2021 */164CHAN6G(2, 5935, 0),165};166167static struct ieee80211_rate ath11k_legacy_rates[] = {168{ .bitrate = 10,169.hw_value = ATH11K_HW_RATE_CCK_LP_1M },170{ .bitrate = 20,171.hw_value = ATH11K_HW_RATE_CCK_LP_2M,172.hw_value_short = ATH11K_HW_RATE_CCK_SP_2M,173.flags = IEEE80211_RATE_SHORT_PREAMBLE },174{ .bitrate = 55,175.hw_value = ATH11K_HW_RATE_CCK_LP_5_5M,176.hw_value_short = ATH11K_HW_RATE_CCK_SP_5_5M,177.flags = IEEE80211_RATE_SHORT_PREAMBLE },178{ .bitrate = 110,179.hw_value = ATH11K_HW_RATE_CCK_LP_11M,180.hw_value_short = ATH11K_HW_RATE_CCK_SP_11M,181.flags = IEEE80211_RATE_SHORT_PREAMBLE },182183{ .bitrate = 60, .hw_value = ATH11K_HW_RATE_OFDM_6M },184{ .bitrate = 90, .hw_value = ATH11K_HW_RATE_OFDM_9M },185{ .bitrate = 120, .hw_value = ATH11K_HW_RATE_OFDM_12M },186{ .bitrate = 180, .hw_value = ATH11K_HW_RATE_OFDM_18M },187{ .bitrate = 240, .hw_value = ATH11K_HW_RATE_OFDM_24M },188{ .bitrate = 360, .hw_value = ATH11K_HW_RATE_OFDM_36M },189{ .bitrate = 480, .hw_value = ATH11K_HW_RATE_OFDM_48M },190{ .bitrate = 540, .hw_value = ATH11K_HW_RATE_OFDM_54M },191};192193static const int194ath11k_phymodes[NUM_NL80211_BANDS][ATH11K_CHAN_WIDTH_NUM] = {195[NL80211_BAND_2GHZ] = {196[NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,197[NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,198[NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20_2G,199[NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20_2G,200[NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40_2G,201[NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80_2G,202[NL80211_CHAN_WIDTH_80P80] = MODE_UNKNOWN,203[NL80211_CHAN_WIDTH_160] = MODE_UNKNOWN,204},205[NL80211_BAND_5GHZ] = {206[NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,207[NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,208[NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20,209[NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20,210[NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40,211[NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80,212[NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,213[NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80,214},215[NL80211_BAND_6GHZ] = {216[NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,217[NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,218[NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20,219[NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20,220[NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40,221[NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80,222[NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,223[NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80,224},225226};227228const struct htt_rx_ring_tlv_filter ath11k_mac_mon_status_filter_default = {229.rx_filter = HTT_RX_FILTER_TLV_FLAGS_MPDU_START |230HTT_RX_FILTER_TLV_FLAGS_PPDU_END |231HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE,232.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0,233.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1,234.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2,235.pkt_filter_flags3 = HTT_RX_FP_DATA_FILTER_FLASG3 |236HTT_RX_FP_CTRL_FILTER_FLASG3237};238239#define ATH11K_MAC_FIRST_OFDM_RATE_IDX 4240#define ath11k_g_rates ath11k_legacy_rates241#define ath11k_g_rates_size (ARRAY_SIZE(ath11k_legacy_rates))242#define ath11k_a_rates (ath11k_legacy_rates + 4)243#define ath11k_a_rates_size (ARRAY_SIZE(ath11k_legacy_rates) - 4)244245#define ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD 200 /* in msecs */246247/* Overhead due to the processing of channel switch events from FW */248#define ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD 10 /* in msecs */249250static const u32 ath11k_smps_map[] = {251[WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,252[WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,253[WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,254[WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,255};256257enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy)258{259enum nl80211_he_ru_alloc ret;260261switch (ru_phy) {262case RU_26:263ret = NL80211_RATE_INFO_HE_RU_ALLOC_26;264break;265case RU_52:266ret = NL80211_RATE_INFO_HE_RU_ALLOC_52;267break;268case RU_106:269ret = NL80211_RATE_INFO_HE_RU_ALLOC_106;270break;271case RU_242:272ret = NL80211_RATE_INFO_HE_RU_ALLOC_242;273break;274case RU_484:275ret = NL80211_RATE_INFO_HE_RU_ALLOC_484;276break;277case RU_996:278ret = NL80211_RATE_INFO_HE_RU_ALLOC_996;279break;280default:281ret = NL80211_RATE_INFO_HE_RU_ALLOC_26;282break;283}284285return ret;286}287288enum nl80211_he_ru_alloc ath11k_mac_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones)289{290enum nl80211_he_ru_alloc ret;291292switch (ru_tones) {293case 26:294ret = NL80211_RATE_INFO_HE_RU_ALLOC_26;295break;296case 52:297ret = NL80211_RATE_INFO_HE_RU_ALLOC_52;298break;299case 106:300ret = NL80211_RATE_INFO_HE_RU_ALLOC_106;301break;302case 242:303ret = NL80211_RATE_INFO_HE_RU_ALLOC_242;304break;305case 484:306ret = NL80211_RATE_INFO_HE_RU_ALLOC_484;307break;308case 996:309ret = NL80211_RATE_INFO_HE_RU_ALLOC_996;310break;311case (996 * 2):312ret = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;313break;314default:315ret = NL80211_RATE_INFO_HE_RU_ALLOC_26;316break;317}318319return ret;320}321322enum nl80211_he_gi ath11k_mac_he_gi_to_nl80211_he_gi(u8 sgi)323{324enum nl80211_he_gi ret;325326switch (sgi) {327case RX_MSDU_START_SGI_0_8_US:328ret = NL80211_RATE_INFO_HE_GI_0_8;329break;330case RX_MSDU_START_SGI_1_6_US:331ret = NL80211_RATE_INFO_HE_GI_1_6;332break;333case RX_MSDU_START_SGI_3_2_US:334ret = NL80211_RATE_INFO_HE_GI_3_2;335break;336default:337ret = NL80211_RATE_INFO_HE_GI_0_8;338break;339}340341return ret;342}343344u8 ath11k_mac_bw_to_mac80211_bw(u8 bw)345{346u8 ret = 0;347348switch (bw) {349case ATH11K_BW_20:350ret = RATE_INFO_BW_20;351break;352case ATH11K_BW_40:353ret = RATE_INFO_BW_40;354break;355case ATH11K_BW_80:356ret = RATE_INFO_BW_80;357break;358case ATH11K_BW_160:359ret = RATE_INFO_BW_160;360break;361}362363return ret;364}365366enum ath11k_supported_bw ath11k_mac_mac80211_bw_to_ath11k_bw(enum rate_info_bw bw)367{368switch (bw) {369case RATE_INFO_BW_20:370return ATH11K_BW_20;371case RATE_INFO_BW_40:372return ATH11K_BW_40;373case RATE_INFO_BW_80:374return ATH11K_BW_80;375case RATE_INFO_BW_160:376return ATH11K_BW_160;377default:378return ATH11K_BW_20;379}380}381382int ath11k_mac_hw_ratecode_to_legacy_rate(u8 hw_rc, u8 preamble, u8 *rateidx,383u16 *rate)384{385/* As default, it is OFDM rates */386int i = ATH11K_MAC_FIRST_OFDM_RATE_IDX;387int max_rates_idx = ath11k_g_rates_size;388389if (preamble == WMI_RATE_PREAMBLE_CCK) {390hw_rc &= ~ATH11k_HW_RATECODE_CCK_SHORT_PREAM_MASK;391i = 0;392max_rates_idx = ATH11K_MAC_FIRST_OFDM_RATE_IDX;393}394395while (i < max_rates_idx) {396if (hw_rc == ath11k_legacy_rates[i].hw_value) {397*rateidx = i;398*rate = ath11k_legacy_rates[i].bitrate;399return 0;400}401i++;402}403404return -EINVAL;405}406407static int get_num_chains(u32 mask)408{409int num_chains = 0;410411while (mask) {412if (mask & BIT(0))413num_chains++;414mask >>= 1;415}416417return num_chains;418}419420u8 ath11k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,421u32 bitrate)422{423int i;424425for (i = 0; i < sband->n_bitrates; i++)426if (sband->bitrates[i].bitrate == bitrate)427return i;428429return 0;430}431432static u32433ath11k_mac_max_ht_nss(const u8 *ht_mcs_mask)434{435int nss;436437for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--)438if (ht_mcs_mask[nss])439return nss + 1;440441return 1;442}443444static u32445ath11k_mac_max_vht_nss(const u16 *vht_mcs_mask)446{447int nss;448449for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--)450if (vht_mcs_mask[nss])451return nss + 1;452453return 1;454}455456static u32457ath11k_mac_max_he_nss(const u16 *he_mcs_mask)458{459int nss;460461for (nss = NL80211_HE_NSS_MAX - 1; nss >= 0; nss--)462if (he_mcs_mask[nss])463return nss + 1;464465return 1;466}467468static u8 ath11k_parse_mpdudensity(u8 mpdudensity)469{470/* 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":471* 0 for no restriction472* 1 for 1/4 us473* 2 for 1/2 us474* 3 for 1 us475* 4 for 2 us476* 5 for 4 us477* 6 for 8 us478* 7 for 16 us479*/480switch (mpdudensity) {481case 0:482return 0;483case 1:484case 2:485case 3:486/* Our lower layer calculations limit our precision to487* 1 microsecond488*/489return 1;490case 4:491return 2;492case 5:493return 4;494case 6:495return 8;496case 7:497return 16;498default:499return 0;500}501}502503static int ath11k_mac_vif_chan(struct ieee80211_vif *vif,504struct cfg80211_chan_def *def)505{506struct ieee80211_chanctx_conf *conf;507508rcu_read_lock();509conf = rcu_dereference(vif->bss_conf.chanctx_conf);510if (!conf) {511rcu_read_unlock();512return -ENOENT;513}514515*def = conf->def;516rcu_read_unlock();517518return 0;519}520521static bool ath11k_mac_bitrate_is_cck(int bitrate)522{523switch (bitrate) {524case 10:525case 20:526case 55:527case 110:528return true;529}530531return false;532}533534u8 ath11k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,535u8 hw_rate, bool cck)536{537const struct ieee80211_rate *rate;538int i;539540for (i = 0; i < sband->n_bitrates; i++) {541rate = &sband->bitrates[i];542543if (ath11k_mac_bitrate_is_cck(rate->bitrate) != cck)544continue;545546if (rate->hw_value == hw_rate)547return i;548else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&549rate->hw_value_short == hw_rate)550return i;551}552553return 0;554}555556static u8 ath11k_mac_bitrate_to_rate(int bitrate)557{558return DIV_ROUND_UP(bitrate, 5) |559(ath11k_mac_bitrate_is_cck(bitrate) ? BIT(7) : 0);560}561562static void ath11k_get_arvif_iter(void *data, u8 *mac,563struct ieee80211_vif *vif)564{565struct ath11k_vif_iter *arvif_iter = data;566struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);567568if (arvif->vdev_id == arvif_iter->vdev_id)569arvif_iter->arvif = arvif;570}571572struct ath11k_vif *ath11k_mac_get_arvif(struct ath11k *ar, u32 vdev_id)573{574struct ath11k_vif_iter arvif_iter;575u32 flags;576577memset(&arvif_iter, 0, sizeof(struct ath11k_vif_iter));578arvif_iter.vdev_id = vdev_id;579580flags = IEEE80211_IFACE_ITER_RESUME_ALL;581ieee80211_iterate_active_interfaces_atomic(ar->hw,582flags,583ath11k_get_arvif_iter,584&arvif_iter);585if (!arvif_iter.arvif) {586ath11k_warn(ar->ab, "No VIF found for vdev %d\n", vdev_id);587return NULL;588}589590return arvif_iter.arvif;591}592593struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab,594u32 vdev_id)595{596int i;597struct ath11k_pdev *pdev;598struct ath11k_vif *arvif;599600for (i = 0; i < ab->num_radios; i++) {601pdev = rcu_dereference(ab->pdevs_active[i]);602if (pdev && pdev->ar &&603(pdev->ar->allocated_vdev_map & (1LL << vdev_id))) {604arvif = ath11k_mac_get_arvif(pdev->ar, vdev_id);605if (arvif)606return arvif;607}608}609610return NULL;611}612613struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base *ab, u32 vdev_id)614{615int i;616struct ath11k_pdev *pdev;617618for (i = 0; i < ab->num_radios; i++) {619pdev = rcu_dereference(ab->pdevs_active[i]);620if (pdev && pdev->ar) {621if (pdev->ar->allocated_vdev_map & (1LL << vdev_id))622return pdev->ar;623}624}625626return NULL;627}628629struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, u32 pdev_id)630{631int i;632struct ath11k_pdev *pdev;633634if (ab->hw_params.single_pdev_only) {635pdev = rcu_dereference(ab->pdevs_active[0]);636return pdev ? pdev->ar : NULL;637}638639if (WARN_ON(pdev_id > ab->num_radios))640return NULL;641642for (i = 0; i < ab->num_radios; i++) {643if (ab->fw_mode == ATH11K_FIRMWARE_MODE_FTM)644pdev = &ab->pdevs[i];645else646pdev = rcu_dereference(ab->pdevs_active[i]);647648if (pdev && pdev->pdev_id == pdev_id)649return (pdev->ar ? pdev->ar : NULL);650}651652return NULL;653}654655struct ath11k_vif *ath11k_mac_get_vif_up(struct ath11k_base *ab)656{657struct ath11k *ar;658struct ath11k_pdev *pdev;659struct ath11k_vif *arvif;660int i;661662for (i = 0; i < ab->num_radios; i++) {663pdev = &ab->pdevs[i];664ar = pdev->ar;665list_for_each_entry(arvif, &ar->arvifs, list) {666if (arvif->is_up)667return arvif;668}669}670671return NULL;672}673674static bool ath11k_mac_band_match(enum nl80211_band band1, enum WMI_HOST_WLAN_BAND band2)675{676return (((band1 == NL80211_BAND_2GHZ) && (band2 & WMI_HOST_WLAN_2G_CAP)) ||677(((band1 == NL80211_BAND_5GHZ) || (band1 == NL80211_BAND_6GHZ)) &&678(band2 & WMI_HOST_WLAN_5G_CAP)));679}680681u8 ath11k_mac_get_target_pdev_id_from_vif(struct ath11k_vif *arvif)682{683struct ath11k *ar = arvif->ar;684struct ath11k_base *ab = ar->ab;685struct ieee80211_vif *vif = arvif->vif;686struct cfg80211_chan_def def;687enum nl80211_band band;688u8 pdev_id = ab->target_pdev_ids[0].pdev_id;689int i;690691if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))692return pdev_id;693694band = def.chan->band;695696for (i = 0; i < ab->target_pdev_count; i++) {697if (ath11k_mac_band_match(band, ab->target_pdev_ids[i].supported_bands))698return ab->target_pdev_ids[i].pdev_id;699}700701return pdev_id;702}703704u8 ath11k_mac_get_target_pdev_id(struct ath11k *ar)705{706struct ath11k_vif *arvif;707708arvif = ath11k_mac_get_vif_up(ar->ab);709710if (arvif)711return ath11k_mac_get_target_pdev_id_from_vif(arvif);712else713return ar->ab->target_pdev_ids[0].pdev_id;714}715716static void ath11k_pdev_caps_update(struct ath11k *ar)717{718struct ath11k_base *ab = ar->ab;719720ar->max_tx_power = ab->target_caps.hw_max_tx_power;721722/* FIXME Set min_tx_power to ab->target_caps.hw_min_tx_power.723* But since the received value in svcrdy is same as hw_max_tx_power,724* we can set ar->min_tx_power to 0 currently until725* this is fixed in firmware726*/727ar->min_tx_power = 0;728729ar->txpower_limit_2g = ar->max_tx_power;730ar->txpower_limit_5g = ar->max_tx_power;731ar->txpower_scale = WMI_HOST_TP_SCALE_MAX;732}733734static int ath11k_mac_txpower_recalc(struct ath11k *ar)735{736struct ath11k_pdev *pdev = ar->pdev;737struct ath11k_vif *arvif;738int ret, txpower = -1;739u32 param;740741lockdep_assert_held(&ar->conf_mutex);742743list_for_each_entry(arvif, &ar->arvifs, list) {744if (arvif->txpower <= 0)745continue;746747if (txpower == -1)748txpower = arvif->txpower;749else750txpower = min(txpower, arvif->txpower);751}752753if (txpower == -1)754return 0;755756/* txpwr is set as 2 units per dBm in FW*/757txpower = min_t(u32, max_t(u32, ar->min_tx_power, txpower),758ar->max_tx_power) * 2;759760ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "txpower to set in hw %d\n",761txpower / 2);762763if ((pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) &&764ar->txpower_limit_2g != txpower) {765param = WMI_PDEV_PARAM_TXPOWER_LIMIT2G;766ret = ath11k_wmi_pdev_set_param(ar, param,767txpower, ar->pdev->pdev_id);768if (ret)769goto fail;770ar->txpower_limit_2g = txpower;771}772773if ((pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) &&774ar->txpower_limit_5g != txpower) {775param = WMI_PDEV_PARAM_TXPOWER_LIMIT5G;776ret = ath11k_wmi_pdev_set_param(ar, param,777txpower, ar->pdev->pdev_id);778if (ret)779goto fail;780ar->txpower_limit_5g = txpower;781}782783return 0;784785fail:786ath11k_warn(ar->ab, "failed to recalc txpower limit %d using pdev param %d: %d\n",787txpower / 2, param, ret);788return ret;789}790791static int ath11k_recalc_rtscts_prot(struct ath11k_vif *arvif)792{793struct ath11k *ar = arvif->ar;794u32 vdev_param, rts_cts = 0;795int ret;796797lockdep_assert_held(&ar->conf_mutex);798799vdev_param = WMI_VDEV_PARAM_ENABLE_RTSCTS;800801/* Enable RTS/CTS protection for sw retries (when legacy stations802* are in BSS) or by default only for second rate series.803* TODO: Check if we need to enable CTS 2 Self in any case804*/805rts_cts = WMI_USE_RTS_CTS;806807if (arvif->num_legacy_stations > 0)808rts_cts |= WMI_RTSCTS_ACROSS_SW_RETRIES << 4;809else810rts_cts |= WMI_RTSCTS_FOR_SECOND_RATESERIES << 4;811812/* Need not send duplicate param value to firmware */813if (arvif->rtscts_prot_mode == rts_cts)814return 0;815816arvif->rtscts_prot_mode = rts_cts;817818ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %d recalc rts/cts prot %d\n",819arvif->vdev_id, rts_cts);820821ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,822vdev_param, rts_cts);823if (ret)824ath11k_warn(ar->ab, "failed to recalculate rts/cts prot for vdev %d: %d\n",825arvif->vdev_id, ret);826827return ret;828}829830static int ath11k_mac_set_kickout(struct ath11k_vif *arvif)831{832struct ath11k *ar = arvif->ar;833u32 param;834int ret;835836ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_STA_KICKOUT_TH,837ATH11K_KICKOUT_THRESHOLD,838ar->pdev->pdev_id);839if (ret) {840ath11k_warn(ar->ab, "failed to set kickout threshold on vdev %i: %d\n",841arvif->vdev_id, ret);842return ret;843}844845param = WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS;846ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param,847ATH11K_KEEPALIVE_MIN_IDLE);848if (ret) {849ath11k_warn(ar->ab, "failed to set keepalive minimum idle time on vdev %i: %d\n",850arvif->vdev_id, ret);851return ret;852}853854param = WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS;855ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param,856ATH11K_KEEPALIVE_MAX_IDLE);857if (ret) {858ath11k_warn(ar->ab, "failed to set keepalive maximum idle time on vdev %i: %d\n",859arvif->vdev_id, ret);860return ret;861}862863param = WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS;864ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param,865ATH11K_KEEPALIVE_MAX_UNRESPONSIVE);866if (ret) {867ath11k_warn(ar->ab, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",868arvif->vdev_id, ret);869return ret;870}871872return 0;873}874875void ath11k_mac_peer_cleanup_all(struct ath11k *ar)876{877struct ath11k_peer *peer, *tmp;878struct ath11k_base *ab = ar->ab;879880lockdep_assert_held(&ar->conf_mutex);881882mutex_lock(&ab->tbl_mtx_lock);883spin_lock_bh(&ab->base_lock);884list_for_each_entry_safe(peer, tmp, &ab->peers, list) {885ath11k_peer_rx_tid_cleanup(ar, peer);886ath11k_peer_rhash_delete(ab, peer);887list_del(&peer->list);888kfree(peer);889}890spin_unlock_bh(&ab->base_lock);891mutex_unlock(&ab->tbl_mtx_lock);892893ar->num_peers = 0;894ar->num_stations = 0;895}896897static inline int ath11k_mac_vdev_setup_sync(struct ath11k *ar)898{899lockdep_assert_held(&ar->conf_mutex);900901if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))902return -ESHUTDOWN;903904if (!wait_for_completion_timeout(&ar->vdev_setup_done,905ATH11K_VDEV_SETUP_TIMEOUT_HZ))906return -ETIMEDOUT;907908return ar->last_wmi_vdev_start_status ? -EINVAL : 0;909}910911static void912ath11k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,913struct ieee80211_chanctx_conf *conf,914void *data)915{916struct cfg80211_chan_def **def = data;917918*def = &conf->def;919}920921static int ath11k_mac_monitor_vdev_start(struct ath11k *ar, int vdev_id,922struct cfg80211_chan_def *chandef)923{924struct ieee80211_channel *channel;925struct wmi_vdev_start_req_arg arg = {};926int ret;927928lockdep_assert_held(&ar->conf_mutex);929930channel = chandef->chan;931932arg.vdev_id = vdev_id;933arg.channel.freq = channel->center_freq;934arg.channel.band_center_freq1 = chandef->center_freq1;935arg.channel.band_center_freq2 = chandef->center_freq2;936937arg.channel.mode = ath11k_phymodes[chandef->chan->band][chandef->width];938arg.channel.chan_radar = !!(channel->flags & IEEE80211_CHAN_RADAR);939940arg.channel.min_power = 0;941arg.channel.max_power = channel->max_power;942arg.channel.max_reg_power = channel->max_reg_power;943arg.channel.max_antenna_gain = channel->max_antenna_gain;944945arg.pref_tx_streams = ar->num_tx_chains;946arg.pref_rx_streams = ar->num_rx_chains;947948arg.channel.passive = !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR);949950reinit_completion(&ar->vdev_setup_done);951reinit_completion(&ar->vdev_delete_done);952953ret = ath11k_wmi_vdev_start(ar, &arg, false);954if (ret) {955ath11k_warn(ar->ab, "failed to request monitor vdev %i start: %d\n",956vdev_id, ret);957return ret;958}959960ret = ath11k_mac_vdev_setup_sync(ar);961if (ret) {962ath11k_warn(ar->ab, "failed to synchronize setup for monitor vdev %i start: %d\n",963vdev_id, ret);964return ret;965}966967ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr, NULL, 0, 0);968if (ret) {969ath11k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n",970vdev_id, ret);971goto vdev_stop;972}973974ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "monitor vdev %i started\n",975vdev_id);976977return 0;978979vdev_stop:980reinit_completion(&ar->vdev_setup_done);981982ret = ath11k_wmi_vdev_stop(ar, vdev_id);983if (ret) {984ath11k_warn(ar->ab, "failed to stop monitor vdev %i after start failure: %d\n",985vdev_id, ret);986return ret;987}988989ret = ath11k_mac_vdev_setup_sync(ar);990if (ret) {991ath11k_warn(ar->ab, "failed to synchronize setup for vdev %i stop: %d\n",992vdev_id, ret);993return ret;994}995996return -EIO;997}998999static int ath11k_mac_monitor_vdev_stop(struct ath11k *ar)1000{1001int ret;10021003lockdep_assert_held(&ar->conf_mutex);10041005reinit_completion(&ar->vdev_setup_done);10061007ret = ath11k_wmi_vdev_stop(ar, ar->monitor_vdev_id);1008if (ret) {1009ath11k_warn(ar->ab, "failed to request monitor vdev %i stop: %d\n",1010ar->monitor_vdev_id, ret);1011return ret;1012}10131014ret = ath11k_mac_vdev_setup_sync(ar);1015if (ret) {1016ath11k_warn(ar->ab, "failed to synchronize monitor vdev %i stop: %d\n",1017ar->monitor_vdev_id, ret);1018return ret;1019}10201021ret = ath11k_wmi_vdev_down(ar, ar->monitor_vdev_id);1022if (ret) {1023ath11k_warn(ar->ab, "failed to put down monitor vdev %i: %d\n",1024ar->monitor_vdev_id, ret);1025return ret;1026}10271028ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "monitor vdev %i stopped\n",1029ar->monitor_vdev_id);10301031return 0;1032}10331034static int ath11k_mac_monitor_vdev_create(struct ath11k *ar)1035{1036struct ath11k_pdev *pdev = ar->pdev;1037struct vdev_create_params param = {};1038int bit, ret;1039u8 tmp_addr[6] = {};1040u16 nss;10411042lockdep_assert_held(&ar->conf_mutex);10431044if (test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags))1045return 0;10461047if (ar->ab->free_vdev_map == 0) {1048ath11k_warn(ar->ab, "failed to find free vdev id for monitor vdev\n");1049return -ENOMEM;1050}10511052bit = __ffs64(ar->ab->free_vdev_map);10531054ar->monitor_vdev_id = bit;10551056param.if_id = ar->monitor_vdev_id;1057param.type = WMI_VDEV_TYPE_MONITOR;1058param.subtype = WMI_VDEV_SUBTYPE_NONE;1059param.pdev_id = pdev->pdev_id;10601061if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) {1062param.chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains;1063param.chains[NL80211_BAND_2GHZ].rx = ar->num_rx_chains;1064}1065if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) {1066param.chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains;1067param.chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains;1068}10691070ret = ath11k_wmi_vdev_create(ar, tmp_addr, ¶m);1071if (ret) {1072ath11k_warn(ar->ab, "failed to request monitor vdev %i creation: %d\n",1073ar->monitor_vdev_id, ret);1074ar->monitor_vdev_id = -1;1075return ret;1076}10771078nss = get_num_chains(ar->cfg_tx_chainmask) ? : 1;1079ret = ath11k_wmi_vdev_set_param_cmd(ar, ar->monitor_vdev_id,1080WMI_VDEV_PARAM_NSS, nss);1081if (ret) {1082ath11k_warn(ar->ab, "failed to set vdev %d chainmask 0x%x, nss %d :%d\n",1083ar->monitor_vdev_id, ar->cfg_tx_chainmask, nss, ret);1084goto err_vdev_del;1085}10861087ret = ath11k_mac_txpower_recalc(ar);1088if (ret) {1089ath11k_warn(ar->ab, "failed to recalc txpower for monitor vdev %d: %d\n",1090ar->monitor_vdev_id, ret);1091goto err_vdev_del;1092}10931094ar->allocated_vdev_map |= 1LL << ar->monitor_vdev_id;1095ar->ab->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);1096ar->num_created_vdevs++;1097set_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags);10981099ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "monitor vdev %d created\n",1100ar->monitor_vdev_id);11011102return 0;11031104err_vdev_del:1105ath11k_wmi_vdev_delete(ar, ar->monitor_vdev_id);1106ar->monitor_vdev_id = -1;1107return ret;1108}11091110static int ath11k_mac_monitor_vdev_delete(struct ath11k *ar)1111{1112int ret;1113unsigned long time_left;11141115lockdep_assert_held(&ar->conf_mutex);11161117if (!test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags))1118return 0;11191120reinit_completion(&ar->vdev_delete_done);11211122ret = ath11k_wmi_vdev_delete(ar, ar->monitor_vdev_id);1123if (ret) {1124ath11k_warn(ar->ab, "failed to request wmi monitor vdev %i removal: %d\n",1125ar->monitor_vdev_id, ret);1126return ret;1127}11281129time_left = wait_for_completion_timeout(&ar->vdev_delete_done,1130ATH11K_VDEV_DELETE_TIMEOUT_HZ);1131if (time_left == 0) {1132ath11k_warn(ar->ab, "Timeout in receiving vdev delete response\n");1133} else {1134ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "monitor vdev %d deleted\n",1135ar->monitor_vdev_id);11361137ar->allocated_vdev_map &= ~(1LL << ar->monitor_vdev_id);1138ar->ab->free_vdev_map |= 1LL << (ar->monitor_vdev_id);1139ar->num_created_vdevs--;1140ar->monitor_vdev_id = -1;1141clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags);1142}11431144return ret;1145}11461147static int ath11k_mac_monitor_start(struct ath11k *ar)1148{1149struct cfg80211_chan_def *chandef = NULL;1150int ret;11511152lockdep_assert_held(&ar->conf_mutex);11531154if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags))1155return 0;11561157ieee80211_iter_chan_contexts_atomic(ar->hw,1158ath11k_mac_get_any_chandef_iter,1159&chandef);1160if (!chandef)1161return 0;11621163ret = ath11k_mac_monitor_vdev_start(ar, ar->monitor_vdev_id, chandef);1164if (ret) {1165ath11k_warn(ar->ab, "failed to start monitor vdev: %d\n", ret);1166ath11k_mac_monitor_vdev_delete(ar);1167return ret;1168}11691170set_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags);11711172ar->num_started_vdevs++;1173ret = ath11k_dp_tx_htt_monitor_mode_ring_config(ar, false);1174if (ret) {1175ath11k_warn(ar->ab, "failed to configure htt monitor mode ring during start: %d",1176ret);1177return ret;1178}11791180ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "monitor started\n");11811182return 0;1183}11841185static int ath11k_mac_monitor_stop(struct ath11k *ar)1186{1187int ret;11881189lockdep_assert_held(&ar->conf_mutex);11901191if (!test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags))1192return 0;11931194ret = ath11k_mac_monitor_vdev_stop(ar);1195if (ret) {1196ath11k_warn(ar->ab, "failed to stop monitor vdev: %d\n", ret);1197return ret;1198}11991200clear_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags);1201ar->num_started_vdevs--;12021203ret = ath11k_dp_tx_htt_monitor_mode_ring_config(ar, true);1204if (ret) {1205ath11k_warn(ar->ab, "failed to configure htt monitor mode ring during stop: %d",1206ret);1207return ret;1208}12091210ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "monitor stopped ret %d\n", ret);12111212return 0;1213}12141215static int ath11k_mac_vif_setup_ps(struct ath11k_vif *arvif)1216{1217struct ath11k *ar = arvif->ar;1218struct ieee80211_vif *vif = arvif->vif;1219struct ieee80211_conf *conf = &ar->hw->conf;1220enum wmi_sta_powersave_param param;1221enum wmi_sta_ps_mode psmode;1222int ret;1223int timeout;1224bool enable_ps;12251226lockdep_assert_held(&arvif->ar->conf_mutex);12271228if (arvif->vif->type != NL80211_IFTYPE_STATION)1229return 0;12301231enable_ps = arvif->ps;12321233if (enable_ps) {1234psmode = WMI_STA_PS_MODE_ENABLED;1235param = WMI_STA_PS_PARAM_INACTIVITY_TIME;12361237timeout = conf->dynamic_ps_timeout;1238if (timeout == 0) {1239/* firmware doesn't like 0 */1240timeout = ieee80211_tu_to_usec(vif->bss_conf.beacon_int) / 1000;1241}12421243ret = ath11k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,1244timeout);1245if (ret) {1246ath11k_warn(ar->ab, "failed to set inactivity time for vdev %d: %i\n",1247arvif->vdev_id, ret);1248return ret;1249}1250} else {1251psmode = WMI_STA_PS_MODE_DISABLED;1252}12531254ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %d psmode %s\n",1255arvif->vdev_id, psmode ? "enable" : "disable");12561257ret = ath11k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id, psmode);1258if (ret) {1259ath11k_warn(ar->ab, "failed to set sta power save mode %d for vdev %d: %d\n",1260psmode, arvif->vdev_id, ret);1261return ret;1262}12631264return 0;1265}12661267static int ath11k_mac_config_ps(struct ath11k *ar)1268{1269struct ath11k_vif *arvif;1270int ret = 0;12711272lockdep_assert_held(&ar->conf_mutex);12731274list_for_each_entry(arvif, &ar->arvifs, list) {1275ret = ath11k_mac_vif_setup_ps(arvif);1276if (ret) {1277ath11k_warn(ar->ab, "failed to setup powersave: %d\n", ret);1278break;1279}1280}12811282return ret;1283}12841285static int ath11k_mac_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)1286{1287struct ath11k *ar = hw->priv;1288struct ieee80211_conf *conf = &hw->conf;1289int ret = 0;12901291mutex_lock(&ar->conf_mutex);12921293if (changed & IEEE80211_CONF_CHANGE_MONITOR) {1294if (conf->flags & IEEE80211_CONF_MONITOR) {1295set_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags);12961297if (test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED,1298&ar->monitor_flags))1299goto out;13001301ret = ath11k_mac_monitor_vdev_create(ar);1302if (ret) {1303ath11k_warn(ar->ab, "failed to create monitor vdev: %d",1304ret);1305goto out;1306}13071308ret = ath11k_mac_monitor_start(ar);1309if (ret) {1310ath11k_warn(ar->ab, "failed to start monitor: %d",1311ret);1312goto err_mon_del;1313}1314} else {1315clear_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags);13161317if (!test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED,1318&ar->monitor_flags))1319goto out;13201321ret = ath11k_mac_monitor_stop(ar);1322if (ret) {1323ath11k_warn(ar->ab, "failed to stop monitor: %d",1324ret);1325goto out;1326}13271328ret = ath11k_mac_monitor_vdev_delete(ar);1329if (ret) {1330ath11k_warn(ar->ab, "failed to delete monitor vdev: %d",1331ret);1332goto out;1333}1334}1335}13361337out:1338mutex_unlock(&ar->conf_mutex);1339return ret;13401341err_mon_del:1342ath11k_mac_monitor_vdev_delete(ar);1343mutex_unlock(&ar->conf_mutex);1344return ret;1345}13461347static void ath11k_mac_setup_nontx_vif_rsnie(struct ath11k_vif *arvif,1348bool tx_arvif_rsnie_present,1349const u8 *profile, u8 profile_len)1350{1351if (cfg80211_find_ie(WLAN_EID_RSN, profile, profile_len)) {1352arvif->rsnie_present = true;1353} else if (tx_arvif_rsnie_present) {1354int i;1355u8 nie_len;1356const u8 *nie = cfg80211_find_ext_ie(WLAN_EID_EXT_NON_INHERITANCE,1357profile, profile_len);1358if (!nie)1359return;13601361nie_len = nie[1];1362nie += 2;1363for (i = 0; i < nie_len; i++) {1364if (nie[i] == WLAN_EID_RSN) {1365arvif->rsnie_present = false;1366break;1367}1368}1369}1370}13711372static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,1373struct ath11k_vif *arvif,1374struct sk_buff *bcn)1375{1376struct ieee80211_mgmt *mgmt;1377const u8 *ies, *profile, *next_profile;1378int ies_len;13791380ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);1381mgmt = (struct ieee80211_mgmt *)bcn->data;1382ies += sizeof(mgmt->u.beacon);1383ies_len = skb_tail_pointer(bcn) - ies;13841385ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ies, ies_len);1386arvif->rsnie_present = tx_arvif->rsnie_present;13871388while (ies) {1389u8 mbssid_len;13901391ies_len -= (2 + ies[1]);1392mbssid_len = ies[1] - 1;1393profile = &ies[3];13941395while (mbssid_len) {1396u8 profile_len;13971398profile_len = profile[1];1399next_profile = profile + (2 + profile_len);1400mbssid_len -= (2 + profile_len);14011402profile += 2;1403profile_len -= (2 + profile[1]);1404profile += (2 + profile[1]); /* nontx capabilities */1405profile_len -= (2 + profile[1]);1406profile += (2 + profile[1]); /* SSID */1407if (profile[2] == arvif->vif->bss_conf.bssid_index) {1408profile_len -= 5;1409profile = profile + 5;1410ath11k_mac_setup_nontx_vif_rsnie(arvif,1411tx_arvif->rsnie_present,1412profile,1413profile_len);1414return true;1415}1416profile = next_profile;1417}1418ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, profile,1419ies_len);1420}14211422return false;1423}14241425static int ath11k_mac_setup_bcn_p2p_ie(struct ath11k_vif *arvif,1426struct sk_buff *bcn)1427{1428struct ath11k *ar = arvif->ar;1429struct ieee80211_mgmt *mgmt;1430const u8 *p2p_ie;1431int ret;14321433mgmt = (void *)bcn->data;1434p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,1435mgmt->u.beacon.variable,1436bcn->len - (mgmt->u.beacon.variable -1437bcn->data));1438if (!p2p_ie)1439return -ENOENT;14401441ret = ath11k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);1442if (ret) {1443ath11k_warn(ar->ab, "failed to submit P2P GO bcn ie for vdev %i: %d\n",1444arvif->vdev_id, ret);1445return ret;1446}14471448return ret;1449}14501451static int ath11k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,1452u8 oui_type, size_t ie_offset)1453{1454size_t len;1455const u8 *next, *end;1456u8 *ie;14571458if (WARN_ON(skb->len < ie_offset))1459return -EINVAL;14601461ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,1462skb->data + ie_offset,1463skb->len - ie_offset);1464if (!ie)1465return -ENOENT;14661467len = ie[1] + 2;1468end = skb->data + skb->len;1469next = ie + len;14701471if (WARN_ON(next > end))1472return -EINVAL;14731474memmove(ie, next, end - next);1475skb_trim(skb, skb->len - len);14761477return 0;1478}14791480static int ath11k_mac_set_vif_params(struct ath11k_vif *arvif,1481struct sk_buff *bcn)1482{1483struct ath11k_base *ab = arvif->ar->ab;1484struct ieee80211_mgmt *mgmt;1485int ret = 0;1486u8 *ies;14871488ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);1489mgmt = (struct ieee80211_mgmt *)bcn->data;1490ies += sizeof(mgmt->u.beacon);14911492if (cfg80211_find_ie(WLAN_EID_RSN, ies, (skb_tail_pointer(bcn) - ies)))1493arvif->rsnie_present = true;1494else1495arvif->rsnie_present = false;14961497if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,1498WLAN_OUI_TYPE_MICROSOFT_WPA,1499ies, (skb_tail_pointer(bcn) - ies)))1500arvif->wpaie_present = true;1501else1502arvif->wpaie_present = false;15031504if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)1505return ret;15061507ret = ath11k_mac_setup_bcn_p2p_ie(arvif, bcn);1508if (ret) {1509ath11k_warn(ab, "failed to setup P2P GO bcn ie: %d\n",1510ret);1511return ret;1512}15131514/* P2P IE is inserted by firmware automatically (as1515* configured above) so remove it from the base beacon1516* template to avoid duplicate P2P IEs in beacon frames.1517*/1518ret = ath11k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA,1519WLAN_OUI_TYPE_WFA_P2P,1520offsetof(struct ieee80211_mgmt,1521u.beacon.variable));1522if (ret) {1523ath11k_warn(ab, "failed to remove P2P vendor ie: %d\n",1524ret);1525return ret;1526}15271528return ret;1529}15301531static struct ath11k_vif *ath11k_mac_get_tx_arvif(struct ath11k_vif *arvif)1532{1533struct ieee80211_bss_conf *link_conf, *tx_bss_conf;15341535lockdep_assert_wiphy(arvif->ar->hw->wiphy);15361537link_conf = &arvif->vif->bss_conf;1538tx_bss_conf = wiphy_dereference(arvif->ar->hw->wiphy, link_conf->tx_bss_conf);1539if (tx_bss_conf)1540return ath11k_vif_to_arvif(tx_bss_conf->vif);15411542return NULL;1543}15441545static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif,1546struct ath11k_vif *tx_arvif)1547{1548struct ieee80211_ema_beacons *beacons;1549int ret = 0;1550bool nontx_vif_params_set = false;1551u32 params = 0;1552u8 i = 0;15531554beacons = ieee80211_beacon_get_template_ema_list(tx_arvif->ar->hw,1555tx_arvif->vif, 0);1556if (!beacons || !beacons->cnt) {1557ath11k_warn(arvif->ar->ab,1558"failed to get ema beacon templates from mac80211\n");1559return -EPERM;1560}15611562if (tx_arvif == arvif) {1563if (ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb))1564return -EINVAL;1565} else {1566arvif->wpaie_present = tx_arvif->wpaie_present;1567}15681569for (i = 0; i < beacons->cnt; i++) {1570if (tx_arvif != arvif && !nontx_vif_params_set)1571nontx_vif_params_set =1572ath11k_mac_set_nontx_vif_params(tx_arvif, arvif,1573beacons->bcn[i].skb);15741575params = beacons->cnt;1576params |= (i << WMI_EMA_TMPL_IDX_SHIFT);1577params |= ((!i ? 1 : 0) << WMI_EMA_FIRST_TMPL_SHIFT);1578params |= ((i + 1 == beacons->cnt ? 1 : 0) << WMI_EMA_LAST_TMPL_SHIFT);15791580ret = ath11k_wmi_bcn_tmpl(tx_arvif->ar, tx_arvif->vdev_id,1581&beacons->bcn[i].offs,1582beacons->bcn[i].skb, params);1583if (ret) {1584ath11k_warn(tx_arvif->ar->ab,1585"failed to set ema beacon template id %i error %d\n",1586i, ret);1587break;1588}1589}15901591ieee80211_beacon_free_ema_list(beacons);15921593if (tx_arvif != arvif && !nontx_vif_params_set)1594return -EINVAL; /* Profile not found in the beacons */15951596return ret;1597}15981599static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif,1600struct ath11k_vif *tx_arvif)1601{1602struct ath11k *ar = arvif->ar;1603struct ath11k_base *ab = ar->ab;1604struct ieee80211_hw *hw = ar->hw;1605struct ieee80211_vif *vif = arvif->vif;1606struct ieee80211_mutable_offsets offs = {};1607struct sk_buff *bcn;1608int ret;16091610if (tx_arvif != arvif) {1611ar = tx_arvif->ar;1612ab = ar->ab;1613hw = ar->hw;1614vif = tx_arvif->vif;1615}16161617bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0);1618if (!bcn) {1619ath11k_warn(ab, "failed to get beacon template from mac80211\n");1620return -EPERM;1621}16221623if (tx_arvif == arvif) {1624if (ath11k_mac_set_vif_params(tx_arvif, bcn))1625return -EINVAL;1626} else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) {1627return -EINVAL;1628}16291630ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0);1631kfree_skb(bcn);16321633if (ret)1634ath11k_warn(ab, "failed to submit beacon template command: %d\n",1635ret);16361637return ret;1638}16391640static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)1641{1642struct ieee80211_vif *vif = arvif->vif;1643struct ath11k_vif *tx_arvif;16441645if (arvif->vdev_type != WMI_VDEV_TYPE_AP)1646return 0;16471648/* Target does not expect beacon templates for the already up1649* non-transmitting interfaces, and results in a crash if sent.1650*/1651tx_arvif = ath11k_mac_get_tx_arvif(arvif);1652if (tx_arvif) {1653if (arvif != tx_arvif && arvif->is_up)1654return 0;16551656if (vif->bss_conf.ema_ap)1657return ath11k_mac_setup_bcn_tmpl_ema(arvif, tx_arvif);1658} else {1659tx_arvif = arvif;1660}16611662return ath11k_mac_setup_bcn_tmpl_mbssid(arvif, tx_arvif);1663}16641665void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif)1666{1667struct ieee80211_vif *vif = arvif->vif;16681669if (!vif->bss_conf.color_change_active && !arvif->bcca_zero_sent)1670return;16711672if (vif->bss_conf.color_change_active &&1673ieee80211_beacon_cntdwn_is_complete(vif, 0)) {1674arvif->bcca_zero_sent = true;1675ieee80211_color_change_finish(vif, 0);1676return;1677}16781679arvif->bcca_zero_sent = false;16801681if (vif->bss_conf.color_change_active)1682ieee80211_beacon_update_cntdwn(vif, 0);1683ath11k_mac_setup_bcn_tmpl(arvif);1684}16851686static void ath11k_control_beaconing(struct ath11k_vif *arvif,1687struct ieee80211_bss_conf *info)1688{1689struct ath11k *ar = arvif->ar;1690struct ath11k_vif *tx_arvif;1691int ret = 0;16921693lockdep_assert_held(&arvif->ar->conf_mutex);16941695if (!info->enable_beacon) {1696ret = ath11k_wmi_vdev_down(ar, arvif->vdev_id);1697if (ret)1698ath11k_warn(ar->ab, "failed to down vdev_id %i: %d\n",1699arvif->vdev_id, ret);17001701arvif->is_up = false;1702return;1703}17041705/* Install the beacon template to the FW */1706ret = ath11k_mac_setup_bcn_tmpl(arvif);1707if (ret) {1708ath11k_warn(ar->ab, "failed to update bcn tmpl during vdev up: %d\n",1709ret);1710return;1711}17121713arvif->aid = 0;17141715ether_addr_copy(arvif->bssid, info->bssid);17161717tx_arvif = ath11k_mac_get_tx_arvif(arvif);1718ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,1719arvif->bssid,1720tx_arvif ? tx_arvif->bssid : NULL,1721info->bssid_index,17221 << info->bssid_indicator);1723if (ret) {1724ath11k_warn(ar->ab, "failed to bring up vdev %d: %i\n",1725arvif->vdev_id, ret);1726return;1727}17281729arvif->is_up = true;17301731ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %d up\n", arvif->vdev_id);1732}17331734static void ath11k_mac_handle_beacon_iter(void *data, u8 *mac,1735struct ieee80211_vif *vif)1736{1737struct sk_buff *skb = data;1738struct ieee80211_mgmt *mgmt = (void *)skb->data;1739struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);17401741if (vif->type != NL80211_IFTYPE_STATION)1742return;17431744if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))1745return;17461747cancel_delayed_work(&arvif->connection_loss_work);1748}17491750void ath11k_mac_handle_beacon(struct ath11k *ar, struct sk_buff *skb)1751{1752ieee80211_iterate_active_interfaces_atomic(ar->hw,1753IEEE80211_IFACE_ITER_NORMAL,1754ath11k_mac_handle_beacon_iter,1755skb);1756}17571758static void ath11k_mac_handle_beacon_miss_iter(void *data, u8 *mac,1759struct ieee80211_vif *vif)1760{1761u32 *vdev_id = data;1762struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);1763struct ath11k *ar = arvif->ar;1764struct ieee80211_hw *hw = ar->hw;17651766if (arvif->vdev_id != *vdev_id)1767return;17681769if (!arvif->is_up)1770return;17711772ieee80211_beacon_loss(vif);17731774/* Firmware doesn't report beacon loss events repeatedly. If AP probe1775* (done by mac80211) succeeds but beacons do not resume then it1776* doesn't make sense to continue operation. Queue connection loss work1777* which can be cancelled when beacon is received.1778*/1779ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,1780ATH11K_CONNECTION_LOSS_HZ);1781}17821783void ath11k_mac_handle_beacon_miss(struct ath11k *ar, u32 vdev_id)1784{1785ieee80211_iterate_active_interfaces_atomic(ar->hw,1786IEEE80211_IFACE_ITER_NORMAL,1787ath11k_mac_handle_beacon_miss_iter,1788&vdev_id);1789}17901791static void ath11k_mac_vif_sta_connection_loss_work(struct work_struct *work)1792{1793struct ath11k_vif *arvif = container_of(work, struct ath11k_vif,1794connection_loss_work.work);1795struct ieee80211_vif *vif = arvif->vif;17961797if (!arvif->is_up)1798return;17991800ieee80211_connection_loss(vif);1801}18021803static void ath11k_peer_assoc_h_basic(struct ath11k *ar,1804struct ieee80211_vif *vif,1805struct ieee80211_sta *sta,1806struct peer_assoc_params *arg)1807{1808struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);1809u32 aid;18101811lockdep_assert_held(&ar->conf_mutex);18121813if (vif->type == NL80211_IFTYPE_STATION)1814aid = vif->cfg.aid;1815else1816aid = sta->aid;18171818ether_addr_copy(arg->peer_mac, sta->addr);1819arg->vdev_id = arvif->vdev_id;1820arg->peer_associd = aid;1821arg->auth_flag = true;1822/* TODO: STA WAR in ath10k for listen interval required? */1823arg->peer_listen_intval = ar->hw->conf.listen_interval;1824arg->peer_nss = 1;1825arg->peer_caps = vif->bss_conf.assoc_capability;1826}18271828static void ath11k_peer_assoc_h_crypto(struct ath11k *ar,1829struct ieee80211_vif *vif,1830struct ieee80211_sta *sta,1831struct peer_assoc_params *arg)1832{1833struct ieee80211_bss_conf *info = &vif->bss_conf;1834struct cfg80211_chan_def def;1835struct cfg80211_bss *bss;1836struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);1837const u8 *rsnie = NULL;1838const u8 *wpaie = NULL;18391840lockdep_assert_held(&ar->conf_mutex);18411842if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))1843return;18441845bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,1846IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);18471848if (arvif->rsnie_present || arvif->wpaie_present) {1849arg->need_ptk_4_way = true;1850if (arvif->wpaie_present)1851arg->need_gtk_2_way = true;1852} else if (bss) {1853const struct cfg80211_bss_ies *ies;18541855rcu_read_lock();1856rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);18571858ies = rcu_dereference(bss->ies);18591860wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,1861WLAN_OUI_TYPE_MICROSOFT_WPA,1862ies->data,1863ies->len);1864rcu_read_unlock();1865cfg80211_put_bss(ar->hw->wiphy, bss);1866}18671868/* FIXME: base on RSN IE/WPA IE is a correct idea? */1869if (rsnie || wpaie) {1870ath11k_dbg(ar->ab, ATH11K_DBG_WMI,1871"%s: rsn ie found\n", __func__);1872arg->need_ptk_4_way = true;1873}18741875if (wpaie) {1876ath11k_dbg(ar->ab, ATH11K_DBG_WMI,1877"%s: wpa ie found\n", __func__);1878arg->need_gtk_2_way = true;1879}18801881if (sta->mfp) {1882/* TODO: Need to check if FW supports PMF? */1883arg->is_pmf_enabled = true;1884}18851886/* TODO: safe_mode_enabled (bypass 4-way handshake) flag req? */1887}18881889static void ath11k_peer_assoc_h_rates(struct ath11k *ar,1890struct ieee80211_vif *vif,1891struct ieee80211_sta *sta,1892struct peer_assoc_params *arg)1893{1894struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);1895struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;1896struct cfg80211_chan_def def;1897const struct ieee80211_supported_band *sband;1898const struct ieee80211_rate *rates;1899enum nl80211_band band;1900u32 ratemask;1901u8 rate;1902int i;19031904lockdep_assert_held(&ar->conf_mutex);19051906if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))1907return;19081909band = def.chan->band;1910sband = ar->hw->wiphy->bands[band];1911ratemask = sta->deflink.supp_rates[band];1912ratemask &= arvif->bitrate_mask.control[band].legacy;1913rates = sband->bitrates;19141915rateset->num_rates = 0;19161917for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {1918if (!(ratemask & 1))1919continue;19201921rate = ath11k_mac_bitrate_to_rate(rates->bitrate);1922rateset->rates[rateset->num_rates] = rate;1923rateset->num_rates++;1924}1925}19261927static bool1928ath11k_peer_assoc_h_ht_masked(const u8 *ht_mcs_mask)1929{1930int nss;19311932for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)1933if (ht_mcs_mask[nss])1934return false;19351936return true;1937}19381939static bool1940ath11k_peer_assoc_h_vht_masked(const u16 *vht_mcs_mask)1941{1942int nss;19431944for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)1945if (vht_mcs_mask[nss])1946return false;19471948return true;1949}19501951static void ath11k_peer_assoc_h_ht(struct ath11k *ar,1952struct ieee80211_vif *vif,1953struct ieee80211_sta *sta,1954struct peer_assoc_params *arg)1955{1956const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;1957struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);1958struct cfg80211_chan_def def;1959enum nl80211_band band;1960const u8 *ht_mcs_mask;1961int i, n;1962u8 max_nss;1963u32 stbc;19641965lockdep_assert_held(&ar->conf_mutex);19661967if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))1968return;19691970if (!ht_cap->ht_supported)1971return;19721973band = def.chan->band;1974ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;19751976if (ath11k_peer_assoc_h_ht_masked(ht_mcs_mask))1977return;19781979arg->ht_flag = true;19801981arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +1982ht_cap->ampdu_factor)) - 1;19831984arg->peer_mpdu_density =1985ath11k_parse_mpdudensity(ht_cap->ampdu_density);19861987arg->peer_ht_caps = ht_cap->cap;1988arg->peer_rate_caps |= WMI_HOST_RC_HT_FLAG;19891990if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)1991arg->ldpc_flag = true;19921993if (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) {1994arg->bw_40 = true;1995arg->peer_rate_caps |= WMI_HOST_RC_CW40_FLAG;1996}19971998/* As firmware handles this two flags (IEEE80211_HT_CAP_SGI_201999* and IEEE80211_HT_CAP_SGI_40) for enabling SGI, we reset2000* both flags if guard interval is Default GI2001*/2002if (arvif->bitrate_mask.control[band].gi == NL80211_TXRATE_DEFAULT_GI)2003arg->peer_ht_caps &= ~(IEEE80211_HT_CAP_SGI_20 |2004IEEE80211_HT_CAP_SGI_40);20052006if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {2007if (ht_cap->cap & (IEEE80211_HT_CAP_SGI_20 |2008IEEE80211_HT_CAP_SGI_40))2009arg->peer_rate_caps |= WMI_HOST_RC_SGI_FLAG;2010}20112012if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {2013arg->peer_rate_caps |= WMI_HOST_RC_TX_STBC_FLAG;2014arg->stbc_flag = true;2015}20162017if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {2018stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;2019stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;2020stbc = stbc << WMI_HOST_RC_RX_STBC_FLAG_S;2021arg->peer_rate_caps |= stbc;2022arg->stbc_flag = true;2023}20242025if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])2026arg->peer_rate_caps |= WMI_HOST_RC_TS_FLAG;2027else if (ht_cap->mcs.rx_mask[1])2028arg->peer_rate_caps |= WMI_HOST_RC_DS_FLAG;20292030for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)2031if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&2032(ht_mcs_mask[i / 8] & BIT(i % 8))) {2033max_nss = (i / 8) + 1;2034arg->peer_ht_rates.rates[n++] = i;2035}20362037/* This is a workaround for HT-enabled STAs which break the spec2038* and have no HT capabilities RX mask (no HT RX MCS map).2039*2040* As per spec, in section 20.3.5 Modulation and coding scheme (MCS),2041* MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.2042*2043* Firmware asserts if such situation occurs.2044*/2045if (n == 0) {2046arg->peer_ht_rates.num_rates = 8;2047for (i = 0; i < arg->peer_ht_rates.num_rates; i++)2048arg->peer_ht_rates.rates[i] = i;2049} else {2050arg->peer_ht_rates.num_rates = n;2051arg->peer_nss = min(sta->deflink.rx_nss, max_nss);2052}20532054ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "ht peer %pM mcs cnt %d nss %d\n",2055arg->peer_mac,2056arg->peer_ht_rates.num_rates,2057arg->peer_nss);2058}20592060static int ath11k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)2061{2062switch ((mcs_map >> (2 * nss)) & 0x3) {2063case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;2064case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;2065case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;2066}2067return 0;2068}20692070static u162071ath11k_peer_assoc_h_vht_limit(u16 tx_mcs_set,2072const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])2073{2074int idx_limit;2075int nss;2076u16 mcs_map;2077u16 mcs;20782079for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {2080mcs_map = ath11k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &2081vht_mcs_limit[nss];20822083if (mcs_map)2084idx_limit = fls(mcs_map) - 1;2085else2086idx_limit = -1;20872088switch (idx_limit) {2089case 0:2090case 1:2091case 2:2092case 3:2093case 4:2094case 5:2095case 6:2096case 7:2097mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;2098break;2099case 8:2100mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;2101break;2102case 9:2103mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;2104break;2105default:2106WARN_ON(1);2107fallthrough;2108case -1:2109mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;2110break;2111}21122113tx_mcs_set &= ~(0x3 << (nss * 2));2114tx_mcs_set |= mcs << (nss * 2);2115}21162117return tx_mcs_set;2118}21192120static u8 ath11k_get_nss_160mhz(struct ath11k *ar,2121u8 max_nss)2122{2123u8 nss_ratio_info = ar->pdev->cap.nss_ratio_info;2124u8 max_sup_nss = 0;21252126switch (nss_ratio_info) {2127case WMI_NSS_RATIO_1BY2_NSS:2128max_sup_nss = max_nss >> 1;2129break;2130case WMI_NSS_RATIO_3BY4_NSS:2131ath11k_warn(ar->ab, "WMI_NSS_RATIO_3BY4_NSS not supported\n");2132break;2133case WMI_NSS_RATIO_1_NSS:2134max_sup_nss = max_nss;2135break;2136case WMI_NSS_RATIO_2_NSS:2137ath11k_warn(ar->ab, "WMI_NSS_RATIO_2_NSS not supported\n");2138break;2139default:2140ath11k_warn(ar->ab, "invalid nss ratio received from firmware: %d\n",2141nss_ratio_info);2142break;2143}21442145return max_sup_nss;2146}21472148static void ath11k_peer_assoc_h_vht(struct ath11k *ar,2149struct ieee80211_vif *vif,2150struct ieee80211_sta *sta,2151struct peer_assoc_params *arg)2152{2153const struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;2154struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);2155struct cfg80211_chan_def def;2156enum nl80211_band band;2157u16 *vht_mcs_mask;2158u8 ampdu_factor;2159u8 max_nss, vht_mcs;2160int i, vht_nss, nss_idx;2161bool user_rate_valid = true;2162u32 rx_nss, tx_nss, nss_160;21632164if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))2165return;21662167if (!vht_cap->vht_supported)2168return;21692170band = def.chan->band;2171vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;21722173if (ath11k_peer_assoc_h_vht_masked(vht_mcs_mask))2174return;21752176arg->vht_flag = true;21772178/* TODO: similar flags required? */2179arg->vht_capable = true;21802181if (def.chan->band == NL80211_BAND_2GHZ)2182arg->vht_ng_flag = true;21832184arg->peer_vht_caps = vht_cap->cap;21852186ampdu_factor = (vht_cap->cap &2187IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>2188IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;21892190/* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to2191* zero in VHT IE. Using it would result in degraded throughput.2192* arg->peer_max_mpdu at this point contains HT max_mpdu so keep2193* it if VHT max_mpdu is smaller.2194*/2195arg->peer_max_mpdu = max(arg->peer_max_mpdu,2196(1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +2197ampdu_factor)) - 1);21982199if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)2200arg->bw_80 = true;22012202if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160)2203arg->bw_160 = true;22042205vht_nss = ath11k_mac_max_vht_nss(vht_mcs_mask);22062207if (vht_nss > sta->deflink.rx_nss) {2208user_rate_valid = false;2209for (nss_idx = sta->deflink.rx_nss - 1; nss_idx >= 0; nss_idx--) {2210if (vht_mcs_mask[nss_idx]) {2211user_rate_valid = true;2212break;2213}2214}2215}22162217if (!user_rate_valid) {2218ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "setting vht range mcs value to peer supported nss %d for peer %pM\n",2219sta->deflink.rx_nss, sta->addr);2220vht_mcs_mask[sta->deflink.rx_nss - 1] = vht_mcs_mask[vht_nss - 1];2221}22222223/* Calculate peer NSS capability from VHT capabilities if STA2224* supports VHT.2225*/2226for (i = 0, max_nss = 0; i < NL80211_VHT_NSS_MAX; i++) {2227vht_mcs = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) >>2228(2 * i) & 3;22292230if (vht_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED &&2231vht_mcs_mask[i])2232max_nss = i + 1;2233}2234arg->peer_nss = min(sta->deflink.rx_nss, max_nss);2235arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest);2236arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);2237arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest);2238arg->tx_mcs_set = ath11k_peer_assoc_h_vht_limit(2239__le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);22402241/* In IPQ8074 platform, VHT mcs rate 10 and 11 is enabled by default.2242* VHT mcs rate 10 and 11 is not supported in 11ac standard.2243* so explicitly disable the VHT MCS rate 10 and 11 in 11ac mode.2244*/2245arg->tx_mcs_set &= ~IEEE80211_VHT_MCS_SUPPORT_0_11_MASK;2246arg->tx_mcs_set |= IEEE80211_DISABLE_VHT_MCS_SUPPORT_0_11;22472248if ((arg->tx_mcs_set & IEEE80211_VHT_MCS_NOT_SUPPORTED) ==2249IEEE80211_VHT_MCS_NOT_SUPPORTED)2250arg->peer_vht_caps &= ~IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;22512252/* TODO: Check */2253arg->tx_max_mcs_nss = 0xFF;22542255if (arg->peer_phymode == MODE_11AC_VHT160 ||2256arg->peer_phymode == MODE_11AC_VHT80_80) {2257tx_nss = ath11k_get_nss_160mhz(ar, max_nss);2258rx_nss = min(arg->peer_nss, tx_nss);2259arg->peer_bw_rxnss_override = ATH11K_BW_NSS_MAP_ENABLE;22602261if (!rx_nss) {2262ath11k_warn(ar->ab, "invalid max_nss\n");2263return;2264}22652266if (arg->peer_phymode == MODE_11AC_VHT160)2267nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_160MHZ, rx_nss - 1);2268else2269nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_80_80MHZ, rx_nss - 1);22702271arg->peer_bw_rxnss_override |= nss_160;2272}22732274ath11k_dbg(ar->ab, ATH11K_DBG_MAC,2275"vht peer %pM max_mpdu %d flags 0x%x nss_override 0x%x\n",2276sta->addr, arg->peer_max_mpdu, arg->peer_flags,2277arg->peer_bw_rxnss_override);2278}22792280static int ath11k_mac_get_max_he_mcs_map(u16 mcs_map, int nss)2281{2282switch ((mcs_map >> (2 * nss)) & 0x3) {2283case IEEE80211_HE_MCS_SUPPORT_0_7: return BIT(8) - 1;2284case IEEE80211_HE_MCS_SUPPORT_0_9: return BIT(10) - 1;2285case IEEE80211_HE_MCS_SUPPORT_0_11: return BIT(12) - 1;2286}2287return 0;2288}22892290static u16 ath11k_peer_assoc_h_he_limit(u16 tx_mcs_set,2291const u16 he_mcs_limit[NL80211_HE_NSS_MAX])2292{2293int idx_limit;2294int nss;2295u16 mcs_map;2296u16 mcs;22972298for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) {2299mcs_map = ath11k_mac_get_max_he_mcs_map(tx_mcs_set, nss) &2300he_mcs_limit[nss];23012302if (mcs_map)2303idx_limit = fls(mcs_map) - 1;2304else2305idx_limit = -1;23062307switch (idx_limit) {2308case 0 ... 7:2309mcs = IEEE80211_HE_MCS_SUPPORT_0_7;2310break;2311case 8:2312case 9:2313mcs = IEEE80211_HE_MCS_SUPPORT_0_9;2314break;2315case 10:2316case 11:2317mcs = IEEE80211_HE_MCS_SUPPORT_0_11;2318break;2319default:2320WARN_ON(1);2321fallthrough;2322case -1:2323mcs = IEEE80211_HE_MCS_NOT_SUPPORTED;2324break;2325}23262327tx_mcs_set &= ~(0x3 << (nss * 2));2328tx_mcs_set |= mcs << (nss * 2);2329}23302331return tx_mcs_set;2332}23332334static bool2335ath11k_peer_assoc_h_he_masked(const u16 *he_mcs_mask)2336{2337int nss;23382339for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++)2340if (he_mcs_mask[nss])2341return false;23422343return true;2344}23452346static void ath11k_peer_assoc_h_he(struct ath11k *ar,2347struct ieee80211_vif *vif,2348struct ieee80211_sta *sta,2349struct peer_assoc_params *arg)2350{2351struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);2352struct cfg80211_chan_def def;2353const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;2354enum nl80211_band band;2355u16 he_mcs_mask[NL80211_HE_NSS_MAX];2356u8 max_nss, he_mcs;2357u16 he_tx_mcs = 0, v = 0;2358int i, he_nss, nss_idx;2359bool user_rate_valid = true;2360u32 rx_nss, tx_nss, nss_160;2361u8 ampdu_factor, rx_mcs_80, rx_mcs_160;2362u16 mcs_160_map, mcs_80_map;2363bool support_160;23642365if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))2366return;23672368if (!he_cap->has_he)2369return;23702371band = def.chan->band;2372memcpy(he_mcs_mask, arvif->bitrate_mask.control[band].he_mcs,2373sizeof(he_mcs_mask));23742375if (ath11k_peer_assoc_h_he_masked(he_mcs_mask))2376return;23772378arg->he_flag = true;2379support_160 = !!(he_cap->he_cap_elem.phy_cap_info[0] &2380IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G);23812382/* Supported HE-MCS and NSS Set of peer he_cap is intersection with self he_cp */2383mcs_160_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);2384mcs_80_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80);23852386/* Initialize rx_mcs_160 to 9 which is an invalid value */2387rx_mcs_160 = 9;2388if (support_160) {2389for (i = 7; i >= 0; i--) {2390u8 mcs_160 = (mcs_160_map >> (2 * i)) & 3;23912392if (mcs_160 != IEEE80211_VHT_MCS_NOT_SUPPORTED) {2393rx_mcs_160 = i + 1;2394break;2395}2396}2397}23982399/* Initialize rx_mcs_80 to 9 which is an invalid value */2400rx_mcs_80 = 9;2401for (i = 7; i >= 0; i--) {2402u8 mcs_80 = (mcs_80_map >> (2 * i)) & 3;24032404if (mcs_80 != IEEE80211_VHT_MCS_NOT_SUPPORTED) {2405rx_mcs_80 = i + 1;2406break;2407}2408}24092410if (support_160)2411max_nss = min(rx_mcs_80, rx_mcs_160);2412else2413max_nss = rx_mcs_80;24142415arg->peer_nss = min(sta->deflink.rx_nss, max_nss);24162417memcpy_and_pad(&arg->peer_he_cap_macinfo,2418sizeof(arg->peer_he_cap_macinfo),2419he_cap->he_cap_elem.mac_cap_info,2420sizeof(he_cap->he_cap_elem.mac_cap_info),24210);2422memcpy_and_pad(&arg->peer_he_cap_phyinfo,2423sizeof(arg->peer_he_cap_phyinfo),2424he_cap->he_cap_elem.phy_cap_info,2425sizeof(he_cap->he_cap_elem.phy_cap_info),24260);2427arg->peer_he_ops = vif->bss_conf.he_oper.params;24282429/* the top most byte is used to indicate BSS color info */2430arg->peer_he_ops &= 0xffffff;24312432/* As per section 26.6.1 11ax Draft5.0, if the Max AMPDU Exponent Extension2433* in HE cap is zero, use the arg->peer_max_mpdu as calculated while parsing2434* VHT caps(if VHT caps is present) or HT caps (if VHT caps is not present).2435*2436* For non-zero value of Max AMPDU Extponent Extension in HE MAC caps,2437* if a HE STA sends VHT cap and HE cap IE in assoc request then, use2438* MAX_AMPDU_LEN_FACTOR as 20 to calculate max_ampdu length.2439* If a HE STA that does not send VHT cap, but HE and HT cap in assoc2440* request, then use MAX_AMPDU_LEN_FACTOR as 16 to calculate max_ampdu2441* length.2442*/2443ampdu_factor = u8_get_bits(he_cap->he_cap_elem.mac_cap_info[3],2444IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK);24452446if (ampdu_factor) {2447if (sta->deflink.vht_cap.vht_supported)2448arg->peer_max_mpdu = (1 << (IEEE80211_HE_VHT_MAX_AMPDU_FACTOR +2449ampdu_factor)) - 1;2450else if (sta->deflink.ht_cap.ht_supported)2451arg->peer_max_mpdu = (1 << (IEEE80211_HE_HT_MAX_AMPDU_FACTOR +2452ampdu_factor)) - 1;2453}24542455if (he_cap->he_cap_elem.phy_cap_info[6] &2456IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {2457int bit = 7;2458int nss, ru;24592460arg->peer_ppet.numss_m1 = he_cap->ppe_thres[0] &2461IEEE80211_PPE_THRES_NSS_MASK;2462arg->peer_ppet.ru_bit_mask =2463(he_cap->ppe_thres[0] &2464IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK) >>2465IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS;24662467for (nss = 0; nss <= arg->peer_ppet.numss_m1; nss++) {2468for (ru = 0; ru < 4; ru++) {2469u32 val = 0;2470int i;24712472if ((arg->peer_ppet.ru_bit_mask & BIT(ru)) == 0)2473continue;2474for (i = 0; i < 6; i++) {2475val >>= 1;2476val |= ((he_cap->ppe_thres[bit / 8] >>2477(bit % 8)) & 0x1) << 5;2478bit++;2479}2480arg->peer_ppet.ppet16_ppet8_ru3_ru0[nss] |=2481val << (ru * 6);2482}2483}2484}24852486if (he_cap->he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_RES)2487arg->twt_responder = true;2488if (he_cap->he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_REQ)2489arg->twt_requester = true;24902491he_nss = ath11k_mac_max_he_nss(he_mcs_mask);24922493if (he_nss > sta->deflink.rx_nss) {2494user_rate_valid = false;2495for (nss_idx = sta->deflink.rx_nss - 1; nss_idx >= 0; nss_idx--) {2496if (he_mcs_mask[nss_idx]) {2497user_rate_valid = true;2498break;2499}2500}2501}25022503if (!user_rate_valid) {2504ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "setting he range mcs value to peer supported nss %d for peer %pM\n",2505sta->deflink.rx_nss, sta->addr);2506he_mcs_mask[sta->deflink.rx_nss - 1] = he_mcs_mask[he_nss - 1];2507}25082509switch (sta->deflink.bandwidth) {2510case IEEE80211_STA_RX_BW_160:2511if (he_cap->he_cap_elem.phy_cap_info[0] &2512IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) {2513v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80p80);2514v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);2515arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;25162517v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80p80);2518arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;25192520arg->peer_he_mcs_count++;2521he_tx_mcs = v;2522}2523v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);2524arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;25252526v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160);2527v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);2528arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;25292530arg->peer_he_mcs_count++;2531if (!he_tx_mcs)2532he_tx_mcs = v;2533fallthrough;25342535default:2536v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80);2537arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;25382539v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80);2540v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);2541arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;25422543arg->peer_he_mcs_count++;2544if (!he_tx_mcs)2545he_tx_mcs = v;2546break;2547}25482549/* Calculate peer NSS capability from HE capabilities if STA2550* supports HE.2551*/2552for (i = 0, max_nss = 0; i < NL80211_HE_NSS_MAX; i++) {2553he_mcs = he_tx_mcs >> (2 * i) & 3;25542555/* In case of fixed rates, MCS Range in he_tx_mcs might have2556* unsupported range, with he_mcs_mask set, so check either of them2557* to find nss.2558*/2559if (he_mcs != IEEE80211_HE_MCS_NOT_SUPPORTED ||2560he_mcs_mask[i])2561max_nss = i + 1;2562}2563arg->peer_nss = min(sta->deflink.rx_nss, max_nss);25642565if (arg->peer_phymode == MODE_11AX_HE160 ||2566arg->peer_phymode == MODE_11AX_HE80_80) {2567tx_nss = ath11k_get_nss_160mhz(ar, max_nss);2568rx_nss = min(arg->peer_nss, tx_nss);2569arg->peer_bw_rxnss_override = ATH11K_BW_NSS_MAP_ENABLE;25702571if (!rx_nss) {2572ath11k_warn(ar->ab, "invalid max_nss\n");2573return;2574}25752576if (arg->peer_phymode == MODE_11AX_HE160)2577nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_160MHZ, rx_nss - 1);2578else2579nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_80_80MHZ, rx_nss - 1);25802581arg->peer_bw_rxnss_override |= nss_160;2582}25832584ath11k_dbg(ar->ab, ATH11K_DBG_MAC,2585"he peer %pM nss %d mcs cnt %d nss_override 0x%x\n",2586sta->addr, arg->peer_nss,2587arg->peer_he_mcs_count,2588arg->peer_bw_rxnss_override);2589}25902591static void ath11k_peer_assoc_h_he_6ghz(struct ath11k *ar,2592struct ieee80211_vif *vif,2593struct ieee80211_sta *sta,2594struct peer_assoc_params *arg)2595{2596const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;2597struct cfg80211_chan_def def;2598enum nl80211_band band;2599u8 ampdu_factor;26002601if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))2602return;26032604band = def.chan->band;26052606if (!arg->he_flag || band != NL80211_BAND_6GHZ || !sta->deflink.he_6ghz_capa.capa)2607return;26082609if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)2610arg->bw_40 = true;26112612if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)2613arg->bw_80 = true;26142615if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160)2616arg->bw_160 = true;26172618arg->peer_he_caps_6ghz = le16_to_cpu(sta->deflink.he_6ghz_capa.capa);2619arg->peer_mpdu_density =2620ath11k_parse_mpdudensity(FIELD_GET(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START,2621arg->peer_he_caps_6ghz));26222623/* From IEEE Std 802.11ax-2021 - Section 10.12.2: An HE STA shall be capable of2624* receiving A-MPDU where the A-MPDU pre-EOF padding length is up to the value2625* indicated by the Maximum A-MPDU Length Exponent Extension field in the HE2626* Capabilities element and the Maximum A-MPDU Length Exponent field in HE 6 GHz2627* Band Capabilities element in the 6 GHz band.2628*2629* Here, we are extracting the Max A-MPDU Exponent Extension from HE caps and2630* factor is the Maximum A-MPDU Length Exponent from HE 6 GHZ Band capability.2631*/2632ampdu_factor = FIELD_GET(IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK,2633he_cap->he_cap_elem.mac_cap_info[3]) +2634FIELD_GET(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP,2635arg->peer_he_caps_6ghz);26362637arg->peer_max_mpdu = (1u << (IEEE80211_HE_6GHZ_MAX_AMPDU_FACTOR +2638ampdu_factor)) - 1;2639}26402641static void ath11k_peer_assoc_h_smps(struct ieee80211_sta *sta,2642struct peer_assoc_params *arg)2643{2644const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;2645int smps;26462647if (!ht_cap->ht_supported && !sta->deflink.he_6ghz_capa.capa)2648return;26492650if (ht_cap->ht_supported) {2651smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;2652smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;2653} else {2654smps = le16_get_bits(sta->deflink.he_6ghz_capa.capa,2655IEEE80211_HE_6GHZ_CAP_SM_PS);2656}26572658switch (smps) {2659case WLAN_HT_CAP_SM_PS_STATIC:2660arg->static_mimops_flag = true;2661break;2662case WLAN_HT_CAP_SM_PS_DYNAMIC:2663arg->dynamic_mimops_flag = true;2664break;2665case WLAN_HT_CAP_SM_PS_DISABLED:2666arg->spatial_mux_flag = true;2667break;2668default:2669break;2670}2671}26722673static void ath11k_peer_assoc_h_qos(struct ath11k *ar,2674struct ieee80211_vif *vif,2675struct ieee80211_sta *sta,2676struct peer_assoc_params *arg)2677{2678struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);26792680switch (arvif->vdev_type) {2681case WMI_VDEV_TYPE_AP:2682if (sta->wme) {2683/* TODO: Check WME vs QoS */2684arg->is_wme_set = true;2685arg->qos_flag = true;2686}26872688if (sta->wme && sta->uapsd_queues) {2689/* TODO: Check WME vs QoS */2690arg->is_wme_set = true;2691arg->apsd_flag = true;2692arg->peer_rate_caps |= WMI_HOST_RC_UAPSD_FLAG;2693}2694break;2695case WMI_VDEV_TYPE_STA:2696if (sta->wme) {2697arg->is_wme_set = true;2698arg->qos_flag = true;2699}2700break;2701default:2702break;2703}27042705ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "peer %pM qos %d\n",2706sta->addr, arg->qos_flag);2707}27082709static int ath11k_peer_assoc_qos_ap(struct ath11k *ar,2710struct ath11k_vif *arvif,2711struct ieee80211_sta *sta)2712{2713struct ap_ps_params params;2714u32 max_sp;2715u32 uapsd;2716int ret;27172718lockdep_assert_held(&ar->conf_mutex);27192720params.vdev_id = arvif->vdev_id;27212722ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "uapsd_queues 0x%x max_sp %d\n",2723sta->uapsd_queues, sta->max_sp);27242725uapsd = 0;2726if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)2727uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |2728WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;2729if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)2730uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |2731WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;2732if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)2733uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |2734WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;2735if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)2736uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |2737WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;27382739max_sp = 0;2740if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)2741max_sp = sta->max_sp;27422743params.param = WMI_AP_PS_PEER_PARAM_UAPSD;2744params.value = uapsd;2745ret = ath11k_wmi_send_set_ap_ps_param_cmd(ar, sta->addr, ¶ms);2746if (ret)2747goto err;27482749params.param = WMI_AP_PS_PEER_PARAM_MAX_SP;2750params.value = max_sp;2751ret = ath11k_wmi_send_set_ap_ps_param_cmd(ar, sta->addr, ¶ms);2752if (ret)2753goto err;27542755/* TODO revisit during testing */2756params.param = WMI_AP_PS_PEER_PARAM_SIFS_RESP_FRMTYPE;2757params.value = DISABLE_SIFS_RESPONSE_TRIGGER;2758ret = ath11k_wmi_send_set_ap_ps_param_cmd(ar, sta->addr, ¶ms);2759if (ret)2760goto err;27612762params.param = WMI_AP_PS_PEER_PARAM_SIFS_RESP_UAPSD;2763params.value = DISABLE_SIFS_RESPONSE_TRIGGER;2764ret = ath11k_wmi_send_set_ap_ps_param_cmd(ar, sta->addr, ¶ms);2765if (ret)2766goto err;27672768return 0;27692770err:2771ath11k_warn(ar->ab, "failed to set ap ps peer param %d for vdev %i: %d\n",2772params.param, arvif->vdev_id, ret);2773return ret;2774}27752776static bool ath11k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)2777{2778return sta->deflink.supp_rates[NL80211_BAND_2GHZ] >>2779ATH11K_MAC_FIRST_OFDM_RATE_IDX;2780}27812782static enum wmi_phy_mode ath11k_mac_get_phymode_vht(struct ath11k *ar,2783struct ieee80211_sta *sta)2784{2785if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) {2786switch (sta->deflink.vht_cap.cap &2787IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {2788case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:2789return MODE_11AC_VHT160;2790case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:2791return MODE_11AC_VHT80_80;2792default:2793/* not sure if this is a valid case? */2794return MODE_11AC_VHT160;2795}2796}27972798if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)2799return MODE_11AC_VHT80;28002801if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)2802return MODE_11AC_VHT40;28032804if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)2805return MODE_11AC_VHT20;28062807return MODE_UNKNOWN;2808}28092810static enum wmi_phy_mode ath11k_mac_get_phymode_he(struct ath11k *ar,2811struct ieee80211_sta *sta)2812{2813if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) {2814if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] &2815IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)2816return MODE_11AX_HE160;2817else if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] &2818IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)2819return MODE_11AX_HE80_80;2820/* not sure if this is a valid case? */2821return MODE_11AX_HE160;2822}28232824if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)2825return MODE_11AX_HE80;28262827if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)2828return MODE_11AX_HE40;28292830if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)2831return MODE_11AX_HE20;28322833return MODE_UNKNOWN;2834}28352836static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,2837struct ieee80211_vif *vif,2838struct ieee80211_sta *sta,2839struct peer_assoc_params *arg)2840{2841struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);2842struct cfg80211_chan_def def;2843enum nl80211_band band;2844const u8 *ht_mcs_mask;2845const u16 *vht_mcs_mask;2846const u16 *he_mcs_mask;2847enum wmi_phy_mode phymode = MODE_UNKNOWN;28482849if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))2850return;28512852band = def.chan->band;2853ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;2854vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;2855he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;28562857switch (band) {2858case NL80211_BAND_2GHZ:2859if (sta->deflink.he_cap.has_he &&2860!ath11k_peer_assoc_h_he_masked(he_mcs_mask)) {2861if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)2862phymode = MODE_11AX_HE80_2G;2863else if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)2864phymode = MODE_11AX_HE40_2G;2865else2866phymode = MODE_11AX_HE20_2G;2867} else if (sta->deflink.vht_cap.vht_supported &&2868!ath11k_peer_assoc_h_vht_masked(vht_mcs_mask)) {2869if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)2870phymode = MODE_11AC_VHT40;2871else2872phymode = MODE_11AC_VHT20;2873} else if (sta->deflink.ht_cap.ht_supported &&2874!ath11k_peer_assoc_h_ht_masked(ht_mcs_mask)) {2875if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)2876phymode = MODE_11NG_HT40;2877else2878phymode = MODE_11NG_HT20;2879} else if (ath11k_mac_sta_has_ofdm_only(sta)) {2880phymode = MODE_11G;2881} else {2882phymode = MODE_11B;2883}2884break;2885case NL80211_BAND_5GHZ:2886case NL80211_BAND_6GHZ:2887/* Check HE first */2888if (sta->deflink.he_cap.has_he &&2889!ath11k_peer_assoc_h_he_masked(he_mcs_mask)) {2890phymode = ath11k_mac_get_phymode_he(ar, sta);2891} else if (sta->deflink.vht_cap.vht_supported &&2892!ath11k_peer_assoc_h_vht_masked(vht_mcs_mask)) {2893phymode = ath11k_mac_get_phymode_vht(ar, sta);2894} else if (sta->deflink.ht_cap.ht_supported &&2895!ath11k_peer_assoc_h_ht_masked(ht_mcs_mask)) {2896if (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40)2897phymode = MODE_11NA_HT40;2898else2899phymode = MODE_11NA_HT20;2900} else {2901phymode = MODE_11A;2902}2903break;2904default:2905break;2906}29072908ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "peer %pM phymode %s\n",2909sta->addr, ath11k_wmi_phymode_str(phymode));29102911arg->peer_phymode = phymode;2912WARN_ON(phymode == MODE_UNKNOWN);2913}29142915static void ath11k_peer_assoc_prepare(struct ath11k *ar,2916struct ieee80211_vif *vif,2917struct ieee80211_sta *sta,2918struct peer_assoc_params *arg,2919bool reassoc)2920{2921struct ath11k_sta *arsta;29222923lockdep_assert_held(&ar->conf_mutex);29242925arsta = ath11k_sta_to_arsta(sta);29262927memset(arg, 0, sizeof(*arg));29282929reinit_completion(&ar->peer_assoc_done);29302931arg->peer_new_assoc = !reassoc;2932ath11k_peer_assoc_h_basic(ar, vif, sta, arg);2933ath11k_peer_assoc_h_crypto(ar, vif, sta, arg);2934ath11k_peer_assoc_h_rates(ar, vif, sta, arg);2935ath11k_peer_assoc_h_phymode(ar, vif, sta, arg);2936ath11k_peer_assoc_h_ht(ar, vif, sta, arg);2937ath11k_peer_assoc_h_vht(ar, vif, sta, arg);2938ath11k_peer_assoc_h_he(ar, vif, sta, arg);2939ath11k_peer_assoc_h_he_6ghz(ar, vif, sta, arg);2940ath11k_peer_assoc_h_qos(ar, vif, sta, arg);2941ath11k_peer_assoc_h_smps(sta, arg);29422943arsta->peer_nss = arg->peer_nss;29442945/* TODO: amsdu_disable req? */2946}29472948static int ath11k_setup_peer_smps(struct ath11k *ar, struct ath11k_vif *arvif,2949const u8 *addr,2950const struct ieee80211_sta_ht_cap *ht_cap,2951u16 he_6ghz_capa)2952{2953int smps;29542955if (!ht_cap->ht_supported && !he_6ghz_capa)2956return 0;29572958if (ht_cap->ht_supported) {2959smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;2960smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;2961} else {2962smps = FIELD_GET(IEEE80211_HE_6GHZ_CAP_SM_PS, he_6ghz_capa);2963}29642965if (smps >= ARRAY_SIZE(ath11k_smps_map))2966return -EINVAL;29672968return ath11k_wmi_set_peer_param(ar, addr, arvif->vdev_id,2969WMI_PEER_MIMO_PS_STATE,2970ath11k_smps_map[smps]);2971}29722973static bool ath11k_mac_set_he_txbf_conf(struct ath11k_vif *arvif)2974{2975struct ath11k *ar = arvif->ar;2976u32 param, value;2977int ret;29782979if (!arvif->vif->bss_conf.he_support)2980return true;29812982param = WMI_VDEV_PARAM_SET_HEMU_MODE;2983value = 0;2984if (arvif->vif->bss_conf.he_su_beamformer) {2985value |= FIELD_PREP(HE_MODE_SU_TX_BFER, HE_SU_BFER_ENABLE);2986if (arvif->vif->bss_conf.he_mu_beamformer &&2987arvif->vdev_type == WMI_VDEV_TYPE_AP)2988value |= FIELD_PREP(HE_MODE_MU_TX_BFER, HE_MU_BFER_ENABLE);2989}29902991if (arvif->vif->type != NL80211_IFTYPE_MESH_POINT) {2992value |= FIELD_PREP(HE_MODE_DL_OFDMA, HE_DL_MUOFDMA_ENABLE) |2993FIELD_PREP(HE_MODE_UL_OFDMA, HE_UL_MUOFDMA_ENABLE);29942995if (arvif->vif->bss_conf.he_full_ul_mumimo)2996value |= FIELD_PREP(HE_MODE_UL_MUMIMO, HE_UL_MUMIMO_ENABLE);29972998if (arvif->vif->bss_conf.he_su_beamformee)2999value |= FIELD_PREP(HE_MODE_SU_TX_BFEE, HE_SU_BFEE_ENABLE);3000}30013002ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, value);3003if (ret) {3004ath11k_warn(ar->ab, "failed to set vdev %d HE MU mode: %d\n",3005arvif->vdev_id, ret);3006return false;3007}30083009param = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE;3010value = FIELD_PREP(HE_VHT_SOUNDING_MODE, HE_VHT_SOUNDING_MODE_ENABLE) |3011FIELD_PREP(HE_TRIG_NONTRIG_SOUNDING_MODE,3012HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE);3013ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3014param, value);3015if (ret) {3016ath11k_warn(ar->ab, "failed to set vdev %d sounding mode: %d\n",3017arvif->vdev_id, ret);3018return false;3019}3020return true;3021}30223023static bool ath11k_mac_vif_recalc_sta_he_txbf(struct ath11k *ar,3024struct ieee80211_vif *vif,3025struct ieee80211_sta_he_cap *he_cap)3026{3027struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);3028struct ieee80211_he_cap_elem he_cap_elem = {};3029struct ieee80211_sta_he_cap *cap_band = NULL;3030struct cfg80211_chan_def def;3031u32 param = WMI_VDEV_PARAM_SET_HEMU_MODE;3032u32 hemode = 0;3033int ret;30343035if (!vif->bss_conf.he_support)3036return true;30373038if (vif->type != NL80211_IFTYPE_STATION)3039return false;30403041if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))3042return false;30433044if (def.chan->band == NL80211_BAND_2GHZ)3045cap_band = &ar->mac.iftype[NL80211_BAND_2GHZ][vif->type].he_cap;3046else3047cap_band = &ar->mac.iftype[NL80211_BAND_5GHZ][vif->type].he_cap;30483049memcpy(&he_cap_elem, &cap_band->he_cap_elem, sizeof(he_cap_elem));30503051if (HECAP_PHY_SUBFME_GET(he_cap_elem.phy_cap_info)) {3052if (HECAP_PHY_SUBFMR_GET(he_cap->he_cap_elem.phy_cap_info))3053hemode |= FIELD_PREP(HE_MODE_SU_TX_BFEE, HE_SU_BFEE_ENABLE);3054if (HECAP_PHY_MUBFMR_GET(he_cap->he_cap_elem.phy_cap_info))3055hemode |= FIELD_PREP(HE_MODE_MU_TX_BFEE, HE_MU_BFEE_ENABLE);3056}30573058if (vif->type != NL80211_IFTYPE_MESH_POINT) {3059hemode |= FIELD_PREP(HE_MODE_DL_OFDMA, HE_DL_MUOFDMA_ENABLE) |3060FIELD_PREP(HE_MODE_UL_OFDMA, HE_UL_MUOFDMA_ENABLE);30613062if (HECAP_PHY_ULMUMIMO_GET(he_cap_elem.phy_cap_info))3063if (HECAP_PHY_ULMUMIMO_GET(he_cap->he_cap_elem.phy_cap_info))3064hemode |= FIELD_PREP(HE_MODE_UL_MUMIMO,3065HE_UL_MUMIMO_ENABLE);30663067if (FIELD_GET(HE_MODE_MU_TX_BFEE, hemode))3068hemode |= FIELD_PREP(HE_MODE_SU_TX_BFEE, HE_SU_BFEE_ENABLE);30693070if (FIELD_GET(HE_MODE_MU_TX_BFER, hemode))3071hemode |= FIELD_PREP(HE_MODE_SU_TX_BFER, HE_SU_BFER_ENABLE);3072}30733074ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, hemode);3075if (ret) {3076ath11k_warn(ar->ab, "failed to submit vdev param txbf 0x%x: %d\n",3077hemode, ret);3078return false;3079}30803081return true;3082}30833084static void ath11k_bss_assoc(struct ieee80211_hw *hw,3085struct ieee80211_vif *vif,3086struct ieee80211_bss_conf *bss_conf)3087{3088struct ath11k *ar = hw->priv;3089struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);3090struct peer_assoc_params peer_arg;3091struct ieee80211_sta *ap_sta;3092struct ath11k_peer *peer;3093bool is_auth = false;3094struct ieee80211_sta_he_cap he_cap;3095int ret;30963097lockdep_assert_held(&ar->conf_mutex);30983099ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %i assoc bssid %pM aid %d\n",3100arvif->vdev_id, arvif->bssid, arvif->aid);31013102rcu_read_lock();31033104ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);3105if (!ap_sta) {3106ath11k_warn(ar->ab, "failed to find station entry for bss %pM vdev %i\n",3107bss_conf->bssid, arvif->vdev_id);3108rcu_read_unlock();3109return;3110}31113112/* he_cap here is updated at assoc success for sta mode only */3113he_cap = ap_sta->deflink.he_cap;31143115ath11k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg, false);31163117rcu_read_unlock();31183119if (!ath11k_mac_vif_recalc_sta_he_txbf(ar, vif, &he_cap)) {3120ath11k_warn(ar->ab, "failed to recalc he txbf for vdev %i on bss %pM\n",3121arvif->vdev_id, bss_conf->bssid);3122return;3123}31243125peer_arg.is_assoc = true;31263127ret = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg);3128if (ret) {3129ath11k_warn(ar->ab, "failed to run peer assoc for %pM vdev %i: %d\n",3130bss_conf->bssid, arvif->vdev_id, ret);3131return;3132}31333134if (!wait_for_completion_timeout(&ar->peer_assoc_done, 1 * HZ)) {3135ath11k_warn(ar->ab, "failed to get peer assoc conf event for %pM vdev %i\n",3136bss_conf->bssid, arvif->vdev_id);3137return;3138}31393140ret = ath11k_setup_peer_smps(ar, arvif, bss_conf->bssid,3141&ap_sta->deflink.ht_cap,3142le16_to_cpu(ap_sta->deflink.he_6ghz_capa.capa));3143if (ret) {3144ath11k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n",3145arvif->vdev_id, ret);3146return;3147}31483149WARN_ON(arvif->is_up);31503151arvif->aid = vif->cfg.aid;3152ether_addr_copy(arvif->bssid, bss_conf->bssid);31533154ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid,3155NULL, 0, 0);3156if (ret) {3157ath11k_warn(ar->ab, "failed to set vdev %d up: %d\n",3158arvif->vdev_id, ret);3159return;3160}31613162arvif->is_up = true;3163arvif->rekey_data.enable_offload = false;31643165ath11k_dbg(ar->ab, ATH11K_DBG_MAC,3166"vdev %d up (associated) bssid %pM aid %d\n",3167arvif->vdev_id, bss_conf->bssid, vif->cfg.aid);31683169spin_lock_bh(&ar->ab->base_lock);31703171peer = ath11k_peer_find(ar->ab, arvif->vdev_id, arvif->bssid);3172if (peer && peer->is_authorized)3173is_auth = true;31743175spin_unlock_bh(&ar->ab->base_lock);31763177if (is_auth) {3178ret = ath11k_wmi_set_peer_param(ar, arvif->bssid,3179arvif->vdev_id,3180WMI_PEER_AUTHORIZE,31811);3182if (ret)3183ath11k_warn(ar->ab, "Unable to authorize BSS peer: %d\n", ret);3184}31853186ret = ath11k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id,3187&bss_conf->he_obss_pd);3188if (ret)3189ath11k_warn(ar->ab, "failed to set vdev %i OBSS PD parameters: %d\n",3190arvif->vdev_id, ret);31913192ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3193WMI_VDEV_PARAM_DTIM_POLICY,3194WMI_DTIM_POLICY_STICK);3195if (ret)3196ath11k_warn(ar->ab, "failed to set vdev %d dtim policy: %d\n",3197arvif->vdev_id, ret);31983199ath11k_mac_11d_scan_stop_all(ar->ab);3200}32013202static void ath11k_bss_disassoc(struct ieee80211_hw *hw,3203struct ieee80211_vif *vif)3204{3205struct ath11k *ar = hw->priv;3206struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);3207int ret;32083209lockdep_assert_held(&ar->conf_mutex);32103211ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %i disassoc bssid %pM\n",3212arvif->vdev_id, arvif->bssid);32133214ret = ath11k_wmi_vdev_down(ar, arvif->vdev_id);3215if (ret)3216ath11k_warn(ar->ab, "failed to down vdev %i: %d\n",3217arvif->vdev_id, ret);32183219arvif->is_up = false;32203221memset(&arvif->rekey_data, 0, sizeof(arvif->rekey_data));32223223cancel_delayed_work_sync(&arvif->connection_loss_work);3224}32253226static u32 ath11k_mac_get_rate_hw_value(int bitrate)3227{3228u32 preamble;3229u16 hw_value;3230int rate;3231size_t i;32323233if (ath11k_mac_bitrate_is_cck(bitrate))3234preamble = WMI_RATE_PREAMBLE_CCK;3235else3236preamble = WMI_RATE_PREAMBLE_OFDM;32373238for (i = 0; i < ARRAY_SIZE(ath11k_legacy_rates); i++) {3239if (ath11k_legacy_rates[i].bitrate != bitrate)3240continue;32413242hw_value = ath11k_legacy_rates[i].hw_value;3243rate = ATH11K_HW_RATE_CODE(hw_value, 0, preamble);32443245return rate;3246}32473248return -EINVAL;3249}32503251static void ath11k_recalculate_mgmt_rate(struct ath11k *ar,3252struct ieee80211_vif *vif,3253struct cfg80211_chan_def *def)3254{3255struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);3256const struct ieee80211_supported_band *sband;3257u8 basic_rate_idx;3258int hw_rate_code;3259u32 vdev_param;3260u16 bitrate;3261int ret;32623263lockdep_assert_held(&ar->conf_mutex);32643265sband = ar->hw->wiphy->bands[def->chan->band];3266basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;3267bitrate = sband->bitrates[basic_rate_idx].bitrate;32683269hw_rate_code = ath11k_mac_get_rate_hw_value(bitrate);3270if (hw_rate_code < 0) {3271ath11k_warn(ar->ab, "bitrate not supported %d\n", bitrate);3272return;3273}32743275vdev_param = WMI_VDEV_PARAM_MGMT_RATE;3276ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, vdev_param,3277hw_rate_code);3278if (ret)3279ath11k_warn(ar->ab, "failed to set mgmt tx rate %d\n", ret);32803281/* For WCN6855, firmware will clear this param when vdev starts, hence3282* cache it here so that we can reconfigure it once vdev starts.3283*/3284ar->hw_rate_code = hw_rate_code;32853286vdev_param = WMI_VDEV_PARAM_BEACON_RATE;3287ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, vdev_param,3288hw_rate_code);3289if (ret)3290ath11k_warn(ar->ab, "failed to set beacon tx rate %d\n", ret);3291}32923293static int ath11k_mac_fils_discovery(struct ath11k_vif *arvif,3294struct ieee80211_bss_conf *info)3295{3296struct ath11k *ar = arvif->ar;3297struct sk_buff *tmpl;3298int ret;3299u32 interval;3300bool unsol_bcast_probe_resp_enabled = false;33013302if (info->fils_discovery.max_interval) {3303interval = info->fils_discovery.max_interval;33043305tmpl = ieee80211_get_fils_discovery_tmpl(ar->hw, arvif->vif);3306if (tmpl)3307ret = ath11k_wmi_fils_discovery_tmpl(ar, arvif->vdev_id,3308tmpl);3309} else if (info->unsol_bcast_probe_resp_interval) {3310unsol_bcast_probe_resp_enabled = 1;3311interval = info->unsol_bcast_probe_resp_interval;33123313tmpl = ieee80211_get_unsol_bcast_probe_resp_tmpl(ar->hw,3314arvif->vif);3315if (tmpl)3316ret = ath11k_wmi_probe_resp_tmpl(ar, arvif->vdev_id,3317tmpl);3318} else { /* Disable */3319return ath11k_wmi_fils_discovery(ar, arvif->vdev_id, 0, false);3320}33213322if (!tmpl) {3323ath11k_warn(ar->ab,3324"mac vdev %i failed to retrieve %s template\n",3325arvif->vdev_id, (unsol_bcast_probe_resp_enabled ?3326"unsolicited broadcast probe response" :3327"FILS discovery"));3328return -EPERM;3329}3330kfree_skb(tmpl);33313332if (!ret)3333ret = ath11k_wmi_fils_discovery(ar, arvif->vdev_id, interval,3334unsol_bcast_probe_resp_enabled);33353336return ret;3337}33383339static int ath11k_mac_config_obss_pd(struct ath11k *ar,3340struct ieee80211_he_obss_pd *he_obss_pd)3341{3342u32 bitmap[2], param_id, param_val, pdev_id;3343int ret;3344s8 non_srg_th = 0, srg_th = 0;33453346pdev_id = ar->pdev->pdev_id;33473348/* Set and enable SRG/non-SRG OBSS PD Threshold */3349param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD;3350if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) {3351ret = ath11k_wmi_pdev_set_param(ar, param_id, 0, pdev_id);3352if (ret)3353ath11k_warn(ar->ab,3354"failed to set obss_pd_threshold for pdev: %u\n",3355pdev_id);3356return ret;3357}33583359ath11k_dbg(ar->ab, ATH11K_DBG_MAC,3360"obss pd sr_ctrl %x non_srg_thres %u srg_max %u\n",3361he_obss_pd->sr_ctrl, he_obss_pd->non_srg_max_offset,3362he_obss_pd->max_offset);33633364param_val = 0;33653366if (he_obss_pd->sr_ctrl &3367IEEE80211_HE_SPR_NON_SRG_OBSS_PD_SR_DISALLOWED) {3368non_srg_th = ATH11K_OBSS_PD_MAX_THRESHOLD;3369} else {3370if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT)3371non_srg_th = (ATH11K_OBSS_PD_MAX_THRESHOLD +3372he_obss_pd->non_srg_max_offset);3373else3374non_srg_th = ATH11K_OBSS_PD_NON_SRG_MAX_THRESHOLD;33753376param_val |= ATH11K_OBSS_PD_NON_SRG_EN;3377}33783379if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT) {3380srg_th = ATH11K_OBSS_PD_MAX_THRESHOLD + he_obss_pd->max_offset;3381param_val |= ATH11K_OBSS_PD_SRG_EN;3382}33833384if (test_bit(WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT,3385ar->ab->wmi_ab.svc_map)) {3386param_val |= ATH11K_OBSS_PD_THRESHOLD_IN_DBM;3387param_val |= FIELD_PREP(GENMASK(15, 8), srg_th);3388} else {3389non_srg_th -= ATH11K_DEFAULT_NOISE_FLOOR;3390/* SRG not supported and threshold in dB */3391param_val &= ~(ATH11K_OBSS_PD_SRG_EN |3392ATH11K_OBSS_PD_THRESHOLD_IN_DBM);3393}33943395param_val |= (non_srg_th & GENMASK(7, 0));3396ret = ath11k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);3397if (ret) {3398ath11k_warn(ar->ab,3399"failed to set obss_pd_threshold for pdev: %u\n",3400pdev_id);3401return ret;3402}34033404/* Enable OBSS PD for all access category */3405param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC;3406param_val = 0xf;3407ret = ath11k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);3408if (ret) {3409ath11k_warn(ar->ab,3410"failed to set obss_pd_per_ac for pdev: %u\n",3411pdev_id);3412return ret;3413}34143415/* Set SR Prohibit */3416param_id = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT;3417param_val = !!(he_obss_pd->sr_ctrl &3418IEEE80211_HE_SPR_HESIGA_SR_VAL15_ALLOWED);3419ret = ath11k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);3420if (ret) {3421ath11k_warn(ar->ab, "failed to set sr_prohibit for pdev: %u\n",3422pdev_id);3423return ret;3424}34253426if (!test_bit(WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT,3427ar->ab->wmi_ab.svc_map))3428return 0;34293430/* Set SRG BSS Color Bitmap */3431memcpy(bitmap, he_obss_pd->bss_color_bitmap, sizeof(bitmap));3432ret = ath11k_wmi_pdev_set_srg_bss_color_bitmap(ar, bitmap);3433if (ret) {3434ath11k_warn(ar->ab,3435"failed to set bss_color_bitmap for pdev: %u\n",3436pdev_id);3437return ret;3438}34393440/* Set SRG Partial BSSID Bitmap */3441memcpy(bitmap, he_obss_pd->partial_bssid_bitmap, sizeof(bitmap));3442ret = ath11k_wmi_pdev_set_srg_patial_bssid_bitmap(ar, bitmap);3443if (ret) {3444ath11k_warn(ar->ab,3445"failed to set partial_bssid_bitmap for pdev: %u\n",3446pdev_id);3447return ret;3448}34493450memset(bitmap, 0xff, sizeof(bitmap));34513452/* Enable all BSS Colors for SRG */3453ret = ath11k_wmi_pdev_srg_obss_color_enable_bitmap(ar, bitmap);3454if (ret) {3455ath11k_warn(ar->ab,3456"failed to set srg_color_en_bitmap pdev: %u\n",3457pdev_id);3458return ret;3459}34603461/* Enable all partial BSSID mask for SRG */3462ret = ath11k_wmi_pdev_srg_obss_bssid_enable_bitmap(ar, bitmap);3463if (ret) {3464ath11k_warn(ar->ab,3465"failed to set srg_bssid_en_bitmap pdev: %u\n",3466pdev_id);3467return ret;3468}34693470/* Enable all BSS Colors for non-SRG */3471ret = ath11k_wmi_pdev_non_srg_obss_color_enable_bitmap(ar, bitmap);3472if (ret) {3473ath11k_warn(ar->ab,3474"failed to set non_srg_color_en_bitmap pdev: %u\n",3475pdev_id);3476return ret;3477}34783479/* Enable all partial BSSID mask for non-SRG */3480ret = ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(ar, bitmap);3481if (ret) {3482ath11k_warn(ar->ab,3483"failed to set non_srg_bssid_en_bitmap pdev: %u\n",3484pdev_id);3485return ret;3486}34873488return 0;3489}34903491static bool ath11k_mac_supports_station_tpc(struct ath11k *ar,3492struct ath11k_vif *arvif,3493const struct cfg80211_chan_def *chandef)3494{3495return ath11k_wmi_supports_6ghz_cc_ext(ar) &&3496test_bit(WMI_TLV_SERVICE_EXT_TPC_REG_SUPPORT, ar->ab->wmi_ab.svc_map) &&3497arvif->vdev_type == WMI_VDEV_TYPE_STA &&3498arvif->vdev_subtype == WMI_VDEV_SUBTYPE_NONE &&3499chandef->chan &&3500chandef->chan->band == NL80211_BAND_6GHZ;3501}35023503static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,3504struct ieee80211_vif *vif,3505struct ieee80211_bss_conf *info,3506u64 changed)3507{3508struct ath11k *ar = hw->priv;3509struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);3510struct cfg80211_chan_def def;3511u32 param_id, param_value;3512enum nl80211_band band;3513u32 vdev_param;3514int mcast_rate;3515u32 preamble;3516u16 hw_value;3517u16 bitrate;3518int ret = 0;3519u8 rateidx;3520u32 rate, param;3521u32 ipv4_cnt;35223523mutex_lock(&ar->conf_mutex);35243525if (changed & BSS_CHANGED_BEACON_INT) {3526arvif->beacon_interval = info->beacon_int;35273528param_id = WMI_VDEV_PARAM_BEACON_INTERVAL;3529ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3530param_id,3531arvif->beacon_interval);3532if (ret)3533ath11k_warn(ar->ab, "Failed to set beacon interval for VDEV: %d\n",3534arvif->vdev_id);3535else3536ath11k_dbg(ar->ab, ATH11K_DBG_MAC,3537"Beacon interval: %d set for VDEV: %d\n",3538arvif->beacon_interval, arvif->vdev_id);3539}35403541if (changed & BSS_CHANGED_BEACON) {3542param_id = WMI_PDEV_PARAM_BEACON_TX_MODE;3543param_value = WMI_BEACON_STAGGERED_MODE;3544ret = ath11k_wmi_pdev_set_param(ar, param_id,3545param_value, ar->pdev->pdev_id);3546if (ret)3547ath11k_warn(ar->ab, "Failed to set beacon mode for VDEV: %d\n",3548arvif->vdev_id);3549else3550ath11k_dbg(ar->ab, ATH11K_DBG_MAC,3551"Set staggered beacon mode for VDEV: %d\n",3552arvif->vdev_id);35533554if (!arvif->do_not_send_tmpl || !arvif->bcca_zero_sent) {3555ret = ath11k_mac_setup_bcn_tmpl(arvif);3556if (ret)3557ath11k_warn(ar->ab, "failed to update bcn template: %d\n",3558ret);3559}35603561if (arvif->bcca_zero_sent)3562arvif->do_not_send_tmpl = true;3563else3564arvif->do_not_send_tmpl = false;35653566if (vif->bss_conf.he_support) {3567ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3568WMI_VDEV_PARAM_BA_MODE,3569WMI_BA_MODE_BUFFER_SIZE_256);3570if (ret)3571ath11k_warn(ar->ab,3572"failed to set BA BUFFER SIZE 256 for vdev: %d\n",3573arvif->vdev_id);3574else3575ath11k_dbg(ar->ab, ATH11K_DBG_MAC,3576"Set BA BUFFER SIZE 256 for VDEV: %d\n",3577arvif->vdev_id);3578}3579}35803581if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {3582arvif->dtim_period = info->dtim_period;35833584param_id = WMI_VDEV_PARAM_DTIM_PERIOD;3585ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3586param_id,3587arvif->dtim_period);35883589if (ret)3590ath11k_warn(ar->ab, "Failed to set dtim period for VDEV %d: %i\n",3591arvif->vdev_id, ret);3592else3593ath11k_dbg(ar->ab, ATH11K_DBG_MAC,3594"DTIM period: %d set for VDEV: %d\n",3595arvif->dtim_period, arvif->vdev_id);3596}35973598if (changed & BSS_CHANGED_SSID &&3599vif->type == NL80211_IFTYPE_AP) {3600arvif->u.ap.ssid_len = vif->cfg.ssid_len;3601if (vif->cfg.ssid_len)3602memcpy(arvif->u.ap.ssid, vif->cfg.ssid,3603vif->cfg.ssid_len);3604arvif->u.ap.hidden_ssid = info->hidden_ssid;3605}36063607if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))3608ether_addr_copy(arvif->bssid, info->bssid);36093610if (changed & BSS_CHANGED_BEACON_ENABLED) {3611if (info->enable_beacon)3612ath11k_mac_set_he_txbf_conf(arvif);3613ath11k_control_beaconing(arvif, info);36143615if (arvif->is_up && vif->bss_conf.he_support &&3616vif->bss_conf.he_oper.params) {3617param_id = WMI_VDEV_PARAM_HEOPS_0_31;3618param_value = vif->bss_conf.he_oper.params;3619ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3620param_id, param_value);3621ath11k_dbg(ar->ab, ATH11K_DBG_MAC,3622"he oper param: %x set for VDEV: %d\n",3623param_value, arvif->vdev_id);36243625if (ret)3626ath11k_warn(ar->ab, "Failed to set he oper params %x for VDEV %d: %i\n",3627param_value, arvif->vdev_id, ret);3628}3629}36303631if (changed & BSS_CHANGED_ERP_CTS_PROT) {3632u32 cts_prot;36333634cts_prot = !!(info->use_cts_prot);3635param_id = WMI_VDEV_PARAM_PROTECTION_MODE;36363637if (arvif->is_started) {3638ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3639param_id, cts_prot);3640if (ret)3641ath11k_warn(ar->ab, "Failed to set CTS prot for VDEV: %d\n",3642arvif->vdev_id);3643else3644ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "Set CTS prot: %d for VDEV: %d\n",3645cts_prot, arvif->vdev_id);3646} else {3647ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "defer protection mode setup, vdev is not ready yet\n");3648}3649}36503651if (changed & BSS_CHANGED_ERP_SLOT) {3652u32 slottime;36533654if (info->use_short_slot)3655slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */36563657else3658slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */36593660param_id = WMI_VDEV_PARAM_SLOT_TIME;3661ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3662param_id, slottime);3663if (ret)3664ath11k_warn(ar->ab, "Failed to set erp slot for VDEV: %d\n",3665arvif->vdev_id);3666else3667ath11k_dbg(ar->ab, ATH11K_DBG_MAC,3668"Set slottime: %d for VDEV: %d\n",3669slottime, arvif->vdev_id);3670}36713672if (changed & BSS_CHANGED_ERP_PREAMBLE) {3673u32 preamble;36743675if (info->use_short_preamble)3676preamble = WMI_VDEV_PREAMBLE_SHORT;3677else3678preamble = WMI_VDEV_PREAMBLE_LONG;36793680param_id = WMI_VDEV_PARAM_PREAMBLE;3681ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3682param_id, preamble);3683if (ret)3684ath11k_warn(ar->ab, "Failed to set preamble for VDEV: %d\n",3685arvif->vdev_id);3686else3687ath11k_dbg(ar->ab, ATH11K_DBG_MAC,3688"Set preamble: %d for VDEV: %d\n",3689preamble, arvif->vdev_id);3690}36913692if (changed & BSS_CHANGED_ASSOC) {3693if (vif->cfg.assoc)3694ath11k_bss_assoc(hw, vif, info);3695else3696ath11k_bss_disassoc(hw, vif);3697}36983699if (changed & BSS_CHANGED_TXPOWER) {3700ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev_id %i txpower %d\n",3701arvif->vdev_id, info->txpower);3702arvif->txpower = info->txpower;3703ath11k_mac_txpower_recalc(ar);3704}37053706if (changed & BSS_CHANGED_PS &&3707ar->ab->hw_params.supports_sta_ps) {3708arvif->ps = vif->cfg.ps;37093710ret = ath11k_mac_config_ps(ar);3711if (ret)3712ath11k_warn(ar->ab, "failed to setup ps on vdev %i: %d\n",3713arvif->vdev_id, ret);3714}37153716if (changed & BSS_CHANGED_MCAST_RATE &&3717!ath11k_mac_vif_chan(arvif->vif, &def)) {3718band = def.chan->band;3719mcast_rate = vif->bss_conf.mcast_rate[band];37203721if (mcast_rate > 0)3722rateidx = mcast_rate - 1;3723else3724rateidx = ffs(vif->bss_conf.basic_rates) - 1;37253726if (ar->pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP)3727rateidx += ATH11K_MAC_FIRST_OFDM_RATE_IDX;37283729bitrate = ath11k_legacy_rates[rateidx].bitrate;3730hw_value = ath11k_legacy_rates[rateidx].hw_value;37313732if (ath11k_mac_bitrate_is_cck(bitrate))3733preamble = WMI_RATE_PREAMBLE_CCK;3734else3735preamble = WMI_RATE_PREAMBLE_OFDM;37363737rate = ATH11K_HW_RATE_CODE(hw_value, 0, preamble);37383739ath11k_dbg(ar->ab, ATH11K_DBG_MAC,3740"vdev %d mcast_rate %x\n",3741arvif->vdev_id, rate);37423743vdev_param = WMI_VDEV_PARAM_MCAST_DATA_RATE;3744ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3745vdev_param, rate);3746if (ret)3747ath11k_warn(ar->ab,3748"failed to set mcast rate on vdev %i: %d\n",3749arvif->vdev_id, ret);37503751vdev_param = WMI_VDEV_PARAM_BCAST_DATA_RATE;3752ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3753vdev_param, rate);3754if (ret)3755ath11k_warn(ar->ab,3756"failed to set bcast rate on vdev %i: %d\n",3757arvif->vdev_id, ret);3758}37593760if (changed & BSS_CHANGED_BASIC_RATES &&3761!ath11k_mac_vif_chan(arvif->vif, &def))3762ath11k_recalculate_mgmt_rate(ar, vif, &def);37633764if (changed & BSS_CHANGED_TWT) {3765struct wmi_twt_enable_params twt_params = {};37663767if (info->twt_requester || info->twt_responder) {3768ath11k_wmi_fill_default_twt_params(&twt_params);3769ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id,3770&twt_params);3771} else {3772ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);3773}3774}37753776if (changed & BSS_CHANGED_HE_OBSS_PD)3777ath11k_mac_config_obss_pd(ar, &info->he_obss_pd);37783779if (changed & BSS_CHANGED_HE_BSS_COLOR) {3780if (vif->type == NL80211_IFTYPE_AP) {3781ret = ath11k_wmi_send_obss_color_collision_cfg_cmd(3782ar, arvif->vdev_id, info->he_bss_color.color,3783ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS,3784info->he_bss_color.enabled);3785if (ret)3786ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n",3787arvif->vdev_id, ret);37883789param_id = WMI_VDEV_PARAM_BSS_COLOR;3790if (info->he_bss_color.enabled)3791param_value = info->he_bss_color.color <<3792IEEE80211_HE_OPERATION_BSS_COLOR_OFFSET;3793else3794param_value = IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED;37953796ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,3797param_id,3798param_value);3799if (ret)3800ath11k_warn(ar->ab,3801"failed to set bss color param on vdev %i: %d\n",3802arvif->vdev_id, ret);38033804ath11k_dbg(ar->ab, ATH11K_DBG_MAC,3805"bss color param 0x%x set on vdev %i\n",3806param_value, arvif->vdev_id);3807} else if (vif->type == NL80211_IFTYPE_STATION) {3808ret = ath11k_wmi_send_bss_color_change_enable_cmd(ar,3809arvif->vdev_id,38101);3811if (ret)3812ath11k_warn(ar->ab, "failed to enable bss color change on vdev %i: %d\n",3813arvif->vdev_id, ret);3814ret = ath11k_wmi_send_obss_color_collision_cfg_cmd(3815ar, arvif->vdev_id, 0,3816ATH11K_BSS_COLOR_COLLISION_DETECTION_STA_PERIOD_MS, 1);3817if (ret)3818ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n",3819arvif->vdev_id, ret);3820}3821}38223823if (changed & BSS_CHANGED_FTM_RESPONDER &&3824arvif->ftm_responder != info->ftm_responder &&3825test_bit(WMI_TLV_SERVICE_RTT, ar->ab->wmi_ab.svc_map) &&3826(vif->type == NL80211_IFTYPE_AP ||3827vif->type == NL80211_IFTYPE_MESH_POINT)) {3828arvif->ftm_responder = info->ftm_responder;3829param = WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE;3830ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param,3831arvif->ftm_responder);3832if (ret)3833ath11k_warn(ar->ab, "Failed to set ftm responder %i: %d\n",3834arvif->vdev_id, ret);3835}38363837if (changed & BSS_CHANGED_FILS_DISCOVERY ||3838changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP)3839ath11k_mac_fils_discovery(arvif, info);38403841if (changed & BSS_CHANGED_ARP_FILTER) {3842ipv4_cnt = min(vif->cfg.arp_addr_cnt, ATH11K_IPV4_MAX_COUNT);3843memcpy(arvif->arp_ns_offload.ipv4_addr,3844vif->cfg.arp_addr_list,3845ipv4_cnt * sizeof(u32));3846memcpy(arvif->arp_ns_offload.mac_addr, vif->addr, ETH_ALEN);3847arvif->arp_ns_offload.ipv4_count = ipv4_cnt;38483849ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "arp_addr_cnt %d vif->addr %pM, offload_addr %pI4\n",3850vif->cfg.arp_addr_cnt,3851vif->addr, arvif->arp_ns_offload.ipv4_addr);3852}38533854mutex_unlock(&ar->conf_mutex);3855}38563857void __ath11k_mac_scan_finish(struct ath11k *ar)3858{3859lockdep_assert_held(&ar->data_lock);38603861switch (ar->scan.state) {3862case ATH11K_SCAN_IDLE:3863break;3864case ATH11K_SCAN_RUNNING:3865case ATH11K_SCAN_ABORTING:3866if (ar->scan.is_roc && ar->scan.roc_notify)3867ieee80211_remain_on_channel_expired(ar->hw);3868fallthrough;3869case ATH11K_SCAN_STARTING:3870if (!ar->scan.is_roc) {3871struct cfg80211_scan_info info = {3872.aborted = ((ar->scan.state ==3873ATH11K_SCAN_ABORTING) ||3874(ar->scan.state ==3875ATH11K_SCAN_STARTING)),3876};38773878ieee80211_scan_completed(ar->hw, &info);3879}38803881ar->scan.state = ATH11K_SCAN_IDLE;3882ar->scan_channel = NULL;3883ar->scan.roc_freq = 0;3884cancel_delayed_work(&ar->scan.timeout);3885complete_all(&ar->scan.completed);3886break;3887}3888}38893890void ath11k_mac_scan_finish(struct ath11k *ar)3891{3892spin_lock_bh(&ar->data_lock);3893__ath11k_mac_scan_finish(ar);3894spin_unlock_bh(&ar->data_lock);3895}38963897static int ath11k_scan_stop(struct ath11k *ar)3898{3899struct scan_cancel_param arg = {3900.req_type = WLAN_SCAN_CANCEL_SINGLE,3901.scan_id = ATH11K_SCAN_ID,3902};3903int ret;39043905lockdep_assert_held(&ar->conf_mutex);39063907/* TODO: Fill other STOP Params */3908arg.pdev_id = ar->pdev->pdev_id;39093910ret = ath11k_wmi_send_scan_stop_cmd(ar, &arg);3911if (ret) {3912ath11k_warn(ar->ab, "failed to stop wmi scan: %d\n", ret);3913goto out;3914}39153916ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);3917if (ret == 0) {3918ath11k_warn(ar->ab,3919"failed to receive scan abort comple: timed out\n");3920ret = -ETIMEDOUT;3921} else if (ret > 0) {3922ret = 0;3923}39243925out:3926/* Scan state should be updated upon scan completion but in case3927* firmware fails to deliver the event (for whatever reason) it is3928* desired to clean up scan state anyway. Firmware may have just3929* dropped the scan completion event delivery due to transport pipe3930* being overflown with data and/or it can recover on its own before3931* next scan request is submitted.3932*/3933spin_lock_bh(&ar->data_lock);3934if (ar->scan.state != ATH11K_SCAN_IDLE)3935__ath11k_mac_scan_finish(ar);3936spin_unlock_bh(&ar->data_lock);39373938return ret;3939}39403941static void ath11k_scan_abort(struct ath11k *ar)3942{3943int ret;39443945lockdep_assert_held(&ar->conf_mutex);39463947spin_lock_bh(&ar->data_lock);39483949switch (ar->scan.state) {3950case ATH11K_SCAN_IDLE:3951/* This can happen if timeout worker kicked in and called3952* abortion while scan completion was being processed.3953*/3954break;3955case ATH11K_SCAN_STARTING:3956case ATH11K_SCAN_ABORTING:3957ath11k_warn(ar->ab, "refusing scan abortion due to invalid scan state: %d\n",3958ar->scan.state);3959break;3960case ATH11K_SCAN_RUNNING:3961ar->scan.state = ATH11K_SCAN_ABORTING;3962spin_unlock_bh(&ar->data_lock);39633964ret = ath11k_scan_stop(ar);3965if (ret)3966ath11k_warn(ar->ab, "failed to abort scan: %d\n", ret);39673968spin_lock_bh(&ar->data_lock);3969break;3970}39713972spin_unlock_bh(&ar->data_lock);3973}39743975static void ath11k_scan_timeout_work(struct work_struct *work)3976{3977struct ath11k *ar = container_of(work, struct ath11k,3978scan.timeout.work);39793980mutex_lock(&ar->conf_mutex);3981ath11k_scan_abort(ar);3982mutex_unlock(&ar->conf_mutex);3983}39843985static int ath11k_start_scan(struct ath11k *ar,3986struct scan_req_params *arg)3987{3988int ret;3989unsigned long timeout = 1 * HZ;39903991lockdep_assert_held(&ar->conf_mutex);39923993if (ath11k_spectral_get_mode(ar) == ATH11K_SPECTRAL_BACKGROUND)3994ath11k_spectral_reset_buffer(ar);39953996ret = ath11k_wmi_send_scan_start_cmd(ar, arg);3997if (ret)3998return ret;39994000if (test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ar->ab->wmi_ab.svc_map)) {4001timeout = 5 * HZ;40024003if (ar->supports_6ghz)4004timeout += 5 * HZ;4005}40064007ret = wait_for_completion_timeout(&ar->scan.started, timeout);4008if (ret == 0) {4009ret = ath11k_scan_stop(ar);4010if (ret)4011ath11k_warn(ar->ab, "failed to stop scan: %d\n", ret);40124013return -ETIMEDOUT;4014}40154016/* If we failed to start the scan, return error code at4017* this point. This is probably due to some issue in the4018* firmware, but no need to wedge the driver due to that...4019*/4020spin_lock_bh(&ar->data_lock);4021if (ar->scan.state == ATH11K_SCAN_IDLE) {4022spin_unlock_bh(&ar->data_lock);4023return -EINVAL;4024}4025spin_unlock_bh(&ar->data_lock);40264027return 0;4028}40294030static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw,4031struct ieee80211_vif *vif,4032struct ieee80211_scan_request *hw_req)4033{4034struct ath11k *ar = hw->priv;4035struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);4036struct cfg80211_scan_request *req = &hw_req->req;4037struct scan_req_params *arg = NULL;4038int ret = 0;4039int i;4040u32 scan_timeout;40414042/* Firmwares advertising the support of triggering 11D algorithm4043* on the scan results of a regular scan expects driver to send4044* WMI_11D_SCAN_START_CMDID before sending WMI_START_SCAN_CMDID.4045* With this feature, separate 11D scan can be avoided since4046* regdomain can be determined with the scan results of the4047* regular scan.4048*/4049if (ar->state_11d == ATH11K_11D_PREPARING &&4050test_bit(WMI_TLV_SERVICE_SUPPORT_11D_FOR_HOST_SCAN,4051ar->ab->wmi_ab.svc_map))4052ath11k_mac_11d_scan_start(ar, arvif->vdev_id);40534054mutex_lock(&ar->conf_mutex);40554056spin_lock_bh(&ar->data_lock);4057switch (ar->scan.state) {4058case ATH11K_SCAN_IDLE:4059reinit_completion(&ar->scan.started);4060reinit_completion(&ar->scan.completed);4061ar->scan.state = ATH11K_SCAN_STARTING;4062ar->scan.is_roc = false;4063ar->scan.vdev_id = arvif->vdev_id;4064ret = 0;4065break;4066case ATH11K_SCAN_STARTING:4067case ATH11K_SCAN_RUNNING:4068case ATH11K_SCAN_ABORTING:4069ret = -EBUSY;4070break;4071}4072spin_unlock_bh(&ar->data_lock);40734074if (ret)4075goto exit;40764077arg = kzalloc(sizeof(*arg), GFP_KERNEL);40784079if (!arg) {4080ret = -ENOMEM;4081goto exit;4082}40834084ath11k_wmi_start_scan_init(ar, arg);4085arg->vdev_id = arvif->vdev_id;4086arg->scan_id = ATH11K_SCAN_ID;40874088if (ar->ab->hw_params.single_pdev_only)4089arg->scan_f_filter_prb_req = 1;40904091if (req->ie_len) {4092arg->extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL);4093if (!arg->extraie.ptr) {4094ret = -ENOMEM;4095goto exit;4096}4097arg->extraie.len = req->ie_len;4098}40994100if (req->n_ssids) {4101arg->num_ssids = req->n_ssids;4102for (i = 0; i < arg->num_ssids; i++) {4103arg->ssid[i].length = req->ssids[i].ssid_len;4104memcpy(&arg->ssid[i].ssid, req->ssids[i].ssid,4105req->ssids[i].ssid_len);4106}4107} else {4108arg->scan_f_passive = 1;4109}41104111if (req->n_channels) {4112arg->num_chan = req->n_channels;4113arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list),4114GFP_KERNEL);41154116if (!arg->chan_list) {4117ret = -ENOMEM;4118goto exit;4119}41204121for (i = 0; i < arg->num_chan; i++) {4122if (test_bit(WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL,4123ar->ab->wmi_ab.svc_map)) {4124arg->chan_list[i] =4125u32_encode_bits(req->channels[i]->center_freq,4126WMI_SCAN_CONFIG_PER_CHANNEL_MASK);41274128/* If NL80211_SCAN_FLAG_COLOCATED_6GHZ is set in scan4129* flags, then scan all PSC channels in 6 GHz band and4130* those non-PSC channels where RNR IE is found during4131* the legacy 2.4/5 GHz scan.4132* If NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set,4133* then all channels in 6 GHz will be scanned.4134*/4135if (req->channels[i]->band == NL80211_BAND_6GHZ &&4136req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ &&4137!cfg80211_channel_is_psc(req->channels[i]))4138arg->chan_list[i] |=4139WMI_SCAN_CH_FLAG_SCAN_ONLY_IF_RNR_FOUND;4140} else {4141arg->chan_list[i] = req->channels[i]->center_freq;4142}4143}4144}41454146if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {4147arg->scan_f_add_spoofed_mac_in_probe = 1;4148ether_addr_copy(arg->mac_addr.addr, req->mac_addr);4149ether_addr_copy(arg->mac_mask.addr, req->mac_addr_mask);4150}41514152/* if duration is set, default dwell times will be overwritten */4153if (req->duration) {4154arg->dwell_time_active = req->duration;4155arg->dwell_time_active_2g = req->duration;4156arg->dwell_time_active_6g = req->duration;4157arg->dwell_time_passive = req->duration;4158arg->dwell_time_passive_6g = req->duration;4159arg->burst_duration = req->duration;41604161scan_timeout = min_t(u32, arg->max_rest_time *4162(arg->num_chan - 1) + (req->duration +4163ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) *4164arg->num_chan, arg->max_scan_time);4165} else {4166scan_timeout = arg->max_scan_time;4167}41684169/* Add a margin to account for event/command processing */4170scan_timeout += ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD;41714172ret = ath11k_start_scan(ar, arg);4173if (ret) {4174ath11k_warn(ar->ab, "failed to start hw scan: %d\n", ret);4175spin_lock_bh(&ar->data_lock);4176ar->scan.state = ATH11K_SCAN_IDLE;4177spin_unlock_bh(&ar->data_lock);4178}41794180ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,4181msecs_to_jiffies(scan_timeout));41824183exit:4184if (arg) {4185kfree(arg->chan_list);4186kfree(arg->extraie.ptr);4187kfree(arg);4188}41894190mutex_unlock(&ar->conf_mutex);41914192if (ar->state_11d == ATH11K_11D_PREPARING)4193ath11k_mac_11d_scan_start(ar, arvif->vdev_id);41944195return ret;4196}41974198static void ath11k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw,4199struct ieee80211_vif *vif)4200{4201struct ath11k *ar = hw->priv;42024203mutex_lock(&ar->conf_mutex);4204ath11k_scan_abort(ar);4205mutex_unlock(&ar->conf_mutex);42064207cancel_delayed_work_sync(&ar->scan.timeout);4208}42094210static int ath11k_install_key(struct ath11k_vif *arvif,4211struct ieee80211_key_conf *key,4212enum set_key_cmd cmd,4213const u8 *macaddr, u32 flags)4214{4215int ret;4216struct ath11k *ar = arvif->ar;4217struct wmi_vdev_install_key_arg arg = {4218.vdev_id = arvif->vdev_id,4219.key_idx = key->keyidx,4220.key_len = key->keylen,4221.key_data = key->key,4222.key_flags = flags,4223.macaddr = macaddr,4224};42254226lockdep_assert_held(&arvif->ar->conf_mutex);42274228reinit_completion(&ar->install_key_done);42294230if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))4231return 0;42324233if (cmd == DISABLE_KEY) {4234arg.key_cipher = WMI_CIPHER_NONE;4235arg.key_data = NULL;4236goto install;4237}42384239switch (key->cipher) {4240case WLAN_CIPHER_SUITE_CCMP:4241case WLAN_CIPHER_SUITE_CCMP_256:4242arg.key_cipher = WMI_CIPHER_AES_CCM;4243/* TODO: Re-check if flag is valid */4244key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;4245break;4246case WLAN_CIPHER_SUITE_TKIP:4247arg.key_cipher = WMI_CIPHER_TKIP;4248arg.key_txmic_len = 8;4249arg.key_rxmic_len = 8;4250break;4251case WLAN_CIPHER_SUITE_GCMP:4252case WLAN_CIPHER_SUITE_GCMP_256:4253arg.key_cipher = WMI_CIPHER_AES_GCM;4254key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;4255break;4256default:4257ath11k_warn(ar->ab, "cipher %d is not supported\n", key->cipher);4258return -EOPNOTSUPP;4259}42604261if (test_bit(ATH11K_FLAG_RAW_MODE, &ar->ab->dev_flags))4262key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV |4263IEEE80211_KEY_FLAG_RESERVE_TAILROOM;42644265install:4266ret = ath11k_wmi_vdev_install_key(arvif->ar, &arg);42674268if (ret)4269return ret;42704271if (!wait_for_completion_timeout(&ar->install_key_done, 1 * HZ))4272return -ETIMEDOUT;42734274return ar->install_key_status ? -EINVAL : 0;4275}42764277static int ath11k_clear_peer_keys(struct ath11k_vif *arvif,4278const u8 *addr)4279{4280struct ath11k *ar = arvif->ar;4281struct ath11k_base *ab = ar->ab;4282struct ath11k_peer *peer;4283int first_errno = 0;4284int ret;4285int i;4286u32 flags = 0;42874288lockdep_assert_held(&ar->conf_mutex);42894290spin_lock_bh(&ab->base_lock);4291peer = ath11k_peer_find(ab, arvif->vdev_id, addr);4292spin_unlock_bh(&ab->base_lock);42934294if (!peer)4295return -ENOENT;42964297for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {4298if (!peer->keys[i])4299continue;43004301/* key flags are not required to delete the key */4302ret = ath11k_install_key(arvif, peer->keys[i],4303DISABLE_KEY, addr, flags);4304if (ret < 0 && first_errno == 0)4305first_errno = ret;43064307if (ret < 0)4308ath11k_warn(ab, "failed to remove peer key %d: %d\n",4309i, ret);43104311spin_lock_bh(&ab->base_lock);4312peer->keys[i] = NULL;4313spin_unlock_bh(&ab->base_lock);4314}43154316return first_errno;4317}43184319static int ath11k_set_group_keys(struct ath11k_vif *arvif)4320{4321struct ath11k *ar = arvif->ar;4322struct ath11k_base *ab = ar->ab;4323const u8 *addr = arvif->bssid;4324int i, ret, first_errno = 0;4325struct ath11k_peer *peer;43264327spin_lock_bh(&ab->base_lock);4328peer = ath11k_peer_find(ab, arvif->vdev_id, addr);4329spin_unlock_bh(&ab->base_lock);43304331if (!peer)4332return -ENOENT;43334334for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {4335struct ieee80211_key_conf *key = peer->keys[i];43364337if (!key || (key->flags & IEEE80211_KEY_FLAG_PAIRWISE))4338continue;43394340ret = ath11k_install_key(arvif, key, SET_KEY, addr,4341WMI_KEY_GROUP);4342if (ret < 0 && first_errno == 0)4343first_errno = ret;43444345if (ret < 0)4346ath11k_warn(ab, "failed to set group key of idx %d for vdev %d: %d\n",4347i, arvif->vdev_id, ret);4348}43494350return first_errno;4351}43524353static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,4354struct ieee80211_vif *vif, struct ieee80211_sta *sta,4355struct ieee80211_key_conf *key)4356{4357struct ath11k *ar = hw->priv;4358struct ath11k_base *ab = ar->ab;4359struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);4360struct ath11k_peer *peer;4361struct ath11k_sta *arsta;4362bool is_ap_with_no_sta;4363const u8 *peer_addr;4364int ret = 0;4365u32 flags = 0;43664367/* BIP needs to be done in software */4368if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||4369key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||4370key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 ||4371key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)4372return 1;43734374if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))4375return 1;43764377if (key->keyidx > WMI_MAX_KEY_INDEX)4378return -ENOSPC;43794380mutex_lock(&ar->conf_mutex);43814382if (sta)4383peer_addr = sta->addr;4384else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)4385peer_addr = vif->bss_conf.bssid;4386else4387peer_addr = vif->addr;43884389key->hw_key_idx = key->keyidx;43904391/* the peer should not disappear in mid-way (unless FW goes awry) since4392* we already hold conf_mutex. we just make sure its there now.4393*/4394spin_lock_bh(&ab->base_lock);4395peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr);43964397/* flush the fragments cache during key (re)install to4398* ensure all frags in the new frag list belong to the same key.4399*/4400if (peer && sta && cmd == SET_KEY)4401ath11k_peer_frags_flush(ar, peer);4402spin_unlock_bh(&ab->base_lock);44034404if (!peer) {4405if (cmd == SET_KEY) {4406ath11k_warn(ab, "cannot install key for non-existent peer %pM\n",4407peer_addr);4408ret = -EOPNOTSUPP;4409goto exit;4410} else {4411/* if the peer doesn't exist there is no key to disable4412* anymore4413*/4414goto exit;4415}4416}44174418if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)4419flags = WMI_KEY_PAIRWISE;4420else4421flags = WMI_KEY_GROUP;44224423ath11k_dbg(ar->ab, ATH11K_DBG_MAC,4424"%s for peer %pM on vdev %d flags 0x%X, type = %d, num_sta %d\n",4425cmd == SET_KEY ? "SET_KEY" : "DEL_KEY", peer_addr, arvif->vdev_id,4426flags, arvif->vdev_type, arvif->num_stations);44274428/* Allow group key clearing only in AP mode when no stations are4429* associated. There is a known race condition in firmware where4430* group addressed packets may be dropped if the key is cleared4431* and immediately set again during rekey.4432*4433* During GTK rekey, mac80211 issues a clear key (if the old key4434* exists) followed by an install key operation for same key4435* index. This causes ath11k to send two WMI commands in quick4436* succession: one to clear the old key and another to install the4437* new key in the same slot.4438*4439* Under certain conditions—especially under high load or time4440* sensitive scenarios, firmware may process these commands4441* asynchronously in a way that firmware assumes the key is4442* cleared whereas hardware has a valid key. This inconsistency4443* between hardware and firmware leads to group addressed packet4444* drops after rekey.4445* Only setting the same key again can restore a valid key in4446* firmware and allow packets to be transmitted.4447*4448* There is a use case where an AP can transition from Secure mode4449* to open mode without a vdev restart by just deleting all4450* associated peers and clearing key, Hence allow clear key for4451* that case alone. Mark arvif->reinstall_group_keys in such cases4452* and reinstall the same key when the first peer is added,4453* allowing firmware to recover from the race if it had occurred.4454*/44554456is_ap_with_no_sta = (vif->type == NL80211_IFTYPE_AP &&4457!arvif->num_stations);4458if (flags == WMI_KEY_PAIRWISE || cmd == SET_KEY || is_ap_with_no_sta) {4459ret = ath11k_install_key(arvif, key, cmd, peer_addr, flags);4460if (ret) {4461ath11k_warn(ab, "ath11k_install_key failed (%d)\n", ret);4462goto exit;4463}44644465ret = ath11k_dp_peer_rx_pn_replay_config(arvif, peer_addr, cmd, key);4466if (ret) {4467ath11k_warn(ab, "failed to offload PN replay detection %d\n",4468ret);4469goto exit;4470}44714472if (flags == WMI_KEY_GROUP && cmd == SET_KEY && is_ap_with_no_sta)4473arvif->reinstall_group_keys = true;4474}44754476spin_lock_bh(&ab->base_lock);4477peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr);4478if (peer && cmd == SET_KEY) {4479peer->keys[key->keyidx] = key;4480if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {4481peer->ucast_keyidx = key->keyidx;4482peer->sec_type = ath11k_dp_tx_get_encrypt_type(key->cipher);4483} else {4484peer->mcast_keyidx = key->keyidx;4485peer->sec_type_grp = ath11k_dp_tx_get_encrypt_type(key->cipher);4486}4487} else if (peer && cmd == DISABLE_KEY) {4488peer->keys[key->keyidx] = NULL;4489if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)4490peer->ucast_keyidx = 0;4491else4492peer->mcast_keyidx = 0;4493} else if (!peer)4494/* impossible unless FW goes crazy */4495ath11k_warn(ab, "peer %pM disappeared!\n", peer_addr);44964497if (sta) {4498arsta = ath11k_sta_to_arsta(sta);44994500switch (key->cipher) {4501case WLAN_CIPHER_SUITE_TKIP:4502case WLAN_CIPHER_SUITE_CCMP:4503case WLAN_CIPHER_SUITE_CCMP_256:4504case WLAN_CIPHER_SUITE_GCMP:4505case WLAN_CIPHER_SUITE_GCMP_256:4506if (cmd == SET_KEY)4507arsta->pn_type = HAL_PN_TYPE_WPA;4508else4509arsta->pn_type = HAL_PN_TYPE_NONE;4510break;4511default:4512arsta->pn_type = HAL_PN_TYPE_NONE;4513break;4514}4515}45164517spin_unlock_bh(&ab->base_lock);45184519exit:4520mutex_unlock(&ar->conf_mutex);4521return ret;4522}45234524static int4525ath11k_mac_bitrate_mask_num_ht_rates(struct ath11k *ar,4526enum nl80211_band band,4527const struct cfg80211_bitrate_mask *mask)4528{4529int num_rates = 0;4530int i;45314532for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)4533num_rates += hweight8(mask->control[band].ht_mcs[i]);45344535return num_rates;4536}45374538static int4539ath11k_mac_bitrate_mask_num_vht_rates(struct ath11k *ar,4540enum nl80211_band band,4541const struct cfg80211_bitrate_mask *mask)4542{4543int num_rates = 0;4544int i;45454546for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)4547num_rates += hweight16(mask->control[band].vht_mcs[i]);45484549return num_rates;4550}45514552static int4553ath11k_mac_bitrate_mask_num_he_rates(struct ath11k *ar,4554enum nl80211_band band,4555const struct cfg80211_bitrate_mask *mask)4556{4557int num_rates = 0;4558int i;45594560for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++)4561num_rates += hweight16(mask->control[band].he_mcs[i]);45624563return num_rates;4564}45654566static int4567ath11k_mac_set_peer_vht_fixed_rate(struct ath11k_vif *arvif,4568struct ieee80211_sta *sta,4569const struct cfg80211_bitrate_mask *mask,4570enum nl80211_band band)4571{4572struct ath11k *ar = arvif->ar;4573u8 vht_rate, nss;4574u32 rate_code;4575int ret, i;45764577lockdep_assert_held(&ar->conf_mutex);45784579nss = 0;45804581for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {4582if (hweight16(mask->control[band].vht_mcs[i]) == 1) {4583nss = i + 1;4584vht_rate = ffs(mask->control[band].vht_mcs[i]) - 1;4585}4586}45874588if (!nss) {4589ath11k_warn(ar->ab, "No single VHT Fixed rate found to set for %pM",4590sta->addr);4591return -EINVAL;4592}45934594/* Avoid updating invalid nss as fixed rate*/4595if (nss > sta->deflink.rx_nss)4596return -EINVAL;45974598ath11k_dbg(ar->ab, ATH11K_DBG_MAC,4599"Setting Fixed VHT Rate for peer %pM. Device will not switch to any other selected rates",4600sta->addr);46014602rate_code = ATH11K_HW_RATE_CODE(vht_rate, nss - 1,4603WMI_RATE_PREAMBLE_VHT);4604ret = ath11k_wmi_set_peer_param(ar, sta->addr,4605arvif->vdev_id,4606WMI_PEER_PARAM_FIXED_RATE,4607rate_code);4608if (ret)4609ath11k_warn(ar->ab,4610"failed to update STA %pM Fixed Rate %d: %d\n",4611sta->addr, rate_code, ret);46124613return ret;4614}46154616static int4617ath11k_mac_set_peer_he_fixed_rate(struct ath11k_vif *arvif,4618struct ieee80211_sta *sta,4619const struct cfg80211_bitrate_mask *mask,4620enum nl80211_band band)4621{4622struct ath11k *ar = arvif->ar;4623u8 he_rate, nss;4624u32 rate_code;4625int ret, i;46264627lockdep_assert_held(&ar->conf_mutex);46284629nss = 0;46304631for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {4632if (hweight16(mask->control[band].he_mcs[i]) == 1) {4633nss = i + 1;4634he_rate = ffs(mask->control[band].he_mcs[i]) - 1;4635}4636}46374638if (!nss) {4639ath11k_warn(ar->ab, "No single he fixed rate found to set for %pM",4640sta->addr);4641return -EINVAL;4642}46434644/* Avoid updating invalid nss as fixed rate */4645if (nss > sta->deflink.rx_nss)4646return -EINVAL;46474648ath11k_dbg(ar->ab, ATH11K_DBG_MAC,4649"setting fixed he rate for peer %pM, device will not switch to any other selected rates",4650sta->addr);46514652rate_code = ATH11K_HW_RATE_CODE(he_rate, nss - 1,4653WMI_RATE_PREAMBLE_HE);46544655ret = ath11k_wmi_set_peer_param(ar, sta->addr,4656arvif->vdev_id,4657WMI_PEER_PARAM_FIXED_RATE,4658rate_code);4659if (ret)4660ath11k_warn(ar->ab,4661"failed to update sta %pM fixed rate %d: %d\n",4662sta->addr, rate_code, ret);46634664return ret;4665}46664667static int4668ath11k_mac_set_peer_ht_fixed_rate(struct ath11k_vif *arvif,4669struct ieee80211_sta *sta,4670const struct cfg80211_bitrate_mask *mask,4671enum nl80211_band band)4672{4673struct ath11k *ar = arvif->ar;4674u8 ht_rate, nss = 0;4675u32 rate_code;4676int ret, i;46774678lockdep_assert_held(&ar->conf_mutex);46794680for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {4681if (hweight8(mask->control[band].ht_mcs[i]) == 1) {4682nss = i + 1;4683ht_rate = ffs(mask->control[band].ht_mcs[i]) - 1;4684}4685}46864687if (!nss) {4688ath11k_warn(ar->ab, "No single HT Fixed rate found to set for %pM",4689sta->addr);4690return -EINVAL;4691}46924693/* Avoid updating invalid nss as fixed rate*/4694if (nss > sta->deflink.rx_nss)4695return -EINVAL;46964697ath11k_dbg(ar->ab, ATH11K_DBG_MAC,4698"Setting Fixed HT Rate for peer %pM. Device will not switch to any other selected rates",4699sta->addr);47004701rate_code = ATH11K_HW_RATE_CODE(ht_rate, nss - 1,4702WMI_RATE_PREAMBLE_HT);4703ret = ath11k_wmi_set_peer_param(ar, sta->addr,4704arvif->vdev_id,4705WMI_PEER_PARAM_FIXED_RATE,4706rate_code);4707if (ret)4708ath11k_warn(ar->ab,4709"failed to update STA %pM HT Fixed Rate %d: %d\n",4710sta->addr, rate_code, ret);47114712return ret;4713}47144715static int ath11k_station_assoc(struct ath11k *ar,4716struct ieee80211_vif *vif,4717struct ieee80211_sta *sta,4718bool reassoc)4719{4720struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);4721struct peer_assoc_params peer_arg;4722int ret = 0;4723struct cfg80211_chan_def def;4724enum nl80211_band band;4725struct cfg80211_bitrate_mask *mask;4726u8 num_ht_rates, num_vht_rates, num_he_rates;47274728lockdep_assert_held(&ar->conf_mutex);47294730if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))4731return -EPERM;47324733band = def.chan->band;4734mask = &arvif->bitrate_mask;47354736ath11k_peer_assoc_prepare(ar, vif, sta, &peer_arg, reassoc);47374738peer_arg.is_assoc = true;4739ret = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg);4740if (ret) {4741ath11k_warn(ar->ab, "failed to run peer assoc for STA %pM vdev %i: %d\n",4742sta->addr, arvif->vdev_id, ret);4743return ret;4744}47454746if (!wait_for_completion_timeout(&ar->peer_assoc_done, 1 * HZ)) {4747ath11k_warn(ar->ab, "failed to get peer assoc conf event for %pM vdev %i\n",4748sta->addr, arvif->vdev_id);4749return -ETIMEDOUT;4750}47514752num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask);4753num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask);4754num_ht_rates = ath11k_mac_bitrate_mask_num_ht_rates(ar, band, mask);47554756/* If single VHT/HE rate is configured (by set_bitrate_mask()),4757* peer_assoc will disable VHT/HE. This is now enabled by a peer specific4758* fixed param.4759* Note that all other rates and NSS will be disabled for this peer.4760*/4761if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) {4762ret = ath11k_mac_set_peer_vht_fixed_rate(arvif, sta, mask,4763band);4764if (ret)4765return ret;4766} else if (sta->deflink.he_cap.has_he && num_he_rates == 1) {4767ret = ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask,4768band);4769if (ret)4770return ret;4771} else if (sta->deflink.ht_cap.ht_supported && num_ht_rates == 1) {4772ret = ath11k_mac_set_peer_ht_fixed_rate(arvif, sta, mask,4773band);4774if (ret)4775return ret;4776}47774778/* Re-assoc is run only to update supported rates for given station. It4779* doesn't make much sense to reconfigure the peer completely.4780*/4781if (reassoc)4782return 0;47834784ret = ath11k_setup_peer_smps(ar, arvif, sta->addr,4785&sta->deflink.ht_cap,4786le16_to_cpu(sta->deflink.he_6ghz_capa.capa));4787if (ret) {4788ath11k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n",4789arvif->vdev_id, ret);4790return ret;4791}47924793if (!sta->wme) {4794arvif->num_legacy_stations++;4795ret = ath11k_recalc_rtscts_prot(arvif);4796if (ret)4797return ret;4798}47994800if (sta->wme && sta->uapsd_queues) {4801ret = ath11k_peer_assoc_qos_ap(ar, arvif, sta);4802if (ret) {4803ath11k_warn(ar->ab, "failed to set qos params for STA %pM for vdev %i: %d\n",4804sta->addr, arvif->vdev_id, ret);4805return ret;4806}4807}48084809return 0;4810}48114812static int ath11k_station_disassoc(struct ath11k *ar,4813struct ieee80211_vif *vif,4814struct ieee80211_sta *sta)4815{4816struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);4817int ret = 0;48184819lockdep_assert_held(&ar->conf_mutex);48204821if (!sta->wme) {4822arvif->num_legacy_stations--;4823ret = ath11k_recalc_rtscts_prot(arvif);4824if (ret)4825return ret;4826}48274828ret = ath11k_clear_peer_keys(arvif, sta->addr);4829if (ret) {4830ath11k_warn(ar->ab, "failed to clear all peer keys for vdev %i: %d\n",4831arvif->vdev_id, ret);4832return ret;4833}4834return 0;4835}48364837static u32 ath11k_mac_max_nss(const u8 *ht_mcs_mask, const u16 *vht_mcs_mask,4838const u16 *he_mcs_mask)4839{4840return max3(ath11k_mac_max_ht_nss(ht_mcs_mask),4841ath11k_mac_max_vht_nss(vht_mcs_mask),4842ath11k_mac_max_he_nss(he_mcs_mask));4843}48444845static void ath11k_sta_rc_update_wk(struct work_struct *wk)4846{4847struct ath11k *ar;4848struct ath11k_vif *arvif;4849struct ath11k_sta *arsta;4850struct ieee80211_sta *sta;4851struct cfg80211_chan_def def;4852enum nl80211_band band;4853const u8 *ht_mcs_mask;4854const u16 *vht_mcs_mask;4855const u16 *he_mcs_mask;4856u32 changed, bw, nss, smps, bw_prev;4857int err, num_ht_rates, num_vht_rates, num_he_rates;4858const struct cfg80211_bitrate_mask *mask;4859struct peer_assoc_params peer_arg;4860enum wmi_phy_mode peer_phymode;48614862arsta = container_of(wk, struct ath11k_sta, update_wk);4863sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);4864arvif = arsta->arvif;4865ar = arvif->ar;48664867if (WARN_ON(ath11k_mac_vif_chan(arvif->vif, &def)))4868return;48694870band = def.chan->band;4871ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;4872vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;4873he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;48744875spin_lock_bh(&ar->data_lock);48764877changed = arsta->changed;4878arsta->changed = 0;48794880bw = arsta->bw;4881bw_prev = arsta->bw_prev;4882nss = arsta->nss;4883smps = arsta->smps;48844885spin_unlock_bh(&ar->data_lock);48864887mutex_lock(&ar->conf_mutex);48884889nss = max_t(u32, 1, nss);4890nss = min(nss, ath11k_mac_max_nss(ht_mcs_mask, vht_mcs_mask, he_mcs_mask));48914892if (changed & IEEE80211_RC_BW_CHANGED) {4893/* Get the peer phymode */4894ath11k_peer_assoc_h_phymode(ar, arvif->vif, sta, &peer_arg);4895peer_phymode = peer_arg.peer_phymode;48964897ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "update sta %pM peer bw %d phymode %d\n",4898sta->addr, bw, peer_phymode);48994900if (bw > bw_prev) {4901/* BW is upgraded. In this case we send WMI_PEER_PHYMODE4902* followed by WMI_PEER_CHWIDTH4903*/4904ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "BW upgrade for sta %pM new BW %d, old BW %d\n",4905sta->addr, bw, bw_prev);49064907err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,4908WMI_PEER_PHYMODE, peer_phymode);49094910if (err) {4911ath11k_warn(ar->ab, "failed to update STA %pM peer phymode %d: %d\n",4912sta->addr, peer_phymode, err);4913goto err_rc_bw_changed;4914}49154916err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,4917WMI_PEER_CHWIDTH, bw);49184919if (err)4920ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n",4921sta->addr, bw, err);4922} else {4923/* BW is downgraded. In this case we send WMI_PEER_CHWIDTH4924* followed by WMI_PEER_PHYMODE4925*/4926ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "BW downgrade for sta %pM new BW %d,old BW %d\n",4927sta->addr, bw, bw_prev);49284929err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,4930WMI_PEER_CHWIDTH, bw);49314932if (err) {4933ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n",4934sta->addr, bw, err);4935goto err_rc_bw_changed;4936}49374938err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,4939WMI_PEER_PHYMODE, peer_phymode);49404941if (err)4942ath11k_warn(ar->ab, "failed to update STA %pM peer phymode %d: %d\n",4943sta->addr, peer_phymode, err);4944}4945}49464947if (changed & IEEE80211_RC_NSS_CHANGED) {4948ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "update sta %pM nss %d\n",4949sta->addr, nss);49504951err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,4952WMI_PEER_NSS, nss);4953if (err)4954ath11k_warn(ar->ab, "failed to update STA %pM nss %d: %d\n",4955sta->addr, nss, err);4956}49574958if (changed & IEEE80211_RC_SMPS_CHANGED) {4959ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "update sta %pM smps %d\n",4960sta->addr, smps);49614962err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,4963WMI_PEER_MIMO_PS_STATE, smps);4964if (err)4965ath11k_warn(ar->ab, "failed to update STA %pM smps %d: %d\n",4966sta->addr, smps, err);4967}49684969if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {4970mask = &arvif->bitrate_mask;4971num_ht_rates = ath11k_mac_bitrate_mask_num_ht_rates(ar, band,4972mask);4973num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band,4974mask);4975num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band,4976mask);49774978/* Peer_assoc_prepare will reject vht rates in4979* bitrate_mask if its not available in range format and4980* sets vht tx_rateset as unsupported. So multiple VHT MCS4981* setting(eg. MCS 4,5,6) per peer is not supported here.4982* But, Single rate in VHT mask can be set as per-peer4983* fixed rate. But even if any HT rates are configured in4984* the bitrate mask, device will not switch to those rates4985* when per-peer Fixed rate is set.4986* TODO: Check RATEMASK_CMDID to support auto rates selection4987* across HT/VHT and for multiple VHT MCS support.4988*/4989if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) {4990ath11k_mac_set_peer_vht_fixed_rate(arvif, sta, mask,4991band);4992} else if (sta->deflink.he_cap.has_he && num_he_rates == 1) {4993ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask,4994band);4995} else if (sta->deflink.ht_cap.ht_supported && num_ht_rates == 1) {4996ath11k_mac_set_peer_ht_fixed_rate(arvif, sta, mask,4997band);4998} else {4999/* If the peer is non-VHT/HE or no fixed VHT/HE rate5000* is provided in the new bitrate mask we set the5001* other rates using peer_assoc command. Also clear5002* the peer fixed rate settings as it has higher proprity5003* than peer assoc5004*/5005err = ath11k_wmi_set_peer_param(ar, sta->addr,5006arvif->vdev_id,5007WMI_PEER_PARAM_FIXED_RATE,5008WMI_FIXED_RATE_NONE);5009if (err)5010ath11k_warn(ar->ab,5011"failed to disable peer fixed rate for sta %pM: %d\n",5012sta->addr, err);50135014ath11k_peer_assoc_prepare(ar, arvif->vif, sta,5015&peer_arg, true);50165017peer_arg.is_assoc = false;5018err = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg);5019if (err)5020ath11k_warn(ar->ab, "failed to run peer assoc for STA %pM vdev %i: %d\n",5021sta->addr, arvif->vdev_id, err);50225023if (!wait_for_completion_timeout(&ar->peer_assoc_done, 1 * HZ))5024ath11k_warn(ar->ab, "failed to get peer assoc conf event for %pM vdev %i\n",5025sta->addr, arvif->vdev_id);5026}5027}50285029err_rc_bw_changed:5030mutex_unlock(&ar->conf_mutex);5031}50325033static void ath11k_sta_set_4addr_wk(struct work_struct *wk)5034{5035struct ath11k *ar;5036struct ath11k_vif *arvif;5037struct ath11k_sta *arsta;5038struct ieee80211_sta *sta;5039int ret = 0;50405041arsta = container_of(wk, struct ath11k_sta, set_4addr_wk);5042sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);5043arvif = arsta->arvif;5044ar = arvif->ar;50455046ath11k_dbg(ar->ab, ATH11K_DBG_MAC,5047"setting USE_4ADDR for peer %pM\n", sta->addr);50485049ret = ath11k_wmi_set_peer_param(ar, sta->addr,5050arvif->vdev_id,5051WMI_PEER_USE_4ADDR, 1);50525053if (ret)5054ath11k_warn(ar->ab, "failed to set peer %pM 4addr capability: %d\n",5055sta->addr, ret);5056}50575058static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif,5059struct ieee80211_sta *sta)5060{5061struct ath11k *ar = arvif->ar;50625063lockdep_assert_held(&ar->conf_mutex);50645065if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)5066return 0;50675068if (ar->num_stations >= ar->max_num_stations)5069return -ENOBUFS;50705071ar->num_stations++;5072arvif->num_stations++;50735074return 0;5075}50765077static void ath11k_mac_dec_num_stations(struct ath11k_vif *arvif,5078struct ieee80211_sta *sta)5079{5080struct ath11k *ar = arvif->ar;50815082lockdep_assert_held(&ar->conf_mutex);50835084if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)5085return;50865087ar->num_stations--;5088arvif->num_stations--;5089}50905091static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar,5092struct ieee80211_sta *sta)5093{5094u32 bw = WMI_PEER_CHWIDTH_20MHZ;50955096switch (sta->deflink.bandwidth) {5097case IEEE80211_STA_RX_BW_20:5098bw = WMI_PEER_CHWIDTH_20MHZ;5099break;5100case IEEE80211_STA_RX_BW_40:5101bw = WMI_PEER_CHWIDTH_40MHZ;5102break;5103case IEEE80211_STA_RX_BW_80:5104bw = WMI_PEER_CHWIDTH_80MHZ;5105break;5106case IEEE80211_STA_RX_BW_160:5107bw = WMI_PEER_CHWIDTH_160MHZ;5108break;5109default:5110ath11k_warn(ar->ab, "Invalid bandwidth %d for %pM\n",5111sta->deflink.bandwidth, sta->addr);5112bw = WMI_PEER_CHWIDTH_20MHZ;5113break;5114}51155116return bw;5117}51185119static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw,5120struct ieee80211_vif *vif,5121struct ieee80211_sta *sta)5122{5123struct ath11k *ar = hw->priv;5124struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);5125int ret = 0;5126s16 txpwr;51275128if (sta->deflink.txpwr.type == NL80211_TX_POWER_AUTOMATIC) {5129txpwr = 0;5130} else {5131txpwr = sta->deflink.txpwr.power;5132if (!txpwr)5133return -EINVAL;5134}51355136if (txpwr > ATH11K_TX_POWER_MAX_VAL || txpwr < ATH11K_TX_POWER_MIN_VAL)5137return -EINVAL;51385139mutex_lock(&ar->conf_mutex);51405141ret = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,5142WMI_PEER_USE_FIXED_PWR, txpwr);5143if (ret) {5144ath11k_warn(ar->ab, "failed to set tx power for station ret: %d\n",5145ret);5146goto out;5147}51485149out:5150mutex_unlock(&ar->conf_mutex);5151return ret;5152}51535154static void ath11k_mac_op_sta_set_4addr(struct ieee80211_hw *hw,5155struct ieee80211_vif *vif,5156struct ieee80211_sta *sta, bool enabled)5157{5158struct ath11k *ar = hw->priv;5159struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);51605161if (enabled && !arsta->use_4addr_set) {5162ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk);5163arsta->use_4addr_set = true;5164}5165}51665167static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw,5168struct ieee80211_vif *vif,5169struct ieee80211_link_sta *link_sta,5170u32 changed)5171{5172struct ieee80211_sta *sta = link_sta->sta;5173struct ath11k *ar = hw->priv;5174struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);5175struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);5176struct ath11k_peer *peer;5177u32 bw, smps;51785179spin_lock_bh(&ar->ab->base_lock);51805181peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);5182if (!peer) {5183spin_unlock_bh(&ar->ab->base_lock);5184ath11k_warn(ar->ab, "mac sta rc update failed to find peer %pM on vdev %i\n",5185sta->addr, arvif->vdev_id);5186return;5187}51885189spin_unlock_bh(&ar->ab->base_lock);51905191ath11k_dbg(ar->ab, ATH11K_DBG_MAC,5192"sta rc update for %pM changed %08x bw %d nss %d smps %d\n",5193sta->addr, changed, sta->deflink.bandwidth,5194sta->deflink.rx_nss,5195sta->deflink.smps_mode);51965197spin_lock_bh(&ar->data_lock);51985199if (changed & IEEE80211_RC_BW_CHANGED) {5200bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta);5201arsta->bw_prev = arsta->bw;5202arsta->bw = bw;5203}52045205if (changed & IEEE80211_RC_NSS_CHANGED)5206arsta->nss = sta->deflink.rx_nss;52075208if (changed & IEEE80211_RC_SMPS_CHANGED) {5209smps = WMI_PEER_SMPS_PS_NONE;52105211switch (sta->deflink.smps_mode) {5212case IEEE80211_SMPS_AUTOMATIC:5213case IEEE80211_SMPS_OFF:5214smps = WMI_PEER_SMPS_PS_NONE;5215break;5216case IEEE80211_SMPS_STATIC:5217smps = WMI_PEER_SMPS_STATIC;5218break;5219case IEEE80211_SMPS_DYNAMIC:5220smps = WMI_PEER_SMPS_DYNAMIC;5221break;5222default:5223ath11k_warn(ar->ab, "Invalid smps %d in sta rc update for %pM\n",5224sta->deflink.smps_mode, sta->addr);5225smps = WMI_PEER_SMPS_PS_NONE;5226break;5227}52285229arsta->smps = smps;5230}52315232arsta->changed |= changed;52335234spin_unlock_bh(&ar->data_lock);52355236ieee80211_queue_work(hw, &arsta->update_wk);5237}52385239static int ath11k_conf_tx_uapsd(struct ath11k *ar, struct ieee80211_vif *vif,5240u16 ac, bool enable)5241{5242struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);5243u32 value = 0;5244int ret = 0;52455246if (arvif->vdev_type != WMI_VDEV_TYPE_STA)5247return 0;52485249switch (ac) {5250case IEEE80211_AC_VO:5251value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |5252WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;5253break;5254case IEEE80211_AC_VI:5255value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |5256WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;5257break;5258case IEEE80211_AC_BE:5259value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |5260WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;5261break;5262case IEEE80211_AC_BK:5263value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |5264WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;5265break;5266}52675268if (enable)5269arvif->u.sta.uapsd |= value;5270else5271arvif->u.sta.uapsd &= ~value;52725273ret = ath11k_wmi_set_sta_ps_param(ar, arvif->vdev_id,5274WMI_STA_PS_PARAM_UAPSD,5275arvif->u.sta.uapsd);5276if (ret) {5277ath11k_warn(ar->ab, "could not set uapsd params %d\n", ret);5278goto exit;5279}52805281if (arvif->u.sta.uapsd)5282value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;5283else5284value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;52855286ret = ath11k_wmi_set_sta_ps_param(ar, arvif->vdev_id,5287WMI_STA_PS_PARAM_RX_WAKE_POLICY,5288value);5289if (ret)5290ath11k_warn(ar->ab, "could not set rx wake param %d\n", ret);52915292exit:5293return ret;5294}52955296static int ath11k_mac_op_conf_tx_mu_edca(struct ieee80211_hw *hw,5297struct ieee80211_vif *vif,5298unsigned int link_id, u16 ac,5299const struct ieee80211_tx_queue_params *params)5300{5301struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);5302struct ath11k *ar = hw->priv;5303struct wmi_wmm_params_arg *p;5304int ret;53055306switch (ac) {5307case IEEE80211_AC_VO:5308p = &arvif->muedca_params.ac_vo;5309break;5310case IEEE80211_AC_VI:5311p = &arvif->muedca_params.ac_vi;5312break;5313case IEEE80211_AC_BE:5314p = &arvif->muedca_params.ac_be;5315break;5316case IEEE80211_AC_BK:5317p = &arvif->muedca_params.ac_bk;5318break;5319default:5320ath11k_warn(ar->ab, "error ac: %d", ac);5321return -EINVAL;5322}53235324p->cwmin = u8_get_bits(params->mu_edca_param_rec.ecw_min_max, GENMASK(3, 0));5325p->cwmax = u8_get_bits(params->mu_edca_param_rec.ecw_min_max, GENMASK(7, 4));5326p->aifs = u8_get_bits(params->mu_edca_param_rec.aifsn, GENMASK(3, 0));5327p->txop = params->mu_edca_param_rec.mu_edca_timer;53285329ret = ath11k_wmi_send_wmm_update_cmd_tlv(ar, arvif->vdev_id,5330&arvif->muedca_params,5331WMI_WMM_PARAM_TYPE_11AX_MU_EDCA);5332return ret;5333}53345335static int ath11k_mac_op_conf_tx(struct ieee80211_hw *hw,5336struct ieee80211_vif *vif,5337unsigned int link_id, u16 ac,5338const struct ieee80211_tx_queue_params *params)5339{5340struct ath11k *ar = hw->priv;5341struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);5342struct wmi_wmm_params_arg *p = NULL;5343int ret;53445345mutex_lock(&ar->conf_mutex);53465347switch (ac) {5348case IEEE80211_AC_VO:5349p = &arvif->wmm_params.ac_vo;5350break;5351case IEEE80211_AC_VI:5352p = &arvif->wmm_params.ac_vi;5353break;5354case IEEE80211_AC_BE:5355p = &arvif->wmm_params.ac_be;5356break;5357case IEEE80211_AC_BK:5358p = &arvif->wmm_params.ac_bk;5359break;5360}53615362if (WARN_ON(!p)) {5363ret = -EINVAL;5364goto exit;5365}53665367p->cwmin = params->cw_min;5368p->cwmax = params->cw_max;5369p->aifs = params->aifs;5370p->txop = params->txop;53715372ret = ath11k_wmi_send_wmm_update_cmd_tlv(ar, arvif->vdev_id,5373&arvif->wmm_params,5374WMI_WMM_PARAM_TYPE_LEGACY);5375if (ret) {5376ath11k_warn(ar->ab, "failed to set wmm params: %d\n", ret);5377goto exit;5378}53795380if (params->mu_edca) {5381ret = ath11k_mac_op_conf_tx_mu_edca(hw, vif, link_id, ac,5382params);5383if (ret) {5384ath11k_warn(ar->ab, "failed to set mu_edca params: %d\n", ret);5385goto exit;5386}5387}53885389ret = ath11k_conf_tx_uapsd(ar, vif, ac, params->uapsd);53905391if (ret)5392ath11k_warn(ar->ab, "failed to set sta uapsd: %d\n", ret);53935394exit:5395mutex_unlock(&ar->conf_mutex);5396return ret;5397}53985399static struct ieee80211_sta_ht_cap5400ath11k_create_ht_cap(struct ath11k *ar, u32 ar_ht_cap, u32 rate_cap_rx_chainmask)5401{5402int i;5403struct ieee80211_sta_ht_cap ht_cap = {};5404u32 ar_vht_cap = ar->pdev->cap.vht_cap;54055406if (!(ar_ht_cap & WMI_HT_CAP_ENABLED))5407return ht_cap;54085409ht_cap.ht_supported = 1;5410ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;5411ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;5412ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;5413ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;5414ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT;54155416if (ar_ht_cap & WMI_HT_CAP_HT20_SGI)5417ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;54185419if (ar_ht_cap & WMI_HT_CAP_HT40_SGI)5420ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;54215422if (ar_ht_cap & WMI_HT_CAP_DYNAMIC_SMPS) {5423u32 smps;54245425smps = WLAN_HT_CAP_SM_PS_DYNAMIC;5426smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;54275428ht_cap.cap |= smps;5429}54305431if (ar_ht_cap & WMI_HT_CAP_TX_STBC)5432ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;54335434if (ar_ht_cap & WMI_HT_CAP_RX_STBC) {5435u32 stbc;54365437stbc = ar_ht_cap;5438stbc &= WMI_HT_CAP_RX_STBC;5439stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;5440stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;5441stbc &= IEEE80211_HT_CAP_RX_STBC;54425443ht_cap.cap |= stbc;5444}54455446if (ar_ht_cap & WMI_HT_CAP_RX_LDPC)5447ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;54485449if (ar_ht_cap & WMI_HT_CAP_L_SIG_TXOP_PROT)5450ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;54515452if (ar_vht_cap & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)5453ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;54545455for (i = 0; i < ar->num_rx_chains; i++) {5456if (rate_cap_rx_chainmask & BIT(i))5457ht_cap.mcs.rx_mask[i] = 0xFF;5458}54595460ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;54615462return ht_cap;5463}54645465static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif)5466{5467u32 value = 0;5468struct ath11k *ar = arvif->ar;5469int nsts;5470int sound_dim;5471u32 vht_cap = ar->pdev->cap.vht_cap;5472u32 vdev_param = WMI_VDEV_PARAM_TXBF;54735474if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) {5475nsts = vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;5476nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;5477value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);5478}54795480if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {5481sound_dim = vht_cap &5482IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;5483sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;5484if (sound_dim > (ar->num_tx_chains - 1))5485sound_dim = ar->num_tx_chains - 1;5486value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);5487}54885489if (!value)5490return 0;54915492if (vht_cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) {5493value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;54945495if ((vht_cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) &&5496arvif->vdev_type == WMI_VDEV_TYPE_AP)5497value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;5498}54995500/* TODO: SUBFEE not validated in HK, disable here until validated? */55015502if (vht_cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) {5503value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;55045505if ((vht_cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) &&5506arvif->vdev_type == WMI_VDEV_TYPE_STA)5507value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;5508}55095510return ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,5511vdev_param, value);5512}55135514static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap)5515{5516bool subfer, subfee;5517int sound_dim = 0, nsts = 0;55185519subfer = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE));5520subfee = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE));55215522if (ar->num_tx_chains < 2) {5523*vht_cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);5524subfer = false;5525}55265527if (ar->num_rx_chains < 2) {5528*vht_cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);5529subfee = false;5530}55315532/* If SU Beaformer is not set, then disable MU Beamformer Capability */5533if (!subfer)5534*vht_cap &= ~(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);55355536/* If SU Beaformee is not set, then disable MU Beamformee Capability */5537if (!subfee)5538*vht_cap &= ~(IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);55395540sound_dim = (*vht_cap & IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK);5541sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;5542*vht_cap &= ~IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;55435544nsts = (*vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK);5545nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;5546*vht_cap &= ~IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;55475548/* Enable Sounding Dimension Field only if SU BF is enabled */5549if (subfer) {5550if (sound_dim > (ar->num_tx_chains - 1))5551sound_dim = ar->num_tx_chains - 1;55525553sound_dim <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;5554sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;5555*vht_cap |= sound_dim;5556}55575558/* Enable Beamformee STS Field only if SU BF is enabled */5559if (subfee) {5560nsts <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;5561nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;5562*vht_cap |= nsts;5563}5564}55655566static struct ieee80211_sta_vht_cap5567ath11k_create_vht_cap(struct ath11k *ar, u32 rate_cap_tx_chainmask,5568u32 rate_cap_rx_chainmask)5569{5570struct ieee80211_sta_vht_cap vht_cap = {};5571u16 txmcs_map, rxmcs_map;5572int i;55735574vht_cap.vht_supported = 1;5575vht_cap.cap = ar->pdev->cap.vht_cap;55765577if (ar->pdev->cap.nss_ratio_enabled)5578vht_cap.vht_mcs.tx_highest |=5579cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);55805581ath11k_set_vht_txbf_cap(ar, &vht_cap.cap);55825583rxmcs_map = 0;5584txmcs_map = 0;5585for (i = 0; i < 8; i++) {5586if (i < ar->num_tx_chains && rate_cap_tx_chainmask & BIT(i))5587txmcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);5588else5589txmcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);55905591if (i < ar->num_rx_chains && rate_cap_rx_chainmask & BIT(i))5592rxmcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);5593else5594rxmcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);5595}55965597if (rate_cap_tx_chainmask <= 1)5598vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;55995600vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(rxmcs_map);5601vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(txmcs_map);56025603return vht_cap;5604}56055606static void ath11k_mac_setup_ht_vht_cap(struct ath11k *ar,5607struct ath11k_pdev_cap *cap,5608u32 *ht_cap_info)5609{5610struct ieee80211_supported_band *band;5611u32 rate_cap_tx_chainmask;5612u32 rate_cap_rx_chainmask;5613u32 ht_cap;56145615rate_cap_tx_chainmask = ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift;5616rate_cap_rx_chainmask = ar->cfg_rx_chainmask >> cap->rx_chain_mask_shift;56175618if (cap->supported_bands & WMI_HOST_WLAN_2G_CAP) {5619band = &ar->mac.sbands[NL80211_BAND_2GHZ];5620ht_cap = cap->band[NL80211_BAND_2GHZ].ht_cap_info;5621if (ht_cap_info)5622*ht_cap_info = ht_cap;5623band->ht_cap = ath11k_create_ht_cap(ar, ht_cap,5624rate_cap_rx_chainmask);5625}56265627if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&5628(ar->ab->hw_params.single_pdev_only ||5629!ar->supports_6ghz)) {5630band = &ar->mac.sbands[NL80211_BAND_5GHZ];5631ht_cap = cap->band[NL80211_BAND_5GHZ].ht_cap_info;5632if (ht_cap_info)5633*ht_cap_info = ht_cap;5634band->ht_cap = ath11k_create_ht_cap(ar, ht_cap,5635rate_cap_rx_chainmask);5636band->vht_cap = ath11k_create_vht_cap(ar, rate_cap_tx_chainmask,5637rate_cap_rx_chainmask);5638}5639}56405641static int ath11k_check_chain_mask(struct ath11k *ar, u32 ant, bool is_tx_ant)5642{5643/* TODO: Check the request chainmask against the supported5644* chainmask table which is advertised in extented_service_ready event5645*/56465647return 0;5648}56495650static void ath11k_gen_ppe_thresh(struct ath11k_ppe_threshold *fw_ppet,5651u8 *he_ppet)5652{5653int nss, ru;5654u8 bit = 7;56555656he_ppet[0] = fw_ppet->numss_m1 & IEEE80211_PPE_THRES_NSS_MASK;5657he_ppet[0] |= (fw_ppet->ru_bit_mask <<5658IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS) &5659IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK;5660for (nss = 0; nss <= fw_ppet->numss_m1; nss++) {5661for (ru = 0; ru < 4; ru++) {5662u8 val;5663int i;56645665if ((fw_ppet->ru_bit_mask & BIT(ru)) == 0)5666continue;5667val = (fw_ppet->ppet16_ppet8_ru3_ru0[nss] >> (ru * 6)) &56680x3f;5669val = ((val >> 3) & 0x7) | ((val & 0x7) << 3);5670for (i = 5; i >= 0; i--) {5671he_ppet[bit / 8] |=5672((val >> i) & 0x1) << ((bit % 8));5673bit++;5674}5675}5676}5677}56785679static void5680ath11k_mac_filter_he_cap_mesh(struct ieee80211_he_cap_elem *he_cap_elem)5681{5682u8 m;56835684m = IEEE80211_HE_MAC_CAP0_TWT_RES |5685IEEE80211_HE_MAC_CAP0_TWT_REQ;5686he_cap_elem->mac_cap_info[0] &= ~m;56875688m = IEEE80211_HE_MAC_CAP2_TRS |5689IEEE80211_HE_MAC_CAP2_BCAST_TWT |5690IEEE80211_HE_MAC_CAP2_MU_CASCADING;5691he_cap_elem->mac_cap_info[2] &= ~m;56925693m = IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED |5694IEEE80211_HE_MAC_CAP2_BCAST_TWT |5695IEEE80211_HE_MAC_CAP2_MU_CASCADING;5696he_cap_elem->mac_cap_info[3] &= ~m;56975698m = IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG |5699IEEE80211_HE_MAC_CAP4_BQR;5700he_cap_elem->mac_cap_info[4] &= ~m;57015702m = IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION |5703IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU |5704IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING |5705IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX;5706he_cap_elem->mac_cap_info[5] &= ~m;57075708m = IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |5709IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;5710he_cap_elem->phy_cap_info[2] &= ~m;57115712m = IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU |5713IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK |5714IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK;5715he_cap_elem->phy_cap_info[3] &= ~m;57165717m = IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;5718he_cap_elem->phy_cap_info[4] &= ~m;57195720m = IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK;5721he_cap_elem->phy_cap_info[5] &= ~m;57225723m = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |5724IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB |5725IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |5726IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO;5727he_cap_elem->phy_cap_info[6] &= ~m;57285729m = IEEE80211_HE_PHY_CAP7_PSR_BASED_SR |5730IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |5731IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ |5732IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ;5733he_cap_elem->phy_cap_info[7] &= ~m;57345735m = IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |5736IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |5737IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |5738IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU;5739he_cap_elem->phy_cap_info[8] &= ~m;57405741m = IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM |5742IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |5743IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU |5744IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |5745IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |5746IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;5747he_cap_elem->phy_cap_info[9] &= ~m;5748}57495750static __le16 ath11k_mac_setup_he_6ghz_cap(struct ath11k_pdev_cap *pcap,5751struct ath11k_band_cap *bcap)5752{5753u8 val;57545755bcap->he_6ghz_capa = IEEE80211_HT_MPDU_DENSITY_NONE;5756if (bcap->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)5757bcap->he_6ghz_capa |=5758FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS,5759WLAN_HT_CAP_SM_PS_DYNAMIC);5760else5761bcap->he_6ghz_capa |=5762FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS,5763WLAN_HT_CAP_SM_PS_DISABLED);5764val = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,5765pcap->vht_cap);5766bcap->he_6ghz_capa |=5767FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP, val);5768val = FIELD_GET(IEEE80211_VHT_CAP_MAX_MPDU_MASK, pcap->vht_cap);5769bcap->he_6ghz_capa |=5770FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN, val);5771if (pcap->vht_cap & IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN)5772bcap->he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;5773if (pcap->vht_cap & IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN)5774bcap->he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS;57755776return cpu_to_le16(bcap->he_6ghz_capa);5777}57785779static void ath11k_mac_set_hemcsmap(struct ath11k *ar,5780struct ath11k_pdev_cap *cap,5781struct ieee80211_sta_he_cap *he_cap,5782int band)5783{5784u16 txmcs_map, rxmcs_map;5785u32 i;57865787rxmcs_map = 0;5788txmcs_map = 0;5789for (i = 0; i < 8; i++) {5790if (i < ar->num_tx_chains &&5791(ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))5792txmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);5793else5794txmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);57955796if (i < ar->num_rx_chains &&5797(ar->cfg_rx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))5798rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);5799else5800rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);5801}5802he_cap->he_mcs_nss_supp.rx_mcs_80 =5803cpu_to_le16(rxmcs_map & 0xffff);5804he_cap->he_mcs_nss_supp.tx_mcs_80 =5805cpu_to_le16(txmcs_map & 0xffff);5806he_cap->he_mcs_nss_supp.rx_mcs_160 =5807cpu_to_le16(rxmcs_map & 0xffff);5808he_cap->he_mcs_nss_supp.tx_mcs_160 =5809cpu_to_le16(txmcs_map & 0xffff);5810he_cap->he_mcs_nss_supp.rx_mcs_80p80 =5811cpu_to_le16(rxmcs_map & 0xffff);5812he_cap->he_mcs_nss_supp.tx_mcs_80p80 =5813cpu_to_le16(txmcs_map & 0xffff);5814}58155816static int ath11k_mac_copy_he_cap(struct ath11k *ar,5817struct ath11k_pdev_cap *cap,5818struct ieee80211_sband_iftype_data *data,5819int band)5820{5821int i, idx = 0;58225823for (i = 0; i < NUM_NL80211_IFTYPES; i++) {5824struct ieee80211_sta_he_cap *he_cap = &data[idx].he_cap;5825struct ath11k_band_cap *band_cap = &cap->band[band];5826struct ieee80211_he_cap_elem *he_cap_elem =5827&he_cap->he_cap_elem;58285829switch (i) {5830case NL80211_IFTYPE_STATION:5831case NL80211_IFTYPE_AP:5832case NL80211_IFTYPE_MESH_POINT:5833break;58345835default:5836continue;5837}58385839data[idx].types_mask = BIT(i);5840he_cap->has_he = true;5841memcpy(he_cap_elem->mac_cap_info, band_cap->he_cap_info,5842sizeof(he_cap_elem->mac_cap_info));5843memcpy(he_cap_elem->phy_cap_info, band_cap->he_cap_phy_info,5844sizeof(he_cap_elem->phy_cap_info));58455846he_cap_elem->mac_cap_info[1] &=5847IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK;58485849he_cap_elem->phy_cap_info[5] &=5850~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK;5851he_cap_elem->phy_cap_info[5] |= ar->num_tx_chains - 1;58525853switch (i) {5854case NL80211_IFTYPE_AP:5855he_cap_elem->phy_cap_info[3] &=5856~IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK;5857he_cap_elem->phy_cap_info[9] |=5858IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;5859break;5860case NL80211_IFTYPE_STATION:5861he_cap_elem->mac_cap_info[0] &=5862~IEEE80211_HE_MAC_CAP0_TWT_RES;5863he_cap_elem->mac_cap_info[0] |=5864IEEE80211_HE_MAC_CAP0_TWT_REQ;5865he_cap_elem->phy_cap_info[9] |=5866IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU;5867break;5868case NL80211_IFTYPE_MESH_POINT:5869ath11k_mac_filter_he_cap_mesh(he_cap_elem);5870break;5871}58725873ath11k_mac_set_hemcsmap(ar, cap, he_cap, band);58745875memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));5876if (he_cap_elem->phy_cap_info[6] &5877IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT)5878ath11k_gen_ppe_thresh(&band_cap->he_ppet,5879he_cap->ppe_thres);58805881if (band == NL80211_BAND_6GHZ) {5882data[idx].he_6ghz_capa.capa =5883ath11k_mac_setup_he_6ghz_cap(cap, band_cap);5884}5885idx++;5886}58875888return idx;5889}58905891static void ath11k_mac_setup_he_cap(struct ath11k *ar,5892struct ath11k_pdev_cap *cap)5893{5894struct ieee80211_supported_band *band;5895int count;58965897if (cap->supported_bands & WMI_HOST_WLAN_2G_CAP) {5898count = ath11k_mac_copy_he_cap(ar, cap,5899ar->mac.iftype[NL80211_BAND_2GHZ],5900NL80211_BAND_2GHZ);5901band = &ar->mac.sbands[NL80211_BAND_2GHZ];5902_ieee80211_set_sband_iftype_data(band,5903ar->mac.iftype[NL80211_BAND_2GHZ],5904count);5905}59065907if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) {5908count = ath11k_mac_copy_he_cap(ar, cap,5909ar->mac.iftype[NL80211_BAND_5GHZ],5910NL80211_BAND_5GHZ);5911band = &ar->mac.sbands[NL80211_BAND_5GHZ];5912_ieee80211_set_sband_iftype_data(band,5913ar->mac.iftype[NL80211_BAND_5GHZ],5914count);5915}59165917if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&5918ar->supports_6ghz) {5919count = ath11k_mac_copy_he_cap(ar, cap,5920ar->mac.iftype[NL80211_BAND_6GHZ],5921NL80211_BAND_6GHZ);5922band = &ar->mac.sbands[NL80211_BAND_6GHZ];5923_ieee80211_set_sband_iftype_data(band,5924ar->mac.iftype[NL80211_BAND_6GHZ],5925count);5926}5927}59285929static int __ath11k_set_antenna(struct ath11k *ar, u32 tx_ant, u32 rx_ant)5930{5931int ret;59325933lockdep_assert_held(&ar->conf_mutex);59345935if (ath11k_check_chain_mask(ar, tx_ant, true))5936return -EINVAL;59375938if (ath11k_check_chain_mask(ar, rx_ant, false))5939return -EINVAL;59405941ar->cfg_tx_chainmask = tx_ant;5942ar->cfg_rx_chainmask = rx_ant;59435944if (ar->state != ATH11K_STATE_ON &&5945ar->state != ATH11K_STATE_RESTARTED)5946return 0;59475948ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_TX_CHAIN_MASK,5949tx_ant, ar->pdev->pdev_id);5950if (ret) {5951ath11k_warn(ar->ab, "failed to set tx-chainmask: %d, req 0x%x\n",5952ret, tx_ant);5953return ret;5954}59555956ar->num_tx_chains = get_num_chains(tx_ant);59575958ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_RX_CHAIN_MASK,5959rx_ant, ar->pdev->pdev_id);5960if (ret) {5961ath11k_warn(ar->ab, "failed to set rx-chainmask: %d, req 0x%x\n",5962ret, rx_ant);5963return ret;5964}59655966ar->num_rx_chains = get_num_chains(rx_ant);59675968/* Reload HT/VHT/HE capability */5969ath11k_mac_setup_ht_vht_cap(ar, &ar->pdev->cap, NULL);5970ath11k_mac_setup_he_cap(ar, &ar->pdev->cap);59715972return 0;5973}59745975static void ath11k_mgmt_over_wmi_tx_drop(struct ath11k *ar, struct sk_buff *skb)5976{5977int num_mgmt;59785979ieee80211_free_txskb(ar->hw, skb);59805981num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx);59825983if (num_mgmt < 0)5984WARN_ON_ONCE(1);59855986if (!num_mgmt)5987wake_up(&ar->txmgmt_empty_waitq);5988}59895990static void ath11k_mac_tx_mgmt_free(struct ath11k *ar, int buf_id)5991{5992struct sk_buff *msdu;5993struct ieee80211_tx_info *info;59945995spin_lock_bh(&ar->txmgmt_idr_lock);5996msdu = idr_remove(&ar->txmgmt_idr, buf_id);5997spin_unlock_bh(&ar->txmgmt_idr_lock);59985999if (!msdu)6000return;60016002dma_unmap_single(ar->ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len,6003DMA_TO_DEVICE);60046005info = IEEE80211_SKB_CB(msdu);6006memset(&info->status, 0, sizeof(info->status));60076008ath11k_mgmt_over_wmi_tx_drop(ar, msdu);6009}60106011int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx)6012{6013struct ath11k *ar = ctx;60146015ath11k_mac_tx_mgmt_free(ar, buf_id);60166017return 0;6018}60196020static int ath11k_mac_vif_txmgmt_idr_remove(int buf_id, void *skb, void *ctx)6021{6022struct ieee80211_vif *vif = ctx;6023struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB((struct sk_buff *)skb);6024struct ath11k *ar = skb_cb->ar;60256026if (skb_cb->vif == vif)6027ath11k_mac_tx_mgmt_free(ar, buf_id);60286029return 0;6030}60316032static int ath11k_mac_mgmt_tx_wmi(struct ath11k *ar, struct ath11k_vif *arvif,6033struct sk_buff *skb)6034{6035struct ath11k_base *ab = ar->ab;6036struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;6037struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);6038struct ieee80211_tx_info *info;6039enum hal_encrypt_type enctype;6040unsigned int mic_len;6041dma_addr_t paddr;6042int buf_id;6043int ret;60446045ATH11K_SKB_CB(skb)->ar = ar;60466047spin_lock_bh(&ar->txmgmt_idr_lock);6048buf_id = idr_alloc(&ar->txmgmt_idr, skb, 0,6049ATH11K_TX_MGMT_NUM_PENDING_MAX, GFP_ATOMIC);6050spin_unlock_bh(&ar->txmgmt_idr_lock);60516052ath11k_dbg(ar->ab, ATH11K_DBG_MAC,6053"tx mgmt frame, buf id %d\n", buf_id);60546055if (buf_id < 0)6056return -ENOSPC;60576058info = IEEE80211_SKB_CB(skb);6059if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) {6060if ((ieee80211_is_action(hdr->frame_control) ||6061ieee80211_is_deauth(hdr->frame_control) ||6062ieee80211_is_disassoc(hdr->frame_control)) &&6063ieee80211_has_protected(hdr->frame_control)) {6064if (!(skb_cb->flags & ATH11K_SKB_CIPHER_SET))6065ath11k_warn(ab, "WMI management tx frame without ATH11K_SKB_CIPHER_SET");60666067enctype = ath11k_dp_tx_get_encrypt_type(skb_cb->cipher);6068mic_len = ath11k_dp_rx_crypto_mic_len(ar, enctype);6069skb_put(skb, mic_len);6070}6071}60726073paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);6074if (dma_mapping_error(ab->dev, paddr)) {6075ath11k_warn(ab, "failed to DMA map mgmt Tx buffer\n");6076ret = -EIO;6077goto err_free_idr;6078}60796080ATH11K_SKB_CB(skb)->paddr = paddr;60816082ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb);6083if (ret) {6084ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret);6085goto err_unmap_buf;6086}60876088return 0;60896090err_unmap_buf:6091dma_unmap_single(ab->dev, ATH11K_SKB_CB(skb)->paddr,6092skb->len, DMA_TO_DEVICE);6093err_free_idr:6094spin_lock_bh(&ar->txmgmt_idr_lock);6095idr_remove(&ar->txmgmt_idr, buf_id);6096spin_unlock_bh(&ar->txmgmt_idr_lock);60976098return ret;6099}61006101static void ath11k_mgmt_over_wmi_tx_purge(struct ath11k *ar)6102{6103struct sk_buff *skb;61046105while ((skb = skb_dequeue(&ar->wmi_mgmt_tx_queue)) != NULL)6106ath11k_mgmt_over_wmi_tx_drop(ar, skb);6107}61086109static void ath11k_mgmt_over_wmi_tx_work(struct work_struct *work)6110{6111struct ath11k *ar = container_of(work, struct ath11k, wmi_mgmt_tx_work);6112struct ath11k_skb_cb *skb_cb;6113struct ath11k_vif *arvif;6114struct sk_buff *skb;6115int ret;61166117while ((skb = skb_dequeue(&ar->wmi_mgmt_tx_queue)) != NULL) {6118skb_cb = ATH11K_SKB_CB(skb);6119if (!skb_cb->vif) {6120ath11k_warn(ar->ab, "no vif found for mgmt frame\n");6121ath11k_mgmt_over_wmi_tx_drop(ar, skb);6122continue;6123}61246125arvif = ath11k_vif_to_arvif(skb_cb->vif);6126mutex_lock(&ar->conf_mutex);6127if (ar->allocated_vdev_map & (1LL << arvif->vdev_id)) {6128ret = ath11k_mac_mgmt_tx_wmi(ar, arvif, skb);6129if (ret) {6130ath11k_warn(ar->ab, "failed to tx mgmt frame, vdev_id %d :%d\n",6131arvif->vdev_id, ret);6132ath11k_mgmt_over_wmi_tx_drop(ar, skb);6133} else {6134ath11k_dbg(ar->ab, ATH11K_DBG_MAC,6135"tx mgmt frame, vdev_id %d\n",6136arvif->vdev_id);6137}6138} else {6139ath11k_warn(ar->ab,6140"dropping mgmt frame for vdev %d, is_started %d\n",6141arvif->vdev_id,6142arvif->is_started);6143ath11k_mgmt_over_wmi_tx_drop(ar, skb);6144}6145mutex_unlock(&ar->conf_mutex);6146}6147}61486149static int ath11k_mac_mgmt_tx(struct ath11k *ar, struct sk_buff *skb,6150bool is_prb_rsp)6151{6152struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;61536154if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))6155return -ESHUTDOWN;61566157/* Drop probe response packets when the pending management tx6158* count has reached a certain threshold, so as to prioritize6159* other mgmt packets like auth and assoc to be sent on time6160* for establishing successful connections.6161*/6162if (is_prb_rsp &&6163atomic_read(&ar->num_pending_mgmt_tx) > ATH11K_PRB_RSP_DROP_THRESHOLD) {6164ath11k_warn(ar->ab,6165"dropping probe response as pending queue is almost full\n");6166return -ENOSPC;6167}61686169if (skb_queue_len_lockless(q) >= ATH11K_TX_MGMT_NUM_PENDING_MAX) {6170ath11k_warn(ar->ab, "mgmt tx queue is full\n");6171return -ENOSPC;6172}61736174skb_queue_tail(q, skb);6175atomic_inc(&ar->num_pending_mgmt_tx);6176queue_work(ar->ab->workqueue_aux, &ar->wmi_mgmt_tx_work);61776178return 0;6179}61806181static void ath11k_mac_op_tx(struct ieee80211_hw *hw,6182struct ieee80211_tx_control *control,6183struct sk_buff *skb)6184{6185struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);6186struct ath11k *ar = hw->priv;6187struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);6188struct ieee80211_vif *vif = info->control.vif;6189struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);6190struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;6191struct ieee80211_key_conf *key = info->control.hw_key;6192struct ath11k_sta *arsta = NULL;6193u32 info_flags = info->flags;6194bool is_prb_rsp;6195int ret;61966197memset(skb_cb, 0, sizeof(*skb_cb));6198skb_cb->vif = vif;61996200if (key) {6201skb_cb->cipher = key->cipher;6202skb_cb->flags |= ATH11K_SKB_CIPHER_SET;6203}62046205if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {6206skb_cb->flags |= ATH11K_SKB_HW_80211_ENCAP;6207} else if (ieee80211_is_mgmt(hdr->frame_control)) {6208is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control);6209ret = ath11k_mac_mgmt_tx(ar, skb, is_prb_rsp);6210if (ret) {6211ath11k_warn(ar->ab, "failed to queue management frame %d\n",6212ret);6213ieee80211_free_txskb(ar->hw, skb);6214}6215return;6216}62176218if (control->sta)6219arsta = ath11k_sta_to_arsta(control->sta);62206221ret = ath11k_dp_tx(ar, arvif, arsta, skb);6222if (unlikely(ret)) {6223ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret);6224ieee80211_free_txskb(ar->hw, skb);6225}6226}62276228void ath11k_mac_drain_tx(struct ath11k *ar)6229{6230/* make sure rcu-protected mac80211 tx path itself is drained */6231synchronize_net();62326233cancel_work_sync(&ar->wmi_mgmt_tx_work);6234ath11k_mgmt_over_wmi_tx_purge(ar);6235}62366237static int ath11k_mac_config_mon_status_default(struct ath11k *ar, bool enable)6238{6239struct htt_rx_ring_tlv_filter tlv_filter = {};6240struct ath11k_base *ab = ar->ab;6241int i, ret = 0;6242u32 ring_id;62436244if (enable) {6245tlv_filter = ath11k_mac_mon_status_filter_default;6246if (ath11k_debugfs_rx_filter(ar))6247tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar);6248}62496250for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {6251ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;6252ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,6253ar->dp.mac_id + i,6254HAL_RXDMA_MONITOR_STATUS,6255DP_RX_BUFFER_SIZE,6256&tlv_filter);6257}62586259if (enable && !ar->ab->hw_params.rxdma1_enable)6260mod_timer(&ar->ab->mon_reap_timer, jiffies +6261msecs_to_jiffies(ATH11K_MON_TIMER_INTERVAL));62626263return ret;6264}62656266static void ath11k_mac_wait_reconfigure(struct ath11k_base *ab)6267{6268int recovery_start_count;62696270if (!ab->is_reset)6271return;62726273recovery_start_count = atomic_inc_return(&ab->recovery_start_count);6274ath11k_dbg(ab, ATH11K_DBG_MAC, "recovery start count %d\n", recovery_start_count);62756276if (recovery_start_count == ab->num_radios) {6277complete(&ab->recovery_start);6278ath11k_dbg(ab, ATH11K_DBG_MAC, "recovery started success\n");6279}62806281ath11k_dbg(ab, ATH11K_DBG_MAC, "waiting reconfigure...\n");62826283wait_for_completion_timeout(&ab->reconfigure_complete,6284ATH11K_RECONFIGURE_TIMEOUT_HZ);6285}62866287static int ath11k_mac_op_start(struct ieee80211_hw *hw)6288{6289struct ath11k *ar = hw->priv;6290struct ath11k_base *ab = ar->ab;6291struct ath11k_pdev *pdev = ar->pdev;6292int ret;62936294if (ath11k_ftm_mode) {6295ath11k_warn(ab, "mac operations not supported in factory test mode\n");6296return -EOPNOTSUPP;6297}62986299ath11k_mac_drain_tx(ar);6300mutex_lock(&ar->conf_mutex);63016302switch (ar->state) {6303case ATH11K_STATE_OFF:6304ar->state = ATH11K_STATE_ON;6305break;6306case ATH11K_STATE_RESTARTING:6307ar->state = ATH11K_STATE_RESTARTED;6308ath11k_mac_wait_reconfigure(ab);6309break;6310case ATH11K_STATE_RESTARTED:6311case ATH11K_STATE_WEDGED:6312case ATH11K_STATE_ON:6313case ATH11K_STATE_FTM:6314WARN_ON(1);6315ret = -EINVAL;6316goto err;6317}63186319ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS,63201, pdev->pdev_id);63216322if (ret) {6323ath11k_err(ar->ab, "failed to enable PMF QOS: (%d\n", ret);6324goto err;6325}63266327ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_DYNAMIC_BW, 1,6328pdev->pdev_id);6329if (ret) {6330ath11k_err(ar->ab, "failed to enable dynamic bw: %d\n", ret);6331goto err;6332}63336334if (test_bit(WMI_TLV_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi->wmi_ab->svc_map)) {6335ret = ath11k_wmi_scan_prob_req_oui(ar, ar->mac_addr);6336if (ret) {6337ath11k_err(ab, "failed to set prob req oui: %i\n", ret);6338goto err;6339}6340}63416342ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_ARP_AC_OVERRIDE,63430, pdev->pdev_id);6344if (ret) {6345ath11k_err(ab, "failed to set ac override for ARP: %d\n",6346ret);6347goto err;6348}63496350ret = ath11k_wmi_send_dfs_phyerr_offload_enable_cmd(ar, pdev->pdev_id);6351if (ret) {6352ath11k_err(ab, "failed to offload radar detection: %d\n",6353ret);6354goto err;6355}63566357ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,6358HTT_PPDU_STATS_TAG_DEFAULT);6359if (ret) {6360ath11k_err(ab, "failed to req ppdu stats: %d\n", ret);6361goto err;6362}63636364ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_MESH_MCAST_ENABLE,63651, pdev->pdev_id);63666367if (ret) {6368ath11k_err(ar->ab, "failed to enable MESH MCAST ENABLE: (%d\n", ret);6369goto err;6370}63716372__ath11k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);63736374/* TODO: Do we need to enable ANI? */63756376ath11k_reg_update_chan_list(ar, false);63776378ar->num_started_vdevs = 0;6379ar->num_created_vdevs = 0;6380ar->num_peers = 0;6381ar->allocated_vdev_map = 0;63826383/* Configure monitor status ring with default rx_filter to get rx status6384* such as rssi, rx_duration.6385*/6386ret = ath11k_mac_config_mon_status_default(ar, true);6387if (ret) {6388ath11k_err(ab, "failed to configure monitor status ring with default rx_filter: (%d)\n",6389ret);6390goto err;6391}63926393/* Configure the hash seed for hash based reo dest ring selection */6394ath11k_wmi_pdev_lro_cfg(ar, ar->pdev->pdev_id);63956396/* allow device to enter IMPS */6397if (ab->hw_params.idle_ps) {6398ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_IDLE_PS_CONFIG,63991, pdev->pdev_id);6400if (ret) {6401ath11k_err(ab, "failed to enable idle ps: %d\n", ret);6402goto err;6403}6404}64056406mutex_unlock(&ar->conf_mutex);64076408rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx],6409&ab->pdevs[ar->pdev_idx]);64106411return 0;64126413err:6414ar->state = ATH11K_STATE_OFF;6415mutex_unlock(&ar->conf_mutex);64166417return ret;6418}64196420static void ath11k_mac_op_stop(struct ieee80211_hw *hw, bool suspend)6421{6422struct ath11k *ar = hw->priv;6423struct htt_ppdu_stats_info *ppdu_stats, *tmp;6424struct scan_chan_list_params *params;6425int ret;64266427ath11k_mac_drain_tx(ar);64286429mutex_lock(&ar->conf_mutex);6430ret = ath11k_mac_config_mon_status_default(ar, false);6431if (ret)6432ath11k_err(ar->ab, "failed to clear rx_filter for monitor status ring: (%d)\n",6433ret);64346435clear_bit(ATH11K_CAC_RUNNING, &ar->dev_flags);6436ar->state = ATH11K_STATE_OFF;6437mutex_unlock(&ar->conf_mutex);64386439cancel_delayed_work_sync(&ar->scan.timeout);6440cancel_work_sync(&ar->channel_update_work);6441cancel_work_sync(&ar->regd_update_work);6442cancel_work_sync(&ar->ab->update_11d_work);64436444if (ar->state_11d == ATH11K_11D_PREPARING) {6445ar->state_11d = ATH11K_11D_IDLE;6446complete(&ar->completed_11d_scan);6447}64486449spin_lock_bh(&ar->data_lock);64506451list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) {6452list_del(&ppdu_stats->list);6453kfree(ppdu_stats);6454}64556456while ((params = list_first_entry_or_null(&ar->channel_update_queue,6457struct scan_chan_list_params,6458list))) {6459list_del(¶ms->list);6460kfree(params);6461}64626463spin_unlock_bh(&ar->data_lock);64646465rcu_assign_pointer(ar->ab->pdevs_active[ar->pdev_idx], NULL);64666467synchronize_rcu();64686469atomic_set(&ar->num_pending_mgmt_tx, 0);6470}64716472static int ath11k_mac_setup_vdev_params_mbssid(struct ath11k_vif *arvif,6473u32 *flags, u32 *tx_vdev_id)6474{6475struct ath11k *ar = arvif->ar;6476struct ath11k_vif *tx_arvif;64776478*tx_vdev_id = 0;6479tx_arvif = ath11k_mac_get_tx_arvif(arvif);6480if (!tx_arvif) {6481*flags = WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP;6482return 0;6483}64846485if (arvif->vif->bss_conf.nontransmitted) {6486if (ar->hw->wiphy != tx_arvif->ar->hw->wiphy)6487return -EINVAL;64886489*flags = WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP;6490*tx_vdev_id = tx_arvif->vdev_id;6491} else if (tx_arvif == arvif) {6492*flags = WMI_HOST_VDEV_FLAGS_TRANSMIT_AP;6493} else {6494return -EINVAL;6495}64966497if (arvif->vif->bss_conf.ema_ap)6498*flags |= WMI_HOST_VDEV_FLAGS_EMA_MODE;64996500return 0;6501}65026503static int ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,6504struct vdev_create_params *params)6505{6506struct ath11k *ar = arvif->ar;6507struct ath11k_pdev *pdev = ar->pdev;6508int ret;65096510params->if_id = arvif->vdev_id;6511params->type = arvif->vdev_type;6512params->subtype = arvif->vdev_subtype;6513params->pdev_id = pdev->pdev_id;6514params->mbssid_flags = 0;6515params->mbssid_tx_vdev_id = 0;65166517if (!test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT,6518ar->ab->wmi_ab.svc_map)) {6519ret = ath11k_mac_setup_vdev_params_mbssid(arvif,6520¶ms->mbssid_flags,6521¶ms->mbssid_tx_vdev_id);6522if (ret)6523return ret;6524}65256526if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) {6527params->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains;6528params->chains[NL80211_BAND_2GHZ].rx = ar->num_rx_chains;6529}6530if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) {6531params->chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains;6532params->chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains;6533}6534if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP &&6535ar->supports_6ghz) {6536params->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains;6537params->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains;6538}6539return 0;6540}65416542static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw,6543struct ieee80211_vif *vif)6544{6545struct ath11k *ar = hw->priv;6546struct ath11k_base *ab = ar->ab;6547struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);6548u32 param_id, param_value;6549int ret;65506551param_id = WMI_VDEV_PARAM_TX_ENCAP_TYPE;6552if (ath11k_frame_mode != ATH11K_HW_TXRX_ETHERNET ||6553(vif->type != NL80211_IFTYPE_STATION &&6554vif->type != NL80211_IFTYPE_AP))6555vif->offload_flags &= ~(IEEE80211_OFFLOAD_ENCAP_ENABLED |6556IEEE80211_OFFLOAD_DECAP_ENABLED);65576558if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)6559param_value = ATH11K_HW_TXRX_ETHERNET;6560else if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))6561param_value = ATH11K_HW_TXRX_RAW;6562else6563param_value = ATH11K_HW_TXRX_NATIVE_WIFI;65646565ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,6566param_id, param_value);6567if (ret) {6568ath11k_warn(ab, "failed to set vdev %d tx encap mode: %d\n",6569arvif->vdev_id, ret);6570vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;6571}65726573param_id = WMI_VDEV_PARAM_RX_DECAP_TYPE;6574if (vif->offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED)6575param_value = ATH11K_HW_TXRX_ETHERNET;6576else if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))6577param_value = ATH11K_HW_TXRX_RAW;6578else6579param_value = ATH11K_HW_TXRX_NATIVE_WIFI;65806581ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,6582param_id, param_value);6583if (ret) {6584ath11k_warn(ab, "failed to set vdev %d rx decap mode: %d\n",6585arvif->vdev_id, ret);6586vif->offload_flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;6587}6588}65896590static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab)6591{6592struct ath11k *ar;6593struct ath11k_pdev *pdev;6594struct ath11k_vif *arvif;6595int i;65966597for (i = 0; i < ab->num_radios; i++) {6598pdev = &ab->pdevs[i];6599ar = pdev->ar;6600list_for_each_entry(arvif, &ar->arvifs, list) {6601if (arvif->is_up && arvif->vdev_type == WMI_VDEV_TYPE_AP)6602return true;6603}6604}6605return false;6606}66076608void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id)6609{6610struct wmi_11d_scan_start_params param;6611int ret;66126613mutex_lock(&ar->ab->vdev_id_11d_lock);66146615ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev id for 11d scan %d\n",6616ar->vdev_id_11d_scan);66176618if (ar->regdom_set_by_user)6619goto fin;66206621if (ar->vdev_id_11d_scan != ATH11K_11D_INVALID_VDEV_ID)6622goto fin;66236624if (!test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ar->ab->wmi_ab.svc_map))6625goto fin;66266627if (ath11k_mac_vif_ap_active_any(ar->ab))6628goto fin;66296630param.vdev_id = vdev_id;6631param.start_interval_msec = 0;6632param.scan_period_msec = ATH11K_SCAN_11D_INTERVAL;66336634ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "start 11d scan\n");66356636ret = ath11k_wmi_send_11d_scan_start_cmd(ar, ¶m);6637if (ret) {6638ath11k_warn(ar->ab, "failed to start 11d scan vdev %d ret: %d\n",6639vdev_id, ret);6640} else {6641ar->vdev_id_11d_scan = vdev_id;6642if (ar->state_11d == ATH11K_11D_PREPARING)6643ar->state_11d = ATH11K_11D_RUNNING;6644}66456646fin:6647if (ar->state_11d == ATH11K_11D_PREPARING) {6648ar->state_11d = ATH11K_11D_IDLE;6649complete(&ar->completed_11d_scan);6650}66516652mutex_unlock(&ar->ab->vdev_id_11d_lock);6653}66546655void ath11k_mac_11d_scan_stop(struct ath11k *ar)6656{6657int ret;6658u32 vdev_id;66596660if (!test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ar->ab->wmi_ab.svc_map))6661return;66626663ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "stop 11d scan\n");66646665mutex_lock(&ar->ab->vdev_id_11d_lock);66666667ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "stop 11d vdev id %d\n",6668ar->vdev_id_11d_scan);66696670if (ar->state_11d == ATH11K_11D_PREPARING) {6671ar->state_11d = ATH11K_11D_IDLE;6672complete(&ar->completed_11d_scan);6673}66746675if (ar->vdev_id_11d_scan != ATH11K_11D_INVALID_VDEV_ID) {6676vdev_id = ar->vdev_id_11d_scan;66776678ret = ath11k_wmi_send_11d_scan_stop_cmd(ar, vdev_id);6679if (ret) {6680ath11k_warn(ar->ab,6681"failed to stopt 11d scan vdev %d ret: %d\n",6682vdev_id, ret);6683} else {6684ar->vdev_id_11d_scan = ATH11K_11D_INVALID_VDEV_ID;6685ar->state_11d = ATH11K_11D_IDLE;6686complete(&ar->completed_11d_scan);6687}6688}6689mutex_unlock(&ar->ab->vdev_id_11d_lock);6690}66916692void ath11k_mac_11d_scan_stop_all(struct ath11k_base *ab)6693{6694struct ath11k *ar;6695struct ath11k_pdev *pdev;6696int i;66976698ath11k_dbg(ab, ATH11K_DBG_MAC, "stop soc 11d scan\n");66996700for (i = 0; i < ab->num_radios; i++) {6701pdev = &ab->pdevs[i];6702ar = pdev->ar;67036704ath11k_mac_11d_scan_stop(ar);6705}6706}67076708static int ath11k_mac_vdev_delete(struct ath11k *ar, struct ath11k_vif *arvif)6709{6710unsigned long time_left;6711struct ieee80211_vif *vif = arvif->vif;6712int ret = 0;67136714lockdep_assert_held(&ar->conf_mutex);67156716reinit_completion(&ar->vdev_delete_done);67176718ret = ath11k_wmi_vdev_delete(ar, arvif->vdev_id);6719if (ret) {6720ath11k_warn(ar->ab, "failed to delete WMI vdev %d: %d\n",6721arvif->vdev_id, ret);6722return ret;6723}67246725time_left = wait_for_completion_timeout(&ar->vdev_delete_done,6726ATH11K_VDEV_DELETE_TIMEOUT_HZ);6727if (time_left == 0) {6728ath11k_warn(ar->ab, "Timeout in receiving vdev delete response\n");6729return -ETIMEDOUT;6730}67316732ar->ab->free_vdev_map |= 1LL << (arvif->vdev_id);6733ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id);6734ar->num_created_vdevs--;67356736ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %pM deleted, vdev_id %d\n",6737vif->addr, arvif->vdev_id);67386739return ret;6740}67416742static void ath11k_mac_bcn_tx_work(struct work_struct *work)6743{6744struct ath11k_vif *arvif = container_of(work, struct ath11k_vif,6745bcn_tx_work);67466747mutex_lock(&arvif->ar->conf_mutex);6748ath11k_mac_bcn_tx_event(arvif);6749mutex_unlock(&arvif->ar->conf_mutex);6750}67516752static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,6753struct ieee80211_vif *vif)6754{6755struct ath11k *ar = hw->priv;6756struct ath11k_base *ab = ar->ab;6757struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);6758struct vdev_create_params vdev_param = {};6759struct peer_create_params peer_param;6760u32 param_id, param_value;6761u16 nss;6762int i;6763int ret, fbret;6764int bit;67656766vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;67676768mutex_lock(&ar->conf_mutex);67696770if (vif->type == NL80211_IFTYPE_AP &&6771ar->num_peers > (ar->max_num_peers - 1)) {6772ath11k_warn(ab, "failed to create vdev due to insufficient peer entry resource in firmware\n");6773ret = -ENOBUFS;6774goto err;6775}67766777if (ar->num_created_vdevs > (TARGET_NUM_VDEVS(ab) - 1)) {6778ath11k_warn(ab, "failed to create vdev %u, reached max vdev limit %d\n",6779ar->num_created_vdevs, TARGET_NUM_VDEVS(ab));6780ret = -EBUSY;6781goto err;6782}67836784memset(arvif, 0, sizeof(*arvif));67856786arvif->ar = ar;6787arvif->vif = vif;67886789INIT_LIST_HEAD(&arvif->list);6790INIT_WORK(&arvif->bcn_tx_work, ath11k_mac_bcn_tx_work);6791INIT_DELAYED_WORK(&arvif->connection_loss_work,6792ath11k_mac_vif_sta_connection_loss_work);67936794for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {6795arvif->bitrate_mask.control[i].legacy = 0xffffffff;6796arvif->bitrate_mask.control[i].gi = NL80211_TXRATE_FORCE_SGI;6797memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,6798sizeof(arvif->bitrate_mask.control[i].ht_mcs));6799memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,6800sizeof(arvif->bitrate_mask.control[i].vht_mcs));6801memset(arvif->bitrate_mask.control[i].he_mcs, 0xff,6802sizeof(arvif->bitrate_mask.control[i].he_mcs));6803}68046805bit = __ffs64(ab->free_vdev_map);68066807arvif->vdev_id = bit;6808arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;68096810switch (vif->type) {6811case NL80211_IFTYPE_UNSPECIFIED:6812case NL80211_IFTYPE_STATION:6813arvif->vdev_type = WMI_VDEV_TYPE_STA;6814if (vif->p2p)6815arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT;6816break;6817case NL80211_IFTYPE_MESH_POINT:6818arvif->vdev_subtype = WMI_VDEV_SUBTYPE_MESH_11S;6819fallthrough;6820case NL80211_IFTYPE_AP:6821arvif->vdev_type = WMI_VDEV_TYPE_AP;6822if (vif->p2p)6823arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO;6824break;6825case NL80211_IFTYPE_MONITOR:6826arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;6827ar->monitor_vdev_id = bit;6828break;6829case NL80211_IFTYPE_P2P_DEVICE:6830arvif->vdev_type = WMI_VDEV_TYPE_STA;6831arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;6832break;68336834default:6835WARN_ON(1);6836break;6837}68386839ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "add interface id %d type %d subtype %d map %llx\n",6840arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,6841ab->free_vdev_map);68426843vif->cab_queue = arvif->vdev_id % (ATH11K_HW_MAX_QUEUES - 1);6844for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)6845vif->hw_queue[i] = i % (ATH11K_HW_MAX_QUEUES - 1);68466847ret = ath11k_mac_setup_vdev_create_params(arvif, &vdev_param);6848if (ret) {6849ath11k_warn(ab, "failed to create vdev parameters %d: %d\n",6850arvif->vdev_id, ret);6851goto err;6852}68536854ret = ath11k_wmi_vdev_create(ar, vif->addr, &vdev_param);6855if (ret) {6856ath11k_warn(ab, "failed to create WMI vdev %d: %d\n",6857arvif->vdev_id, ret);6858goto err;6859}68606861ar->num_created_vdevs++;6862ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM created, vdev_id %d\n",6863vif->addr, arvif->vdev_id);6864ar->allocated_vdev_map |= 1LL << arvif->vdev_id;6865ab->free_vdev_map &= ~(1LL << arvif->vdev_id);68666867spin_lock_bh(&ar->data_lock);6868list_add(&arvif->list, &ar->arvifs);6869spin_unlock_bh(&ar->data_lock);68706871ath11k_mac_op_update_vif_offload(hw, vif);68726873nss = get_num_chains(ar->cfg_tx_chainmask) ? : 1;6874ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,6875WMI_VDEV_PARAM_NSS, nss);6876if (ret) {6877ath11k_warn(ab, "failed to set vdev %d chainmask 0x%x, nss %d :%d\n",6878arvif->vdev_id, ar->cfg_tx_chainmask, nss, ret);6879goto err_vdev_del;6880}68816882switch (arvif->vdev_type) {6883case WMI_VDEV_TYPE_AP:6884peer_param.vdev_id = arvif->vdev_id;6885peer_param.peer_addr = vif->addr;6886peer_param.peer_type = WMI_PEER_TYPE_DEFAULT;6887ret = ath11k_peer_create(ar, arvif, NULL, &peer_param);6888if (ret) {6889ath11k_warn(ab, "failed to vdev %d create peer for AP: %d\n",6890arvif->vdev_id, ret);6891goto err_vdev_del;6892}68936894ret = ath11k_mac_set_kickout(arvif);6895if (ret) {6896ath11k_warn(ar->ab, "failed to set vdev %i kickout parameters: %d\n",6897arvif->vdev_id, ret);6898goto err_peer_del;6899}69006901ath11k_mac_11d_scan_stop_all(ar->ab);6902break;6903case WMI_VDEV_TYPE_STA:6904param_id = WMI_STA_PS_PARAM_RX_WAKE_POLICY;6905param_value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;6906ret = ath11k_wmi_set_sta_ps_param(ar, arvif->vdev_id,6907param_id, param_value);6908if (ret) {6909ath11k_warn(ar->ab, "failed to set vdev %d RX wake policy: %d\n",6910arvif->vdev_id, ret);6911goto err_peer_del;6912}69136914param_id = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;6915param_value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;6916ret = ath11k_wmi_set_sta_ps_param(ar, arvif->vdev_id,6917param_id, param_value);6918if (ret) {6919ath11k_warn(ar->ab, "failed to set vdev %d TX wake threshold: %d\n",6920arvif->vdev_id, ret);6921goto err_peer_del;6922}69236924param_id = WMI_STA_PS_PARAM_PSPOLL_COUNT;6925param_value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;6926ret = ath11k_wmi_set_sta_ps_param(ar, arvif->vdev_id,6927param_id, param_value);6928if (ret) {6929ath11k_warn(ar->ab, "failed to set vdev %d pspoll count: %d\n",6930arvif->vdev_id, ret);6931goto err_peer_del;6932}69336934ret = ath11k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id,6935WMI_STA_PS_MODE_DISABLED);6936if (ret) {6937ath11k_warn(ar->ab, "failed to disable vdev %d ps mode: %d\n",6938arvif->vdev_id, ret);6939goto err_peer_del;6940}69416942if (test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ab->wmi_ab.svc_map)) {6943reinit_completion(&ar->completed_11d_scan);6944ar->state_11d = ATH11K_11D_PREPARING;6945}6946break;6947case WMI_VDEV_TYPE_MONITOR:6948set_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags);6949break;6950default:6951break;6952}69536954arvif->txpower = vif->bss_conf.txpower;6955ret = ath11k_mac_txpower_recalc(ar);6956if (ret)6957goto err_peer_del;69586959param_id = WMI_VDEV_PARAM_RTS_THRESHOLD;6960param_value = ar->hw->wiphy->rts_threshold;6961ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,6962param_id, param_value);6963if (ret) {6964ath11k_warn(ar->ab, "failed to set rts threshold for vdev %d: %d\n",6965arvif->vdev_id, ret);6966}69676968ath11k_dp_vdev_tx_attach(ar, arvif);69696970if (vif->type != NL80211_IFTYPE_MONITOR &&6971test_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags)) {6972ret = ath11k_mac_monitor_vdev_create(ar);6973if (ret)6974ath11k_warn(ar->ab, "failed to create monitor vdev during add interface: %d",6975ret);6976}69776978if (ath11k_wmi_supports_6ghz_cc_ext(ar)) {6979struct cur_regulatory_info *reg_info;69806981reg_info = &ab->reg_info_store[ar->pdev_idx];6982ath11k_dbg(ab, ATH11K_DBG_MAC, "interface added to change reg rules\n");6983ath11k_reg_handle_chan_list(ab, reg_info, IEEE80211_REG_LPI_AP);6984}69856986mutex_unlock(&ar->conf_mutex);69876988return 0;69896990err_peer_del:6991if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {6992fbret = ath11k_peer_delete(ar, arvif->vdev_id, vif->addr);6993if (fbret) {6994ath11k_warn(ar->ab, "fallback fail to delete peer addr %pM vdev_id %d ret %d\n",6995vif->addr, arvif->vdev_id, fbret);6996goto err;6997}6998}69997000err_vdev_del:7001ath11k_mac_vdev_delete(ar, arvif);7002spin_lock_bh(&ar->data_lock);7003list_del(&arvif->list);7004spin_unlock_bh(&ar->data_lock);70057006err:7007mutex_unlock(&ar->conf_mutex);70087009return ret;7010}70117012static int ath11k_mac_vif_unref(int buf_id, void *skb, void *ctx)7013{7014struct ieee80211_vif *vif = ctx;7015struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);70167017if (skb_cb->vif == vif)7018skb_cb->vif = NULL;70197020return 0;7021}70227023static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw,7024struct ieee80211_vif *vif)7025{7026struct ath11k *ar = hw->priv;7027struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);7028struct ath11k_base *ab = ar->ab;7029int ret;7030int i;70317032cancel_delayed_work_sync(&arvif->connection_loss_work);7033cancel_work_sync(&arvif->bcn_tx_work);70347035mutex_lock(&ar->conf_mutex);70367037ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n",7038arvif->vdev_id);70397040ret = ath11k_spectral_vif_stop(arvif);7041if (ret)7042ath11k_warn(ab, "failed to stop spectral for vdev %i: %d\n",7043arvif->vdev_id, ret);70447045if (arvif->vdev_type == WMI_VDEV_TYPE_STA)7046ath11k_mac_11d_scan_stop(ar);70477048if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {7049ret = ath11k_peer_delete(ar, arvif->vdev_id, vif->addr);7050if (ret)7051ath11k_warn(ab, "failed to submit AP self-peer removal on vdev %d: %d\n",7052arvif->vdev_id, ret);7053}70547055ret = ath11k_mac_vdev_delete(ar, arvif);7056if (ret) {7057ath11k_warn(ab, "failed to delete vdev %d: %d\n",7058arvif->vdev_id, ret);7059goto err_vdev_del;7060}70617062if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {7063clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags);7064ar->monitor_vdev_id = -1;7065} else if (test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags) &&7066!test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) {7067ret = ath11k_mac_monitor_vdev_delete(ar);7068if (ret)7069/* continue even if there's an error */7070ath11k_warn(ar->ab, "failed to delete vdev monitor during remove interface: %d",7071ret);7072}70737074err_vdev_del:7075spin_lock_bh(&ar->data_lock);7076list_del(&arvif->list);7077spin_unlock_bh(&ar->data_lock);70787079ath11k_peer_cleanup(ar, arvif->vdev_id);70807081idr_for_each(&ar->txmgmt_idr,7082ath11k_mac_vif_txmgmt_idr_remove, vif);70837084for (i = 0; i < ab->hw_params.max_tx_ring; i++) {7085spin_lock_bh(&ab->dp.tx_ring[i].tx_idr_lock);7086idr_for_each(&ab->dp.tx_ring[i].txbuf_idr,7087ath11k_mac_vif_unref, vif);7088spin_unlock_bh(&ab->dp.tx_ring[i].tx_idr_lock);7089}70907091/* Recalc txpower for remaining vdev */7092ath11k_mac_txpower_recalc(ar);70937094/* TODO: recalc traffic pause state based on the available vdevs */70957096mutex_unlock(&ar->conf_mutex);7097}70987099/* FIXME: Has to be verified. */7100#define SUPPORTED_FILTERS \7101(FIF_ALLMULTI | \7102FIF_CONTROL | \7103FIF_PSPOLL | \7104FIF_OTHER_BSS | \7105FIF_BCN_PRBRESP_PROMISC | \7106FIF_PROBE_REQ | \7107FIF_FCSFAIL)71087109static void ath11k_mac_op_configure_filter(struct ieee80211_hw *hw,7110unsigned int changed_flags,7111unsigned int *total_flags,7112u64 multicast)7113{7114struct ath11k *ar = hw->priv;71157116mutex_lock(&ar->conf_mutex);71177118*total_flags &= SUPPORTED_FILTERS;7119ar->filter_flags = *total_flags;71207121mutex_unlock(&ar->conf_mutex);7122}71237124static int ath11k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx,7125u32 *tx_ant, u32 *rx_ant)7126{7127struct ath11k *ar = hw->priv;71287129mutex_lock(&ar->conf_mutex);71307131*tx_ant = ar->cfg_tx_chainmask;7132*rx_ant = ar->cfg_rx_chainmask;71337134mutex_unlock(&ar->conf_mutex);71357136return 0;7137}71387139static int ath11k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx,7140u32 tx_ant, u32 rx_ant)7141{7142struct ath11k *ar = hw->priv;7143int ret;71447145mutex_lock(&ar->conf_mutex);7146ret = __ath11k_set_antenna(ar, tx_ant, rx_ant);7147mutex_unlock(&ar->conf_mutex);71487149return ret;7150}71517152static int ath11k_mac_op_ampdu_action(struct ieee80211_hw *hw,7153struct ieee80211_vif *vif,7154struct ieee80211_ampdu_params *params)7155{7156struct ath11k *ar = hw->priv;7157int ret = -EINVAL;71587159mutex_lock(&ar->conf_mutex);71607161switch (params->action) {7162case IEEE80211_AMPDU_RX_START:7163ret = ath11k_dp_rx_ampdu_start(ar, params);7164break;7165case IEEE80211_AMPDU_RX_STOP:7166ret = ath11k_dp_rx_ampdu_stop(ar, params);7167break;7168case IEEE80211_AMPDU_TX_START:7169case IEEE80211_AMPDU_TX_STOP_CONT:7170case IEEE80211_AMPDU_TX_STOP_FLUSH:7171case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:7172case IEEE80211_AMPDU_TX_OPERATIONAL:7173/* Tx A-MPDU aggregation offloaded to hw/fw so deny mac802117174* Tx aggregation requests.7175*/7176ret = -EOPNOTSUPP;7177break;7178}71797180mutex_unlock(&ar->conf_mutex);71817182return ret;7183}71847185static int ath11k_mac_op_add_chanctx(struct ieee80211_hw *hw,7186struct ieee80211_chanctx_conf *ctx)7187{7188struct ath11k *ar = hw->priv;7189struct ath11k_base *ab = ar->ab;71907191ath11k_dbg(ab, ATH11K_DBG_MAC,7192"chanctx add freq %u width %d ptr %p\n",7193ctx->def.chan->center_freq, ctx->def.width, ctx);71947195mutex_lock(&ar->conf_mutex);71967197spin_lock_bh(&ar->data_lock);7198/* TODO: In case of multiple channel context, populate rx_channel from7199* Rx PPDU desc information.7200*/7201ar->rx_channel = ctx->def.chan;7202spin_unlock_bh(&ar->data_lock);72037204mutex_unlock(&ar->conf_mutex);72057206return 0;7207}72087209static void ath11k_mac_op_remove_chanctx(struct ieee80211_hw *hw,7210struct ieee80211_chanctx_conf *ctx)7211{7212struct ath11k *ar = hw->priv;7213struct ath11k_base *ab = ar->ab;72147215ath11k_dbg(ab, ATH11K_DBG_MAC,7216"chanctx remove freq %u width %d ptr %p\n",7217ctx->def.chan->center_freq, ctx->def.width, ctx);72187219mutex_lock(&ar->conf_mutex);72207221spin_lock_bh(&ar->data_lock);7222/* TODO: In case of there is one more channel context left, populate7223* rx_channel with the channel of that remaining channel context.7224*/7225ar->rx_channel = NULL;7226spin_unlock_bh(&ar->data_lock);72277228mutex_unlock(&ar->conf_mutex);7229}72307231static int7232ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,7233struct ieee80211_chanctx_conf *ctx,7234bool restart)7235{7236struct ath11k *ar = arvif->ar;7237struct ath11k_base *ab = ar->ab;7238struct wmi_vdev_start_req_arg arg = {};7239const struct cfg80211_chan_def *chandef = &ctx->def;7240int ret = 0;7241unsigned int dfs_cac_time;72427243lockdep_assert_held(&ar->conf_mutex);72447245reinit_completion(&ar->vdev_setup_done);72467247arg.vdev_id = arvif->vdev_id;7248arg.dtim_period = arvif->dtim_period;7249arg.bcn_intval = arvif->beacon_interval;72507251arg.channel.freq = chandef->chan->center_freq;7252arg.channel.band_center_freq1 = chandef->center_freq1;7253arg.channel.band_center_freq2 = chandef->center_freq2;7254arg.channel.mode =7255ath11k_phymodes[chandef->chan->band][chandef->width];72567257arg.channel.min_power = 0;7258arg.channel.max_power = chandef->chan->max_power;7259arg.channel.max_reg_power = chandef->chan->max_reg_power;7260arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain;72617262arg.pref_tx_streams = ar->num_tx_chains;7263arg.pref_rx_streams = ar->num_rx_chains;72647265arg.mbssid_flags = 0;7266arg.mbssid_tx_vdev_id = 0;7267if (test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT,7268ar->ab->wmi_ab.svc_map)) {7269ret = ath11k_mac_setup_vdev_params_mbssid(arvif,7270&arg.mbssid_flags,7271&arg.mbssid_tx_vdev_id);7272if (ret)7273return ret;7274}72757276if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {7277arg.ssid = arvif->u.ap.ssid;7278arg.ssid_len = arvif->u.ap.ssid_len;7279arg.hidden_ssid = arvif->u.ap.hidden_ssid;72807281/* For now allow DFS for AP mode */7282arg.channel.chan_radar =7283!!(chandef->chan->flags & IEEE80211_CHAN_RADAR);72847285arg.channel.freq2_radar = ctx->radar_enabled;72867287arg.channel.passive = arg.channel.chan_radar;72887289spin_lock_bh(&ab->base_lock);7290arg.regdomain = ar->ab->dfs_region;7291spin_unlock_bh(&ab->base_lock);7292}72937294arg.channel.passive |= !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR);72957296ath11k_dbg(ab, ATH11K_DBG_MAC,7297"vdev %d start center_freq %d phymode %s\n",7298arg.vdev_id, arg.channel.freq,7299ath11k_wmi_phymode_str(arg.channel.mode));73007301ret = ath11k_wmi_vdev_start(ar, &arg, restart);7302if (ret) {7303ath11k_warn(ar->ab, "failed to %s WMI vdev %i\n",7304restart ? "restart" : "start", arg.vdev_id);7305return ret;7306}73077308ret = ath11k_mac_vdev_setup_sync(ar);7309if (ret) {7310ath11k_warn(ab, "failed to synchronize setup for vdev %i %s: %d\n",7311arg.vdev_id, restart ? "restart" : "start", ret);7312return ret;7313}73147315/* TODO: For now we only set TPC power here. However when7316* channel changes, say CSA, it should be updated again.7317*/7318if (ath11k_mac_supports_station_tpc(ar, arvif, chandef)) {7319ath11k_mac_fill_reg_tpc_info(ar, arvif->vif, &arvif->chanctx);7320ath11k_wmi_send_vdev_set_tpc_power(ar, arvif->vdev_id,7321&arvif->reg_tpc_info);7322}73237324if (!restart)7325ar->num_started_vdevs++;73267327ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM started, vdev_id %d\n",7328arvif->vif->addr, arvif->vdev_id);73297330/* Enable CAC Flag in the driver by checking the all sub-channel's DFS7331* state as NL80211_DFS_USABLE which indicates CAC needs to be7332* done before channel usage. This flags is used to drop rx packets.7333* during CAC.7334*/7335/* TODO Set the flag for other interface types as required */7336if (arvif->vdev_type == WMI_VDEV_TYPE_AP && ctx->radar_enabled &&7337cfg80211_chandef_dfs_usable(ar->hw->wiphy, chandef)) {7338set_bit(ATH11K_CAC_RUNNING, &ar->dev_flags);7339dfs_cac_time = cfg80211_chandef_dfs_cac_time(ar->hw->wiphy,7340chandef);7341ath11k_dbg(ab, ATH11K_DBG_MAC,7342"cac started dfs_cac_time %u center_freq %d center_freq1 %d for vdev %d\n",7343dfs_cac_time, arg.channel.freq, chandef->center_freq1,7344arg.vdev_id);7345}73467347ret = ath11k_mac_set_txbf_conf(arvif);7348if (ret)7349ath11k_warn(ab, "failed to set txbf conf for vdev %d: %d\n",7350arvif->vdev_id, ret);73517352return 0;7353}73547355static int ath11k_mac_vdev_stop(struct ath11k_vif *arvif)7356{7357struct ath11k *ar = arvif->ar;7358int ret;73597360lockdep_assert_held(&ar->conf_mutex);73617362reinit_completion(&ar->vdev_setup_done);73637364ret = ath11k_wmi_vdev_stop(ar, arvif->vdev_id);7365if (ret) {7366ath11k_warn(ar->ab, "failed to stop WMI vdev %i: %d\n",7367arvif->vdev_id, ret);7368goto err;7369}73707371ret = ath11k_mac_vdev_setup_sync(ar);7372if (ret) {7373ath11k_warn(ar->ab, "failed to synchronize setup for vdev %i: %d\n",7374arvif->vdev_id, ret);7375goto err;7376}73777378WARN_ON(ar->num_started_vdevs == 0);73797380ar->num_started_vdevs--;7381ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %pM stopped, vdev_id %d\n",7382arvif->vif->addr, arvif->vdev_id);73837384if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) {7385clear_bit(ATH11K_CAC_RUNNING, &ar->dev_flags);7386ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "CAC Stopped for vdev %d\n",7387arvif->vdev_id);7388}73897390return 0;7391err:7392return ret;7393}73947395static int ath11k_mac_vdev_start(struct ath11k_vif *arvif,7396struct ieee80211_chanctx_conf *ctx)7397{7398return ath11k_mac_vdev_start_restart(arvif, ctx, false);7399}74007401static int ath11k_mac_vdev_restart(struct ath11k_vif *arvif,7402struct ieee80211_chanctx_conf *ctx)7403{7404return ath11k_mac_vdev_start_restart(arvif, ctx, true);7405}74067407struct ath11k_mac_change_chanctx_arg {7408struct ieee80211_chanctx_conf *ctx;7409struct ieee80211_vif_chanctx_switch *vifs;7410int n_vifs;7411int next_vif;7412};74137414static void7415ath11k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,7416struct ieee80211_vif *vif)7417{7418struct ath11k_mac_change_chanctx_arg *arg = data;74197420if (rcu_access_pointer(vif->bss_conf.chanctx_conf) != arg->ctx)7421return;74227423arg->n_vifs++;7424}74257426static void7427ath11k_mac_change_chanctx_fill_iter(void *data, u8 *mac,7428struct ieee80211_vif *vif)7429{7430struct ath11k_mac_change_chanctx_arg *arg = data;7431struct ieee80211_chanctx_conf *ctx;74327433ctx = rcu_access_pointer(vif->bss_conf.chanctx_conf);7434if (ctx != arg->ctx)7435return;74367437if (WARN_ON(arg->next_vif == arg->n_vifs))7438return;74397440arg->vifs[arg->next_vif].vif = vif;7441arg->vifs[arg->next_vif].old_ctx = ctx;7442arg->vifs[arg->next_vif].new_ctx = ctx;7443arg->next_vif++;7444}74457446static void7447ath11k_mac_update_vif_chan(struct ath11k *ar,7448struct ieee80211_vif_chanctx_switch *vifs,7449int n_vifs)7450{7451struct ath11k_base *ab = ar->ab;7452struct ath11k_vif *arvif, *tx_arvif;7453int ret;7454int i;7455bool monitor_vif = false;74567457lockdep_assert_held(&ar->conf_mutex);74587459/* Associated channel resources of all relevant vdevs7460* should be available for the channel switch now.7461*/74627463/* TODO: Update ar->rx_channel */74647465for (i = 0; i < n_vifs; i++) {7466arvif = ath11k_vif_to_arvif(vifs[i].vif);74677468if (WARN_ON(!arvif->is_started))7469continue;74707471/* change_chanctx can be called even before vdev_up from7472* ieee80211_start_ap->ieee80211_vif_use_channel->7473* ieee80211_recalc_radar_chanctx.7474*7475* Firmware expect vdev_restart only if vdev is up.7476* If vdev is down then it expect vdev_stop->vdev_start.7477*/7478if (arvif->is_up) {7479ret = ath11k_mac_vdev_restart(arvif, vifs[i].new_ctx);7480if (ret) {7481ath11k_warn(ab, "failed to restart vdev %d: %d\n",7482arvif->vdev_id, ret);7483continue;7484}7485} else {7486ret = ath11k_mac_vdev_stop(arvif);7487if (ret) {7488ath11k_warn(ab, "failed to stop vdev %d: %d\n",7489arvif->vdev_id, ret);7490continue;7491}74927493ret = ath11k_mac_vdev_start(arvif, vifs[i].new_ctx);7494if (ret)7495ath11k_warn(ab, "failed to start vdev %d: %d\n",7496arvif->vdev_id, ret);74977498continue;7499}75007501ret = ath11k_mac_setup_bcn_tmpl(arvif);7502if (ret)7503ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n",7504ret);75057506tx_arvif = ath11k_mac_get_tx_arvif(arvif);7507ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,7508arvif->bssid,7509tx_arvif ? tx_arvif->bssid : NULL,7510arvif->vif->bss_conf.bssid_index,75111 << arvif->vif->bss_conf.bssid_indicator);7512if (ret) {7513ath11k_warn(ab, "failed to bring vdev up %d: %d\n",7514arvif->vdev_id, ret);7515continue;7516}7517}75187519/* Restart the internal monitor vdev on new channel */7520if (!monitor_vif &&7521test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) {7522ret = ath11k_mac_monitor_stop(ar);7523if (ret) {7524ath11k_warn(ar->ab, "failed to stop monitor during vif channel update: %d",7525ret);7526return;7527}75287529ret = ath11k_mac_monitor_start(ar);7530if (ret) {7531ath11k_warn(ar->ab, "failed to start monitor during vif channel update: %d",7532ret);7533return;7534}7535}7536}75377538static void7539ath11k_mac_update_active_vif_chan(struct ath11k *ar,7540struct ieee80211_chanctx_conf *ctx)7541{7542struct ath11k_mac_change_chanctx_arg arg = { .ctx = ctx };75437544lockdep_assert_held(&ar->conf_mutex);75457546ieee80211_iterate_active_interfaces_atomic(ar->hw,7547IEEE80211_IFACE_ITER_NORMAL,7548ath11k_mac_change_chanctx_cnt_iter,7549&arg);7550if (arg.n_vifs == 0)7551return;75527553arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]), GFP_KERNEL);7554if (!arg.vifs)7555return;75567557ieee80211_iterate_active_interfaces_atomic(ar->hw,7558IEEE80211_IFACE_ITER_NORMAL,7559ath11k_mac_change_chanctx_fill_iter,7560&arg);75617562ath11k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);75637564kfree(arg.vifs);7565}75667567static void ath11k_mac_op_change_chanctx(struct ieee80211_hw *hw,7568struct ieee80211_chanctx_conf *ctx,7569u32 changed)7570{7571struct ath11k *ar = hw->priv;7572struct ath11k_base *ab = ar->ab;75737574mutex_lock(&ar->conf_mutex);75757576ath11k_dbg(ab, ATH11K_DBG_MAC,7577"chanctx change freq %u width %d ptr %p changed %x\n",7578ctx->def.chan->center_freq, ctx->def.width, ctx, changed);75797580/* This shouldn't really happen because channel switching should use7581* switch_vif_chanctx().7582*/7583if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))7584goto unlock;75857586if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH ||7587changed & IEEE80211_CHANCTX_CHANGE_RADAR)7588ath11k_mac_update_active_vif_chan(ar, ctx);75897590/* TODO: Recalc radar detection */75917592unlock:7593mutex_unlock(&ar->conf_mutex);7594}75957596static int ath11k_mac_start_vdev_delay(struct ieee80211_hw *hw,7597struct ieee80211_vif *vif)7598{7599struct ath11k *ar = hw->priv;7600struct ath11k_base *ab = ar->ab;7601struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);7602int ret;76037604if (WARN_ON(arvif->is_started))7605return -EBUSY;76067607ret = ath11k_mac_vdev_start(arvif, &arvif->chanctx);7608if (ret) {7609ath11k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",7610arvif->vdev_id, vif->addr,7611arvif->chanctx.def.chan->center_freq, ret);7612return ret;7613}76147615/* Reconfigure hardware rate code since it is cleared by firmware.7616*/7617if (ar->hw_rate_code > 0) {7618u32 vdev_param = WMI_VDEV_PARAM_MGMT_RATE;76197620ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, vdev_param,7621ar->hw_rate_code);7622if (ret) {7623ath11k_warn(ar->ab, "failed to set mgmt tx rate %d\n", ret);7624return ret;7625}7626}76277628if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {7629ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, 0, ar->mac_addr,7630NULL, 0, 0);7631if (ret) {7632ath11k_warn(ab, "failed put monitor up: %d\n", ret);7633return ret;7634}7635}76367637arvif->is_started = true;76387639/* TODO: Setup ps and cts/rts protection */7640return 0;7641}76427643static int ath11k_mac_stop_vdev_early(struct ieee80211_hw *hw,7644struct ieee80211_vif *vif)7645{7646struct ath11k *ar = hw->priv;7647struct ath11k_base *ab = ar->ab;7648struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);7649int ret;76507651if (WARN_ON(!arvif->is_started))7652return -EBUSY;76537654ret = ath11k_mac_vdev_stop(arvif);7655if (ret) {7656ath11k_warn(ab, "failed to stop vdev %i: %d\n",7657arvif->vdev_id, ret);7658return ret;7659}76607661arvif->is_started = false;76627663/* TODO: Setup ps and cts/rts protection */7664return 0;7665}76667667static u8 ath11k_mac_get_num_pwr_levels(struct cfg80211_chan_def *chan_def)7668{7669if (chan_def->chan->flags & IEEE80211_CHAN_PSD) {7670switch (chan_def->width) {7671case NL80211_CHAN_WIDTH_20:7672return 1;7673case NL80211_CHAN_WIDTH_40:7674return 2;7675case NL80211_CHAN_WIDTH_80:7676return 4;7677case NL80211_CHAN_WIDTH_80P80:7678case NL80211_CHAN_WIDTH_160:7679return 8;7680default:7681return 1;7682}7683} else {7684switch (chan_def->width) {7685case NL80211_CHAN_WIDTH_20:7686return 1;7687case NL80211_CHAN_WIDTH_40:7688return 2;7689case NL80211_CHAN_WIDTH_80:7690return 3;7691case NL80211_CHAN_WIDTH_80P80:7692case NL80211_CHAN_WIDTH_160:7693return 4;7694default:7695return 1;7696}7697}7698}76997700static u16 ath11k_mac_get_6ghz_start_frequency(struct cfg80211_chan_def *chan_def)7701{7702u16 diff_seq;77037704/* It is to get the lowest channel number's center frequency of the chan.7705* For example,7706* bandwidth=40 MHz, center frequency is 5965, lowest channel is 17707* with center frequency 5955, its diff is 5965 - 5955 = 10.7708* bandwidth=80 MHz, center frequency is 5985, lowest channel is 17709* with center frequency 5955, its diff is 5985 - 5955 = 30.7710* bandwidth=160 MHz, center frequency is 6025, lowest channel is 17711* with center frequency 5955, its diff is 6025 - 5955 = 70.7712*/7713switch (chan_def->width) {7714case NL80211_CHAN_WIDTH_160:7715diff_seq = 70;7716break;7717case NL80211_CHAN_WIDTH_80:7718case NL80211_CHAN_WIDTH_80P80:7719diff_seq = 30;7720break;7721case NL80211_CHAN_WIDTH_40:7722diff_seq = 10;7723break;7724default:7725diff_seq = 0;7726}77277728return chan_def->center_freq1 - diff_seq;7729}77307731static u16 ath11k_mac_get_seg_freq(struct cfg80211_chan_def *chan_def,7732u16 start_seq, u8 seq)7733{7734u16 seg_seq;77357736/* It is to get the center frequency of the specific bandwidth.7737* start_seq means the lowest channel number's center frequency.7738* seq 0/1/2/3 means 20 MHz/40 MHz/80 MHz/160 MHz&80P80.7739* For example,7740* lowest channel is 1, its center frequency 5955,7741* center frequency is 5955 when bandwidth=20 MHz, its diff is 5955 - 5955 = 0.7742* lowest channel is 1, its center frequency 5955,7743* center frequency is 5965 when bandwidth=40 MHz, its diff is 5965 - 5955 = 10.7744* lowest channel is 1, its center frequency 5955,7745* center frequency is 5985 when bandwidth=80 MHz, its diff is 5985 - 5955 = 30.7746* lowest channel is 1, its center frequency 5955,7747* center frequency is 6025 when bandwidth=160 MHz, its diff is 6025 - 5955 = 70.7748*/7749if (chan_def->width == NL80211_CHAN_WIDTH_80P80 && seq == 3)7750return chan_def->center_freq2;77517752seg_seq = 10 * (BIT(seq) - 1);7753return seg_seq + start_seq;7754}77557756static void ath11k_mac_get_psd_channel(struct ath11k *ar,7757u16 step_freq,7758u16 *start_freq,7759u16 *center_freq,7760u8 i,7761struct ieee80211_channel **temp_chan,7762s8 *tx_power)7763{7764/* It is to get the center frequency for each 20 MHz.7765* For example, if the chan is 160 MHz and center frequency is 6025,7766* then it include 8 channels, they are 1/5/9/13/17/21/25/29,7767* channel number 1's center frequency is 5955, it is parameter start_freq.7768* parameter i is the step of the 8 channels. i is 0~7 for the 8 channels.7769* the channel 1/5/9/13/17/21/25/29 maps i=0/1/2/3/4/5/6/7,7770* and maps its center frequency is 5955/5975/5995/6015/6035/6055/6075/6095,7771* the gap is 20 for each channel, parameter step_freq means the gap.7772* after get the center frequency of each channel, it is easy to find the7773* struct ieee80211_channel of it and get the max_reg_power.7774*/7775*center_freq = *start_freq + i * step_freq;7776*temp_chan = ieee80211_get_channel(ar->hw->wiphy, *center_freq);7777*tx_power = (*temp_chan)->max_reg_power;7778}77797780static void ath11k_mac_get_eirp_power(struct ath11k *ar,7781u16 *start_freq,7782u16 *center_freq,7783u8 i,7784struct ieee80211_channel **temp_chan,7785struct cfg80211_chan_def *def,7786s8 *tx_power)7787{7788/* It is to get the center frequency for 20 MHz/40 MHz/80 MHz/7789* 160 MHz&80P80 bandwidth, and then plus 10 to the center frequency,7790* it is the center frequency of a channel number.7791* For example, when configured channel number is 1.7792* center frequency is 5965 when bandwidth=40 MHz, after plus 10, it is 5975,7793* then it is channel number 5.7794* center frequency is 5985 when bandwidth=80 MHz, after plus 10, it is 5995,7795* then it is channel number 9.7796* center frequency is 6025 when bandwidth=160 MHz, after plus 10, it is 6035,7797* then it is channel number 17.7798* after get the center frequency of each channel, it is easy to find the7799* struct ieee80211_channel of it and get the max_reg_power.7800*/7801*center_freq = ath11k_mac_get_seg_freq(def, *start_freq, i);78027803/* For the 20 MHz, its center frequency is same with same channel */7804if (i != 0)7805*center_freq += 10;78067807*temp_chan = ieee80211_get_channel(ar->hw->wiphy, *center_freq);7808*tx_power = (*temp_chan)->max_reg_power;7809}78107811void ath11k_mac_fill_reg_tpc_info(struct ath11k *ar,7812struct ieee80211_vif *vif,7813struct ieee80211_chanctx_conf *ctx)7814{7815struct ath11k_base *ab = ar->ab;7816struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);7817struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;7818struct ath11k_reg_tpc_power_info *reg_tpc_info = &arvif->reg_tpc_info;7819struct ieee80211_channel *chan, *temp_chan;7820u8 pwr_lvl_idx, num_pwr_levels, pwr_reduction;7821bool is_psd_power = false, is_tpe_present = false;7822s8 max_tx_power[ATH11K_NUM_PWR_LEVELS],7823psd_power, tx_power;7824s8 eirp_power = 0;7825u16 start_freq, center_freq;78267827chan = ctx->def.chan;7828start_freq = ath11k_mac_get_6ghz_start_frequency(&ctx->def);7829pwr_reduction = bss_conf->pwr_reduction;78307831if (arvif->reg_tpc_info.num_pwr_levels) {7832is_tpe_present = true;7833num_pwr_levels = arvif->reg_tpc_info.num_pwr_levels;7834} else {7835num_pwr_levels =7836ath11k_mac_get_num_pwr_levels(&bss_conf->chanreq.oper);7837}78387839for (pwr_lvl_idx = 0; pwr_lvl_idx < num_pwr_levels; pwr_lvl_idx++) {7840/* STA received TPE IE*/7841if (is_tpe_present) {7842/* local power is PSD power*/7843if (chan->flags & IEEE80211_CHAN_PSD) {7844/* Connecting AP is psd power */7845if (reg_tpc_info->is_psd_power) {7846is_psd_power = true;7847ath11k_mac_get_psd_channel(ar, 20,7848&start_freq,7849¢er_freq,7850pwr_lvl_idx,7851&temp_chan,7852&tx_power);7853psd_power = temp_chan->psd;7854eirp_power = tx_power;7855max_tx_power[pwr_lvl_idx] =7856min_t(s8,7857psd_power,7858reg_tpc_info->tpe[pwr_lvl_idx]);7859/* Connecting AP is not psd power */7860} else {7861ath11k_mac_get_eirp_power(ar,7862&start_freq,7863¢er_freq,7864pwr_lvl_idx,7865&temp_chan,7866&ctx->def,7867&tx_power);7868psd_power = temp_chan->psd;7869/* convert psd power to EIRP power based7870* on channel width7871*/7872tx_power =7873min_t(s8, tx_power,7874psd_power + 13 + pwr_lvl_idx * 3);7875max_tx_power[pwr_lvl_idx] =7876min_t(s8,7877tx_power,7878reg_tpc_info->tpe[pwr_lvl_idx]);7879}7880/* local power is not PSD power */7881} else {7882/* Connecting AP is psd power */7883if (reg_tpc_info->is_psd_power) {7884is_psd_power = true;7885ath11k_mac_get_psd_channel(ar, 20,7886&start_freq,7887¢er_freq,7888pwr_lvl_idx,7889&temp_chan,7890&tx_power);7891eirp_power = tx_power;7892max_tx_power[pwr_lvl_idx] =7893reg_tpc_info->tpe[pwr_lvl_idx];7894/* Connecting AP is not psd power */7895} else {7896ath11k_mac_get_eirp_power(ar,7897&start_freq,7898¢er_freq,7899pwr_lvl_idx,7900&temp_chan,7901&ctx->def,7902&tx_power);7903max_tx_power[pwr_lvl_idx] =7904min_t(s8,7905tx_power,7906reg_tpc_info->tpe[pwr_lvl_idx]);7907}7908}7909/* STA not received TPE IE */7910} else {7911/* local power is PSD power*/7912if (chan->flags & IEEE80211_CHAN_PSD) {7913is_psd_power = true;7914ath11k_mac_get_psd_channel(ar, 20,7915&start_freq,7916¢er_freq,7917pwr_lvl_idx,7918&temp_chan,7919&tx_power);7920psd_power = temp_chan->psd;7921eirp_power = tx_power;7922max_tx_power[pwr_lvl_idx] = psd_power;7923} else {7924ath11k_mac_get_eirp_power(ar,7925&start_freq,7926¢er_freq,7927pwr_lvl_idx,7928&temp_chan,7929&ctx->def,7930&tx_power);7931max_tx_power[pwr_lvl_idx] = tx_power;7932}7933}79347935if (is_psd_power) {7936/* If AP local power constraint is present */7937if (pwr_reduction)7938eirp_power = eirp_power - pwr_reduction;79397940/* If firmware updated max tx power is non zero, then take7941* the min of firmware updated ap tx power7942* and max power derived from above mentioned parameters.7943*/7944ath11k_dbg(ab, ATH11K_DBG_MAC,7945"eirp power : %d firmware report power : %d\n",7946eirp_power, ar->max_allowed_tx_power);7947/* Firmware reports lower max_allowed_tx_power during vdev7948* start response. In case of 6 GHz, firmware is not aware7949* of EIRP power unless driver sets EIRP power through WMI7950* TPC command. So radio which does not support idle power7951* save can set maximum calculated EIRP power directly to7952* firmware through TPC command without min comparison with7953* vdev start response's max_allowed_tx_power.7954*/7955if (ar->max_allowed_tx_power && ab->hw_params.idle_ps)7956eirp_power = min_t(s8,7957eirp_power,7958ar->max_allowed_tx_power);7959} else {7960/* If AP local power constraint is present */7961if (pwr_reduction)7962max_tx_power[pwr_lvl_idx] =7963max_tx_power[pwr_lvl_idx] - pwr_reduction;7964/* If firmware updated max tx power is non zero, then take7965* the min of firmware updated ap tx power7966* and max power derived from above mentioned parameters.7967*/7968if (ar->max_allowed_tx_power && ab->hw_params.idle_ps)7969max_tx_power[pwr_lvl_idx] =7970min_t(s8,7971max_tx_power[pwr_lvl_idx],7972ar->max_allowed_tx_power);7973}7974reg_tpc_info->chan_power_info[pwr_lvl_idx].chan_cfreq = center_freq;7975reg_tpc_info->chan_power_info[pwr_lvl_idx].tx_power =7976max_tx_power[pwr_lvl_idx];7977}79787979reg_tpc_info->num_pwr_levels = num_pwr_levels;7980reg_tpc_info->is_psd_power = is_psd_power;7981reg_tpc_info->eirp_power = eirp_power;7982reg_tpc_info->ap_power_type =7983ath11k_reg_ap_pwr_convert(vif->bss_conf.power_type);7984}79857986static void ath11k_mac_parse_tx_pwr_env(struct ath11k *ar,7987struct ieee80211_vif *vif,7988struct ieee80211_chanctx_conf *ctx)7989{7990struct ath11k_base *ab = ar->ab;7991struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);7992struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;7993struct ieee80211_parsed_tpe_eirp *non_psd = NULL;7994struct ieee80211_parsed_tpe_psd *psd = NULL;7995enum wmi_reg_6ghz_client_type client_type;7996struct cur_regulatory_info *reg_info;7997u8 local_tpe_count, reg_tpe_count;7998bool use_local_tpe;7999int i;80008001reg_info = &ab->reg_info_store[ar->pdev_idx];8002client_type = reg_info->client_type;80038004local_tpe_count =8005bss_conf->tpe.max_local[client_type].valid +8006bss_conf->tpe.psd_local[client_type].valid;8007reg_tpe_count =8008bss_conf->tpe.max_reg_client[client_type].valid +8009bss_conf->tpe.psd_reg_client[client_type].valid;80108011if (!reg_tpe_count && !local_tpe_count) {8012ath11k_warn(ab,8013"no transmit power envelope match client power type %d\n",8014client_type);8015return;8016} else if (!reg_tpe_count) {8017use_local_tpe = true;8018} else {8019use_local_tpe = false;8020}80218022if (use_local_tpe) {8023psd = &bss_conf->tpe.psd_local[client_type];8024if (!psd->valid)8025psd = NULL;8026non_psd = &bss_conf->tpe.max_local[client_type];8027if (!non_psd->valid)8028non_psd = NULL;8029} else {8030psd = &bss_conf->tpe.psd_reg_client[client_type];8031if (!psd->valid)8032psd = NULL;8033non_psd = &bss_conf->tpe.max_reg_client[client_type];8034if (!non_psd->valid)8035non_psd = NULL;8036}80378038if (non_psd && !psd) {8039arvif->reg_tpc_info.is_psd_power = false;8040arvif->reg_tpc_info.eirp_power = 0;80418042arvif->reg_tpc_info.num_pwr_levels = non_psd->count;80438044for (i = 0; i < arvif->reg_tpc_info.num_pwr_levels; i++) {8045ath11k_dbg(ab, ATH11K_DBG_MAC,8046"non PSD power[%d] : %d\n",8047i, non_psd->power[i]);8048arvif->reg_tpc_info.tpe[i] = non_psd->power[i] / 2;8049}8050}80518052if (psd) {8053arvif->reg_tpc_info.is_psd_power = true;8054arvif->reg_tpc_info.num_pwr_levels = psd->count;80558056for (i = 0; i < arvif->reg_tpc_info.num_pwr_levels; i++) {8057ath11k_dbg(ab, ATH11K_DBG_MAC,8058"TPE PSD power[%d] : %d\n",8059i, psd->power[i]);8060arvif->reg_tpc_info.tpe[i] = psd->power[i] / 2;8061}8062}8063}80648065static int8066ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,8067struct ieee80211_vif *vif,8068struct ieee80211_bss_conf *link_conf,8069struct ieee80211_chanctx_conf *ctx)8070{8071struct ath11k *ar = hw->priv;8072struct ath11k_base *ab = ar->ab;8073struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);8074int ret;80758076mutex_lock(&ar->conf_mutex);80778078ath11k_dbg(ab, ATH11K_DBG_MAC,8079"chanctx assign ptr %p vdev_id %i\n",8080ctx, arvif->vdev_id);80818082if (ath11k_wmi_supports_6ghz_cc_ext(ar) &&8083ctx->def.chan->band == NL80211_BAND_6GHZ &&8084arvif->vdev_type == WMI_VDEV_TYPE_STA) {8085arvif->chanctx = *ctx;8086ath11k_mac_parse_tx_pwr_env(ar, vif, ctx);8087}80888089/* for QCA6390 bss peer must be created before vdev_start */8090if (ab->hw_params.vdev_start_delay &&8091arvif->vdev_type != WMI_VDEV_TYPE_AP &&8092arvif->vdev_type != WMI_VDEV_TYPE_MONITOR &&8093!ath11k_peer_find_by_vdev_id(ab, arvif->vdev_id)) {8094memcpy(&arvif->chanctx, ctx, sizeof(*ctx));8095ret = 0;8096goto out;8097}80988099if (WARN_ON(arvif->is_started)) {8100ret = -EBUSY;8101goto out;8102}81038104if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {8105ret = ath11k_mac_monitor_start(ar);8106if (ret) {8107ath11k_warn(ar->ab, "failed to start monitor during vif channel context assignment: %d",8108ret);8109goto out;8110}81118112arvif->is_started = true;8113goto out;8114}81158116if (!arvif->is_started) {8117ret = ath11k_mac_vdev_start(arvif, ctx);8118if (ret) {8119ath11k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",8120arvif->vdev_id, vif->addr,8121ctx->def.chan->center_freq, ret);8122goto out;8123}81248125arvif->is_started = true;8126}81278128if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR &&8129test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) {8130ret = ath11k_mac_monitor_start(ar);8131if (ret) {8132ath11k_warn(ar->ab, "failed to start monitor during vif channel context assignment: %d",8133ret);8134goto out;8135}8136}81378138/* TODO: Setup ps and cts/rts protection */81398140ret = 0;81418142out:8143mutex_unlock(&ar->conf_mutex);81448145return ret;8146}81478148static void8149ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,8150struct ieee80211_vif *vif,8151struct ieee80211_bss_conf *link_conf,8152struct ieee80211_chanctx_conf *ctx)8153{8154struct ath11k *ar = hw->priv;8155struct ath11k_base *ab = ar->ab;8156struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);8157struct ath11k_peer *peer;8158int ret;81598160mutex_lock(&ar->conf_mutex);81618162ath11k_dbg(ab, ATH11K_DBG_MAC,8163"chanctx unassign ptr %p vdev_id %i\n",8164ctx, arvif->vdev_id);81658166if (ab->hw_params.vdev_start_delay &&8167arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {8168spin_lock_bh(&ab->base_lock);8169peer = ath11k_peer_find_by_addr(ab, ar->mac_addr);8170spin_unlock_bh(&ab->base_lock);8171if (peer)8172ath11k_peer_delete(ar, arvif->vdev_id, ar->mac_addr);8173}81748175if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {8176ret = ath11k_mac_monitor_stop(ar);8177if (ret) {8178ath11k_warn(ar->ab, "failed to stop monitor during vif channel context unassignment: %d",8179ret);8180mutex_unlock(&ar->conf_mutex);8181return;8182}81838184arvif->is_started = false;8185mutex_unlock(&ar->conf_mutex);8186return;8187}81888189if (arvif->is_started) {8190ret = ath11k_mac_vdev_stop(arvif);8191if (ret)8192ath11k_warn(ab, "failed to stop vdev %i: %d\n",8193arvif->vdev_id, ret);81948195arvif->is_started = false;8196}81978198if (ab->hw_params.vdev_start_delay &&8199arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)8200ath11k_wmi_vdev_down(ar, arvif->vdev_id);82018202if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR &&8203ar->num_started_vdevs == 1 &&8204test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) {8205ret = ath11k_mac_monitor_stop(ar);8206if (ret)8207/* continue even if there's an error */8208ath11k_warn(ar->ab, "failed to stop monitor during vif channel context unassignment: %d",8209ret);8210}82118212if (arvif->vdev_type == WMI_VDEV_TYPE_STA)8213ath11k_mac_11d_scan_start(ar, arvif->vdev_id);82148215mutex_unlock(&ar->conf_mutex);8216}82178218static int8219ath11k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,8220struct ieee80211_vif_chanctx_switch *vifs,8221int n_vifs,8222enum ieee80211_chanctx_switch_mode mode)8223{8224struct ath11k *ar = hw->priv;82258226mutex_lock(&ar->conf_mutex);82278228ath11k_dbg(ar->ab, ATH11K_DBG_MAC,8229"chanctx switch n_vifs %d mode %d\n",8230n_vifs, mode);8231ath11k_mac_update_vif_chan(ar, vifs, n_vifs);82328233mutex_unlock(&ar->conf_mutex);82348235return 0;8236}82378238static int8239ath11k_set_vdev_param_to_all_vifs(struct ath11k *ar, int param, u32 value)8240{8241struct ath11k_vif *arvif;8242int ret = 0;82438244mutex_lock(&ar->conf_mutex);8245list_for_each_entry(arvif, &ar->arvifs, list) {8246ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "setting mac vdev %d param %d value %d\n",8247param, arvif->vdev_id, value);82488249ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,8250param, value);8251if (ret) {8252ath11k_warn(ar->ab, "failed to set param %d for vdev %d: %d\n",8253param, arvif->vdev_id, ret);8254break;8255}8256}8257mutex_unlock(&ar->conf_mutex);8258return ret;8259}82608261/* mac80211 stores device specific RTS/Fragmentation threshold value,8262* this is set interface specific to firmware from ath11k driver8263*/8264static int ath11k_mac_op_set_rts_threshold(struct ieee80211_hw *hw,8265int radio_idx, u32 value)8266{8267struct ath11k *ar = hw->priv;8268int param_id = WMI_VDEV_PARAM_RTS_THRESHOLD;82698270return ath11k_set_vdev_param_to_all_vifs(ar, param_id, value);8271}82728273static int ath11k_mac_op_set_frag_threshold(struct ieee80211_hw *hw,8274int radio_idx, u32 value)8275{8276/* Even though there's a WMI vdev param for fragmentation threshold no8277* known firmware actually implements it. Moreover it is not possible to8278* rely frame fragmentation to mac80211 because firmware clears the8279* "more fragments" bit in frame control making it impossible for remote8280* devices to reassemble frames.8281*8282* Hence implement a dummy callback just to say fragmentation isn't8283* supported. This effectively prevents mac80211 from doing frame8284* fragmentation in software.8285*/8286return -EOPNOTSUPP;8287}82888289static int ath11k_mac_flush_tx_complete(struct ath11k *ar)8290{8291long time_left;8292int ret = 0;82938294time_left = wait_event_timeout(ar->dp.tx_empty_waitq,8295(atomic_read(&ar->dp.num_tx_pending) == 0),8296ATH11K_FLUSH_TIMEOUT);8297if (time_left == 0) {8298ath11k_warn(ar->ab, "failed to flush transmit queue, data pkts pending %d\n",8299atomic_read(&ar->dp.num_tx_pending));8300ret = -ETIMEDOUT;8301}83028303time_left = wait_event_timeout(ar->txmgmt_empty_waitq,8304(atomic_read(&ar->num_pending_mgmt_tx) == 0),8305ATH11K_FLUSH_TIMEOUT);8306if (time_left == 0) {8307ath11k_warn(ar->ab, "failed to flush mgmt transmit queue, mgmt pkts pending %d\n",8308atomic_read(&ar->num_pending_mgmt_tx));8309ret = -ETIMEDOUT;8310}83118312return ret;8313}83148315int ath11k_mac_wait_tx_complete(struct ath11k *ar)8316{8317ath11k_mac_drain_tx(ar);8318return ath11k_mac_flush_tx_complete(ar);8319}83208321static void ath11k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,8322u32 queues, bool drop)8323{8324struct ath11k *ar = hw->priv;83258326if (drop)8327return;83288329ath11k_mac_flush_tx_complete(ar);8330}83318332static bool8333ath11k_mac_has_single_legacy_rate(struct ath11k *ar,8334enum nl80211_band band,8335const struct cfg80211_bitrate_mask *mask)8336{8337int num_rates = 0;83388339num_rates = hweight32(mask->control[band].legacy);83408341if (ath11k_mac_bitrate_mask_num_ht_rates(ar, band, mask))8342return false;83438344if (ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask))8345return false;83468347if (ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask))8348return false;83498350return num_rates == 1;8351}83528353static __le168354ath11k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap)8355{8356if (he_cap->he_cap_elem.phy_cap_info[0] &8357IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)8358return he_cap->he_mcs_nss_supp.tx_mcs_80p80;83598360if (he_cap->he_cap_elem.phy_cap_info[0] &8361IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)8362return he_cap->he_mcs_nss_supp.tx_mcs_160;83638364return he_cap->he_mcs_nss_supp.tx_mcs_80;8365}83668367static bool8368ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar,8369struct ath11k_vif *arvif,8370enum nl80211_band band,8371const struct cfg80211_bitrate_mask *mask,8372int *nss)8373{8374struct ieee80211_supported_band *sband = &ar->mac.sbands[band];8375u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);8376const struct ieee80211_sta_he_cap *he_cap;8377u16 he_mcs_map = 0;8378u8 ht_nss_mask = 0;8379u8 vht_nss_mask = 0;8380u8 he_nss_mask = 0;8381int i;83828383/* No need to consider legacy here. Basic rates are always present8384* in bitrate mask8385*/83868387for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {8388if (mask->control[band].ht_mcs[i] == 0)8389continue;8390else if (mask->control[band].ht_mcs[i] ==8391sband->ht_cap.mcs.rx_mask[i])8392ht_nss_mask |= BIT(i);8393else8394return false;8395}83968397for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {8398if (mask->control[band].vht_mcs[i] == 0)8399continue;8400else if (mask->control[band].vht_mcs[i] ==8401ath11k_mac_get_max_vht_mcs_map(vht_mcs_map, i))8402vht_nss_mask |= BIT(i);8403else8404return false;8405}84068407he_cap = ieee80211_get_he_iftype_cap_vif(sband, arvif->vif);8408if (!he_cap)8409return false;84108411he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(he_cap));84128413for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {8414if (mask->control[band].he_mcs[i] == 0)8415continue;84168417if (mask->control[band].he_mcs[i] ==8418ath11k_mac_get_max_he_mcs_map(he_mcs_map, i))8419he_nss_mask |= BIT(i);8420else8421return false;8422}84238424if (ht_nss_mask != vht_nss_mask || ht_nss_mask != he_nss_mask)8425return false;84268427if (ht_nss_mask == 0)8428return false;84298430if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)8431return false;84328433*nss = fls(ht_nss_mask);84348435return true;8436}84378438static int8439ath11k_mac_get_single_legacy_rate(struct ath11k *ar,8440enum nl80211_band band,8441const struct cfg80211_bitrate_mask *mask,8442u32 *rate, u8 *nss)8443{8444int rate_idx;8445u16 bitrate;8446u8 preamble;8447u8 hw_rate;84488449if (hweight32(mask->control[band].legacy) != 1)8450return -EINVAL;84518452rate_idx = ffs(mask->control[band].legacy) - 1;84538454if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ)8455rate_idx += ATH11K_MAC_FIRST_OFDM_RATE_IDX;84568457hw_rate = ath11k_legacy_rates[rate_idx].hw_value;8458bitrate = ath11k_legacy_rates[rate_idx].bitrate;84598460if (ath11k_mac_bitrate_is_cck(bitrate))8461preamble = WMI_RATE_PREAMBLE_CCK;8462else8463preamble = WMI_RATE_PREAMBLE_OFDM;84648465*nss = 1;8466*rate = ATH11K_HW_RATE_CODE(hw_rate, 0, preamble);84678468return 0;8469}84708471static int8472ath11k_mac_set_fixed_rate_gi_ltf(struct ath11k_vif *arvif, u8 he_gi, u8 he_ltf)8473{8474struct ath11k *ar = arvif->ar;8475int ret;84768477/* 0.8 = 0, 1.6 = 2 and 3.2 = 3. */8478if (he_gi && he_gi != 0xFF)8479he_gi += 1;84808481ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,8482WMI_VDEV_PARAM_SGI, he_gi);8483if (ret) {8484ath11k_warn(ar->ab, "failed to set he gi %d: %d\n",8485he_gi, ret);8486return ret;8487}8488/* start from 1 */8489if (he_ltf != 0xFF)8490he_ltf += 1;84918492ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,8493WMI_VDEV_PARAM_HE_LTF, he_ltf);8494if (ret) {8495ath11k_warn(ar->ab, "failed to set he ltf %d: %d\n",8496he_ltf, ret);8497return ret;8498}84998500return 0;8501}85028503static int8504ath11k_mac_set_auto_rate_gi_ltf(struct ath11k_vif *arvif, u16 he_gi, u8 he_ltf)8505{8506struct ath11k *ar = arvif->ar;8507int ret;8508u32 he_ar_gi_ltf;85098510if (he_gi != 0xFF) {8511switch (he_gi) {8512case NL80211_RATE_INFO_HE_GI_0_8:8513he_gi = WMI_AUTORATE_800NS_GI;8514break;8515case NL80211_RATE_INFO_HE_GI_1_6:8516he_gi = WMI_AUTORATE_1600NS_GI;8517break;8518case NL80211_RATE_INFO_HE_GI_3_2:8519he_gi = WMI_AUTORATE_3200NS_GI;8520break;8521default:8522ath11k_warn(ar->ab, "invalid he gi: %d\n", he_gi);8523return -EINVAL;8524}8525}85268527if (he_ltf != 0xFF) {8528switch (he_ltf) {8529case NL80211_RATE_INFO_HE_1XLTF:8530he_ltf = WMI_HE_AUTORATE_LTF_1X;8531break;8532case NL80211_RATE_INFO_HE_2XLTF:8533he_ltf = WMI_HE_AUTORATE_LTF_2X;8534break;8535case NL80211_RATE_INFO_HE_4XLTF:8536he_ltf = WMI_HE_AUTORATE_LTF_4X;8537break;8538default:8539ath11k_warn(ar->ab, "invalid he ltf: %d\n", he_ltf);8540return -EINVAL;8541}8542}85438544he_ar_gi_ltf = he_gi | he_ltf;8545ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,8546WMI_VDEV_PARAM_AUTORATE_MISC_CFG,8547he_ar_gi_ltf);8548if (ret) {8549ath11k_warn(ar->ab,8550"failed to set he autorate gi %u ltf %u: %d\n",8551he_gi, he_ltf, ret);8552return ret;8553}85548555return 0;8556}85578558static int ath11k_mac_set_rate_params(struct ath11k_vif *arvif,8559u32 rate, u8 nss, u8 sgi, u8 ldpc,8560u8 he_gi, u8 he_ltf, bool he_fixed_rate)8561{8562struct ath11k *ar = arvif->ar;8563u32 vdev_param;8564int ret;85658566lockdep_assert_held(&ar->conf_mutex);85678568ath11k_dbg(ar->ab, ATH11K_DBG_MAC,8569"set rate params vdev %i rate 0x%02x nss 0x%02x sgi 0x%02x ldpc 0x%02x he_gi 0x%02x he_ltf 0x%02x he_fixed_rate %d\n",8570arvif->vdev_id, rate, nss, sgi, ldpc, he_gi,8571he_ltf, he_fixed_rate);85728573if (!arvif->vif->bss_conf.he_support) {8574vdev_param = WMI_VDEV_PARAM_FIXED_RATE;8575ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,8576vdev_param, rate);8577if (ret) {8578ath11k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n",8579rate, ret);8580return ret;8581}8582}85838584vdev_param = WMI_VDEV_PARAM_NSS;8585ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,8586vdev_param, nss);8587if (ret) {8588ath11k_warn(ar->ab, "failed to set nss param %d: %d\n",8589nss, ret);8590return ret;8591}85928593vdev_param = WMI_VDEV_PARAM_LDPC;8594ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,8595vdev_param, ldpc);8596if (ret) {8597ath11k_warn(ar->ab, "failed to set ldpc param %d: %d\n",8598ldpc, ret);8599return ret;8600}86018602if (arvif->vif->bss_conf.he_support) {8603if (he_fixed_rate) {8604ret = ath11k_mac_set_fixed_rate_gi_ltf(arvif, he_gi,8605he_ltf);8606if (ret) {8607ath11k_warn(ar->ab, "failed to set fixed rate gi ltf: %d\n",8608ret);8609return ret;8610}8611} else {8612ret = ath11k_mac_set_auto_rate_gi_ltf(arvif, he_gi,8613he_ltf);8614if (ret) {8615ath11k_warn(ar->ab, "failed to set auto rate gi ltf: %d\n",8616ret);8617return ret;8618}8619}8620} else {8621vdev_param = WMI_VDEV_PARAM_SGI;8622ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,8623vdev_param, sgi);8624if (ret) {8625ath11k_warn(ar->ab, "failed to set sgi param %d: %d\n",8626sgi, ret);8627return ret;8628}8629}86308631return 0;8632}86338634static bool8635ath11k_mac_vht_mcs_range_present(struct ath11k *ar,8636enum nl80211_band band,8637const struct cfg80211_bitrate_mask *mask)8638{8639int i;8640u16 vht_mcs;86418642for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {8643vht_mcs = mask->control[band].vht_mcs[i];86448645switch (vht_mcs) {8646case 0:8647case BIT(8) - 1:8648case BIT(9) - 1:8649case BIT(10) - 1:8650break;8651default:8652return false;8653}8654}86558656return true;8657}86588659static bool8660ath11k_mac_he_mcs_range_present(struct ath11k *ar,8661enum nl80211_band band,8662const struct cfg80211_bitrate_mask *mask)8663{8664int i;8665u16 he_mcs;86668667for (i = 0; i < NL80211_HE_NSS_MAX; i++) {8668he_mcs = mask->control[band].he_mcs[i];86698670switch (he_mcs) {8671case 0:8672case BIT(8) - 1:8673case BIT(10) - 1:8674case BIT(12) - 1:8675break;8676default:8677return false;8678}8679}86808681return true;8682}86838684static void ath11k_mac_set_bitrate_mask_iter(void *data,8685struct ieee80211_sta *sta)8686{8687struct ath11k_vif *arvif = data;8688struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);8689struct ath11k *ar = arvif->ar;86908691spin_lock_bh(&ar->data_lock);8692arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;8693spin_unlock_bh(&ar->data_lock);86948695ieee80211_queue_work(ar->hw, &arsta->update_wk);8696}86978698static void ath11k_mac_disable_peer_fixed_rate(void *data,8699struct ieee80211_sta *sta)8700{8701struct ath11k_vif *arvif = data;8702struct ath11k *ar = arvif->ar;8703int ret;87048705ret = ath11k_wmi_set_peer_param(ar, sta->addr,8706arvif->vdev_id,8707WMI_PEER_PARAM_FIXED_RATE,8708WMI_FIXED_RATE_NONE);8709if (ret)8710ath11k_warn(ar->ab,8711"failed to disable peer fixed rate for STA %pM ret %d\n",8712sta->addr, ret);8713}87148715static bool8716ath11k_mac_validate_vht_he_fixed_rate_settings(struct ath11k *ar, enum nl80211_band band,8717const struct cfg80211_bitrate_mask *mask)8718{8719bool he_fixed_rate = false, vht_fixed_rate = false;8720struct ath11k_peer *peer;8721const u16 *vht_mcs_mask, *he_mcs_mask;8722struct ieee80211_link_sta *deflink;8723u8 vht_nss, he_nss;8724bool ret = true;87258726vht_mcs_mask = mask->control[band].vht_mcs;8727he_mcs_mask = mask->control[band].he_mcs;87288729if (ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask) == 1)8730vht_fixed_rate = true;87318732if (ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask) == 1)8733he_fixed_rate = true;87348735if (!vht_fixed_rate && !he_fixed_rate)8736return true;87378738vht_nss = ath11k_mac_max_vht_nss(vht_mcs_mask);8739he_nss = ath11k_mac_max_he_nss(he_mcs_mask);87408741rcu_read_lock();8742spin_lock_bh(&ar->ab->base_lock);8743list_for_each_entry(peer, &ar->ab->peers, list) {8744if (peer->sta) {8745deflink = &peer->sta->deflink;87468747if (vht_fixed_rate && (!deflink->vht_cap.vht_supported ||8748deflink->rx_nss < vht_nss)) {8749ret = false;8750goto out;8751}87528753if (he_fixed_rate && (!deflink->he_cap.has_he ||8754deflink->rx_nss < he_nss)) {8755ret = false;8756goto out;8757}8758}8759}87608761out:8762spin_unlock_bh(&ar->ab->base_lock);8763rcu_read_unlock();8764return ret;8765}87668767static int8768ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,8769struct ieee80211_vif *vif,8770const struct cfg80211_bitrate_mask *mask)8771{8772struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);8773struct cfg80211_chan_def def;8774struct ath11k_pdev_cap *cap;8775struct ath11k *ar = arvif->ar;8776enum nl80211_band band;8777const u8 *ht_mcs_mask;8778const u16 *vht_mcs_mask;8779const u16 *he_mcs_mask;8780u8 he_ltf = 0;8781u8 he_gi = 0;8782u32 rate;8783u8 nss;8784u8 sgi;8785u8 ldpc;8786int single_nss;8787int ret;8788int num_rates;8789bool he_fixed_rate = false;87908791if (ath11k_mac_vif_chan(vif, &def))8792return -EPERM;87938794band = def.chan->band;8795cap = &ar->pdev->cap;8796ht_mcs_mask = mask->control[band].ht_mcs;8797vht_mcs_mask = mask->control[band].vht_mcs;8798he_mcs_mask = mask->control[band].he_mcs;8799ldpc = !!(cap->band[band].ht_cap_info & WMI_HT_CAP_TX_LDPC);88008801sgi = mask->control[band].gi;8802if (sgi == NL80211_TXRATE_FORCE_LGI)8803return -EINVAL;88048805he_gi = mask->control[band].he_gi;8806he_ltf = mask->control[band].he_ltf;88078808/* mac80211 doesn't support sending a fixed HT/VHT MCS alone, rather it8809* requires passing at least one of used basic rates along with them.8810* Fixed rate setting across different preambles(legacy, HT, VHT) is8811* not supported by the FW. Hence use of FIXED_RATE vdev param is not8812* suitable for setting single HT/VHT rates.8813* But, there could be a single basic rate passed from userspace which8814* can be done through the FIXED_RATE param.8815*/8816if (ath11k_mac_has_single_legacy_rate(ar, band, mask)) {8817ret = ath11k_mac_get_single_legacy_rate(ar, band, mask, &rate,8818&nss);8819if (ret) {8820ath11k_warn(ar->ab, "failed to get single legacy rate for vdev %i: %d\n",8821arvif->vdev_id, ret);8822return ret;8823}8824ieee80211_iterate_stations_mtx(ar->hw,8825ath11k_mac_disable_peer_fixed_rate,8826arvif);8827} else if (ath11k_mac_bitrate_mask_get_single_nss(ar, arvif, band, mask,8828&single_nss)) {8829rate = WMI_FIXED_RATE_NONE;8830nss = single_nss;8831mutex_lock(&ar->conf_mutex);8832arvif->bitrate_mask = *mask;8833ieee80211_iterate_stations_atomic(ar->hw,8834ath11k_mac_set_bitrate_mask_iter,8835arvif);8836mutex_unlock(&ar->conf_mutex);8837} else {8838rate = WMI_FIXED_RATE_NONE;88398840if (!ath11k_mac_validate_vht_he_fixed_rate_settings(ar, band, mask))8841ath11k_warn(ar->ab,8842"could not update fixed rate settings to all peers due to mcs/nss incompatibility\n");8843nss = min_t(u32, ar->num_tx_chains,8844ath11k_mac_max_nss(ht_mcs_mask, vht_mcs_mask, he_mcs_mask));88458846/* If multiple rates across different preambles are given8847* we can reconfigure this info with all peers using PEER_ASSOC8848* command with the below exception cases.8849* - Single VHT Rate : peer_assoc command accommodates only MCS8850* range values i.e 0-7, 0-8, 0-9 for VHT. Though mac802118851* mandates passing basic rates along with HT/VHT rates, FW8852* doesn't allow switching from VHT to Legacy. Hence instead of8853* setting legacy and VHT rates using RATEMASK_CMD vdev cmd,8854* we could set this VHT rate as peer fixed rate param, which8855* will override FIXED rate and FW rate control algorithm.8856* If single VHT rate is passed along with HT rates, we select8857* the VHT rate as fixed rate for vht peers.8858* - Multiple VHT Rates : When Multiple VHT rates are given,this8859* can be set using RATEMASK CMD which uses FW rate-ctl alg.8860* TODO: Setting multiple VHT MCS and replacing peer_assoc with8861* RATEMASK_CMDID can cover all use cases of setting rates8862* across multiple preambles and rates within same type.8863* But requires more validation of the command at this point.8864*/88658866num_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band,8867mask);88688869if (!ath11k_mac_vht_mcs_range_present(ar, band, mask) &&8870num_rates > 1) {8871/* TODO: Handle multiple VHT MCS values setting using8872* RATEMASK CMD8873*/8874ath11k_warn(ar->ab,8875"setting %d mcs values in bitrate mask not supported\n",8876num_rates);8877return -EINVAL;8878}88798880num_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band,8881mask);8882if (num_rates == 1)8883he_fixed_rate = true;88848885if (!ath11k_mac_he_mcs_range_present(ar, band, mask) &&8886num_rates > 1) {8887ath11k_warn(ar->ab,8888"Setting more than one HE MCS Value in bitrate mask not supported\n");8889return -EINVAL;8890}88918892mutex_lock(&ar->conf_mutex);8893ieee80211_iterate_stations_mtx(ar->hw,8894ath11k_mac_disable_peer_fixed_rate,8895arvif);88968897arvif->bitrate_mask = *mask;8898ieee80211_iterate_stations_atomic(ar->hw,8899ath11k_mac_set_bitrate_mask_iter,8900arvif);89018902mutex_unlock(&ar->conf_mutex);8903}89048905mutex_lock(&ar->conf_mutex);89068907ret = ath11k_mac_set_rate_params(arvif, rate, nss, sgi, ldpc, he_gi,8908he_ltf, he_fixed_rate);8909if (ret) {8910ath11k_warn(ar->ab, "failed to set rate params on vdev %i: %d\n",8911arvif->vdev_id, ret);8912}89138914mutex_unlock(&ar->conf_mutex);89158916return ret;8917}89188919static void8920ath11k_mac_op_reconfig_complete(struct ieee80211_hw *hw,8921enum ieee80211_reconfig_type reconfig_type)8922{8923struct ath11k *ar = hw->priv;8924struct ath11k_base *ab = ar->ab;8925int recovery_count;8926struct ath11k_vif *arvif;89278928if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)8929return;89308931mutex_lock(&ar->conf_mutex);89328933if (ar->state == ATH11K_STATE_RESTARTED) {8934ath11k_warn(ar->ab, "pdev %d successfully recovered\n",8935ar->pdev->pdev_id);8936ar->state = ATH11K_STATE_ON;8937ieee80211_wake_queues(ar->hw);89388939if (ar->ab->hw_params.current_cc_support &&8940ar->alpha2[0] != 0 && ar->alpha2[1] != 0)8941ath11k_reg_set_cc(ar);89428943if (ab->is_reset) {8944recovery_count = atomic_inc_return(&ab->recovery_count);8945ath11k_dbg(ab, ATH11K_DBG_BOOT,8946"recovery count %d\n", recovery_count);8947/* When there are multiple radios in an SOC,8948* the recovery has to be done for each radio8949*/8950if (recovery_count == ab->num_radios) {8951atomic_dec(&ab->reset_count);8952complete(&ab->reset_complete);8953ab->is_reset = false;8954atomic_set(&ab->fail_cont_count, 0);8955ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset success\n");8956}8957}8958if (ar->ab->hw_params.support_fw_mac_sequence) {8959list_for_each_entry(arvif, &ar->arvifs, list) {8960if (arvif->is_up && arvif->vdev_type == WMI_VDEV_TYPE_STA)8961ieee80211_hw_restart_disconnect(arvif->vif);8962}8963}8964}89658966mutex_unlock(&ar->conf_mutex);8967}89688969static void8970ath11k_mac_update_bss_chan_survey(struct ath11k *ar,8971struct ieee80211_channel *channel)8972{8973int ret;8974enum wmi_bss_chan_info_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ;89758976lockdep_assert_held(&ar->conf_mutex);89778978if (!test_bit(WMI_TLV_SERVICE_BSS_CHANNEL_INFO_64, ar->ab->wmi_ab.svc_map) ||8979ar->rx_channel != channel)8980return;89818982if (ar->scan.state != ATH11K_SCAN_IDLE) {8983ath11k_dbg(ar->ab, ATH11K_DBG_MAC,8984"ignoring bss chan info req while scanning..\n");8985return;8986}89878988reinit_completion(&ar->bss_survey_done);89898990ret = ath11k_wmi_pdev_bss_chan_info_request(ar, type);8991if (ret) {8992ath11k_warn(ar->ab, "failed to send pdev bss chan info request\n");8993return;8994}89958996ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);8997if (ret == 0)8998ath11k_warn(ar->ab, "bss channel survey timed out\n");8999}90009001static int ath11k_mac_op_get_survey(struct ieee80211_hw *hw, int idx,9002struct survey_info *survey)9003{9004struct ath11k *ar = hw->priv;9005struct ieee80211_supported_band *sband;9006struct survey_info *ar_survey;9007int ret = 0;90089009if (idx >= ATH11K_NUM_CHANS)9010return -ENOENT;90119012ar_survey = &ar->survey[idx];90139014mutex_lock(&ar->conf_mutex);90159016sband = hw->wiphy->bands[NL80211_BAND_2GHZ];9017if (sband && idx >= sband->n_channels) {9018idx -= sband->n_channels;9019sband = NULL;9020}90219022if (!sband)9023sband = hw->wiphy->bands[NL80211_BAND_5GHZ];9024if (sband && idx >= sband->n_channels) {9025idx -= sband->n_channels;9026sband = NULL;9027}90289029if (!sband)9030sband = hw->wiphy->bands[NL80211_BAND_6GHZ];9031if (!sband || idx >= sband->n_channels) {9032ret = -ENOENT;9033goto exit;9034}90359036ath11k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);90379038spin_lock_bh(&ar->data_lock);9039memcpy(survey, ar_survey, sizeof(*survey));9040spin_unlock_bh(&ar->data_lock);90419042survey->channel = &sband->channels[idx];90439044if (ar->rx_channel == survey->channel)9045survey->filled |= SURVEY_INFO_IN_USE;90469047exit:9048mutex_unlock(&ar->conf_mutex);9049return ret;9050}90519052static void ath11k_mac_put_chain_rssi(struct station_info *sinfo,9053struct ath11k_sta *arsta,9054char *pre,9055bool clear)9056{9057struct ath11k *ar = arsta->arvif->ar;9058int i;9059s8 rssi;90609061for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {9062sinfo->chains &= ~BIT(i);9063rssi = arsta->chain_signal[i];9064if (clear)9065arsta->chain_signal[i] = ATH11K_INVALID_RSSI_FULL;90669067ath11k_dbg(ar->ab, ATH11K_DBG_MAC,9068"sta statistics %s rssi[%d] %d\n", pre, i, rssi);90699070if (rssi != ATH11K_DEFAULT_NOISE_FLOOR &&9071rssi != ATH11K_INVALID_RSSI_FULL &&9072rssi != ATH11K_INVALID_RSSI_EMPTY &&9073rssi != 0) {9074sinfo->chain_signal[i] = rssi;9075sinfo->chains |= BIT(i);9076sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);9077}9078}9079}90809081static void ath11k_mac_fw_stats_reset(struct ath11k *ar)9082{9083spin_lock_bh(&ar->data_lock);9084ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);9085ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);9086ar->fw_stats.num_vdev_recvd = 0;9087ar->fw_stats.num_bcn_recvd = 0;9088spin_unlock_bh(&ar->data_lock);9089}90909091int ath11k_mac_fw_stats_request(struct ath11k *ar,9092struct stats_request_params *req_param)9093{9094struct ath11k_base *ab = ar->ab;9095unsigned long time_left;9096int ret;90979098lockdep_assert_held(&ar->conf_mutex);90999100ath11k_mac_fw_stats_reset(ar);91019102reinit_completion(&ar->fw_stats_complete);9103reinit_completion(&ar->fw_stats_done);91049105ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);91069107if (ret) {9108ath11k_warn(ab, "could not request fw stats (%d)\n",9109ret);9110return ret;9111}91129113time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);9114if (!time_left)9115return -ETIMEDOUT;91169117/* FW stats can get split when exceeding the stats data buffer limit.9118* In that case, since there is no end marking for the back-to-back9119* received 'update stats' event, we keep a 3 seconds timeout in case,9120* fw_stats_done is not marked yet9121*/9122time_left = wait_for_completion_timeout(&ar->fw_stats_done, 3 * HZ);9123if (!time_left)9124return -ETIMEDOUT;91259126return 0;9127}91289129static int ath11k_mac_get_fw_stats(struct ath11k *ar, u32 pdev_id,9130u32 vdev_id, u32 stats_id)9131{9132struct ath11k_base *ab = ar->ab;9133struct stats_request_params req_param;9134int ret;91359136lockdep_assert_held(&ar->conf_mutex);91379138if (ar->state != ATH11K_STATE_ON)9139return -ENETDOWN;91409141req_param.pdev_id = pdev_id;9142req_param.vdev_id = vdev_id;9143req_param.stats_id = stats_id;91449145ret = ath11k_mac_fw_stats_request(ar, &req_param);9146if (ret)9147ath11k_warn(ab, "failed to request fw stats: %d\n", ret);91489149ath11k_dbg(ab, ATH11K_DBG_WMI,9150"debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",9151pdev_id, vdev_id, stats_id);91529153return ret;9154}91559156static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw,9157struct ieee80211_vif *vif,9158struct ieee80211_sta *sta,9159struct station_info *sinfo)9160{9161struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);9162struct ath11k *ar = arsta->arvif->ar;9163s8 signal;9164bool db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,9165ar->ab->wmi_ab.svc_map);91669167sinfo->rx_duration = arsta->rx_duration;9168sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);91699170sinfo->tx_duration = arsta->tx_duration;9171sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION);91729173if (arsta->txrate.legacy || arsta->txrate.nss) {9174if (arsta->txrate.legacy) {9175sinfo->txrate.legacy = arsta->txrate.legacy;9176} else {9177sinfo->txrate.mcs = arsta->txrate.mcs;9178sinfo->txrate.nss = arsta->txrate.nss;9179sinfo->txrate.bw = arsta->txrate.bw;9180sinfo->txrate.he_gi = arsta->txrate.he_gi;9181sinfo->txrate.he_dcm = arsta->txrate.he_dcm;9182sinfo->txrate.he_ru_alloc = arsta->txrate.he_ru_alloc;9183}9184sinfo->txrate.flags = arsta->txrate.flags;9185sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);9186}91879188ath11k_mac_put_chain_rssi(sinfo, arsta, "ppdu", false);91899190mutex_lock(&ar->conf_mutex);9191if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) &&9192arsta->arvif->vdev_type == WMI_VDEV_TYPE_STA &&9193ar->ab->hw_params.supports_rssi_stats &&9194!ath11k_mac_get_fw_stats(ar, ar->pdev->pdev_id, 0,9195WMI_REQUEST_RSSI_PER_CHAIN_STAT)) {9196ath11k_mac_put_chain_rssi(sinfo, arsta, "fw stats", true);9197}91989199signal = arsta->rssi_comb;9200if (!signal &&9201arsta->arvif->vdev_type == WMI_VDEV_TYPE_STA &&9202ar->ab->hw_params.supports_rssi_stats &&9203!(ath11k_mac_get_fw_stats(ar, ar->pdev->pdev_id, 0,9204WMI_REQUEST_VDEV_STAT)))9205signal = arsta->rssi_beacon;9206mutex_unlock(&ar->conf_mutex);92079208ath11k_dbg(ar->ab, ATH11K_DBG_MAC,9209"sta statistics db2dbm %u rssi comb %d rssi beacon %d\n",9210db2dbm, arsta->rssi_comb, arsta->rssi_beacon);92119212if (signal) {9213sinfo->signal = db2dbm ? signal : signal + ATH11K_DEFAULT_NOISE_FLOOR;9214sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);9215}92169217sinfo->signal_avg = ewma_avg_rssi_read(&arsta->avg_rssi);92189219if (!db2dbm)9220sinfo->signal_avg += ATH11K_DEFAULT_NOISE_FLOOR;92219222sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);9223}92249225#if IS_ENABLED(CONFIG_IPV6)9226static void ath11k_generate_ns_mc_addr(struct ath11k *ar,9227struct ath11k_arp_ns_offload *offload)9228{9229int i;92309231for (i = 0; i < offload->ipv6_count; i++) {9232offload->self_ipv6_addr[i][0] = 0xff;9233offload->self_ipv6_addr[i][1] = 0x02;9234offload->self_ipv6_addr[i][11] = 0x01;9235offload->self_ipv6_addr[i][12] = 0xff;9236offload->self_ipv6_addr[i][13] =9237offload->ipv6_addr[i][13];9238offload->self_ipv6_addr[i][14] =9239offload->ipv6_addr[i][14];9240offload->self_ipv6_addr[i][15] =9241offload->ipv6_addr[i][15];9242ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "NS solicited addr %pI6\n",9243offload->self_ipv6_addr[i]);9244}9245}92469247static void ath11k_mac_op_ipv6_changed(struct ieee80211_hw *hw,9248struct ieee80211_vif *vif,9249struct inet6_dev *idev)9250{9251struct ath11k *ar = hw->priv;9252struct ath11k_arp_ns_offload *offload;9253struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);9254struct inet6_ifaddr *ifa6;9255struct ifacaddr6 *ifaca6;9256u32 count, scope;92579258ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "op ipv6 changed\n");92599260offload = &arvif->arp_ns_offload;9261count = 0;92629263/* The _ipv6_changed() is called with RCU lock already held in9264* atomic_notifier_call_chain(), so we don't need to call9265* rcu_read_lock() again here. But note that with CONFIG_PREEMPT_RT9266* enabled, read_lock_bh() also calls rcu_read_lock(). This is OK9267* because RCU read critical section is allowed to get nested.9268*/9269read_lock_bh(&idev->lock);92709271memset(offload->ipv6_addr, 0, sizeof(offload->ipv6_addr));9272memset(offload->self_ipv6_addr, 0, sizeof(offload->self_ipv6_addr));9273memcpy(offload->mac_addr, vif->addr, ETH_ALEN);92749275/* get unicast address */9276list_for_each_entry(ifa6, &idev->addr_list, if_list) {9277if (count >= ATH11K_IPV6_MAX_COUNT)9278goto generate;92799280if (ifa6->flags & IFA_F_DADFAILED)9281continue;9282scope = ipv6_addr_src_scope(&ifa6->addr);9283if (scope == IPV6_ADDR_SCOPE_LINKLOCAL ||9284scope == IPV6_ADDR_SCOPE_GLOBAL) {9285memcpy(offload->ipv6_addr[count], &ifa6->addr.s6_addr,9286sizeof(ifa6->addr.s6_addr));9287offload->ipv6_type[count] = ATH11K_IPV6_UC_TYPE;9288ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "count %d ipv6 uc %pI6 scope %d\n",9289count, offload->ipv6_addr[count],9290scope);9291count++;9292} else {9293ath11k_warn(ar->ab, "Unsupported ipv6 scope: %d\n", scope);9294}9295}92969297/* get anycast address */9298for (ifaca6 = rcu_dereference(idev->ac_list); ifaca6;9299ifaca6 = rcu_dereference(ifaca6->aca_next)) {9300if (count >= ATH11K_IPV6_MAX_COUNT)9301goto generate;93029303scope = ipv6_addr_src_scope(&ifaca6->aca_addr);9304if (scope == IPV6_ADDR_SCOPE_LINKLOCAL ||9305scope == IPV6_ADDR_SCOPE_GLOBAL) {9306memcpy(offload->ipv6_addr[count], &ifaca6->aca_addr,9307sizeof(ifaca6->aca_addr));9308offload->ipv6_type[count] = ATH11K_IPV6_AC_TYPE;9309ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "count %d ipv6 ac %pI6 scope %d\n",9310count, offload->ipv6_addr[count],9311scope);9312count++;9313} else {9314ath11k_warn(ar->ab, "Unsupported ipv scope: %d\n", scope);9315}9316}93179318generate:9319offload->ipv6_count = count;9320read_unlock_bh(&idev->lock);93219322/* generate ns multicast address */9323ath11k_generate_ns_mc_addr(ar, offload);9324}9325#endif93269327static void ath11k_mac_op_set_rekey_data(struct ieee80211_hw *hw,9328struct ieee80211_vif *vif,9329struct cfg80211_gtk_rekey_data *data)9330{9331struct ath11k *ar = hw->priv;9332struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);9333struct ath11k_rekey_data *rekey_data = &arvif->rekey_data;93349335ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "set rekey data vdev %d\n",9336arvif->vdev_id);93379338mutex_lock(&ar->conf_mutex);93399340memcpy(rekey_data->kck, data->kck, NL80211_KCK_LEN);9341memcpy(rekey_data->kek, data->kek, NL80211_KEK_LEN);93429343/* The supplicant works on big-endian, the firmware expects it on9344* little endian.9345*/9346rekey_data->replay_ctr = get_unaligned_be64(data->replay_ctr);93479348arvif->rekey_data.enable_offload = true;93499350ath11k_dbg_dump(ar->ab, ATH11K_DBG_MAC, "kck", NULL,9351rekey_data->kck, NL80211_KCK_LEN);9352ath11k_dbg_dump(ar->ab, ATH11K_DBG_MAC, "kek", NULL,9353rekey_data->kck, NL80211_KEK_LEN);9354ath11k_dbg_dump(ar->ab, ATH11K_DBG_MAC, "replay ctr", NULL,9355&rekey_data->replay_ctr, sizeof(rekey_data->replay_ctr));93569357mutex_unlock(&ar->conf_mutex);9358}93599360static int ath11k_mac_op_set_bios_sar_specs(struct ieee80211_hw *hw,9361const struct cfg80211_sar_specs *sar)9362{9363struct ath11k *ar = hw->priv;9364const struct cfg80211_sar_sub_specs *sspec;9365int ret, index;9366u8 *sar_tbl;9367u32 i;93689369if (!sar || sar->type != NL80211_SAR_TYPE_POWER ||9370sar->num_sub_specs == 0)9371return -EINVAL;93729373mutex_lock(&ar->conf_mutex);93749375if (!test_bit(WMI_TLV_SERVICE_BIOS_SAR_SUPPORT, ar->ab->wmi_ab.svc_map) ||9376!ar->ab->hw_params.bios_sar_capa) {9377ret = -EOPNOTSUPP;9378goto exit;9379}93809381ret = ath11k_wmi_pdev_set_bios_geo_table_param(ar);9382if (ret) {9383ath11k_warn(ar->ab, "failed to set geo table: %d\n", ret);9384goto exit;9385}93869387sar_tbl = kzalloc(BIOS_SAR_TABLE_LEN, GFP_KERNEL);9388if (!sar_tbl) {9389ret = -ENOMEM;9390goto exit;9391}93929393sspec = sar->sub_specs;9394for (i = 0; i < sar->num_sub_specs; i++) {9395if (sspec->freq_range_index >= (BIOS_SAR_TABLE_LEN >> 1)) {9396ath11k_warn(ar->ab, "Ignore bad frequency index %u, max allowed %u\n",9397sspec->freq_range_index, BIOS_SAR_TABLE_LEN >> 1);9398continue;9399}94009401/* chain0 and chain1 share same power setting */9402sar_tbl[sspec->freq_range_index] = sspec->power;9403index = sspec->freq_range_index + (BIOS_SAR_TABLE_LEN >> 1);9404sar_tbl[index] = sspec->power;9405ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "sar tbl[%d] = %d\n",9406sspec->freq_range_index, sar_tbl[sspec->freq_range_index]);9407sspec++;9408}94099410ret = ath11k_wmi_pdev_set_bios_sar_table_param(ar, sar_tbl);9411if (ret)9412ath11k_warn(ar->ab, "failed to set sar power: %d", ret);94139414kfree(sar_tbl);9415exit:9416mutex_unlock(&ar->conf_mutex);94179418return ret;9419}94209421static int ath11k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw,9422struct ieee80211_vif *vif)9423{9424struct ath11k *ar = hw->priv;94259426mutex_lock(&ar->conf_mutex);94279428spin_lock_bh(&ar->data_lock);9429ar->scan.roc_notify = false;9430spin_unlock_bh(&ar->data_lock);94319432ath11k_scan_abort(ar);94339434mutex_unlock(&ar->conf_mutex);94359436cancel_delayed_work_sync(&ar->scan.timeout);94379438return 0;9439}94409441static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,9442struct ieee80211_vif *vif,9443struct ieee80211_channel *chan,9444int duration,9445enum ieee80211_roc_type type)9446{9447struct ath11k *ar = hw->priv;9448struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);9449struct scan_req_params *arg;9450int ret;9451u32 scan_time_msec;94529453mutex_lock(&ar->conf_mutex);94549455spin_lock_bh(&ar->data_lock);9456switch (ar->scan.state) {9457case ATH11K_SCAN_IDLE:9458reinit_completion(&ar->scan.started);9459reinit_completion(&ar->scan.completed);9460reinit_completion(&ar->scan.on_channel);9461ar->scan.state = ATH11K_SCAN_STARTING;9462ar->scan.is_roc = true;9463ar->scan.vdev_id = arvif->vdev_id;9464ar->scan.roc_freq = chan->center_freq;9465ar->scan.roc_notify = true;9466ret = 0;9467break;9468case ATH11K_SCAN_STARTING:9469case ATH11K_SCAN_RUNNING:9470case ATH11K_SCAN_ABORTING:9471ret = -EBUSY;9472break;9473}9474spin_unlock_bh(&ar->data_lock);94759476if (ret)9477goto exit;94789479scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;94809481arg = kzalloc(sizeof(*arg), GFP_KERNEL);9482if (!arg) {9483ret = -ENOMEM;9484goto exit;9485}9486ath11k_wmi_start_scan_init(ar, arg);9487arg->num_chan = 1;9488arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list),9489GFP_KERNEL);9490if (!arg->chan_list) {9491ret = -ENOMEM;9492goto free_arg;9493}94949495arg->vdev_id = arvif->vdev_id;9496arg->scan_id = ATH11K_SCAN_ID;9497arg->chan_list[0] = chan->center_freq;9498arg->dwell_time_active = scan_time_msec;9499arg->dwell_time_passive = scan_time_msec;9500arg->max_scan_time = scan_time_msec;9501arg->scan_f_passive = 1;9502arg->burst_duration = duration;95039504if (!ar->ab->hw_params.single_pdev_only)9505arg->scan_f_filter_prb_req = 1;95069507ret = ath11k_start_scan(ar, arg);9508if (ret) {9509ath11k_warn(ar->ab, "failed to start roc scan: %d\n", ret);95109511spin_lock_bh(&ar->data_lock);9512ar->scan.state = ATH11K_SCAN_IDLE;9513spin_unlock_bh(&ar->data_lock);9514goto free_chan_list;9515}95169517ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);9518if (ret == 0) {9519ath11k_warn(ar->ab, "failed to switch to channel for roc scan\n");9520ret = ath11k_scan_stop(ar);9521if (ret)9522ath11k_warn(ar->ab, "failed to stop scan: %d\n", ret);9523ret = -ETIMEDOUT;9524goto free_chan_list;9525}95269527ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,9528msecs_to_jiffies(duration));95299530ret = 0;95319532free_chan_list:9533kfree(arg->chan_list);9534free_arg:9535kfree(arg);9536exit:9537mutex_unlock(&ar->conf_mutex);9538return ret;9539}95409541static int ath11k_mac_op_get_txpower(struct ieee80211_hw *hw,9542struct ieee80211_vif *vif,9543unsigned int link_id,9544int *dbm)9545{9546struct ath11k *ar = hw->priv;9547struct ath11k_base *ab = ar->ab;9548struct ath11k_fw_stats_pdev *pdev;9549int ret;95509551/* Final Tx power is minimum of Target Power, CTL power, Regulatory9552* Power, PSD EIRP Power. We just know the Regulatory power from the9553* regulatory rules obtained. FW knows all these power and sets the min9554* of these. Hence, we request the FW pdev stats in which FW reports9555* the minimum of all vdev's channel Tx power.9556*/9557mutex_lock(&ar->conf_mutex);95589559/* Firmware doesn't provide Tx power during CAC hence no need to fetch9560* the stats.9561*/9562if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) {9563mutex_unlock(&ar->conf_mutex);9564return -EAGAIN;9565}95669567ret = ath11k_mac_get_fw_stats(ar, ar->pdev->pdev_id, 0,9568WMI_REQUEST_PDEV_STAT);9569if (ret) {9570ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);9571goto err_fallback;9572}95739574spin_lock_bh(&ar->data_lock);9575pdev = list_first_entry_or_null(&ar->fw_stats.pdevs,9576struct ath11k_fw_stats_pdev, list);9577if (!pdev) {9578spin_unlock_bh(&ar->data_lock);9579goto err_fallback;9580}95819582/* tx power is set as 2 units per dBm in FW. */9583*dbm = pdev->chan_tx_power / 2;95849585spin_unlock_bh(&ar->data_lock);9586mutex_unlock(&ar->conf_mutex);95879588ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "txpower from firmware %d, reported %d dBm\n",9589pdev->chan_tx_power, *dbm);9590return 0;95919592err_fallback:9593mutex_unlock(&ar->conf_mutex);9594/* We didn't get txpower from FW. Hence, relying on vif->bss_conf.txpower */9595*dbm = vif->bss_conf.txpower;9596ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "txpower from firmware NaN, reported %d dBm\n",9597*dbm);9598return 0;9599}96009601static int ath11k_mac_station_add(struct ath11k *ar,9602struct ieee80211_vif *vif,9603struct ieee80211_sta *sta)9604{9605struct ath11k_base *ab = ar->ab;9606struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);9607struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);9608struct peer_create_params peer_param;9609int ret;96109611lockdep_assert_held(&ar->conf_mutex);96129613ret = ath11k_mac_inc_num_stations(arvif, sta);9614if (ret) {9615ath11k_warn(ab, "refusing to associate station: too many connected already (%d)\n",9616ar->max_num_stations);9617goto exit;9618}96199620/* Driver allows the DEL KEY followed by SET KEY sequence for9621* group keys for only when there is no clients associated, if at9622* all firmware has entered the race during that window,9623* reinstalling the same key when the first sta connects will allow9624* firmware to recover from the race.9625*/9626if (arvif->num_stations == 1 && arvif->reinstall_group_keys) {9627ath11k_dbg(ab, ATH11K_DBG_MAC, "set group keys on 1st station add for vdev %d\n",9628arvif->vdev_id);9629ret = ath11k_set_group_keys(arvif);9630if (ret)9631goto dec_num_station;9632arvif->reinstall_group_keys = false;9633}96349635arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL);9636if (!arsta->rx_stats) {9637ret = -ENOMEM;9638goto dec_num_station;9639}96409641peer_param.vdev_id = arvif->vdev_id;9642peer_param.peer_addr = sta->addr;9643peer_param.peer_type = WMI_PEER_TYPE_DEFAULT;96449645ret = ath11k_peer_create(ar, arvif, sta, &peer_param);9646if (ret) {9647ath11k_warn(ab, "Failed to add peer: %pM for VDEV: %d\n",9648sta->addr, arvif->vdev_id);9649goto free_rx_stats;9650}96519652ath11k_dbg(ab, ATH11K_DBG_MAC, "Added peer: %pM for VDEV: %d\n",9653sta->addr, arvif->vdev_id);96549655if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) {9656arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats), GFP_KERNEL);9657if (!arsta->tx_stats) {9658ret = -ENOMEM;9659goto free_peer;9660}9661}96629663if (ieee80211_vif_is_mesh(vif)) {9664ath11k_dbg(ab, ATH11K_DBG_MAC,9665"setting USE_4ADDR for mesh STA %pM\n", sta->addr);9666ret = ath11k_wmi_set_peer_param(ar, sta->addr,9667arvif->vdev_id,9668WMI_PEER_USE_4ADDR, 1);9669if (ret) {9670ath11k_warn(ab, "failed to set mesh STA %pM 4addr capability: %d\n",9671sta->addr, ret);9672goto free_tx_stats;9673}9674}96759676ret = ath11k_dp_peer_setup(ar, arvif->vdev_id, sta->addr);9677if (ret) {9678ath11k_warn(ab, "failed to setup dp for peer %pM on vdev %i (%d)\n",9679sta->addr, arvif->vdev_id, ret);9680goto free_tx_stats;9681}96829683if (ab->hw_params.vdev_start_delay &&9684!arvif->is_started &&9685arvif->vdev_type != WMI_VDEV_TYPE_AP) {9686ret = ath11k_mac_start_vdev_delay(ar->hw, vif);9687if (ret) {9688ath11k_warn(ab, "failed to delay vdev start: %d\n", ret);9689goto free_tx_stats;9690}9691}96929693ewma_avg_rssi_init(&arsta->avg_rssi);9694return 0;96959696free_tx_stats:9697kfree(arsta->tx_stats);9698arsta->tx_stats = NULL;9699free_peer:9700ath11k_peer_delete(ar, arvif->vdev_id, sta->addr);9701free_rx_stats:9702kfree(arsta->rx_stats);9703arsta->rx_stats = NULL;9704dec_num_station:9705ath11k_mac_dec_num_stations(arvif, sta);9706exit:9707return ret;9708}97099710static int ath11k_mac_station_remove(struct ath11k *ar,9711struct ieee80211_vif *vif,9712struct ieee80211_sta *sta)9713{9714struct ath11k_base *ab = ar->ab;9715struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);9716struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);9717int ret;97189719if (ab->hw_params.vdev_start_delay &&9720arvif->is_started &&9721arvif->vdev_type != WMI_VDEV_TYPE_AP) {9722ret = ath11k_mac_stop_vdev_early(ar->hw, vif);9723if (ret) {9724ath11k_warn(ab, "failed to do early vdev stop: %d\n", ret);9725return ret;9726}9727}97289729ath11k_dp_peer_cleanup(ar, arvif->vdev_id, sta->addr);97309731ret = ath11k_peer_delete(ar, arvif->vdev_id, sta->addr);9732if (ret)9733ath11k_warn(ab, "Failed to delete peer: %pM for VDEV: %d\n",9734sta->addr, arvif->vdev_id);9735else9736ath11k_dbg(ab, ATH11K_DBG_MAC, "Removed peer: %pM for VDEV: %d\n",9737sta->addr, arvif->vdev_id);97389739ath11k_mac_dec_num_stations(arvif, sta);97409741kfree(arsta->tx_stats);9742arsta->tx_stats = NULL;97439744kfree(arsta->rx_stats);9745arsta->rx_stats = NULL;97469747return ret;9748}97499750static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,9751struct ieee80211_vif *vif,9752struct ieee80211_sta *sta,9753enum ieee80211_sta_state old_state,9754enum ieee80211_sta_state new_state)9755{9756struct ath11k *ar = hw->priv;9757struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);9758struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);9759enum ieee80211_ap_reg_power power_type;9760struct cur_regulatory_info *reg_info;9761struct ath11k_peer *peer;9762int ret = 0;97639764/* cancel must be done outside the mutex to avoid deadlock */9765if ((old_state == IEEE80211_STA_NONE &&9766new_state == IEEE80211_STA_NOTEXIST)) {9767cancel_work_sync(&arsta->update_wk);9768cancel_work_sync(&arsta->set_4addr_wk);9769}97709771mutex_lock(&ar->conf_mutex);97729773if (old_state == IEEE80211_STA_NOTEXIST &&9774new_state == IEEE80211_STA_NONE) {9775memset(arsta, 0, sizeof(*arsta));9776arsta->arvif = arvif;9777arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;9778INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk);9779INIT_WORK(&arsta->set_4addr_wk, ath11k_sta_set_4addr_wk);97809781ret = ath11k_mac_station_add(ar, vif, sta);9782if (ret)9783ath11k_warn(ar->ab, "Failed to add station: %pM for VDEV: %d\n",9784sta->addr, arvif->vdev_id);9785} else if ((old_state == IEEE80211_STA_NONE &&9786new_state == IEEE80211_STA_NOTEXIST)) {9787ret = ath11k_mac_station_remove(ar, vif, sta);9788if (ret)9789ath11k_warn(ar->ab, "Failed to remove station: %pM for VDEV: %d\n",9790sta->addr, arvif->vdev_id);97919792mutex_lock(&ar->ab->tbl_mtx_lock);9793spin_lock_bh(&ar->ab->base_lock);9794peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);9795if (peer && peer->sta == sta) {9796ath11k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n",9797vif->addr, arvif->vdev_id);9798ath11k_peer_rhash_delete(ar->ab, peer);9799peer->sta = NULL;9800list_del(&peer->list);9801kfree(peer);9802ar->num_peers--;9803}9804spin_unlock_bh(&ar->ab->base_lock);9805mutex_unlock(&ar->ab->tbl_mtx_lock);9806} else if (old_state == IEEE80211_STA_AUTH &&9807new_state == IEEE80211_STA_ASSOC &&9808(vif->type == NL80211_IFTYPE_AP ||9809vif->type == NL80211_IFTYPE_MESH_POINT ||9810vif->type == NL80211_IFTYPE_ADHOC)) {9811ret = ath11k_station_assoc(ar, vif, sta, false);9812if (ret)9813ath11k_warn(ar->ab, "Failed to associate station: %pM\n",9814sta->addr);98159816spin_lock_bh(&ar->data_lock);9817/* Set arsta bw and prev bw */9818arsta->bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta);9819arsta->bw_prev = arsta->bw;9820spin_unlock_bh(&ar->data_lock);9821} else if (old_state == IEEE80211_STA_ASSOC &&9822new_state == IEEE80211_STA_AUTHORIZED) {9823spin_lock_bh(&ar->ab->base_lock);98249825peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);9826if (peer)9827peer->is_authorized = true;98289829spin_unlock_bh(&ar->ab->base_lock);98309831if (vif->type == NL80211_IFTYPE_STATION && arvif->is_up) {9832ret = ath11k_wmi_set_peer_param(ar, sta->addr,9833arvif->vdev_id,9834WMI_PEER_AUTHORIZE,98351);9836if (ret)9837ath11k_warn(ar->ab, "Unable to authorize peer %pM vdev %d: %d\n",9838sta->addr, arvif->vdev_id, ret);9839}98409841if (!ret &&9842ath11k_wmi_supports_6ghz_cc_ext(ar) &&9843arvif->vdev_type == WMI_VDEV_TYPE_STA &&9844arvif->chanctx.def.chan &&9845arvif->chanctx.def.chan->band == NL80211_BAND_6GHZ) {9846reg_info = &ar->ab->reg_info_store[ar->pdev_idx];9847power_type = vif->bss_conf.power_type;98489849if (power_type == IEEE80211_REG_UNSET_AP) {9850ath11k_warn(ar->ab, "invalid power type %d\n",9851power_type);9852ret = -EINVAL;9853} else {9854ret = ath11k_reg_handle_chan_list(ar->ab,9855reg_info,9856power_type);9857if (ret)9858ath11k_warn(ar->ab,9859"failed to handle chan list with power type %d\n",9860power_type);9861}9862}9863} else if (old_state == IEEE80211_STA_AUTHORIZED &&9864new_state == IEEE80211_STA_ASSOC) {9865spin_lock_bh(&ar->ab->base_lock);98669867peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);9868if (peer)9869peer->is_authorized = false;98709871spin_unlock_bh(&ar->ab->base_lock);9872} else if (old_state == IEEE80211_STA_ASSOC &&9873new_state == IEEE80211_STA_AUTH &&9874(vif->type == NL80211_IFTYPE_AP ||9875vif->type == NL80211_IFTYPE_MESH_POINT ||9876vif->type == NL80211_IFTYPE_ADHOC)) {9877ret = ath11k_station_disassoc(ar, vif, sta);9878if (ret)9879ath11k_warn(ar->ab, "Failed to disassociate station: %pM\n",9880sta->addr);9881}98829883mutex_unlock(&ar->conf_mutex);9884return ret;9885}98869887static const struct ieee80211_ops ath11k_ops = {9888.tx = ath11k_mac_op_tx,9889.wake_tx_queue = ieee80211_handle_wake_tx_queue,9890.start = ath11k_mac_op_start,9891.stop = ath11k_mac_op_stop,9892.reconfig_complete = ath11k_mac_op_reconfig_complete,9893.add_interface = ath11k_mac_op_add_interface,9894.remove_interface = ath11k_mac_op_remove_interface,9895.update_vif_offload = ath11k_mac_op_update_vif_offload,9896.config = ath11k_mac_op_config,9897.bss_info_changed = ath11k_mac_op_bss_info_changed,9898.configure_filter = ath11k_mac_op_configure_filter,9899.hw_scan = ath11k_mac_op_hw_scan,9900.cancel_hw_scan = ath11k_mac_op_cancel_hw_scan,9901.set_key = ath11k_mac_op_set_key,9902.set_rekey_data = ath11k_mac_op_set_rekey_data,9903.sta_state = ath11k_mac_op_sta_state,9904.sta_set_4addr = ath11k_mac_op_sta_set_4addr,9905.sta_set_txpwr = ath11k_mac_op_sta_set_txpwr,9906.link_sta_rc_update = ath11k_mac_op_sta_rc_update,9907.conf_tx = ath11k_mac_op_conf_tx,9908.set_antenna = ath11k_mac_op_set_antenna,9909.get_antenna = ath11k_mac_op_get_antenna,9910.ampdu_action = ath11k_mac_op_ampdu_action,9911.add_chanctx = ath11k_mac_op_add_chanctx,9912.remove_chanctx = ath11k_mac_op_remove_chanctx,9913.change_chanctx = ath11k_mac_op_change_chanctx,9914.assign_vif_chanctx = ath11k_mac_op_assign_vif_chanctx,9915.unassign_vif_chanctx = ath11k_mac_op_unassign_vif_chanctx,9916.switch_vif_chanctx = ath11k_mac_op_switch_vif_chanctx,9917.set_rts_threshold = ath11k_mac_op_set_rts_threshold,9918.set_frag_threshold = ath11k_mac_op_set_frag_threshold,9919.set_bitrate_mask = ath11k_mac_op_set_bitrate_mask,9920.get_survey = ath11k_mac_op_get_survey,9921.flush = ath11k_mac_op_flush,9922.sta_statistics = ath11k_mac_op_sta_statistics,9923CFG80211_TESTMODE_CMD(ath11k_tm_cmd)99249925#ifdef CONFIG_PM9926.suspend = ath11k_wow_op_suspend,9927.resume = ath11k_wow_op_resume,9928.set_wakeup = ath11k_wow_op_set_wakeup,9929#endif99309931#ifdef CONFIG_ATH11K_DEBUGFS9932.vif_add_debugfs = ath11k_debugfs_op_vif_add,9933.sta_add_debugfs = ath11k_debugfs_sta_op_add,9934#endif99359936#if IS_ENABLED(CONFIG_IPV6)9937.ipv6_addr_change = ath11k_mac_op_ipv6_changed,9938#endif9939.get_txpower = ath11k_mac_op_get_txpower,99409941.set_sar_specs = ath11k_mac_op_set_bios_sar_specs,9942.remain_on_channel = ath11k_mac_op_remain_on_channel,9943.cancel_remain_on_channel = ath11k_mac_op_cancel_remain_on_channel,9944};99459946static void ath11k_mac_update_ch_list(struct ath11k *ar,9947struct ieee80211_supported_band *band,9948u32 freq_low, u32 freq_high)9949{9950int i;99519952if (!(freq_low && freq_high))9953return;99549955for (i = 0; i < band->n_channels; i++) {9956if (band->channels[i].center_freq < freq_low ||9957band->channels[i].center_freq > freq_high)9958band->channels[i].flags |= IEEE80211_CHAN_DISABLED;9959}9960}99619962static u32 ath11k_get_phy_id(struct ath11k *ar, u32 band)9963{9964struct ath11k_pdev *pdev = ar->pdev;9965struct ath11k_pdev_cap *pdev_cap = &pdev->cap;99669967if (band == WMI_HOST_WLAN_2G_CAP)9968return pdev_cap->band[NL80211_BAND_2GHZ].phy_id;99699970if (band == WMI_HOST_WLAN_5G_CAP)9971return pdev_cap->band[NL80211_BAND_5GHZ].phy_id;99729973ath11k_warn(ar->ab, "unsupported phy cap:%d\n", band);99749975return 0;9976}99779978static int ath11k_mac_setup_channels_rates(struct ath11k *ar,9979u32 supported_bands)9980{9981struct ieee80211_supported_band *band;9982struct ath11k_hal_reg_capabilities_ext *reg_cap, *temp_reg_cap;9983void *channels;9984u32 phy_id;99859986BUILD_BUG_ON((ARRAY_SIZE(ath11k_2ghz_channels) +9987ARRAY_SIZE(ath11k_5ghz_channels) +9988ARRAY_SIZE(ath11k_6ghz_channels)) !=9989ATH11K_NUM_CHANS);99909991reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx];9992temp_reg_cap = reg_cap;99939994if (supported_bands & WMI_HOST_WLAN_2G_CAP) {9995channels = kmemdup(ath11k_2ghz_channels,9996sizeof(ath11k_2ghz_channels),9997GFP_KERNEL);9998if (!channels)9999return -ENOMEM;1000010001band = &ar->mac.sbands[NL80211_BAND_2GHZ];10002band->band = NL80211_BAND_2GHZ;10003band->n_channels = ARRAY_SIZE(ath11k_2ghz_channels);10004band->channels = channels;10005band->n_bitrates = ath11k_g_rates_size;10006band->bitrates = ath11k_g_rates;10007ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;1000810009if (ar->ab->hw_params.single_pdev_only) {10010phy_id = ath11k_get_phy_id(ar, WMI_HOST_WLAN_2G_CAP);10011temp_reg_cap = &ar->ab->hal_reg_cap[phy_id];10012}10013ath11k_mac_update_ch_list(ar, band,10014temp_reg_cap->low_2ghz_chan,10015temp_reg_cap->high_2ghz_chan);10016}1001710018if (supported_bands & WMI_HOST_WLAN_5G_CAP) {10019if (reg_cap->high_5ghz_chan >= ATH11K_MIN_6G_FREQ) {10020channels = kmemdup(ath11k_6ghz_channels,10021sizeof(ath11k_6ghz_channels), GFP_KERNEL);10022if (!channels) {10023kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);10024return -ENOMEM;10025}1002610027ar->supports_6ghz = true;10028band = &ar->mac.sbands[NL80211_BAND_6GHZ];10029band->band = NL80211_BAND_6GHZ;10030band->n_channels = ARRAY_SIZE(ath11k_6ghz_channels);10031band->channels = channels;10032band->n_bitrates = ath11k_a_rates_size;10033band->bitrates = ath11k_a_rates;10034ar->hw->wiphy->bands[NL80211_BAND_6GHZ] = band;1003510036if (ar->ab->hw_params.single_pdev_only) {10037phy_id = ath11k_get_phy_id(ar, WMI_HOST_WLAN_5G_CAP);10038temp_reg_cap = &ar->ab->hal_reg_cap[phy_id];10039}1004010041ath11k_mac_update_ch_list(ar, band,10042temp_reg_cap->low_5ghz_chan,10043temp_reg_cap->high_5ghz_chan);10044}1004510046if (reg_cap->low_5ghz_chan < ATH11K_MIN_6G_FREQ) {10047channels = kmemdup(ath11k_5ghz_channels,10048sizeof(ath11k_5ghz_channels),10049GFP_KERNEL);10050if (!channels) {10051kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);10052kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);10053return -ENOMEM;10054}1005510056band = &ar->mac.sbands[NL80211_BAND_5GHZ];10057band->band = NL80211_BAND_5GHZ;10058band->n_channels = ARRAY_SIZE(ath11k_5ghz_channels);10059band->channels = channels;10060band->n_bitrates = ath11k_a_rates_size;10061band->bitrates = ath11k_a_rates;10062ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;1006310064if (ar->ab->hw_params.single_pdev_only) {10065phy_id = ath11k_get_phy_id(ar, WMI_HOST_WLAN_5G_CAP);10066temp_reg_cap = &ar->ab->hal_reg_cap[phy_id];10067}1006810069ath11k_mac_update_ch_list(ar, band,10070temp_reg_cap->low_5ghz_chan,10071temp_reg_cap->high_5ghz_chan);10072}10073}1007410075return 0;10076}1007710078static void ath11k_mac_setup_mac_address_list(struct ath11k *ar)10079{10080struct mac_address *addresses;10081u16 n_addresses;10082int i;1008310084if (!ar->ab->hw_params.support_dual_stations)10085return;1008610087n_addresses = ar->ab->hw_params.num_vdevs;10088addresses = kcalloc(n_addresses, sizeof(*addresses), GFP_KERNEL);10089if (!addresses)10090return;1009110092memcpy(addresses[0].addr, ar->mac_addr, ETH_ALEN);10093for (i = 1; i < n_addresses; i++) {10094memcpy(addresses[i].addr, ar->mac_addr, ETH_ALEN);10095/* set Local Administered Address bit */10096addresses[i].addr[0] |= 0x2;1009710098addresses[i].addr[0] += (i - 1) << 4;10099}1010010101ar->hw->wiphy->addresses = addresses;10102ar->hw->wiphy->n_addresses = n_addresses;10103}1010410105static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)10106{10107struct ath11k_base *ab = ar->ab;10108struct ieee80211_iface_combination *combinations;10109struct ieee80211_iface_limit *limits;10110int n_limits, n_combos;10111bool p2p;1011210113p2p = ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_P2P_DEVICE);1011410115if (ab->hw_params.support_dual_stations)10116n_combos = 2;10117else10118n_combos = 1;1011910120combinations = kcalloc(n_combos, sizeof(*combinations), GFP_KERNEL);10121if (!combinations)10122return -ENOMEM;1012310124if (p2p)10125n_limits = 3;10126else10127n_limits = 2;1012810129limits = kcalloc(n_limits, sizeof(*limits), GFP_KERNEL);10130if (!limits) {10131kfree(combinations);10132return -ENOMEM;10133}1013410135limits[0].max = 1;10136limits[0].types |= BIT(NL80211_IFTYPE_STATION);10137limits[1].max = 16;10138limits[1].types |= BIT(NL80211_IFTYPE_AP);10139if (IS_ENABLED(CONFIG_MAC80211_MESH) &&10140ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT))10141limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT);1014210143combinations[0].limits = limits;10144combinations[0].n_limits = n_limits;10145combinations[0].beacon_int_infra_match = true;10146combinations[0].beacon_int_min_gcd = 100;10147combinations[0].max_interfaces = 16;10148combinations[0].num_different_channels = 1;10149combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |10150BIT(NL80211_CHAN_WIDTH_20) |10151BIT(NL80211_CHAN_WIDTH_40) |10152BIT(NL80211_CHAN_WIDTH_80) |10153BIT(NL80211_CHAN_WIDTH_80P80) |10154BIT(NL80211_CHAN_WIDTH_160);1015510156if (ab->hw_params.support_dual_stations) {10157limits[0].max = 2;1015810159combinations[1].limits = limits;10160combinations[1].n_limits = n_limits;10161combinations[1].beacon_int_infra_match = true;10162combinations[1].beacon_int_min_gcd = 100;10163combinations[1].max_interfaces = ab->hw_params.num_vdevs;10164combinations[1].num_different_channels = 2;10165}1016610167if (p2p) {10168limits[1].types |= BIT(NL80211_IFTYPE_P2P_CLIENT) |10169BIT(NL80211_IFTYPE_P2P_GO);10170limits[2].max = 1;10171limits[2].types |= BIT(NL80211_IFTYPE_P2P_DEVICE);10172}1017310174ar->hw->wiphy->iface_combinations = combinations;10175ar->hw->wiphy->n_iface_combinations = n_combos;1017610177return 0;10178}1017910180static const u8 ath11k_if_types_ext_capa[] = {10181[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,10182[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,10183[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,10184};1018510186static const u8 ath11k_if_types_ext_capa_sta[] = {10187[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,10188[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,10189[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,10190[9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT,10191};1019210193static const u8 ath11k_if_types_ext_capa_ap[] = {10194[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,10195[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,10196[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,10197[9] = WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT,10198[10] = WLAN_EXT_CAPA11_EMA_SUPPORT,10199};1020010201static const struct wiphy_iftype_ext_capab ath11k_iftypes_ext_capa[] = {10202{10203.extended_capabilities = ath11k_if_types_ext_capa,10204.extended_capabilities_mask = ath11k_if_types_ext_capa,10205.extended_capabilities_len = sizeof(ath11k_if_types_ext_capa),10206}, {10207.iftype = NL80211_IFTYPE_STATION,10208.extended_capabilities = ath11k_if_types_ext_capa_sta,10209.extended_capabilities_mask = ath11k_if_types_ext_capa_sta,10210.extended_capabilities_len =10211sizeof(ath11k_if_types_ext_capa_sta),10212}, {10213.iftype = NL80211_IFTYPE_AP,10214.extended_capabilities = ath11k_if_types_ext_capa_ap,10215.extended_capabilities_mask = ath11k_if_types_ext_capa_ap,10216.extended_capabilities_len =10217sizeof(ath11k_if_types_ext_capa_ap),10218},10219};1022010221static void __ath11k_mac_unregister(struct ath11k *ar)10222{10223cancel_work_sync(&ar->channel_update_work);10224cancel_work_sync(&ar->regd_update_work);1022510226ieee80211_unregister_hw(ar->hw);1022710228idr_for_each(&ar->txmgmt_idr, ath11k_mac_tx_mgmt_pending_free, ar);10229idr_destroy(&ar->txmgmt_idr);1023010231kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);10232kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);10233kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);1023410235kfree(ar->hw->wiphy->iface_combinations[0].limits);10236kfree(ar->hw->wiphy->iface_combinations);1023710238kfree(ar->hw->wiphy->addresses);1023910240SET_IEEE80211_DEV(ar->hw, NULL);10241}1024210243void ath11k_mac_unregister(struct ath11k_base *ab)10244{10245struct ath11k *ar;10246struct ath11k_pdev *pdev;10247int i;1024810249for (i = 0; i < ab->num_radios; i++) {10250pdev = &ab->pdevs[i];10251ar = pdev->ar;10252if (!ar)10253continue;1025410255__ath11k_mac_unregister(ar);10256}1025710258ath11k_peer_rhash_tbl_destroy(ab);10259}1026010261static int __ath11k_mac_register(struct ath11k *ar)10262{10263struct ath11k_base *ab = ar->ab;10264struct ath11k_pdev_cap *cap = &ar->pdev->cap;10265static const u32 cipher_suites[] = {10266WLAN_CIPHER_SUITE_TKIP,10267WLAN_CIPHER_SUITE_CCMP,10268WLAN_CIPHER_SUITE_AES_CMAC,10269WLAN_CIPHER_SUITE_BIP_CMAC_256,10270WLAN_CIPHER_SUITE_BIP_GMAC_128,10271WLAN_CIPHER_SUITE_BIP_GMAC_256,10272WLAN_CIPHER_SUITE_GCMP,10273WLAN_CIPHER_SUITE_GCMP_256,10274WLAN_CIPHER_SUITE_CCMP_256,10275};10276int ret;10277u32 ht_cap = 0;1027810279ath11k_pdev_caps_update(ar);1028010281SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);10282ath11k_mac_setup_mac_address_list(ar);1028310284SET_IEEE80211_DEV(ar->hw, ab->dev);1028510286ret = ath11k_mac_setup_channels_rates(ar,10287cap->supported_bands);10288if (ret)10289goto err;1029010291wiphy_read_of_freq_limits(ar->hw->wiphy);10292ath11k_mac_setup_ht_vht_cap(ar, cap, &ht_cap);10293ath11k_mac_setup_he_cap(ar, cap);1029410295ret = ath11k_mac_setup_iface_combinations(ar);10296if (ret) {10297ath11k_err(ar->ab, "failed to setup interface combinations: %d\n", ret);10298goto err_free_channels;10299}1030010301ar->hw->wiphy->available_antennas_rx = cap->rx_chain_mask;10302ar->hw->wiphy->available_antennas_tx = cap->tx_chain_mask;1030310304ar->hw->wiphy->interface_modes = ab->hw_params.interface_modes;1030510306if (ab->hw_params.single_pdev_only && ar->supports_6ghz)10307ieee80211_hw_set(ar->hw, SINGLE_SCAN_ON_ALL_BANDS);1030810309if (ab->hw_params.supports_multi_bssid) {10310ieee80211_hw_set(ar->hw, SUPPORTS_MULTI_BSSID);10311ieee80211_hw_set(ar->hw, SUPPORTS_ONLY_HE_MULTI_BSSID);10312}1031310314ieee80211_hw_set(ar->hw, SIGNAL_DBM);10315ieee80211_hw_set(ar->hw, SUPPORTS_PS);10316ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);10317ieee80211_hw_set(ar->hw, MFP_CAPABLE);10318ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);10319ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);10320ieee80211_hw_set(ar->hw, AP_LINK_PS);10321ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);10322ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);10323ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);10324ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);10325ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);10326ieee80211_hw_set(ar->hw, QUEUE_CONTROL);10327ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);10328ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);1032910330if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET) {10331ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);10332ieee80211_hw_set(ar->hw, SUPPORTS_RX_DECAP_OFFLOAD);10333}1033410335if (cap->nss_ratio_enabled)10336ieee80211_hw_set(ar->hw, SUPPORTS_VHT_EXT_NSS_BW);1033710338if ((ht_cap & WMI_HT_CAP_ENABLED) || ar->supports_6ghz) {10339ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);10340ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);10341ieee80211_hw_set(ar->hw, SUPPORTS_REORDERING_BUFFER);10342ieee80211_hw_set(ar->hw, SUPPORTS_AMSDU_IN_AMPDU);10343ieee80211_hw_set(ar->hw, USES_RSS);10344}1034510346ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;10347ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;1034810349/* TODO: Check if HT capability advertised from firmware is different10350* for each band for a dual band capable radio. It will be tricky to10351* handle it when the ht capability different for each band.10352*/10353if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS ||10354(ar->supports_6ghz && ab->hw_params.supports_dynamic_smps_6ghz))10355ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;1035610357ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;10358ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;1035910360ar->hw->max_listen_interval = ATH11K_MAX_HW_LISTEN_INTERVAL;1036110362ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;10363ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;10364ar->hw->wiphy->max_remain_on_channel_duration = 5000;1036510366ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;10367ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |10368NL80211_FEATURE_AP_SCAN;1036910370ar->max_num_stations = TARGET_NUM_STATIONS(ab);10371ar->max_num_peers = TARGET_NUM_PEERS_PDEV(ab);1037210373ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;1037410375if (test_bit(WMI_TLV_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi->wmi_ab->svc_map)) {10376ar->hw->wiphy->features |=10377NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;10378}1037910380if (test_bit(WMI_TLV_SERVICE_NLO, ar->wmi->wmi_ab->svc_map)) {10381ar->hw->wiphy->max_sched_scan_ssids = WMI_PNO_MAX_SUPP_NETWORKS;10382ar->hw->wiphy->max_match_sets = WMI_PNO_MAX_SUPP_NETWORKS;10383ar->hw->wiphy->max_sched_scan_ie_len = WMI_PNO_MAX_IE_LENGTH;10384ar->hw->wiphy->max_sched_scan_plans = WMI_PNO_MAX_SCHED_SCAN_PLANS;10385ar->hw->wiphy->max_sched_scan_plan_interval =10386WMI_PNO_MAX_SCHED_SCAN_PLAN_INT;10387ar->hw->wiphy->max_sched_scan_plan_iterations =10388WMI_PNO_MAX_SCHED_SCAN_PLAN_ITRNS;10389ar->hw->wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;10390}1039110392ret = ath11k_wow_init(ar);10393if (ret) {10394ath11k_warn(ar->ab, "failed to init wow: %d\n", ret);10395goto err_free_if_combs;10396}1039710398if (test_bit(WMI_TLV_SERVICE_TX_DATA_MGMT_ACK_RSSI,10399ar->ab->wmi_ab.svc_map))10400wiphy_ext_feature_set(ar->hw->wiphy,10401NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);1040210403ar->hw->queues = ATH11K_HW_MAX_QUEUES;10404ar->hw->wiphy->tx_queue_len = ATH11K_QUEUE_LEN;10405ar->hw->offchannel_tx_hw_queue = ATH11K_HW_MAX_QUEUES - 1;10406ar->hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;1040710408ar->hw->vif_data_size = sizeof(struct ath11k_vif);10409ar->hw->sta_data_size = sizeof(struct ath11k_sta);1041010411wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);10412wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);10413if (test_bit(WMI_TLV_SERVICE_BSS_COLOR_OFFLOAD,10414ar->ab->wmi_ab.svc_map)) {10415wiphy_ext_feature_set(ar->hw->wiphy,10416NL80211_EXT_FEATURE_BSS_COLOR);10417ieee80211_hw_set(ar->hw, DETECTS_COLOR_COLLISION);10418}1041910420ar->hw->wiphy->cipher_suites = cipher_suites;10421ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);1042210423ar->hw->wiphy->iftype_ext_capab = ath11k_iftypes_ext_capa;10424ar->hw->wiphy->num_iftype_ext_capab =10425ARRAY_SIZE(ath11k_iftypes_ext_capa);1042610427if (ar->supports_6ghz) {10428wiphy_ext_feature_set(ar->hw->wiphy,10429NL80211_EXT_FEATURE_FILS_DISCOVERY);10430wiphy_ext_feature_set(ar->hw->wiphy,10431NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP);10432}1043310434wiphy_ext_feature_set(ar->hw->wiphy,10435NL80211_EXT_FEATURE_SET_SCAN_DWELL);1043610437if (test_bit(WMI_TLV_SERVICE_RTT, ar->ab->wmi_ab.svc_map))10438wiphy_ext_feature_set(ar->hw->wiphy,10439NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);1044010441ar->hw->wiphy->mbssid_max_interfaces = TARGET_NUM_VDEVS(ab);10442ar->hw->wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD;1044310444ath11k_reg_init(ar);1044510446if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {10447ar->hw->netdev_features = NETIF_F_HW_CSUM;10448ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);10449ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);10450}1045110452if (test_bit(WMI_TLV_SERVICE_BIOS_SAR_SUPPORT, ar->ab->wmi_ab.svc_map) &&10453ab->hw_params.bios_sar_capa)10454ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa;1045510456ret = ieee80211_register_hw(ar->hw);10457if (ret) {10458ath11k_err(ar->ab, "ieee80211 registration failed: %d\n", ret);10459goto err_free_if_combs;10460}1046110462if (!ab->hw_params.supports_monitor)10463/* There's a race between calling ieee80211_register_hw()10464* and here where the monitor mode is enabled for a little10465* while. But that time is so short and in practise it make10466* a difference in real life.10467*/10468ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR);1046910470/* Apply the regd received during initialization */10471ret = ath11k_regd_update(ar);10472if (ret) {10473ath11k_err(ar->ab, "ath11k regd update failed: %d\n", ret);10474goto err_unregister_hw;10475}1047610477if (ab->hw_params.current_cc_support && ab->new_alpha2[0]) {10478memcpy(&ar->alpha2, ab->new_alpha2, 2);10479ret = ath11k_reg_set_cc(ar);10480if (ret)10481ath11k_warn(ar->ab,10482"failed set cc code for mac register: %d\n", ret);10483}1048410485ret = ath11k_debugfs_register(ar);10486if (ret) {10487ath11k_err(ar->ab, "debugfs registration failed: %d\n", ret);10488goto err_unregister_hw;10489}1049010491return 0;1049210493err_unregister_hw:10494ieee80211_unregister_hw(ar->hw);1049510496err_free_if_combs:10497kfree(ar->hw->wiphy->iface_combinations[0].limits);10498kfree(ar->hw->wiphy->iface_combinations);1049910500err_free_channels:10501kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);10502kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);10503kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);1050410505err:10506SET_IEEE80211_DEV(ar->hw, NULL);10507return ret;10508}1050910510int ath11k_mac_register(struct ath11k_base *ab)10511{10512struct ath11k *ar;10513struct ath11k_pdev *pdev;10514int i;10515int ret;10516u8 mac_addr[ETH_ALEN] = {};1051710518if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))10519return 0;1052010521/* Initialize channel counters frequency value in hertz */10522ab->cc_freq_hz = IPQ8074_CC_FREQ_HERTZ;10523ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1;1052410525ret = ath11k_peer_rhash_tbl_init(ab);10526if (ret)10527return ret;1052810529device_get_mac_address(ab->dev, mac_addr);1053010531for (i = 0; i < ab->num_radios; i++) {10532pdev = &ab->pdevs[i];10533ar = pdev->ar;10534if (ab->pdevs_macaddr_valid) {10535ether_addr_copy(ar->mac_addr, pdev->mac_addr);10536} else {10537if (is_zero_ether_addr(mac_addr))10538ether_addr_copy(ar->mac_addr, ab->mac_addr);10539else10540ether_addr_copy(ar->mac_addr, mac_addr);10541ar->mac_addr[4] += i;10542}1054310544idr_init(&ar->txmgmt_idr);10545spin_lock_init(&ar->txmgmt_idr_lock);1054610547ret = __ath11k_mac_register(ar);10548if (ret)10549goto err_cleanup;1055010551init_waitqueue_head(&ar->txmgmt_empty_waitq);10552}1055310554return 0;1055510556err_cleanup:10557for (i = i - 1; i >= 0; i--) {10558pdev = &ab->pdevs[i];10559ar = pdev->ar;10560__ath11k_mac_unregister(ar);10561}1056210563ath11k_peer_rhash_tbl_destroy(ab);1056410565return ret;10566}1056710568int ath11k_mac_allocate(struct ath11k_base *ab)10569{10570struct ieee80211_hw *hw;10571struct ath11k *ar;10572struct ath11k_pdev *pdev;10573int ret;10574int i;1057510576if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))10577return 0;1057810579for (i = 0; i < ab->num_radios; i++) {10580pdev = &ab->pdevs[i];10581hw = ieee80211_alloc_hw(sizeof(struct ath11k), &ath11k_ops);10582if (!hw) {10583ath11k_warn(ab, "failed to allocate mac80211 hw device\n");10584ret = -ENOMEM;10585goto err_free_mac;10586}1058710588ar = hw->priv;10589ar->hw = hw;10590ar->ab = ab;10591ar->pdev = pdev;10592ar->pdev_idx = i;10593ar->lmac_id = ath11k_hw_get_mac_from_pdev_id(&ab->hw_params, i);1059410595ar->wmi = &ab->wmi_ab.wmi[i];10596/* FIXME wmi[0] is already initialized during attach,10597* Should we do this again?10598*/10599ath11k_wmi_pdev_attach(ab, i);1060010601ar->cfg_tx_chainmask = pdev->cap.tx_chain_mask;10602ar->cfg_rx_chainmask = pdev->cap.rx_chain_mask;10603ar->num_tx_chains = get_num_chains(pdev->cap.tx_chain_mask);10604ar->num_rx_chains = get_num_chains(pdev->cap.rx_chain_mask);1060510606pdev->ar = ar;10607spin_lock_init(&ar->data_lock);10608INIT_LIST_HEAD(&ar->arvifs);10609INIT_LIST_HEAD(&ar->ppdu_stats_info);10610mutex_init(&ar->conf_mutex);10611init_completion(&ar->vdev_setup_done);10612init_completion(&ar->vdev_delete_done);10613init_completion(&ar->peer_assoc_done);10614init_completion(&ar->peer_delete_done);10615init_completion(&ar->install_key_done);10616init_completion(&ar->bss_survey_done);10617init_completion(&ar->scan.started);10618init_completion(&ar->scan.completed);10619init_completion(&ar->scan.on_channel);10620init_completion(&ar->thermal.wmi_sync);1062110622INIT_DELAYED_WORK(&ar->scan.timeout, ath11k_scan_timeout_work);10623INIT_WORK(&ar->channel_update_work, ath11k_regd_update_chan_list_work);10624INIT_LIST_HEAD(&ar->channel_update_queue);10625INIT_WORK(&ar->regd_update_work, ath11k_regd_update_work);1062610627INIT_WORK(&ar->wmi_mgmt_tx_work, ath11k_mgmt_over_wmi_tx_work);10628skb_queue_head_init(&ar->wmi_mgmt_tx_queue);1062910630clear_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags);1063110632ar->monitor_vdev_id = -1;10633clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags);10634ar->vdev_id_11d_scan = ATH11K_11D_INVALID_VDEV_ID;10635init_completion(&ar->completed_11d_scan);1063610637ath11k_fw_stats_init(ar);10638}1063910640return 0;1064110642err_free_mac:10643ath11k_mac_destroy(ab);1064410645return ret;10646}1064710648void ath11k_mac_destroy(struct ath11k_base *ab)10649{10650struct ath11k *ar;10651struct ath11k_pdev *pdev;10652int i;1065310654for (i = 0; i < ab->num_radios; i++) {10655pdev = &ab->pdevs[i];10656ar = pdev->ar;10657if (!ar)10658continue;1065910660ath11k_fw_stats_free(&ar->fw_stats);10661ieee80211_free_hw(ar->hw);10662pdev->ar = NULL;10663}10664}1066510666int ath11k_mac_vif_set_keepalive(struct ath11k_vif *arvif,10667enum wmi_sta_keepalive_method method,10668u32 interval)10669{10670struct ath11k *ar = arvif->ar;10671struct wmi_sta_keepalive_arg arg = {};10672int ret;1067310674lockdep_assert_held(&ar->conf_mutex);1067510676if (arvif->vdev_type != WMI_VDEV_TYPE_STA)10677return 0;1067810679if (!test_bit(WMI_TLV_SERVICE_STA_KEEP_ALIVE, ar->ab->wmi_ab.svc_map))10680return 0;1068110682arg.vdev_id = arvif->vdev_id;10683arg.enabled = 1;10684arg.method = method;10685arg.interval = interval;1068610687ret = ath11k_wmi_sta_keepalive(ar, &arg);10688if (ret) {10689ath11k_warn(ar->ab, "failed to set keepalive on vdev %i: %d\n",10690arvif->vdev_id, ret);10691return ret;10692}1069310694return 0;10695}106961069710698