Path: blob/main/sys/contrib/dev/athk/ath10k/mac.c
105911 views
// SPDX-License-Identifier: ISC1/*2* Copyright (c) 2005-2011 Atheros Communications Inc.3* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.4* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.5* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.6*/78#include "mac.h"910#include <linux/export.h>11#include <net/cfg80211.h>12#include <net/mac80211.h>13#include <linux/etherdevice.h>14#include <linux/acpi.h>15#include <linux/of.h>16#include <linux/bitfield.h>17#include <linux/random.h>1819#include "hif.h"20#include "core.h"21#include "debug.h"22#include "wmi.h"23#include "htt.h"24#include "txrx.h"25#include "testmode.h"26#include "wmi-tlv.h"27#include "wmi-ops.h"28#include "wow.h"29#include "leds.h"3031/*********/32/* Rates */33/*********/3435static struct ieee80211_rate ath10k_rates[] = {36{ .bitrate = 10,37.hw_value = ATH10K_HW_RATE_CCK_LP_1M },38{ .bitrate = 20,39.hw_value = ATH10K_HW_RATE_CCK_LP_2M,40.hw_value_short = ATH10K_HW_RATE_CCK_SP_2M,41.flags = IEEE80211_RATE_SHORT_PREAMBLE },42{ .bitrate = 55,43.hw_value = ATH10K_HW_RATE_CCK_LP_5_5M,44.hw_value_short = ATH10K_HW_RATE_CCK_SP_5_5M,45.flags = IEEE80211_RATE_SHORT_PREAMBLE },46{ .bitrate = 110,47.hw_value = ATH10K_HW_RATE_CCK_LP_11M,48.hw_value_short = ATH10K_HW_RATE_CCK_SP_11M,49.flags = IEEE80211_RATE_SHORT_PREAMBLE },5051{ .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },52{ .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },53{ .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },54{ .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },55{ .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },56{ .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },57{ .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },58{ .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },59};6061static struct ieee80211_rate ath10k_rates_rev2[] = {62{ .bitrate = 10,63.hw_value = ATH10K_HW_RATE_REV2_CCK_LP_1M },64{ .bitrate = 20,65.hw_value = ATH10K_HW_RATE_REV2_CCK_LP_2M,66.hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_2M,67.flags = IEEE80211_RATE_SHORT_PREAMBLE },68{ .bitrate = 55,69.hw_value = ATH10K_HW_RATE_REV2_CCK_LP_5_5M,70.hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_5_5M,71.flags = IEEE80211_RATE_SHORT_PREAMBLE },72{ .bitrate = 110,73.hw_value = ATH10K_HW_RATE_REV2_CCK_LP_11M,74.hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_11M,75.flags = IEEE80211_RATE_SHORT_PREAMBLE },7677{ .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },78{ .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },79{ .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },80{ .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },81{ .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },82{ .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },83{ .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },84{ .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },85};8687static const struct cfg80211_sar_freq_ranges ath10k_sar_freq_ranges[] = {88{.start_freq = 2402, .end_freq = 2494 },89{.start_freq = 5170, .end_freq = 5875 },90};9192static const struct cfg80211_sar_capa ath10k_sar_capa = {93.type = NL80211_SAR_TYPE_POWER,94.num_freq_ranges = (ARRAY_SIZE(ath10k_sar_freq_ranges)),95.freq_ranges = &ath10k_sar_freq_ranges[0],96};9798#define ATH10K_MAC_FIRST_OFDM_RATE_IDX 499100#define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)101#define ath10k_a_rates_size (ARRAY_SIZE(ath10k_rates) - \102ATH10K_MAC_FIRST_OFDM_RATE_IDX)103#define ath10k_g_rates (ath10k_rates + 0)104#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))105106#define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)107#define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))108109#define ath10k_wmi_legacy_rates ath10k_rates110111static bool ath10k_mac_bitrate_is_cck(int bitrate)112{113switch (bitrate) {114case 10:115case 20:116case 55:117case 110:118return true;119}120121return false;122}123124static u8 ath10k_mac_bitrate_to_rate(int bitrate)125{126return DIV_ROUND_UP(bitrate, 5) |127(ath10k_mac_bitrate_is_cck(bitrate) ? BIT(7) : 0);128}129130u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,131u8 hw_rate, bool cck)132{133const struct ieee80211_rate *rate;134int i;135136for (i = 0; i < sband->n_bitrates; i++) {137rate = &sband->bitrates[i];138139if (ath10k_mac_bitrate_is_cck(rate->bitrate) != cck)140continue;141142if (rate->hw_value == hw_rate)143return i;144else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&145rate->hw_value_short == hw_rate)146return i;147}148149return 0;150}151152u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,153u32 bitrate)154{155int i;156157for (i = 0; i < sband->n_bitrates; i++)158if (sband->bitrates[i].bitrate == bitrate)159return i;160161return 0;162}163164static int ath10k_mac_get_rate_hw_value(int bitrate)165{166int i;167u8 hw_value_prefix = 0;168169if (ath10k_mac_bitrate_is_cck(bitrate))170hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;171172for (i = 0; i < ARRAY_SIZE(ath10k_rates); i++) {173if (ath10k_rates[i].bitrate == bitrate)174return hw_value_prefix | ath10k_rates[i].hw_value;175}176177return -EINVAL;178}179180static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)181{182switch ((mcs_map >> (2 * nss)) & 0x3) {183case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;184case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;185case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;186}187return 0;188}189190static u32191ath10k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])192{193int nss;194195for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--)196if (ht_mcs_mask[nss])197return nss + 1;198199return 1;200}201202static u32203ath10k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])204{205int nss;206207for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--)208if (vht_mcs_mask[nss])209return nss + 1;210211return 1;212}213214int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val)215{216enum wmi_host_platform_type platform_type;217int ret;218219if (test_bit(WMI_SERVICE_TX_MODE_DYNAMIC, ar->wmi.svc_map))220platform_type = WMI_HOST_PLATFORM_LOW_PERF;221else222platform_type = WMI_HOST_PLATFORM_HIGH_PERF;223224ret = ath10k_wmi_ext_resource_config(ar, platform_type, val);225226if (ret && ret != -EOPNOTSUPP) {227ath10k_warn(ar, "failed to configure ext resource: %d\n", ret);228return ret;229}230231return 0;232}233234/**********/235/* Crypto */236/**********/237238static int ath10k_send_key(struct ath10k_vif *arvif,239struct ieee80211_key_conf *key,240enum set_key_cmd cmd,241const u8 *macaddr, u32 flags)242{243struct ath10k *ar = arvif->ar;244struct wmi_vdev_install_key_arg arg = {245.vdev_id = arvif->vdev_id,246.key_idx = key->keyidx,247.key_len = key->keylen,248.key_data = key->key,249.key_flags = flags,250.macaddr = macaddr,251};252253lockdep_assert_held(&arvif->ar->conf_mutex);254255switch (key->cipher) {256case WLAN_CIPHER_SUITE_CCMP:257arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM];258key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;259break;260case WLAN_CIPHER_SUITE_TKIP:261arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_TKIP];262arg.key_txmic_len = 8;263arg.key_rxmic_len = 8;264break;265case WLAN_CIPHER_SUITE_WEP40:266case WLAN_CIPHER_SUITE_WEP104:267arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_WEP];268break;269case WLAN_CIPHER_SUITE_CCMP_256:270arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM];271break;272case WLAN_CIPHER_SUITE_GCMP:273case WLAN_CIPHER_SUITE_GCMP_256:274arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_GCM];275key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;276break;277case WLAN_CIPHER_SUITE_BIP_GMAC_128:278case WLAN_CIPHER_SUITE_BIP_GMAC_256:279case WLAN_CIPHER_SUITE_BIP_CMAC_256:280case WLAN_CIPHER_SUITE_AES_CMAC:281WARN_ON(1);282return -EINVAL;283default:284ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);285return -EOPNOTSUPP;286}287288if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))289key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;290291if (cmd == DISABLE_KEY) {292if (flags & WMI_KEY_GROUP) {293/* Not all hardware handles group-key deletion operation294* correctly. Replace the key with a junk value to invalidate it.295*/296get_random_bytes(key->key, key->keylen);297} else {298arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_NONE];299arg.key_data = NULL;300}301}302303return ath10k_wmi_vdev_install_key(arvif->ar, &arg);304}305306static int ath10k_install_key(struct ath10k_vif *arvif,307struct ieee80211_key_conf *key,308enum set_key_cmd cmd,309const u8 *macaddr, u32 flags)310{311struct ath10k *ar = arvif->ar;312int ret;313unsigned long time_left;314315lockdep_assert_held(&ar->conf_mutex);316317reinit_completion(&ar->install_key_done);318319if (arvif->nohwcrypt)320return 1;321322ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);323if (ret)324return ret;325326time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);327if (time_left == 0)328return -ETIMEDOUT;329330return 0;331}332333static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,334const u8 *addr)335{336struct ath10k *ar = arvif->ar;337struct ath10k_peer *peer;338int ret;339int i;340u32 flags;341342lockdep_assert_held(&ar->conf_mutex);343344if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP &&345arvif->vif->type != NL80211_IFTYPE_ADHOC &&346arvif->vif->type != NL80211_IFTYPE_MESH_POINT))347return -EINVAL;348349spin_lock_bh(&ar->data_lock);350peer = ath10k_peer_find(ar, arvif->vdev_id, addr);351spin_unlock_bh(&ar->data_lock);352353if (!peer)354return -ENOENT;355356for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {357if (arvif->wep_keys[i] == NULL)358continue;359360switch (arvif->vif->type) {361case NL80211_IFTYPE_AP:362flags = WMI_KEY_PAIRWISE;363364if (arvif->def_wep_key_idx == i)365flags |= WMI_KEY_TX_USAGE;366367ret = ath10k_install_key(arvif, arvif->wep_keys[i],368SET_KEY, addr, flags);369if (ret < 0)370return ret;371break;372case NL80211_IFTYPE_ADHOC:373ret = ath10k_install_key(arvif, arvif->wep_keys[i],374SET_KEY, addr,375WMI_KEY_PAIRWISE);376if (ret < 0)377return ret;378379ret = ath10k_install_key(arvif, arvif->wep_keys[i],380SET_KEY, addr, WMI_KEY_GROUP);381if (ret < 0)382return ret;383break;384default:385WARN_ON(1);386return -EINVAL;387}388389spin_lock_bh(&ar->data_lock);390peer->keys[i] = arvif->wep_keys[i];391spin_unlock_bh(&ar->data_lock);392}393394/* In some cases (notably with static WEP IBSS with multiple keys)395* multicast Tx becomes broken. Both pairwise and groupwise keys are396* installed already. Using WMI_KEY_TX_USAGE in different combinations397* didn't seem help. Using def_keyid vdev parameter seems to be398* effective so use that.399*400* FIXME: Revisit. Perhaps this can be done in a less hacky way.401*/402if (arvif->vif->type != NL80211_IFTYPE_ADHOC)403return 0;404405if (arvif->def_wep_key_idx == -1)406return 0;407408ret = ath10k_wmi_vdev_set_param(arvif->ar,409arvif->vdev_id,410arvif->ar->wmi.vdev_param->def_keyid,411arvif->def_wep_key_idx);412if (ret) {413ath10k_warn(ar, "failed to re-set def wpa key idxon vdev %i: %d\n",414arvif->vdev_id, ret);415return ret;416}417418return 0;419}420421static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,422const u8 *addr)423{424struct ath10k *ar = arvif->ar;425struct ath10k_peer *peer;426int first_errno = 0;427int ret;428int i;429u32 flags = 0;430431lockdep_assert_held(&ar->conf_mutex);432433spin_lock_bh(&ar->data_lock);434peer = ath10k_peer_find(ar, arvif->vdev_id, addr);435spin_unlock_bh(&ar->data_lock);436437if (!peer)438return -ENOENT;439440for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {441if (peer->keys[i] == NULL)442continue;443444/* key flags are not required to delete the key */445ret = ath10k_install_key(arvif, peer->keys[i],446DISABLE_KEY, addr, flags);447if (ret < 0 && first_errno == 0)448first_errno = ret;449450if (ret < 0)451ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",452i, ret);453454spin_lock_bh(&ar->data_lock);455peer->keys[i] = NULL;456spin_unlock_bh(&ar->data_lock);457}458459return first_errno;460}461462bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,463u8 keyidx)464{465struct ath10k_peer *peer;466int i;467468lockdep_assert_held(&ar->data_lock);469470/* We don't know which vdev this peer belongs to,471* since WMI doesn't give us that information.472*473* FIXME: multi-bss needs to be handled.474*/475peer = ath10k_peer_find(ar, 0, addr);476if (!peer)477return false;478479for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {480if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)481return true;482}483484return false;485}486487static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,488struct ieee80211_key_conf *key)489{490struct ath10k *ar = arvif->ar;491struct ath10k_peer *peer;492u8 addr[ETH_ALEN];493int first_errno = 0;494int ret;495int i;496u32 flags = 0;497498lockdep_assert_held(&ar->conf_mutex);499500for (;;) {501/* since ath10k_install_key we can't hold data_lock all the502* time, so we try to remove the keys incrementally503*/504spin_lock_bh(&ar->data_lock);505i = 0;506list_for_each_entry(peer, &ar->peers, list) {507for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {508if (peer->keys[i] == key) {509ether_addr_copy(addr, peer->addr);510peer->keys[i] = NULL;511break;512}513}514515if (i < ARRAY_SIZE(peer->keys))516break;517}518spin_unlock_bh(&ar->data_lock);519520if (i == ARRAY_SIZE(peer->keys))521break;522/* key flags are not required to delete the key */523ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);524if (ret < 0 && first_errno == 0)525first_errno = ret;526527if (ret)528ath10k_warn(ar, "failed to remove key for %pM: %d\n",529addr, ret);530}531532return first_errno;533}534535static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,536struct ieee80211_key_conf *key)537{538struct ath10k *ar = arvif->ar;539struct ath10k_peer *peer;540int ret;541542lockdep_assert_held(&ar->conf_mutex);543544list_for_each_entry(peer, &ar->peers, list) {545if (ether_addr_equal(peer->addr, arvif->vif->addr))546continue;547548if (ether_addr_equal(peer->addr, arvif->bssid))549continue;550551if (peer->keys[key->keyidx] == key)552continue;553554ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",555arvif->vdev_id, key->keyidx);556557ret = ath10k_install_peer_wep_keys(arvif, peer->addr);558if (ret) {559ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",560arvif->vdev_id, peer->addr, ret);561return ret;562}563}564565return 0;566}567568/*********************/569/* General utilities */570/*********************/571572static inline enum wmi_phy_mode573chan_to_phymode(const struct cfg80211_chan_def *chandef)574{575enum wmi_phy_mode phymode = MODE_UNKNOWN;576577switch (chandef->chan->band) {578case NL80211_BAND_2GHZ:579switch (chandef->width) {580case NL80211_CHAN_WIDTH_20_NOHT:581if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)582phymode = MODE_11B;583else584phymode = MODE_11G;585break;586case NL80211_CHAN_WIDTH_20:587phymode = MODE_11NG_HT20;588break;589case NL80211_CHAN_WIDTH_40:590phymode = MODE_11NG_HT40;591break;592default:593phymode = MODE_UNKNOWN;594break;595}596break;597case NL80211_BAND_5GHZ:598switch (chandef->width) {599case NL80211_CHAN_WIDTH_20_NOHT:600phymode = MODE_11A;601break;602case NL80211_CHAN_WIDTH_20:603phymode = MODE_11NA_HT20;604break;605case NL80211_CHAN_WIDTH_40:606phymode = MODE_11NA_HT40;607break;608case NL80211_CHAN_WIDTH_80:609phymode = MODE_11AC_VHT80;610break;611case NL80211_CHAN_WIDTH_160:612phymode = MODE_11AC_VHT160;613break;614case NL80211_CHAN_WIDTH_80P80:615phymode = MODE_11AC_VHT80_80;616break;617default:618phymode = MODE_UNKNOWN;619break;620}621break;622default:623break;624}625626WARN_ON(phymode == MODE_UNKNOWN);627return phymode;628}629630static u8 ath10k_parse_mpdudensity(u8 mpdudensity)631{632/*633* 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":634* 0 for no restriction635* 1 for 1/4 us636* 2 for 1/2 us637* 3 for 1 us638* 4 for 2 us639* 5 for 4 us640* 6 for 8 us641* 7 for 16 us642*/643switch (mpdudensity) {644case 0:645return 0;646case 1:647case 2:648case 3:649/* Our lower layer calculations limit our precision to650* 1 microsecond651*/652return 1;653case 4:654return 2;655case 5:656return 4;657case 6:658return 8;659case 7:660return 16;661default:662return 0;663}664}665666int ath10k_mac_vif_chan(struct ieee80211_vif *vif,667struct cfg80211_chan_def *def)668{669struct ieee80211_chanctx_conf *conf;670671rcu_read_lock();672conf = rcu_dereference(vif->bss_conf.chanctx_conf);673if (!conf) {674rcu_read_unlock();675return -ENOENT;676}677678*def = conf->def;679rcu_read_unlock();680681return 0;682}683684static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,685struct ieee80211_chanctx_conf *conf,686void *data)687{688int *num = data;689690(*num)++;691}692693static int ath10k_mac_num_chanctxs(struct ath10k *ar)694{695int num = 0;696697ieee80211_iter_chan_contexts_atomic(ar->hw,698ath10k_mac_num_chanctxs_iter,699&num);700701return num;702}703704static void705ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,706struct ieee80211_chanctx_conf *conf,707void *data)708{709struct cfg80211_chan_def **def = data;710711*def = &conf->def;712}713714static void ath10k_wait_for_peer_delete_done(struct ath10k *ar, u32 vdev_id,715const u8 *addr)716{717unsigned long time_left;718int ret;719720if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) {721ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);722if (ret) {723ath10k_warn(ar, "failed wait for peer deleted");724return;725}726727time_left = wait_for_completion_timeout(&ar->peer_delete_done,7285 * HZ);729if (!time_left)730ath10k_warn(ar, "Timeout in receiving peer delete response\n");731}732}733734static int ath10k_peer_create(struct ath10k *ar,735struct ieee80211_vif *vif,736struct ieee80211_sta *sta,737u32 vdev_id,738const u8 *addr,739enum wmi_peer_type peer_type)740{741struct ath10k_peer *peer;742int ret;743744lockdep_assert_held(&ar->conf_mutex);745746/* Each vdev consumes a peer entry as well. */747if (ar->num_peers + list_count_nodes(&ar->arvifs) >= ar->max_num_peers)748return -ENOBUFS;749750ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);751if (ret) {752ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",753addr, vdev_id, ret);754return ret;755}756757ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);758if (ret) {759ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",760addr, vdev_id, ret);761return ret;762}763764spin_lock_bh(&ar->data_lock);765766peer = ath10k_peer_find(ar, vdev_id, addr);767if (!peer) {768spin_unlock_bh(&ar->data_lock);769ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n",770addr, vdev_id);771ath10k_wait_for_peer_delete_done(ar, vdev_id, addr);772return -ENOENT;773}774775peer->vif = vif;776peer->sta = sta;777778spin_unlock_bh(&ar->data_lock);779780ar->num_peers++;781782return 0;783}784785static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)786{787struct ath10k *ar = arvif->ar;788u32 param;789int ret;790791param = ar->wmi.pdev_param->sta_kickout_th;792ret = ath10k_wmi_pdev_set_param(ar, param,793ATH10K_KICKOUT_THRESHOLD);794if (ret) {795ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",796arvif->vdev_id, ret);797return ret;798}799800param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;801ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,802ATH10K_KEEPALIVE_MIN_IDLE);803if (ret) {804ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",805arvif->vdev_id, ret);806return ret;807}808809param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;810ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,811ATH10K_KEEPALIVE_MAX_IDLE);812if (ret) {813ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",814arvif->vdev_id, ret);815return ret;816}817818param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;819ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,820ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);821if (ret) {822ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",823arvif->vdev_id, ret);824return ret;825}826827return 0;828}829830static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)831{832struct ath10k *ar = arvif->ar;833u32 vdev_param;834835vdev_param = ar->wmi.vdev_param->rts_threshold;836return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);837}838839static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)840{841int ret;842843lockdep_assert_held(&ar->conf_mutex);844845ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);846if (ret)847return ret;848849ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);850if (ret)851return ret;852853if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) {854unsigned long time_left;855856time_left = wait_for_completion_timeout857(&ar->peer_delete_done, 5 * HZ);858859if (!time_left) {860ath10k_warn(ar, "Timeout in receiving peer delete response\n");861return -ETIMEDOUT;862}863}864865ar->num_peers--;866867return 0;868}869870static void ath10k_peer_map_cleanup(struct ath10k *ar, struct ath10k_peer *peer)871{872int peer_id, i;873874lockdep_assert_held(&ar->conf_mutex);875876for_each_set_bit(peer_id, peer->peer_ids,877ATH10K_MAX_NUM_PEER_IDS) {878ar->peer_map[peer_id] = NULL;879}880881/* Double check that peer is properly un-referenced from882* the peer_map883*/884for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {885if (ar->peer_map[i] == peer) {886ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %p idx %d)\n",887peer->addr, peer, i);888ar->peer_map[i] = NULL;889}890}891892list_del(&peer->list);893kfree(peer);894ar->num_peers--;895}896897static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)898{899struct ath10k_peer *peer, *tmp;900901lockdep_assert_held(&ar->conf_mutex);902903spin_lock_bh(&ar->data_lock);904list_for_each_entry_safe(peer, tmp, &ar->peers, list) {905if (peer->vdev_id != vdev_id)906continue;907908ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",909peer->addr, vdev_id);910911ath10k_peer_map_cleanup(ar, peer);912}913spin_unlock_bh(&ar->data_lock);914}915916static void ath10k_peer_cleanup_all(struct ath10k *ar)917{918struct ath10k_peer *peer, *tmp;919int i;920921lockdep_assert_held(&ar->conf_mutex);922923spin_lock_bh(&ar->data_lock);924list_for_each_entry_safe(peer, tmp, &ar->peers, list) {925list_del(&peer->list);926kfree(peer);927}928929for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)930ar->peer_map[i] = NULL;931932spin_unlock_bh(&ar->data_lock);933934ar->num_peers = 0;935ar->num_stations = 0;936}937938static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,939struct ieee80211_sta *sta,940enum wmi_tdls_peer_state state)941{942int ret;943struct wmi_tdls_peer_update_cmd_arg arg = {};944struct wmi_tdls_peer_capab_arg cap = {};945struct wmi_channel_arg chan_arg = {};946947lockdep_assert_held(&ar->conf_mutex);948949arg.vdev_id = vdev_id;950arg.peer_state = state;951ether_addr_copy(arg.addr, sta->addr);952953cap.peer_max_sp = sta->max_sp;954cap.peer_uapsd_queues = sta->uapsd_queues;955956if (state == WMI_TDLS_PEER_STATE_CONNECTED &&957!sta->tdls_initiator)958cap.is_peer_responder = 1;959960ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);961if (ret) {962ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",963arg.addr, vdev_id, ret);964return ret;965}966967return 0;968}969970/************************/971/* Interface management */972/************************/973974void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)975{976struct ath10k *ar = arvif->ar;977978lockdep_assert_held(&ar->data_lock);979980if (!arvif->beacon)981return;982983if (!arvif->beacon_buf)984dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,985arvif->beacon->len, DMA_TO_DEVICE);986987if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&988arvif->beacon_state != ATH10K_BEACON_SENT))989return;990991dev_kfree_skb_any(arvif->beacon);992993arvif->beacon = NULL;994arvif->beacon_state = ATH10K_BEACON_SCHEDULED;995}996997static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)998{999struct ath10k *ar = arvif->ar;10001001lockdep_assert_held(&ar->data_lock);10021003ath10k_mac_vif_beacon_free(arvif);10041005if (arvif->beacon_buf) {1006if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)1007kfree(arvif->beacon_buf);1008else1009dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,1010arvif->beacon_buf,1011arvif->beacon_paddr);1012arvif->beacon_buf = NULL;1013}1014}10151016static inline int ath10k_vdev_setup_sync(struct ath10k *ar)1017{1018unsigned long time_left;10191020lockdep_assert_held(&ar->conf_mutex);10211022if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))1023return -ESHUTDOWN;10241025time_left = wait_for_completion_timeout(&ar->vdev_setup_done,1026ATH10K_VDEV_SETUP_TIMEOUT_HZ);1027if (time_left == 0)1028return -ETIMEDOUT;10291030return ar->last_wmi_vdev_start_status;1031}10321033static inline int ath10k_vdev_delete_sync(struct ath10k *ar)1034{1035unsigned long time_left;10361037lockdep_assert_held(&ar->conf_mutex);10381039if (!test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map))1040return 0;10411042if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))1043return -ESHUTDOWN;10441045time_left = wait_for_completion_timeout(&ar->vdev_delete_done,1046ATH10K_VDEV_DELETE_TIMEOUT_HZ);1047if (time_left == 0)1048return -ETIMEDOUT;10491050return 0;1051}10521053static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)1054{1055struct cfg80211_chan_def *chandef = NULL;1056struct ieee80211_channel *channel = NULL;1057struct wmi_vdev_start_request_arg arg = {};1058int ret = 0;10591060lockdep_assert_held(&ar->conf_mutex);10611062ieee80211_iter_chan_contexts_atomic(ar->hw,1063ath10k_mac_get_any_chandef_iter,1064&chandef);1065if (WARN_ON_ONCE(!chandef))1066return -ENOENT;10671068channel = chandef->chan;10691070arg.vdev_id = vdev_id;1071arg.channel.freq = channel->center_freq;1072arg.channel.band_center_freq1 = chandef->center_freq1;1073arg.channel.band_center_freq2 = chandef->center_freq2;10741075/* TODO setup this dynamically, what in case we1076* don't have any vifs?1077*/1078arg.channel.mode = chan_to_phymode(chandef);1079arg.channel.chan_radar =1080!!(channel->flags & IEEE80211_CHAN_RADAR);10811082arg.channel.min_power = 0;1083arg.channel.max_power = channel->max_power * 2;1084arg.channel.max_reg_power = channel->max_reg_power * 2;1085arg.channel.max_antenna_gain = channel->max_antenna_gain;10861087reinit_completion(&ar->vdev_setup_done);1088reinit_completion(&ar->vdev_delete_done);10891090ret = ath10k_wmi_vdev_start(ar, &arg);1091if (ret) {1092ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",1093vdev_id, ret);1094return ret;1095}10961097ret = ath10k_vdev_setup_sync(ar);1098if (ret) {1099ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",1100vdev_id, ret);1101return ret;1102}11031104ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);1105if (ret) {1106ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",1107vdev_id, ret);1108goto vdev_stop;1109}11101111ar->monitor_vdev_id = vdev_id;11121113ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",1114ar->monitor_vdev_id);1115return 0;11161117vdev_stop:1118ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);1119if (ret)1120ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",1121ar->monitor_vdev_id, ret);11221123return ret;1124}11251126static int ath10k_monitor_vdev_stop(struct ath10k *ar)1127{1128int ret = 0;11291130lockdep_assert_held(&ar->conf_mutex);11311132ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);1133if (ret)1134ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",1135ar->monitor_vdev_id, ret);11361137reinit_completion(&ar->vdev_setup_done);1138reinit_completion(&ar->vdev_delete_done);11391140ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);1141if (ret)1142ath10k_warn(ar, "failed to request monitor vdev %i stop: %d\n",1143ar->monitor_vdev_id, ret);11441145ret = ath10k_vdev_setup_sync(ar);1146if (ret)1147ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",1148ar->monitor_vdev_id, ret);11491150ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",1151ar->monitor_vdev_id);1152return ret;1153}11541155static int ath10k_monitor_vdev_create(struct ath10k *ar)1156{1157int bit, ret = 0;11581159lockdep_assert_held(&ar->conf_mutex);11601161if (ar->free_vdev_map == 0) {1162ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");1163return -ENOMEM;1164}11651166bit = __ffs64(ar->free_vdev_map);11671168ar->monitor_vdev_id = bit;11691170ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,1171WMI_VDEV_TYPE_MONITOR,11720, ar->mac_addr);1173if (ret) {1174ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",1175ar->monitor_vdev_id, ret);1176return ret;1177}11781179ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);1180ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",1181ar->monitor_vdev_id);11821183return 0;1184}11851186static int ath10k_monitor_vdev_delete(struct ath10k *ar)1187{1188int ret = 0;11891190lockdep_assert_held(&ar->conf_mutex);11911192ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);1193if (ret) {1194ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",1195ar->monitor_vdev_id, ret);1196return ret;1197}11981199ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;12001201ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",1202ar->monitor_vdev_id);1203return ret;1204}12051206static int ath10k_monitor_start(struct ath10k *ar)1207{1208int ret;12091210lockdep_assert_held(&ar->conf_mutex);12111212ret = ath10k_monitor_vdev_create(ar);1213if (ret) {1214ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);1215return ret;1216}12171218ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);1219if (ret) {1220ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);1221ath10k_monitor_vdev_delete(ar);1222return ret;1223}12241225ar->monitor_started = true;1226ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");12271228return 0;1229}12301231static int ath10k_monitor_stop(struct ath10k *ar)1232{1233int ret;12341235lockdep_assert_held(&ar->conf_mutex);12361237ret = ath10k_monitor_vdev_stop(ar);1238if (ret) {1239ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);1240return ret;1241}12421243ret = ath10k_monitor_vdev_delete(ar);1244if (ret) {1245ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);1246return ret;1247}12481249ar->monitor_started = false;1250ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");12511252return 0;1253}12541255static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)1256{1257int num_ctx;12581259/* At least one chanctx is required to derive a channel to start1260* monitor vdev on.1261*/1262num_ctx = ath10k_mac_num_chanctxs(ar);1263if (num_ctx == 0)1264return false;12651266/* If there's already an existing special monitor interface then don't1267* bother creating another monitor vdev.1268*/1269if (ar->monitor_arvif)1270return false;12711272return ar->monitor ||1273(!test_bit(ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST,1274ar->running_fw->fw_file.fw_features) &&1275(ar->filter_flags & (FIF_OTHER_BSS | FIF_MCAST_ACTION))) ||1276test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);1277}12781279static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)1280{1281int num_ctx;12821283num_ctx = ath10k_mac_num_chanctxs(ar);12841285/* FIXME: Current interface combinations and cfg80211/mac80211 code1286* shouldn't allow this but make sure to prevent handling the following1287* case anyway since multi-channel DFS hasn't been tested at all.1288*/1289if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)1290return false;12911292return true;1293}12941295static int ath10k_monitor_recalc(struct ath10k *ar)1296{1297bool needed;1298bool allowed;1299int ret;13001301lockdep_assert_held(&ar->conf_mutex);13021303needed = ath10k_mac_monitor_vdev_is_needed(ar);1304allowed = ath10k_mac_monitor_vdev_is_allowed(ar);13051306ath10k_dbg(ar, ATH10K_DBG_MAC,1307"mac monitor recalc started? %d needed? %d allowed? %d\n",1308ar->monitor_started, needed, allowed);13091310if (WARN_ON(needed && !allowed)) {1311if (ar->monitor_started) {1312ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");13131314ret = ath10k_monitor_stop(ar);1315if (ret)1316ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",1317ret);1318/* not serious */1319}13201321return -EPERM;1322}13231324if (needed == ar->monitor_started)1325return 0;13261327if (needed)1328return ath10k_monitor_start(ar);1329else1330return ath10k_monitor_stop(ar);1331}13321333static bool ath10k_mac_can_set_cts_prot(struct ath10k_vif *arvif)1334{1335struct ath10k *ar = arvif->ar;13361337lockdep_assert_held(&ar->conf_mutex);13381339if (!arvif->is_started) {1340ath10k_dbg(ar, ATH10K_DBG_MAC, "defer cts setup, vdev is not ready yet\n");1341return false;1342}13431344return true;1345}13461347static int ath10k_mac_set_cts_prot(struct ath10k_vif *arvif)1348{1349struct ath10k *ar = arvif->ar;1350u32 vdev_param;13511352lockdep_assert_held(&ar->conf_mutex);13531354vdev_param = ar->wmi.vdev_param->protection_mode;13551356ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_protection %d\n",1357arvif->vdev_id, arvif->use_cts_prot);13581359return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,1360arvif->use_cts_prot ? 1 : 0);1361}13621363static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)1364{1365struct ath10k *ar = arvif->ar;1366u32 vdev_param, rts_cts = 0;13671368lockdep_assert_held(&ar->conf_mutex);13691370vdev_param = ar->wmi.vdev_param->enable_rtscts;13711372rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);13731374if (arvif->num_legacy_stations > 0)1375rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,1376WMI_RTSCTS_PROFILE);1377else1378rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,1379WMI_RTSCTS_PROFILE);13801381ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d recalc rts/cts prot %d\n",1382arvif->vdev_id, rts_cts);13831384return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,1385rts_cts);1386}13871388static int ath10k_start_cac(struct ath10k *ar)1389{1390int ret;13911392lockdep_assert_held(&ar->conf_mutex);13931394set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);13951396ret = ath10k_monitor_recalc(ar);1397if (ret) {1398ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);1399clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);1400return ret;1401}14021403ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",1404ar->monitor_vdev_id);14051406return 0;1407}14081409static int ath10k_stop_cac(struct ath10k *ar)1410{1411lockdep_assert_held(&ar->conf_mutex);14121413/* CAC is not running - do nothing */1414if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))1415return 0;14161417clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);1418ath10k_monitor_stop(ar);14191420ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");14211422return 0;1423}14241425static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,1426struct ieee80211_chanctx_conf *conf,1427void *data)1428{1429bool *ret = data;14301431if (!*ret && conf->radar_enabled)1432*ret = true;1433}14341435static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)1436{1437bool has_radar = false;14381439ieee80211_iter_chan_contexts_atomic(ar->hw,1440ath10k_mac_has_radar_iter,1441&has_radar);14421443return has_radar;1444}14451446static void ath10k_recalc_radar_detection(struct ath10k *ar)1447{1448int ret;14491450lockdep_assert_held(&ar->conf_mutex);14511452ath10k_stop_cac(ar);14531454if (!ath10k_mac_has_radar_enabled(ar))1455return;14561457if (ar->num_started_vdevs > 0)1458return;14591460ret = ath10k_start_cac(ar);1461if (ret) {1462/*1463* Not possible to start CAC on current channel so starting1464* radiation is not allowed, make this channel DFS_UNAVAILABLE1465* by indicating that radar was detected.1466*/1467ath10k_warn(ar, "failed to start CAC: %d\n", ret);1468ieee80211_radar_detected(ar->hw, NULL);1469}1470}14711472static int ath10k_vdev_stop(struct ath10k_vif *arvif)1473{1474struct ath10k *ar = arvif->ar;1475int ret;14761477lockdep_assert_held(&ar->conf_mutex);14781479reinit_completion(&ar->vdev_setup_done);1480reinit_completion(&ar->vdev_delete_done);14811482ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);1483if (ret) {1484ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",1485arvif->vdev_id, ret);1486return ret;1487}14881489ret = ath10k_vdev_setup_sync(ar);1490if (ret) {1491ath10k_warn(ar, "failed to synchronize setup for vdev %i: %d\n",1492arvif->vdev_id, ret);1493return ret;1494}14951496WARN_ON(ar->num_started_vdevs == 0);14971498if (ar->num_started_vdevs != 0) {1499ar->num_started_vdevs--;1500ath10k_recalc_radar_detection(ar);1501}15021503return ret;1504}15051506static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,1507const struct cfg80211_chan_def *chandef,1508bool restart)1509{1510struct ath10k *ar = arvif->ar;1511struct wmi_vdev_start_request_arg arg = {};1512int ret = 0;15131514lockdep_assert_held(&ar->conf_mutex);15151516reinit_completion(&ar->vdev_setup_done);1517reinit_completion(&ar->vdev_delete_done);15181519arg.vdev_id = arvif->vdev_id;1520arg.dtim_period = arvif->dtim_period;1521arg.bcn_intval = arvif->beacon_interval;15221523arg.channel.freq = chandef->chan->center_freq;1524arg.channel.band_center_freq1 = chandef->center_freq1;1525arg.channel.band_center_freq2 = chandef->center_freq2;1526arg.channel.mode = chan_to_phymode(chandef);15271528arg.channel.min_power = 0;1529arg.channel.max_power = chandef->chan->max_power * 2;1530arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;1531arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain;15321533if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {1534arg.ssid = arvif->u.ap.ssid;1535arg.ssid_len = arvif->u.ap.ssid_len;1536arg.hidden_ssid = arvif->u.ap.hidden_ssid;15371538/* For now allow DFS for AP mode */1539arg.channel.chan_radar =1540!!(chandef->chan->flags & IEEE80211_CHAN_RADAR);1541} else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {1542arg.ssid = arvif->vif->cfg.ssid;1543arg.ssid_len = arvif->vif->cfg.ssid_len;1544}15451546ath10k_dbg(ar, ATH10K_DBG_MAC,1547"mac vdev %d start center_freq %d phymode %s\n",1548arg.vdev_id, arg.channel.freq,1549ath10k_wmi_phymode_str(arg.channel.mode));15501551if (restart)1552ret = ath10k_wmi_vdev_restart(ar, &arg);1553else1554ret = ath10k_wmi_vdev_start(ar, &arg);15551556if (ret) {1557ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",1558arg.vdev_id, ret);1559return ret;1560}15611562ret = ath10k_vdev_setup_sync(ar);1563if (ret) {1564ath10k_warn(ar,1565"failed to synchronize setup for vdev %i restart %d: %d\n",1566arg.vdev_id, restart, ret);1567return ret;1568}15691570ar->num_started_vdevs++;1571ath10k_recalc_radar_detection(ar);15721573return ret;1574}15751576static int ath10k_vdev_start(struct ath10k_vif *arvif,1577const struct cfg80211_chan_def *def)1578{1579return ath10k_vdev_start_restart(arvif, def, false);1580}15811582static int ath10k_vdev_restart(struct ath10k_vif *arvif,1583const struct cfg80211_chan_def *def)1584{1585return ath10k_vdev_start_restart(arvif, def, true);1586}15871588static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,1589struct sk_buff *bcn)1590{1591struct ath10k *ar = arvif->ar;1592struct ieee80211_mgmt *mgmt;1593const u8 *p2p_ie;1594int ret;15951596if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)1597return 0;15981599mgmt = (void *)bcn->data;1600p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,1601mgmt->u.beacon.variable,1602bcn->len - (mgmt->u.beacon.variable -1603bcn->data));1604if (!p2p_ie)1605return -ENOENT;16061607ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);1608if (ret) {1609ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",1610arvif->vdev_id, ret);1611return ret;1612}16131614return 0;1615}16161617static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,1618u8 oui_type, size_t ie_offset)1619{1620size_t len;1621const u8 *next;1622const u8 *end;1623u8 *ie;16241625if (WARN_ON(skb->len < ie_offset))1626return -EINVAL;16271628ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,1629skb->data + ie_offset,1630skb->len - ie_offset);1631if (!ie)1632return -ENOENT;16331634len = ie[1] + 2;1635end = skb->data + skb->len;1636next = ie + len;16371638if (WARN_ON(next > end))1639return -EINVAL;16401641memmove(ie, next, end - next);1642skb_trim(skb, skb->len - len);16431644return 0;1645}16461647static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)1648{1649struct ath10k *ar = arvif->ar;1650struct ieee80211_hw *hw = ar->hw;1651struct ieee80211_vif *vif = arvif->vif;1652struct ieee80211_mutable_offsets offs = {};1653struct sk_buff *bcn;1654int ret;16551656if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))1657return 0;16581659if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&1660arvif->vdev_type != WMI_VDEV_TYPE_IBSS)1661return 0;16621663bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0);1664if (!bcn) {1665ath10k_warn(ar, "failed to get beacon template from mac80211\n");1666return -EPERM;1667}16681669ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);1670if (ret) {1671ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);1672kfree_skb(bcn);1673return ret;1674}16751676/* P2P IE is inserted by firmware automatically (as configured above)1677* so remove it from the base beacon template to avoid duplicate P2P1678* IEs in beacon frames.1679*/1680ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,1681offsetof(struct ieee80211_mgmt,1682u.beacon.variable));16831684ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,16850, NULL, 0);1686kfree_skb(bcn);16871688if (ret) {1689ath10k_warn(ar, "failed to submit beacon template command: %d\n",1690ret);1691return ret;1692}16931694return 0;1695}16961697static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)1698{1699struct ath10k *ar = arvif->ar;1700struct ieee80211_hw *hw = ar->hw;1701struct ieee80211_vif *vif = arvif->vif;1702struct sk_buff *prb;1703int ret;17041705if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))1706return 0;17071708if (arvif->vdev_type != WMI_VDEV_TYPE_AP)1709return 0;17101711/* For mesh, probe response and beacon share the same template */1712if (ieee80211_vif_is_mesh(vif))1713return 0;17141715prb = ieee80211_proberesp_get(hw, vif);1716if (!prb) {1717ath10k_warn(ar, "failed to get probe resp template from mac80211\n");1718return -EPERM;1719}17201721ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);1722kfree_skb(prb);17231724if (ret) {1725ath10k_warn(ar, "failed to submit probe resp template command: %d\n",1726ret);1727return ret;1728}17291730return 0;1731}17321733static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)1734{1735struct ath10k *ar = arvif->ar;1736struct cfg80211_chan_def def;1737int ret;17381739/* When originally vdev is started during assign_vif_chanctx() some1740* information is missing, notably SSID. Firmware revisions with beacon1741* offloading require the SSID to be provided during vdev (re)start to1742* handle hidden SSID properly.1743*1744* Vdev restart must be done after vdev has been both started and1745* upped. Otherwise some firmware revisions (at least 10.2) fail to1746* deliver vdev restart response event causing timeouts during vdev1747* syncing in ath10k.1748*1749* Note: The vdev down/up and template reinstallation could be skipped1750* since only wmi-tlv firmware are known to have beacon offload and1751* wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart1752* response delivery. It's probably more robust to keep it as is.1753*/1754if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))1755return 0;17561757if (WARN_ON(!arvif->is_started))1758return -EINVAL;17591760if (WARN_ON(!arvif->is_up))1761return -EINVAL;17621763if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))1764return -EINVAL;17651766ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);1767if (ret) {1768ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",1769arvif->vdev_id, ret);1770return ret;1771}17721773/* Vdev down reset beacon & presp templates. Reinstall them. Otherwise1774* firmware will crash upon vdev up.1775*/17761777ret = ath10k_mac_setup_bcn_tmpl(arvif);1778if (ret) {1779ath10k_warn(ar, "failed to update beacon template: %d\n", ret);1780return ret;1781}17821783ret = ath10k_mac_setup_prb_tmpl(arvif);1784if (ret) {1785ath10k_warn(ar, "failed to update presp template: %d\n", ret);1786return ret;1787}17881789ret = ath10k_vdev_restart(arvif, &def);1790if (ret) {1791ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",1792arvif->vdev_id, ret);1793return ret;1794}17951796ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,1797arvif->bssid);1798if (ret) {1799ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",1800arvif->vdev_id, ret);1801return ret;1802}18031804return 0;1805}18061807static void ath10k_control_beaconing(struct ath10k_vif *arvif,1808struct ieee80211_bss_conf *info)1809{1810struct ath10k *ar = arvif->ar;1811int ret = 0;18121813lockdep_assert_held(&arvif->ar->conf_mutex);18141815if (!info->enable_beacon) {1816ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);1817if (ret)1818ath10k_warn(ar, "failed to down vdev_id %i: %d\n",1819arvif->vdev_id, ret);18201821arvif->is_up = false;18221823spin_lock_bh(&arvif->ar->data_lock);1824ath10k_mac_vif_beacon_free(arvif);1825spin_unlock_bh(&arvif->ar->data_lock);18261827return;1828}18291830arvif->tx_seq_no = 0x1000;18311832arvif->aid = 0;1833ether_addr_copy(arvif->bssid, info->bssid);18341835ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,1836arvif->bssid);1837if (ret) {1838ath10k_warn(ar, "failed to bring up vdev %d: %i\n",1839arvif->vdev_id, ret);1840return;1841}18421843arvif->is_up = true;18441845ret = ath10k_mac_vif_fix_hidden_ssid(arvif);1846if (ret) {1847ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",1848arvif->vdev_id, ret);1849return;1850}18511852ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);1853}18541855static void ath10k_control_ibss(struct ath10k_vif *arvif,1856struct ieee80211_vif *vif)1857{1858struct ath10k *ar = arvif->ar;1859u32 vdev_param;1860int ret = 0;18611862lockdep_assert_held(&arvif->ar->conf_mutex);18631864if (!vif->cfg.ibss_joined) {1865if (is_zero_ether_addr(arvif->bssid))1866return;18671868eth_zero_addr(arvif->bssid);18691870return;1871}18721873vdev_param = arvif->ar->wmi.vdev_param->atim_window;1874ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,1875ATH10K_DEFAULT_ATIM);1876if (ret)1877ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",1878arvif->vdev_id, ret);1879}18801881static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)1882{1883struct ath10k *ar = arvif->ar;1884u32 param;1885u32 value;1886int ret;18871888lockdep_assert_held(&arvif->ar->conf_mutex);18891890if (arvif->u.sta.uapsd)1891value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;1892else1893value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;18941895param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;1896ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);1897if (ret) {1898ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",1899value, arvif->vdev_id, ret);1900return ret;1901}19021903return 0;1904}19051906static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)1907{1908struct ath10k *ar = arvif->ar;1909u32 param;1910u32 value;1911int ret;19121913lockdep_assert_held(&arvif->ar->conf_mutex);19141915if (arvif->u.sta.uapsd)1916value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;1917else1918value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;19191920param = WMI_STA_PS_PARAM_PSPOLL_COUNT;1921ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,1922param, value);1923if (ret) {1924ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",1925value, arvif->vdev_id, ret);1926return ret;1927}19281929return 0;1930}19311932static int ath10k_mac_num_vifs_started(struct ath10k *ar)1933{1934struct ath10k_vif *arvif;1935int num = 0;19361937lockdep_assert_held(&ar->conf_mutex);19381939list_for_each_entry(arvif, &ar->arvifs, list)1940if (arvif->is_started)1941num++;19421943return num;1944}19451946static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)1947{1948struct ath10k *ar = arvif->ar;1949struct ieee80211_vif *vif = arvif->vif;1950struct ieee80211_conf *conf = &ar->hw->conf;1951enum wmi_sta_powersave_param param;1952enum wmi_sta_ps_mode psmode;1953int ret;1954int ps_timeout;1955bool enable_ps;19561957lockdep_assert_held(&arvif->ar->conf_mutex);19581959if (arvif->vif->type != NL80211_IFTYPE_STATION)1960return 0;19611962enable_ps = arvif->ps;19631964if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&1965!test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,1966ar->running_fw->fw_file.fw_features)) {1967ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",1968arvif->vdev_id);1969enable_ps = false;1970}19711972if (!arvif->is_started) {1973/* mac80211 can update vif powersave state while disconnected.1974* Firmware doesn't behave nicely and consumes more power than1975* necessary if PS is disabled on a non-started vdev. Hence1976* force-enable PS for non-running vdevs.1977*/1978psmode = WMI_STA_PS_MODE_ENABLED;1979} else if (enable_ps) {1980psmode = WMI_STA_PS_MODE_ENABLED;1981param = WMI_STA_PS_PARAM_INACTIVITY_TIME;19821983ps_timeout = conf->dynamic_ps_timeout;1984if (ps_timeout == 0) {1985/* Firmware doesn't like 0 */1986ps_timeout = ieee80211_tu_to_usec(1987vif->bss_conf.beacon_int) / 1000;1988}19891990ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,1991ps_timeout);1992if (ret) {1993ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",1994arvif->vdev_id, ret);1995return ret;1996}1997} else {1998psmode = WMI_STA_PS_MODE_DISABLED;1999}20002001ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",2002arvif->vdev_id, psmode ? "enable" : "disable");20032004ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);2005if (ret) {2006ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",2007psmode, arvif->vdev_id, ret);2008return ret;2009}20102011return 0;2012}20132014static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)2015{2016struct ath10k *ar = arvif->ar;2017struct wmi_sta_keepalive_arg arg = {};2018int ret;20192020lockdep_assert_held(&arvif->ar->conf_mutex);20212022if (arvif->vdev_type != WMI_VDEV_TYPE_STA)2023return 0;20242025if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))2026return 0;20272028/* Some firmware revisions have a bug and ignore the `enabled` field.2029* Instead use the interval to disable the keepalive.2030*/2031arg.vdev_id = arvif->vdev_id;2032arg.enabled = 1;2033arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;2034arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;20352036ret = ath10k_wmi_sta_keepalive(ar, &arg);2037if (ret) {2038ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",2039arvif->vdev_id, ret);2040return ret;2041}20422043return 0;2044}20452046static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)2047{2048struct ath10k *ar = arvif->ar;2049struct ieee80211_vif *vif = arvif->vif;2050int ret;20512052lockdep_assert_held(&arvif->ar->conf_mutex);20532054if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))2055return;20562057if (arvif->vdev_type != WMI_VDEV_TYPE_AP)2058return;20592060if (!vif->bss_conf.csa_active)2061return;20622063if (!arvif->is_up)2064return;20652066if (!ieee80211_beacon_cntdwn_is_complete(vif, 0)) {2067ieee80211_beacon_update_cntdwn(vif, 0);20682069ret = ath10k_mac_setup_bcn_tmpl(arvif);2070if (ret)2071ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",2072ret);20732074ret = ath10k_mac_setup_prb_tmpl(arvif);2075if (ret)2076ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",2077ret);2078} else {2079ieee80211_csa_finish(vif, 0);2080}2081}20822083static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)2084{2085struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,2086ap_csa_work);2087struct ath10k *ar = arvif->ar;20882089mutex_lock(&ar->conf_mutex);2090ath10k_mac_vif_ap_csa_count_down(arvif);2091mutex_unlock(&ar->conf_mutex);2092}20932094static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,2095struct ieee80211_vif *vif)2096{2097struct sk_buff *skb = data;2098struct ieee80211_mgmt *mgmt = (void *)skb->data;2099struct ath10k_vif *arvif = (void *)vif->drv_priv;21002101if (vif->type != NL80211_IFTYPE_STATION)2102return;21032104if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))2105return;21062107cancel_delayed_work(&arvif->connection_loss_work);2108}21092110void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)2111{2112ieee80211_iterate_active_interfaces_atomic(ar->hw,2113ATH10K_ITER_NORMAL_FLAGS,2114ath10k_mac_handle_beacon_iter,2115skb);2116}21172118static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,2119struct ieee80211_vif *vif)2120{2121u32 *vdev_id = data;2122struct ath10k_vif *arvif = (void *)vif->drv_priv;2123struct ath10k *ar = arvif->ar;2124struct ieee80211_hw *hw = ar->hw;21252126if (arvif->vdev_id != *vdev_id)2127return;21282129if (!arvif->is_up)2130return;21312132ieee80211_beacon_loss(vif);21332134/* Firmware doesn't report beacon loss events repeatedly. If AP probe2135* (done by mac80211) succeeds but beacons do not resume then it2136* doesn't make sense to continue operation. Queue connection loss work2137* which can be cancelled when beacon is received.2138*/2139ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,2140ATH10K_CONNECTION_LOSS_HZ);2141}21422143void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)2144{2145ieee80211_iterate_active_interfaces_atomic(ar->hw,2146ATH10K_ITER_NORMAL_FLAGS,2147ath10k_mac_handle_beacon_miss_iter,2148&vdev_id);2149}21502151static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)2152{2153struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,2154connection_loss_work.work);2155struct ieee80211_vif *vif = arvif->vif;21562157if (!arvif->is_up)2158return;21592160ieee80211_connection_loss(vif);2161}21622163/**********************/2164/* Station management */2165/**********************/21662167static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,2168struct ieee80211_vif *vif)2169{2170/* Some firmware revisions have unstable STA powersave when listen2171* interval is set too high (e.g. 5). The symptoms are firmware doesn't2172* generate NullFunc frames properly even if buffered frames have been2173* indicated in Beacon TIM. Firmware would seldom wake up to pull2174* buffered frames. Often pinging the device from AP would simply fail.2175*2176* As a workaround set it to 1.2177*/2178if (vif->type == NL80211_IFTYPE_STATION)2179return 1;21802181return ar->hw->conf.listen_interval;2182}21832184static void ath10k_peer_assoc_h_basic(struct ath10k *ar,2185struct ieee80211_vif *vif,2186struct ieee80211_sta *sta,2187struct wmi_peer_assoc_complete_arg *arg)2188{2189struct ath10k_vif *arvif = (void *)vif->drv_priv;2190u32 aid;21912192lockdep_assert_held(&ar->conf_mutex);21932194if (vif->type == NL80211_IFTYPE_STATION)2195aid = vif->cfg.aid;2196else2197aid = sta->aid;21982199ether_addr_copy(arg->addr, sta->addr);2200arg->vdev_id = arvif->vdev_id;2201arg->peer_aid = aid;2202arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;2203arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);2204arg->peer_num_spatial_streams = 1;2205arg->peer_caps = vif->bss_conf.assoc_capability;2206}22072208static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,2209struct ieee80211_vif *vif,2210struct ieee80211_sta *sta,2211struct wmi_peer_assoc_complete_arg *arg)2212{2213struct ieee80211_bss_conf *info = &vif->bss_conf;2214struct cfg80211_chan_def def;2215struct cfg80211_bss *bss;2216const u8 *rsnie = NULL;2217const u8 *wpaie = NULL;22182219lockdep_assert_held(&ar->conf_mutex);22202221if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))2222return;22232224bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid,2225vif->cfg.ssid_len ? vif->cfg.ssid : NULL,2226vif->cfg.ssid_len,2227IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);2228if (bss) {2229const struct cfg80211_bss_ies *ies;22302231rcu_read_lock();2232rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);22332234ies = rcu_dereference(bss->ies);22352236wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,2237WLAN_OUI_TYPE_MICROSOFT_WPA,2238ies->data,2239ies->len);2240rcu_read_unlock();2241cfg80211_put_bss(ar->hw->wiphy, bss);2242}22432244/* FIXME: base on RSN IE/WPA IE is a correct idea? */2245if (rsnie || wpaie) {2246ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);2247arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;2248}22492250if (wpaie) {2251ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);2252arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;2253}22542255if (sta->mfp &&2256test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT,2257ar->running_fw->fw_file.fw_features)) {2258arg->peer_flags |= ar->wmi.peer_flags->pmf;2259}2260}22612262static void ath10k_peer_assoc_h_rates(struct ath10k *ar,2263struct ieee80211_vif *vif,2264struct ieee80211_sta *sta,2265struct wmi_peer_assoc_complete_arg *arg)2266{2267struct ath10k_vif *arvif = (void *)vif->drv_priv;2268struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;2269struct cfg80211_chan_def def;2270const struct ieee80211_supported_band *sband;2271const struct ieee80211_rate *rates;2272enum nl80211_band band;2273u32 ratemask;2274u8 rate;2275int i;22762277lockdep_assert_held(&ar->conf_mutex);22782279if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))2280return;22812282band = def.chan->band;2283sband = ar->hw->wiphy->bands[band];2284ratemask = sta->deflink.supp_rates[band];2285ratemask &= arvif->bitrate_mask.control[band].legacy;2286rates = sband->bitrates;22872288rateset->num_rates = 0;22892290for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {2291if (!(ratemask & 1))2292continue;22932294rate = ath10k_mac_bitrate_to_rate(rates->bitrate);2295rateset->rates[rateset->num_rates] = rate;2296rateset->num_rates++;2297}2298}22992300static bool2301ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])2302{2303int nss;23042305for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)2306if (ht_mcs_mask[nss])2307return false;23082309return true;2310}23112312static bool2313ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])2314{2315int nss;23162317for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)2318if (vht_mcs_mask[nss])2319return false;23202321return true;2322}23232324static void ath10k_peer_assoc_h_ht(struct ath10k *ar,2325struct ieee80211_vif *vif,2326struct ieee80211_sta *sta,2327struct wmi_peer_assoc_complete_arg *arg)2328{2329const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;2330struct ath10k_vif *arvif = (void *)vif->drv_priv;2331struct cfg80211_chan_def def;2332enum nl80211_band band;2333const u8 *ht_mcs_mask;2334const u16 *vht_mcs_mask;2335int i, n;2336u8 max_nss;2337u32 stbc;23382339lockdep_assert_held(&ar->conf_mutex);23402341if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))2342return;23432344if (!ht_cap->ht_supported)2345return;23462347band = def.chan->band;2348ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;2349vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;23502351if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&2352ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))2353return;23542355arg->peer_flags |= ar->wmi.peer_flags->ht;2356arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +2357ht_cap->ampdu_factor)) - 1;23582359arg->peer_mpdu_density =2360ath10k_parse_mpdudensity(ht_cap->ampdu_density);23612362arg->peer_ht_caps = ht_cap->cap;2363arg->peer_rate_caps |= WMI_RC_HT_FLAG;23642365if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)2366arg->peer_flags |= ar->wmi.peer_flags->ldbc;23672368if (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) {2369arg->peer_flags |= ar->wmi.peer_flags->bw40;2370arg->peer_rate_caps |= WMI_RC_CW40_FLAG;2371}23722373if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {2374if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)2375arg->peer_rate_caps |= WMI_RC_SGI_FLAG;23762377if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)2378arg->peer_rate_caps |= WMI_RC_SGI_FLAG;2379}23802381if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {2382arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;2383arg->peer_flags |= ar->wmi.peer_flags->stbc;2384}23852386if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {2387stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;2388stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;2389stbc = stbc << WMI_RC_RX_STBC_FLAG_S;2390arg->peer_rate_caps |= stbc;2391arg->peer_flags |= ar->wmi.peer_flags->stbc;2392}23932394if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])2395arg->peer_rate_caps |= WMI_RC_TS_FLAG;2396else if (ht_cap->mcs.rx_mask[1])2397arg->peer_rate_caps |= WMI_RC_DS_FLAG;23982399for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)2400if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&2401(ht_mcs_mask[i / 8] & BIT(i % 8))) {2402max_nss = (i / 8) + 1;2403arg->peer_ht_rates.rates[n++] = i;2404}24052406/*2407* This is a workaround for HT-enabled STAs which break the spec2408* and have no HT capabilities RX mask (no HT RX MCS map).2409*2410* As per spec, in section 20.3.5 Modulation and coding scheme (MCS),2411* MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.2412*2413* Firmware asserts if such situation occurs.2414*/2415if (n == 0) {2416arg->peer_ht_rates.num_rates = 8;2417for (i = 0; i < arg->peer_ht_rates.num_rates; i++)2418arg->peer_ht_rates.rates[i] = i;2419} else {2420arg->peer_ht_rates.num_rates = n;2421arg->peer_num_spatial_streams = min(sta->deflink.rx_nss,2422max_nss);2423}24242425ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",2426arg->addr,2427arg->peer_ht_rates.num_rates,2428arg->peer_num_spatial_streams);2429}24302431static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,2432struct ath10k_vif *arvif,2433struct ieee80211_sta *sta)2434{2435u32 uapsd = 0;2436u32 max_sp = 0;2437int ret = 0;24382439lockdep_assert_held(&ar->conf_mutex);24402441if (sta->wme && sta->uapsd_queues) {2442ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",2443sta->uapsd_queues, sta->max_sp);24442445if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)2446uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |2447WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;2448if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)2449uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |2450WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;2451if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)2452uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |2453WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;2454if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)2455uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |2456WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;24572458if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)2459max_sp = sta->max_sp;24602461ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,2462sta->addr,2463WMI_AP_PS_PEER_PARAM_UAPSD,2464uapsd);2465if (ret) {2466ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",2467arvif->vdev_id, ret);2468return ret;2469}24702471ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,2472sta->addr,2473WMI_AP_PS_PEER_PARAM_MAX_SP,2474max_sp);2475if (ret) {2476ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",2477arvif->vdev_id, ret);2478return ret;2479}24802481/* TODO setup this based on STA listen interval and2482* beacon interval. Currently we don't know2483* sta->listen_interval - mac80211 patch required.2484* Currently use 10 seconds2485*/2486ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,2487WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,248810);2489if (ret) {2490ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",2491arvif->vdev_id, ret);2492return ret;2493}2494}24952496return 0;2497}24982499static u162500ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,2501const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])2502{2503int idx_limit;2504int nss;2505u16 mcs_map;2506u16 mcs;25072508for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {2509mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &2510vht_mcs_limit[nss];25112512if (mcs_map)2513idx_limit = fls(mcs_map) - 1;2514else2515idx_limit = -1;25162517switch (idx_limit) {2518case 0:2519case 1:2520case 2:2521case 3:2522case 4:2523case 5:2524case 6:2525default:2526/* see ath10k_mac_can_set_bitrate_mask() */2527WARN_ON(1);2528fallthrough;2529case -1:2530mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;2531break;2532case 7:2533mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;2534break;2535case 8:2536mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;2537break;2538case 9:2539mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;2540break;2541}25422543tx_mcs_set &= ~(0x3 << (nss * 2));2544tx_mcs_set |= mcs << (nss * 2);2545}25462547return tx_mcs_set;2548}25492550static u32 get_160mhz_nss_from_maxrate(int rate)2551{2552u32 nss;25532554switch (rate) {2555case 780:2556nss = 1;2557break;2558case 1560:2559nss = 2;2560break;2561case 2106:2562nss = 3; /* not support MCS9 from spec*/2563break;2564case 3120:2565nss = 4;2566break;2567default:2568nss = 1;2569}25702571return nss;2572}25732574static void ath10k_peer_assoc_h_vht(struct ath10k *ar,2575struct ieee80211_vif *vif,2576struct ieee80211_sta *sta,2577struct wmi_peer_assoc_complete_arg *arg)2578{2579const struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;2580struct ath10k_vif *arvif = (void *)vif->drv_priv;2581struct ath10k_hw_params *hw = &ar->hw_params;2582struct cfg80211_chan_def def;2583enum nl80211_band band;2584const u16 *vht_mcs_mask;2585u8 ampdu_factor;2586u8 max_nss, vht_mcs;2587int i;25882589if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))2590return;25912592if (!vht_cap->vht_supported)2593return;25942595band = def.chan->band;2596vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;25972598if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))2599return;26002601arg->peer_flags |= ar->wmi.peer_flags->vht;26022603if (def.chan->band == NL80211_BAND_2GHZ)2604arg->peer_flags |= ar->wmi.peer_flags->vht_2g;26052606arg->peer_vht_caps = vht_cap->cap;26072608ampdu_factor = (vht_cap->cap &2609IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>2610IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;26112612/* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to2613* zero in VHT IE. Using it would result in degraded throughput.2614* arg->peer_max_mpdu at this point contains HT max_mpdu so keep2615* it if VHT max_mpdu is smaller.2616*/2617arg->peer_max_mpdu = max(arg->peer_max_mpdu,2618(1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +2619ampdu_factor)) - 1);26202621if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)2622arg->peer_flags |= ar->wmi.peer_flags->bw80;26232624if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160)2625arg->peer_flags |= ar->wmi.peer_flags->bw160;26262627/* Calculate peer NSS capability from VHT capabilities if STA2628* supports VHT.2629*/2630for (i = 0, max_nss = 0, vht_mcs = 0; i < NL80211_VHT_NSS_MAX; i++) {2631vht_mcs = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) >>2632(2 * i) & 3;26332634if ((vht_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED) &&2635vht_mcs_mask[i])2636max_nss = i + 1;2637}2638arg->peer_num_spatial_streams = min(sta->deflink.rx_nss, max_nss);2639arg->peer_vht_rates.rx_max_rate =2640__le16_to_cpu(vht_cap->vht_mcs.rx_highest);2641arg->peer_vht_rates.rx_mcs_set =2642__le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);2643arg->peer_vht_rates.tx_max_rate =2644__le16_to_cpu(vht_cap->vht_mcs.tx_highest);2645arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(2646__le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);26472648/* Configure bandwidth-NSS mapping to FW2649* for the chip's tx chains setting on 160Mhz bw2650*/2651if (arg->peer_phymode == MODE_11AC_VHT160 ||2652arg->peer_phymode == MODE_11AC_VHT80_80) {2653u32 rx_nss;2654u32 max_rate;26552656max_rate = arg->peer_vht_rates.rx_max_rate;2657rx_nss = get_160mhz_nss_from_maxrate(max_rate);26582659if (rx_nss == 0)2660rx_nss = arg->peer_num_spatial_streams;2661else2662rx_nss = min(arg->peer_num_spatial_streams, rx_nss);26632664max_rate = hw->vht160_mcs_tx_highest;2665rx_nss = min(rx_nss, get_160mhz_nss_from_maxrate(max_rate));26662667arg->peer_bw_rxnss_override =2668FIELD_PREP(WMI_PEER_NSS_MAP_ENABLE, 1) |2669FIELD_PREP(WMI_PEER_NSS_160MHZ_MASK, (rx_nss - 1));26702671if (arg->peer_phymode == MODE_11AC_VHT80_80) {2672arg->peer_bw_rxnss_override |=2673FIELD_PREP(WMI_PEER_NSS_80_80MHZ_MASK, (rx_nss - 1));2674}2675}2676ath10k_dbg(ar, ATH10K_DBG_MAC,2677"mac vht peer %pM max_mpdu %d flags 0x%x peer_rx_nss_override 0x%x\n",2678sta->addr, arg->peer_max_mpdu,2679arg->peer_flags, arg->peer_bw_rxnss_override);2680}26812682static void ath10k_peer_assoc_h_qos(struct ath10k *ar,2683struct ieee80211_vif *vif,2684struct ieee80211_sta *sta,2685struct wmi_peer_assoc_complete_arg *arg)2686{2687struct ath10k_vif *arvif = (void *)vif->drv_priv;26882689switch (arvif->vdev_type) {2690case WMI_VDEV_TYPE_AP:2691if (sta->wme)2692arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;26932694if (sta->wme && sta->uapsd_queues) {2695arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;2696arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;2697}2698break;2699case WMI_VDEV_TYPE_STA:2700if (sta->wme)2701arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;2702break;2703case WMI_VDEV_TYPE_IBSS:2704if (sta->wme)2705arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;2706break;2707default:2708break;2709}27102711ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",2712sta->addr, !!(arg->peer_flags &2713arvif->ar->wmi.peer_flags->qos));2714}27152716static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)2717{2718return sta->deflink.supp_rates[NL80211_BAND_2GHZ] >>2719ATH10K_MAC_FIRST_OFDM_RATE_IDX;2720}27212722static enum wmi_phy_mode ath10k_mac_get_phymode_vht(struct ath10k *ar,2723struct ieee80211_sta *sta)2724{2725struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;27262727if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) {2728switch (vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {2729case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:2730return MODE_11AC_VHT160;2731case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:2732return MODE_11AC_VHT80_80;2733default:2734/* not sure if this is a valid case? */2735return MODE_11AC_VHT160;2736}2737}27382739if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)2740return MODE_11AC_VHT80;27412742if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)2743return MODE_11AC_VHT40;27442745if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)2746return MODE_11AC_VHT20;27472748return MODE_UNKNOWN;2749}27502751static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,2752struct ieee80211_vif *vif,2753struct ieee80211_sta *sta,2754struct wmi_peer_assoc_complete_arg *arg)2755{2756struct ath10k_vif *arvif = (void *)vif->drv_priv;2757struct cfg80211_chan_def def;2758enum nl80211_band band;2759const u8 *ht_mcs_mask;2760const u16 *vht_mcs_mask;2761enum wmi_phy_mode phymode = MODE_UNKNOWN;27622763if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))2764return;27652766band = def.chan->band;2767ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;2768vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;27692770switch (band) {2771case NL80211_BAND_2GHZ:2772if (sta->deflink.vht_cap.vht_supported &&2773!ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {2774if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)2775phymode = MODE_11AC_VHT40;2776else2777phymode = MODE_11AC_VHT20;2778} else if (sta->deflink.ht_cap.ht_supported &&2779!ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {2780if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)2781phymode = MODE_11NG_HT40;2782else2783phymode = MODE_11NG_HT20;2784} else if (ath10k_mac_sta_has_ofdm_only(sta)) {2785phymode = MODE_11G;2786} else {2787phymode = MODE_11B;2788}27892790break;2791case NL80211_BAND_5GHZ:2792/*2793* Check VHT first.2794*/2795if (sta->deflink.vht_cap.vht_supported &&2796!ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {2797phymode = ath10k_mac_get_phymode_vht(ar, sta);2798} else if (sta->deflink.ht_cap.ht_supported &&2799!ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {2800if (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40)2801phymode = MODE_11NA_HT40;2802else2803phymode = MODE_11NA_HT20;2804} else {2805phymode = MODE_11A;2806}28072808break;2809default:2810break;2811}28122813ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",2814sta->addr, ath10k_wmi_phymode_str(phymode));28152816arg->peer_phymode = phymode;2817WARN_ON(phymode == MODE_UNKNOWN);2818}28192820static int ath10k_peer_assoc_prepare(struct ath10k *ar,2821struct ieee80211_vif *vif,2822struct ieee80211_sta *sta,2823struct wmi_peer_assoc_complete_arg *arg)2824{2825lockdep_assert_held(&ar->conf_mutex);28262827memset(arg, 0, sizeof(*arg));28282829ath10k_peer_assoc_h_basic(ar, vif, sta, arg);2830ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);2831ath10k_peer_assoc_h_rates(ar, vif, sta, arg);2832ath10k_peer_assoc_h_ht(ar, vif, sta, arg);2833ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);2834ath10k_peer_assoc_h_vht(ar, vif, sta, arg);2835ath10k_peer_assoc_h_qos(ar, vif, sta, arg);28362837return 0;2838}28392840static const u32 ath10k_smps_map[] = {2841[WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,2842[WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,2843[WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,2844[WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,2845};28462847static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,2848const u8 *addr,2849const struct ieee80211_sta_ht_cap *ht_cap)2850{2851int smps;28522853if (!ht_cap->ht_supported)2854return 0;28552856smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;2857smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;28582859if (smps >= ARRAY_SIZE(ath10k_smps_map))2860return -EINVAL;28612862return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,2863ar->wmi.peer_param->smps_state,2864ath10k_smps_map[smps]);2865}28662867static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,2868struct ieee80211_vif *vif,2869struct ieee80211_sta_vht_cap vht_cap)2870{2871struct ath10k_vif *arvif = (void *)vif->drv_priv;2872int ret;2873u32 param;2874u32 value;28752876if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)2877return 0;28782879if (!(ar->vht_cap_info &2880(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |2881IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |2882IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |2883IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))2884return 0;28852886param = ar->wmi.vdev_param->txbf;2887value = 0;28882889if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))2890return 0;28912892/* The following logic is correct. If a remote STA advertises support2893* for being a beamformer then we should enable us being a beamformee.2894*/28952896if (ar->vht_cap_info &2897(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |2898IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {2899if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)2900value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;29012902if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)2903value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;2904}29052906if (ar->vht_cap_info &2907(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |2908IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {2909if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)2910value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;29112912if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)2913value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;2914}29152916if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)2917value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;29182919if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)2920value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;29212922ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);2923if (ret) {2924ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",2925value, ret);2926return ret;2927}29282929return 0;2930}29312932static bool ath10k_mac_is_connected(struct ath10k *ar)2933{2934struct ath10k_vif *arvif;29352936list_for_each_entry(arvif, &ar->arvifs, list) {2937if (arvif->is_up && arvif->vdev_type == WMI_VDEV_TYPE_STA)2938return true;2939}29402941return false;2942}29432944static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)2945{2946int ret;2947u32 param;2948int tx_power_2g, tx_power_5g;2949bool connected;29502951lockdep_assert_held(&ar->conf_mutex);29522953/* ath10k internally uses unit of 0.5 dBm so multiply by 2 */2954tx_power_2g = txpower * 2;2955tx_power_5g = txpower * 2;29562957connected = ath10k_mac_is_connected(ar);29582959if (connected && ar->tx_power_2g_limit)2960if (tx_power_2g > ar->tx_power_2g_limit)2961tx_power_2g = ar->tx_power_2g_limit;29622963if (connected && ar->tx_power_5g_limit)2964if (tx_power_5g > ar->tx_power_5g_limit)2965tx_power_5g = ar->tx_power_5g_limit;29662967ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower 2g: %d, 5g: %d\n",2968tx_power_2g, tx_power_5g);29692970param = ar->wmi.pdev_param->txpower_limit2g;2971ret = ath10k_wmi_pdev_set_param(ar, param, tx_power_2g);2972if (ret) {2973ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",2974tx_power_2g, ret);2975return ret;2976}29772978param = ar->wmi.pdev_param->txpower_limit5g;2979ret = ath10k_wmi_pdev_set_param(ar, param, tx_power_5g);2980if (ret) {2981ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",2982tx_power_5g, ret);2983return ret;2984}29852986return 0;2987}29882989static int ath10k_mac_txpower_recalc(struct ath10k *ar)2990{2991struct ath10k_vif *arvif;2992int ret, txpower = -1;29932994lockdep_assert_held(&ar->conf_mutex);29952996list_for_each_entry(arvif, &ar->arvifs, list) {2997/* txpower not initialized yet? */2998if (arvif->txpower == INT_MIN)2999continue;30003001if (txpower == -1)3002txpower = arvif->txpower;3003else3004txpower = min(txpower, arvif->txpower);3005}30063007if (txpower == -1)3008return 0;30093010ret = ath10k_mac_txpower_setup(ar, txpower);3011if (ret) {3012ath10k_warn(ar, "failed to setup tx power %d: %d\n",3013txpower, ret);3014return ret;3015}30163017return 0;3018}30193020static int ath10k_mac_set_sar_power(struct ath10k *ar)3021{3022if (!ar->hw_params.dynamic_sar_support)3023return -EOPNOTSUPP;30243025if (!ath10k_mac_is_connected(ar))3026return 0;30273028/* if connected, then arvif->txpower must be valid */3029return ath10k_mac_txpower_recalc(ar);3030}30313032static int ath10k_mac_set_sar_specs(struct ieee80211_hw *hw,3033const struct cfg80211_sar_specs *sar)3034{3035const struct cfg80211_sar_sub_specs *sub_specs;3036struct ath10k *ar = hw->priv;3037u32 i;3038int ret;30393040mutex_lock(&ar->conf_mutex);30413042if (!ar->hw_params.dynamic_sar_support) {3043ret = -EOPNOTSUPP;3044goto err;3045}30463047if (!sar || sar->type != NL80211_SAR_TYPE_POWER ||3048sar->num_sub_specs == 0) {3049ret = -EINVAL;3050goto err;3051}30523053sub_specs = sar->sub_specs;30543055/* 0dbm is not a practical value for ath10k, so use 03056* as no SAR limitation on it.3057*/3058ar->tx_power_2g_limit = 0;3059ar->tx_power_5g_limit = 0;30603061/* note the power is in 0.25dbm unit, while ath10k uses3062* 0.5dbm unit.3063*/3064for (i = 0; i < sar->num_sub_specs; i++) {3065if (sub_specs->freq_range_index == 0)3066ar->tx_power_2g_limit = sub_specs->power / 2;3067else if (sub_specs->freq_range_index == 1)3068ar->tx_power_5g_limit = sub_specs->power / 2;30693070sub_specs++;3071}30723073ret = ath10k_mac_set_sar_power(ar);3074if (ret) {3075ath10k_warn(ar, "failed to set sar power: %d", ret);3076goto err;3077}30783079err:3080mutex_unlock(&ar->conf_mutex);3081return ret;3082}30833084/* can be called only in mac80211 callbacks due to `key_count` usage */3085static void ath10k_bss_assoc(struct ieee80211_hw *hw,3086struct ieee80211_vif *vif,3087struct ieee80211_bss_conf *bss_conf)3088{3089struct ath10k *ar = hw->priv;3090struct ath10k_vif *arvif = (void *)vif->drv_priv;3091struct ieee80211_sta_ht_cap ht_cap;3092struct ieee80211_sta_vht_cap vht_cap;3093struct wmi_peer_assoc_complete_arg peer_arg;3094struct ieee80211_sta *ap_sta;3095int ret;30963097lockdep_assert_held(&ar->conf_mutex);30983099ath10k_dbg(ar, ATH10K_DBG_MAC, "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) {3106ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",3107bss_conf->bssid, arvif->vdev_id);3108rcu_read_unlock();3109return;3110}31113112/* ap_sta must be accessed only within rcu section which must be left3113* before calling ath10k_setup_peer_smps() which might sleep.3114*/3115ht_cap = ap_sta->deflink.ht_cap;3116vht_cap = ap_sta->deflink.vht_cap;31173118ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);3119if (ret) {3120ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",3121bss_conf->bssid, arvif->vdev_id, ret);3122rcu_read_unlock();3123return;3124}31253126rcu_read_unlock();31273128ret = ath10k_wmi_peer_assoc(ar, &peer_arg);3129if (ret) {3130ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",3131bss_conf->bssid, arvif->vdev_id, ret);3132return;3133}31343135ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);3136if (ret) {3137ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",3138arvif->vdev_id, ret);3139return;3140}31413142ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);3143if (ret) {3144ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",3145arvif->vdev_id, bss_conf->bssid, ret);3146return;3147}31483149ath10k_dbg(ar, ATH10K_DBG_MAC,3150"mac vdev %d up (associated) bssid %pM aid %d\n",3151arvif->vdev_id, bss_conf->bssid, vif->cfg.aid);31523153WARN_ON(arvif->is_up);31543155arvif->aid = vif->cfg.aid;3156ether_addr_copy(arvif->bssid, bss_conf->bssid);31573158ret = ath10k_wmi_pdev_set_param(ar,3159ar->wmi.pdev_param->peer_stats_info_enable, 1);3160if (ret)3161ath10k_warn(ar, "failed to enable peer stats info: %d\n", ret);31623163ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);3164if (ret) {3165ath10k_warn(ar, "failed to set vdev %d up: %d\n",3166arvif->vdev_id, ret);3167return;3168}31693170arvif->is_up = true;31713172ath10k_mac_set_sar_power(ar);31733174/* Workaround: Some firmware revisions (tested with qca61743175* WLAN.RM.2.0-00073) have buggy powersave state machine and must be3176* poked with peer param command.3177*/3178ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,3179ar->wmi.peer_param->dummy_var, 1);3180if (ret) {3181ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",3182arvif->bssid, arvif->vdev_id, ret);3183return;3184}3185}31863187static void ath10k_bss_disassoc(struct ieee80211_hw *hw,3188struct ieee80211_vif *vif)3189{3190struct ath10k *ar = hw->priv;3191struct ath10k_vif *arvif = (void *)vif->drv_priv;3192struct ieee80211_sta_vht_cap vht_cap = {};3193int ret;31943195lockdep_assert_held(&ar->conf_mutex);31963197ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",3198arvif->vdev_id, arvif->bssid);31993200ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);3201if (ret)3202ath10k_warn(ar, "failed to down vdev %i: %d\n",3203arvif->vdev_id, ret);32043205arvif->def_wep_key_idx = -1;32063207ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);3208if (ret) {3209ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",3210arvif->vdev_id, ret);3211return;3212}32133214arvif->is_up = false;32153216ath10k_mac_txpower_recalc(ar);32173218cancel_delayed_work_sync(&arvif->connection_loss_work);3219}32203221static int ath10k_new_peer_tid_config(struct ath10k *ar,3222struct ieee80211_sta *sta,3223struct ath10k_vif *arvif)3224{3225struct wmi_per_peer_per_tid_cfg_arg arg = {};3226struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;3227bool config_apply;3228int ret, i;32293230for (i = 0; i < ATH10K_TID_MAX; i++) {3231config_apply = false;3232if (arvif->retry_long[i] || arvif->ampdu[i] ||3233arvif->rate_ctrl[i] || arvif->rtscts[i]) {3234config_apply = true;3235arg.tid = i;3236arg.vdev_id = arvif->vdev_id;3237arg.retry_count = arvif->retry_long[i];3238arg.aggr_control = arvif->ampdu[i];3239arg.rate_ctrl = arvif->rate_ctrl[i];3240arg.rcode_flags = arvif->rate_code[i];32413242if (arvif->rtscts[i])3243arg.ext_tid_cfg_bitmap =3244WMI_EXT_TID_RTS_CTS_CONFIG;3245else3246arg.ext_tid_cfg_bitmap = 0;32473248arg.rtscts_ctrl = arvif->rtscts[i];3249}32503251if (arvif->noack[i]) {3252arg.ack_policy = arvif->noack[i];3253arg.rate_ctrl = WMI_TID_CONFIG_RATE_CONTROL_DEFAULT_LOWEST_RATE;3254arg.aggr_control = WMI_TID_CONFIG_AGGR_CONTROL_DISABLE;3255config_apply = true;3256}32573258/* Assign default value(-1) to newly connected station.3259* This is to identify station specific tid configuration not3260* configured for the station.3261*/3262arsta->retry_long[i] = -1;3263arsta->noack[i] = -1;3264arsta->ampdu[i] = -1;32653266if (!config_apply)3267continue;32683269ether_addr_copy(arg.peer_macaddr.addr, sta->addr);32703271ret = ath10k_wmi_set_per_peer_per_tid_cfg(ar, &arg);3272if (ret) {3273ath10k_warn(ar, "failed to set per tid retry/aggr config for sta %pM: %d\n",3274sta->addr, ret);3275return ret;3276}32773278memset(&arg, 0, sizeof(arg));3279}32803281return 0;3282}32833284static int ath10k_station_assoc(struct ath10k *ar,3285struct ieee80211_vif *vif,3286struct ieee80211_sta *sta,3287bool reassoc)3288{3289struct ath10k_vif *arvif = (void *)vif->drv_priv;3290struct wmi_peer_assoc_complete_arg peer_arg;3291int ret = 0;32923293lockdep_assert_held(&ar->conf_mutex);32943295ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);3296if (ret) {3297ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",3298sta->addr, arvif->vdev_id, ret);3299return ret;3300}33013302ret = ath10k_wmi_peer_assoc(ar, &peer_arg);3303if (ret) {3304ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",3305sta->addr, arvif->vdev_id, ret);3306return ret;3307}33083309/* Re-assoc is run only to update supported rates for given station. It3310* doesn't make much sense to reconfigure the peer completely.3311*/3312if (!reassoc) {3313ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,3314&sta->deflink.ht_cap);3315if (ret) {3316ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",3317arvif->vdev_id, ret);3318return ret;3319}33203321ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);3322if (ret) {3323ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",3324sta->addr, arvif->vdev_id, ret);3325return ret;3326}33273328if (!sta->wme) {3329arvif->num_legacy_stations++;3330ret = ath10k_recalc_rtscts_prot(arvif);3331if (ret) {3332ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",3333arvif->vdev_id, ret);3334return ret;3335}3336}33373338/* Plumb cached keys only for static WEP */3339if ((arvif->def_wep_key_idx != -1) && (!sta->tdls)) {3340ret = ath10k_install_peer_wep_keys(arvif, sta->addr);3341if (ret) {3342ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",3343arvif->vdev_id, ret);3344return ret;3345}3346}3347}33483349if (!test_bit(WMI_SERVICE_PEER_TID_CONFIGS_SUPPORT, ar->wmi.svc_map))3350return ret;33513352return ath10k_new_peer_tid_config(ar, sta, arvif);3353}33543355static int ath10k_station_disassoc(struct ath10k *ar,3356struct ieee80211_vif *vif,3357struct ieee80211_sta *sta)3358{3359struct ath10k_vif *arvif = (void *)vif->drv_priv;3360int ret = 0;33613362lockdep_assert_held(&ar->conf_mutex);33633364if (!sta->wme) {3365arvif->num_legacy_stations--;3366ret = ath10k_recalc_rtscts_prot(arvif);3367if (ret) {3368ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",3369arvif->vdev_id, ret);3370return ret;3371}3372}33733374ret = ath10k_clear_peer_keys(arvif, sta->addr);3375if (ret) {3376ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",3377arvif->vdev_id, ret);3378return ret;3379}33803381return ret;3382}33833384/**************/3385/* Regulatory */3386/**************/33873388static int ath10k_update_channel_list(struct ath10k *ar)3389{3390struct ieee80211_hw *hw = ar->hw;3391struct ieee80211_supported_band **bands;3392enum nl80211_band band;3393struct ieee80211_channel *channel;3394struct wmi_scan_chan_list_arg arg = {};3395struct wmi_channel_arg *ch;3396bool passive;3397int len;3398int ret;3399int i;34003401lockdep_assert_held(&ar->conf_mutex);34023403bands = hw->wiphy->bands;3404for (band = 0; band < NUM_NL80211_BANDS; band++) {3405if (!bands[band])3406continue;34073408for (i = 0; i < bands[band]->n_channels; i++) {3409if (bands[band]->channels[i].flags &3410IEEE80211_CHAN_DISABLED)3411continue;34123413arg.n_channels++;3414}3415}34163417len = sizeof(struct wmi_channel_arg) * arg.n_channels;3418arg.channels = kzalloc(len, GFP_KERNEL);3419if (!arg.channels)3420return -ENOMEM;34213422ch = arg.channels;3423for (band = 0; band < NUM_NL80211_BANDS; band++) {3424if (!bands[band])3425continue;34263427for (i = 0; i < bands[band]->n_channels; i++) {3428channel = &bands[band]->channels[i];34293430if (channel->flags & IEEE80211_CHAN_DISABLED)3431continue;34323433ch->allow_ht = true;34343435/* FIXME: when should we really allow VHT? */3436ch->allow_vht = true;34373438ch->allow_ibss =3439!(channel->flags & IEEE80211_CHAN_NO_IR);34403441ch->ht40plus =3442!(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);34433444ch->chan_radar =3445!!(channel->flags & IEEE80211_CHAN_RADAR);34463447passive = channel->flags & IEEE80211_CHAN_NO_IR;3448ch->passive = passive;34493450/* the firmware is ignoring the "radar" flag of the3451* channel and is scanning actively using Probe Requests3452* on "Radar detection"/DFS channels which are not3453* marked as "available"3454*/3455ch->passive |= ch->chan_radar;34563457ch->freq = channel->center_freq;3458ch->band_center_freq1 = channel->center_freq;3459ch->min_power = 0;3460ch->max_power = channel->max_power * 2;3461ch->max_reg_power = channel->max_reg_power * 2;3462ch->max_antenna_gain = channel->max_antenna_gain;3463ch->reg_class_id = 0; /* FIXME */34643465/* FIXME: why use only legacy modes, why not any3466* HT/VHT modes? Would that even make any3467* difference?3468*/3469if (channel->band == NL80211_BAND_2GHZ)3470ch->mode = MODE_11G;3471else3472ch->mode = MODE_11A;34733474if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))3475continue;34763477ath10k_dbg(ar, ATH10K_DBG_WMI,3478"mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",3479ch - arg.channels, arg.n_channels,3480ch->freq, ch->max_power, ch->max_reg_power,3481ch->max_antenna_gain, ch->mode);34823483ch++;3484}3485}34863487ret = ath10k_wmi_scan_chan_list(ar, &arg);3488kfree(arg.channels);34893490return ret;3491}34923493static enum wmi_dfs_region3494ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)3495{3496switch (dfs_region) {3497case NL80211_DFS_UNSET:3498return WMI_UNINIT_DFS_DOMAIN;3499case NL80211_DFS_FCC:3500return WMI_FCC_DFS_DOMAIN;3501case NL80211_DFS_ETSI:3502return WMI_ETSI_DFS_DOMAIN;3503case NL80211_DFS_JP:3504return WMI_MKK4_DFS_DOMAIN;3505}3506return WMI_UNINIT_DFS_DOMAIN;3507}35083509static void ath10k_regd_update(struct ath10k *ar)3510{3511struct reg_dmn_pair_mapping *regpair;3512int ret;3513enum wmi_dfs_region wmi_dfs_reg;3514enum nl80211_dfs_regions nl_dfs_reg;35153516lockdep_assert_held(&ar->conf_mutex);35173518ret = ath10k_update_channel_list(ar);3519if (ret)3520ath10k_warn(ar, "failed to update channel list: %d\n", ret);35213522regpair = ar->ath_common.regulatory.regpair;35233524if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {3525nl_dfs_reg = ar->dfs_detector->region;3526wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);3527} else {3528wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;3529}35303531/* Target allows setting up per-band regdomain but ath_common provides3532* a combined one only3533*/3534ret = ath10k_wmi_pdev_set_regdomain(ar,3535regpair->reg_domain,3536regpair->reg_domain, /* 2ghz */3537regpair->reg_domain, /* 5ghz */3538regpair->reg_2ghz_ctl,3539regpair->reg_5ghz_ctl,3540wmi_dfs_reg);3541if (ret)3542ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);3543}35443545static void ath10k_mac_update_channel_list(struct ath10k *ar,3546struct ieee80211_supported_band *band)3547{3548int i;35493550if (ar->low_5ghz_chan && ar->high_5ghz_chan) {3551for (i = 0; i < band->n_channels; i++) {3552if (band->channels[i].center_freq < ar->low_5ghz_chan ||3553band->channels[i].center_freq > ar->high_5ghz_chan)3554band->channels[i].flags |=3555IEEE80211_CHAN_DISABLED;3556}3557}3558}35593560static void ath10k_reg_notifier(struct wiphy *wiphy,3561struct regulatory_request *request)3562{3563struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);3564struct ath10k *ar = hw->priv;3565bool result;35663567ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);35683569if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {3570ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",3571request->dfs_region);3572result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,3573request->dfs_region);3574if (!result)3575ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",3576request->dfs_region);3577}35783579mutex_lock(&ar->conf_mutex);3580if (ar->state == ATH10K_STATE_ON)3581ath10k_regd_update(ar);3582mutex_unlock(&ar->conf_mutex);35833584if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)3585ath10k_mac_update_channel_list(ar,3586ar->hw->wiphy->bands[NL80211_BAND_5GHZ]);3587}35883589static void ath10k_stop_radar_confirmation(struct ath10k *ar)3590{3591spin_lock_bh(&ar->data_lock);3592ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_STOPPED;3593spin_unlock_bh(&ar->data_lock);35943595cancel_work_sync(&ar->radar_confirmation_work);3596}35973598/***************/3599/* TX handlers */3600/***************/36013602enum ath10k_mac_tx_path {3603ATH10K_MAC_TX_HTT,3604ATH10K_MAC_TX_HTT_MGMT,3605ATH10K_MAC_TX_WMI_MGMT,3606ATH10K_MAC_TX_UNKNOWN,3607};36083609void ath10k_mac_tx_lock(struct ath10k *ar, int reason)3610{3611lockdep_assert_held(&ar->htt.tx_lock);36123613WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);3614ar->tx_paused |= BIT(reason);3615ieee80211_stop_queues(ar->hw);3616}36173618static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,3619struct ieee80211_vif *vif)3620{3621struct ath10k *ar = data;3622struct ath10k_vif *arvif = (void *)vif->drv_priv;36233624if (arvif->tx_paused)3625return;36263627ieee80211_wake_queue(ar->hw, arvif->vdev_id);3628}36293630void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)3631{3632lockdep_assert_held(&ar->htt.tx_lock);36333634WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);3635ar->tx_paused &= ~BIT(reason);36363637if (ar->tx_paused)3638return;36393640ieee80211_iterate_active_interfaces_atomic(ar->hw,3641ATH10K_ITER_RESUME_FLAGS,3642ath10k_mac_tx_unlock_iter,3643ar);36443645ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);3646}36473648void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)3649{3650struct ath10k *ar = arvif->ar;36513652lockdep_assert_held(&ar->htt.tx_lock);36533654WARN_ON(reason >= BITS_PER_LONG);3655arvif->tx_paused |= BIT(reason);3656ieee80211_stop_queue(ar->hw, arvif->vdev_id);3657}36583659void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)3660{3661struct ath10k *ar = arvif->ar;36623663lockdep_assert_held(&ar->htt.tx_lock);36643665WARN_ON(reason >= BITS_PER_LONG);3666arvif->tx_paused &= ~BIT(reason);36673668if (ar->tx_paused)3669return;36703671if (arvif->tx_paused)3672return;36733674ieee80211_wake_queue(ar->hw, arvif->vdev_id);3675}36763677static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,3678enum wmi_tlv_tx_pause_id pause_id,3679enum wmi_tlv_tx_pause_action action)3680{3681struct ath10k *ar = arvif->ar;36823683lockdep_assert_held(&ar->htt.tx_lock);36843685switch (action) {3686case WMI_TLV_TX_PAUSE_ACTION_STOP:3687ath10k_mac_vif_tx_lock(arvif, pause_id);3688break;3689case WMI_TLV_TX_PAUSE_ACTION_WAKE:3690ath10k_mac_vif_tx_unlock(arvif, pause_id);3691break;3692default:3693ath10k_dbg(ar, ATH10K_DBG_BOOT,3694"received unknown tx pause action %d on vdev %i, ignoring\n",3695action, arvif->vdev_id);3696break;3697}3698}36993700struct ath10k_mac_tx_pause {3701u32 vdev_id;3702enum wmi_tlv_tx_pause_id pause_id;3703enum wmi_tlv_tx_pause_action action;3704};37053706static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,3707struct ieee80211_vif *vif)3708{3709struct ath10k_vif *arvif = (void *)vif->drv_priv;3710struct ath10k_mac_tx_pause *arg = data;37113712if (arvif->vdev_id != arg->vdev_id)3713return;37143715ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);3716}37173718void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,3719enum wmi_tlv_tx_pause_id pause_id,3720enum wmi_tlv_tx_pause_action action)3721{3722struct ath10k_mac_tx_pause arg = {3723.vdev_id = vdev_id,3724.pause_id = pause_id,3725.action = action,3726};37273728spin_lock_bh(&ar->htt.tx_lock);3729ieee80211_iterate_active_interfaces_atomic(ar->hw,3730ATH10K_ITER_RESUME_FLAGS,3731ath10k_mac_handle_tx_pause_iter,3732&arg);3733spin_unlock_bh(&ar->htt.tx_lock);3734}37353736static enum ath10k_hw_txrx_mode3737ath10k_mac_tx_h_get_txmode(struct ath10k *ar,3738struct ieee80211_vif *vif,3739struct ieee80211_sta *sta,3740struct sk_buff *skb)3741{3742const struct ieee80211_hdr *hdr = (void *)skb->data;3743const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);3744__le16 fc = hdr->frame_control;37453746if (IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)3747return ATH10K_HW_TXRX_ETHERNET;37483749if (!vif || vif->type == NL80211_IFTYPE_MONITOR)3750return ATH10K_HW_TXRX_RAW;37513752if (ieee80211_is_mgmt(fc))3753return ATH10K_HW_TXRX_MGMT;37543755/* Workaround:3756*3757* NullFunc frames are mostly used to ping if a client or AP are still3758* reachable and responsive. This implies tx status reports must be3759* accurate - otherwise either mac80211 or userspace (e.g. hostapd) can3760* come to a conclusion that the other end disappeared and tear down3761* BSS connection or it can never disconnect from BSS/client (which is3762* the case).3763*3764* Firmware with HTT older than 3.0 delivers incorrect tx status for3765* NullFunc frames to driver. However there's a HTT Mgmt Tx command3766* which seems to deliver correct tx reports for NullFunc frames. The3767* downside of using it is it ignores client powersave state so it can3768* end up disconnecting sleeping clients in AP mode. It should fix STA3769* mode though because AP don't sleep.3770*/3771if (ar->htt.target_version_major < 3 &&3772(ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&3773!test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,3774ar->running_fw->fw_file.fw_features))3775return ATH10K_HW_TXRX_MGMT;37763777/* Workaround:3778*3779* Some wmi-tlv firmwares for qca6174 have broken Tx key selection for3780* NativeWifi txmode - it selects AP key instead of peer key. It seems3781* to work with Ethernet txmode so use it.3782*3783* FIXME: Check if raw mode works with TDLS.3784*/3785if (ieee80211_is_data_present(fc) && sta && sta->tdls)3786return ATH10K_HW_TXRX_ETHERNET;37873788if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) ||3789skb_cb->flags & ATH10K_SKB_F_RAW_TX)3790return ATH10K_HW_TXRX_RAW;37913792return ATH10K_HW_TXRX_NATIVE_WIFI;3793}37943795static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,3796struct sk_buff *skb)3797{3798const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);3799const struct ieee80211_hdr *hdr = (void *)skb->data;3800const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |3801IEEE80211_TX_CTL_INJECTED;38023803if (!ieee80211_has_protected(hdr->frame_control))3804return false;38053806if ((info->flags & mask) == mask)3807return false;38083809if (vif)3810return !((struct ath10k_vif *)vif->drv_priv)->nohwcrypt;38113812return true;3813}38143815/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS3816* Control in the header.3817*/3818static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)3819{3820struct ieee80211_hdr *hdr = (void *)skb->data;3821struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);3822u8 *qos_ctl;38233824if (!ieee80211_is_data_qos(hdr->frame_control))3825return;38263827qos_ctl = ieee80211_get_qos_ctl(hdr);3828memmove(skb->data + IEEE80211_QOS_CTL_LEN,3829#if defined(__linux__)3830skb->data, (void *)qos_ctl - (void *)skb->data);3831#elif defined(__FreeBSD__)3832skb->data, qos_ctl - skb->data);3833#endif3834skb_pull(skb, IEEE80211_QOS_CTL_LEN);38353836/* Some firmware revisions don't handle sending QoS NullFunc well.3837* These frames are mainly used for CQM purposes so it doesn't really3838* matter whether QoS NullFunc or NullFunc are sent.3839*/3840hdr = (void *)skb->data;3841if (ieee80211_is_qos_nullfunc(hdr->frame_control))3842cb->flags &= ~ATH10K_SKB_F_QOS;38433844hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);3845}38463847static void ath10k_tx_h_8023(struct sk_buff *skb)3848{3849struct ieee80211_hdr *hdr;3850struct rfc1042_hdr *rfc1042;3851struct ethhdr *eth;3852size_t hdrlen;3853u8 da[ETH_ALEN];3854u8 sa[ETH_ALEN];3855__be16 type;38563857hdr = (void *)skb->data;3858hdrlen = ieee80211_hdrlen(hdr->frame_control);3859#if defined(__linux__)3860rfc1042 = (void *)skb->data + hdrlen;3861#elif defined(__FreeBSD__)3862rfc1042 = (void *)(skb->data + hdrlen);3863#endif38643865ether_addr_copy(da, ieee80211_get_DA(hdr));3866ether_addr_copy(sa, ieee80211_get_SA(hdr));3867type = rfc1042->snap_type;38683869skb_pull(skb, hdrlen + sizeof(*rfc1042));3870skb_push(skb, sizeof(*eth));38713872eth = (void *)skb->data;3873ether_addr_copy(eth->h_dest, da);3874ether_addr_copy(eth->h_source, sa);3875eth->h_proto = type;3876}38773878static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,3879struct ieee80211_vif *vif,3880struct sk_buff *skb)3881{3882struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;3883struct ath10k_vif *arvif = (void *)vif->drv_priv;38843885/* This is case only for P2P_GO */3886if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)3887return;38883889if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {3890spin_lock_bh(&ar->data_lock);3891if (arvif->u.ap.noa_data)3892if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,3893GFP_ATOMIC))3894skb_put_data(skb, arvif->u.ap.noa_data,3895arvif->u.ap.noa_len);3896spin_unlock_bh(&ar->data_lock);3897}3898}38993900static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,3901struct ieee80211_vif *vif,3902struct ieee80211_txq *txq,3903struct ieee80211_sta *sta,3904struct sk_buff *skb, u16 airtime)3905{3906struct ieee80211_hdr *hdr = (void *)skb->data;3907struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);3908const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);3909bool is_data = ieee80211_is_data(hdr->frame_control) ||3910ieee80211_is_data_qos(hdr->frame_control);3911struct ath10k_vif *arvif = (void *)vif->drv_priv;3912struct ath10k_sta *arsta;3913u8 tid, *qos_ctl;3914bool noack = false;39153916cb->flags = 0;39173918if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {3919cb->flags |= ATH10K_SKB_F_QOS; /* Assume data frames are QoS */3920goto finish_cb_fill;3921}39223923if (!ath10k_tx_h_use_hwcrypto(vif, skb))3924cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;39253926if (ieee80211_is_mgmt(hdr->frame_control))3927cb->flags |= ATH10K_SKB_F_MGMT;39283929if (ieee80211_is_data_qos(hdr->frame_control)) {3930cb->flags |= ATH10K_SKB_F_QOS;3931qos_ctl = ieee80211_get_qos_ctl(hdr);3932tid = (*qos_ctl) & IEEE80211_QOS_CTL_TID_MASK;39333934if (arvif->noack[tid] == WMI_PEER_TID_CONFIG_NOACK)3935noack = true;39363937if (sta) {3938arsta = (struct ath10k_sta *)sta->drv_priv;39393940if (arsta->noack[tid] == WMI_PEER_TID_CONFIG_NOACK)3941noack = true;39423943if (arsta->noack[tid] == WMI_PEER_TID_CONFIG_ACK)3944noack = false;3945}39463947if (noack)3948cb->flags |= ATH10K_SKB_F_NOACK_TID;3949}39503951/* Data frames encrypted in software will be posted to firmware3952* with tx encap mode set to RAW. Ex: Multicast traffic generated3953* for a specific VLAN group will always be encrypted in software.3954*/3955if (is_data && ieee80211_has_protected(hdr->frame_control) &&3956!info->control.hw_key) {3957cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;3958cb->flags |= ATH10K_SKB_F_RAW_TX;3959}39603961finish_cb_fill:3962cb->vif = vif;3963cb->txq = txq;3964cb->airtime_est = airtime;3965if (sta) {3966arsta = (struct ath10k_sta *)sta->drv_priv;3967spin_lock_bh(&ar->data_lock);3968cb->ucast_cipher = arsta->ucast_cipher;3969spin_unlock_bh(&ar->data_lock);3970}3971}39723973bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)3974{3975/* FIXME: Not really sure since when the behaviour changed. At some3976* point new firmware stopped requiring creation of peer entries for3977* offchannel tx (and actually creating them causes issues with wmi-htc3978* tx credit replenishment and reliability). Assuming it's at least 3.43979* because that's when the `freq` was introduced to TX_FRM HTT command.3980*/3981return (ar->htt.target_version_major >= 3 &&3982ar->htt.target_version_minor >= 4 &&3983ar->running_fw->fw_file.htt_op_version == ATH10K_FW_HTT_OP_VERSION_TLV);3984}39853986static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)3987{3988struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;39893990if (skb_queue_len_lockless(q) >= ATH10K_MAX_NUM_MGMT_PENDING) {3991ath10k_warn(ar, "wmi mgmt tx queue is full\n");3992return -ENOSPC;3993}39943995skb_queue_tail(q, skb);3996ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);39973998return 0;3999}40004001static enum ath10k_mac_tx_path4002ath10k_mac_tx_h_get_txpath(struct ath10k *ar,4003struct sk_buff *skb,4004enum ath10k_hw_txrx_mode txmode)4005{4006switch (txmode) {4007case ATH10K_HW_TXRX_RAW:4008case ATH10K_HW_TXRX_NATIVE_WIFI:4009case ATH10K_HW_TXRX_ETHERNET:4010return ATH10K_MAC_TX_HTT;4011case ATH10K_HW_TXRX_MGMT:4012if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,4013ar->running_fw->fw_file.fw_features) ||4014test_bit(WMI_SERVICE_MGMT_TX_WMI,4015ar->wmi.svc_map))4016return ATH10K_MAC_TX_WMI_MGMT;4017else if (ar->htt.target_version_major >= 3)4018return ATH10K_MAC_TX_HTT;4019else4020return ATH10K_MAC_TX_HTT_MGMT;4021}40224023return ATH10K_MAC_TX_UNKNOWN;4024}40254026static int ath10k_mac_tx_submit(struct ath10k *ar,4027enum ath10k_hw_txrx_mode txmode,4028enum ath10k_mac_tx_path txpath,4029struct sk_buff *skb)4030{4031struct ath10k_htt *htt = &ar->htt;4032int ret = -EINVAL;40334034switch (txpath) {4035case ATH10K_MAC_TX_HTT:4036ret = ath10k_htt_tx(htt, txmode, skb);4037break;4038case ATH10K_MAC_TX_HTT_MGMT:4039ret = ath10k_htt_mgmt_tx(htt, skb);4040break;4041case ATH10K_MAC_TX_WMI_MGMT:4042ret = ath10k_mac_tx_wmi_mgmt(ar, skb);4043break;4044case ATH10K_MAC_TX_UNKNOWN:4045WARN_ON_ONCE(1);4046ret = -EINVAL;4047break;4048}40494050if (ret) {4051ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",4052ret);4053ieee80211_free_txskb(ar->hw, skb);4054}40554056return ret;4057}40584059/* This function consumes the sk_buff regardless of return value as far as4060* caller is concerned so no freeing is necessary afterwards.4061*/4062static int ath10k_mac_tx(struct ath10k *ar,4063struct ieee80211_vif *vif,4064enum ath10k_hw_txrx_mode txmode,4065enum ath10k_mac_tx_path txpath,4066struct sk_buff *skb, bool noque_offchan)4067{4068struct ieee80211_hw *hw = ar->hw;4069struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);4070const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);4071int ret;40724073/* We should disable CCK RATE due to P2P */4074if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)4075ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");40764077switch (txmode) {4078case ATH10K_HW_TXRX_MGMT:4079case ATH10K_HW_TXRX_NATIVE_WIFI:4080ath10k_tx_h_nwifi(hw, skb);4081ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);4082ath10k_tx_h_seq_no(vif, skb);4083break;4084case ATH10K_HW_TXRX_ETHERNET:4085/* Convert 802.11->802.3 header only if the frame was earlier4086* encapsulated to 802.11 by mac80211. Otherwise pass it as is.4087*/4088if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP))4089ath10k_tx_h_8023(skb);4090break;4091case ATH10K_HW_TXRX_RAW:4092if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) &&4093!(skb_cb->flags & ATH10K_SKB_F_RAW_TX)) {4094WARN_ON_ONCE(1);4095ieee80211_free_txskb(hw, skb);4096return -EOPNOTSUPP;4097}4098}40994100if (!noque_offchan && info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {4101if (!ath10k_mac_tx_frm_has_freq(ar)) {4102ath10k_dbg(ar, ATH10K_DBG_MAC, "mac queued offchannel skb %p len %d\n",4103skb, skb->len);41044105skb_queue_tail(&ar->offchan_tx_queue, skb);4106ieee80211_queue_work(hw, &ar->offchan_tx_work);4107return 0;4108}4109}41104111ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);4112if (ret) {4113ath10k_warn(ar, "failed to submit frame: %d\n", ret);4114return ret;4115}41164117return 0;4118}41194120void ath10k_offchan_tx_purge(struct ath10k *ar)4121{4122struct sk_buff *skb;41234124for (;;) {4125skb = skb_dequeue(&ar->offchan_tx_queue);4126if (!skb)4127break;41284129ieee80211_free_txskb(ar->hw, skb);4130}4131}41324133void ath10k_offchan_tx_work(struct work_struct *work)4134{4135struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);4136struct ath10k_peer *peer;4137struct ath10k_vif *arvif;4138enum ath10k_hw_txrx_mode txmode;4139enum ath10k_mac_tx_path txpath;4140struct ieee80211_hdr *hdr;4141struct ieee80211_vif *vif;4142struct ieee80211_sta *sta;4143struct sk_buff *skb;4144const u8 *peer_addr;4145int vdev_id;4146int ret;4147unsigned long time_left;4148bool tmp_peer_created = false;41494150/* FW requirement: We must create a peer before FW will send out4151* an offchannel frame. Otherwise the frame will be stuck and4152* never transmitted. We delete the peer upon tx completion.4153* It is unlikely that a peer for offchannel tx will already be4154* present. However it may be in some rare cases so account for that.4155* Otherwise we might remove a legitimate peer and break stuff.4156*/41574158for (;;) {4159skb = skb_dequeue(&ar->offchan_tx_queue);4160if (!skb)4161break;41624163mutex_lock(&ar->conf_mutex);41644165ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p len %d\n",4166skb, skb->len);41674168hdr = (struct ieee80211_hdr *)skb->data;4169peer_addr = ieee80211_get_DA(hdr);41704171spin_lock_bh(&ar->data_lock);4172vdev_id = ar->scan.vdev_id;4173peer = ath10k_peer_find(ar, vdev_id, peer_addr);4174spin_unlock_bh(&ar->data_lock);41754176if (peer) {4177ath10k_warn(ar, "peer %pM on vdev %d already present\n",4178peer_addr, vdev_id);4179} else {4180ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,4181peer_addr,4182WMI_PEER_TYPE_DEFAULT);4183if (ret)4184ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",4185peer_addr, vdev_id, ret);4186tmp_peer_created = (ret == 0);4187}41884189spin_lock_bh(&ar->data_lock);4190reinit_completion(&ar->offchan_tx_completed);4191ar->offchan_tx_skb = skb;4192spin_unlock_bh(&ar->data_lock);41934194/* It's safe to access vif and sta - conf_mutex guarantees that4195* sta_state() and remove_interface() are locked exclusively4196* out wrt to this offchannel worker.4197*/4198arvif = ath10k_get_arvif(ar, vdev_id);4199if (arvif) {4200vif = arvif->vif;4201sta = ieee80211_find_sta(vif, peer_addr);4202} else {4203vif = NULL;4204sta = NULL;4205}42064207txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);4208txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);42094210ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, true);4211if (ret) {4212ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",4213ret);4214/* not serious */4215}42164217time_left =4218wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);4219if (time_left == 0)4220ath10k_warn(ar, "timed out waiting for offchannel skb %p, len: %d\n",4221skb, skb->len);42224223if (!peer && tmp_peer_created) {4224ret = ath10k_peer_delete(ar, vdev_id, peer_addr);4225if (ret)4226ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",4227peer_addr, vdev_id, ret);4228}42294230mutex_unlock(&ar->conf_mutex);4231}4232}42334234void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)4235{4236struct sk_buff *skb;42374238for (;;) {4239skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);4240if (!skb)4241break;42424243ieee80211_free_txskb(ar->hw, skb);4244}4245}42464247void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)4248{4249struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);4250struct sk_buff *skb;4251dma_addr_t paddr;4252int ret;42534254for (;;) {4255skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);4256if (!skb)4257break;42584259if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF,4260ar->running_fw->fw_file.fw_features)) {4261paddr = dma_map_single(ar->dev, skb->data,4262skb->len, DMA_TO_DEVICE);4263if (dma_mapping_error(ar->dev, paddr)) {4264ieee80211_free_txskb(ar->hw, skb);4265continue;4266}4267ret = ath10k_wmi_mgmt_tx_send(ar, skb, paddr);4268if (ret) {4269ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n",4270ret);4271/* remove this msdu from idr tracking */4272ath10k_wmi_cleanup_mgmt_tx_send(ar, skb);42734274dma_unmap_single(ar->dev, paddr, skb->len,4275DMA_TO_DEVICE);4276ieee80211_free_txskb(ar->hw, skb);4277}4278} else {4279ret = ath10k_wmi_mgmt_tx(ar, skb);4280if (ret) {4281ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",4282ret);4283ieee80211_free_txskb(ar->hw, skb);4284}4285}4286}4287}42884289static void ath10k_mac_txq_init(struct ieee80211_txq *txq)4290{4291struct ath10k_txq *artxq;42924293if (!txq)4294return;42954296artxq = (void *)txq->drv_priv;4297INIT_LIST_HEAD(&artxq->list);4298}42994300static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)4301{4302struct ath10k_skb_cb *cb;4303struct sk_buff *msdu;4304int msdu_id;43054306if (!txq)4307return;43084309spin_lock_bh(&ar->htt.tx_lock);4310idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {4311cb = ATH10K_SKB_CB(msdu);4312if (cb->txq == txq)4313cb->txq = NULL;4314}4315spin_unlock_bh(&ar->htt.tx_lock);4316}43174318struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,4319u16 peer_id,4320u8 tid)4321{4322struct ath10k_peer *peer;43234324lockdep_assert_held(&ar->data_lock);43254326peer = ar->peer_map[peer_id];4327if (!peer)4328return NULL;43294330if (peer->removed)4331return NULL;43324333if (peer->sta)4334return peer->sta->txq[tid];4335else if (peer->vif)4336return peer->vif->txq;4337else4338return NULL;4339}43404341static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,4342struct ieee80211_txq *txq)4343{4344struct ath10k *ar = hw->priv;4345struct ath10k_txq *artxq = (void *)txq->drv_priv;43464347/* No need to get locks */4348if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)4349return true;43504351if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)4352return true;43534354if (artxq->num_fw_queued < artxq->num_push_allowed)4355return true;43564357return false;4358}43594360/* Return estimated airtime in microsecond, which is calculated using last4361* reported TX rate. This is just a rough estimation because host driver has no4362* knowledge of the actual transmit rate, retries or aggregation. If actual4363* airtime can be reported by firmware, then delta between estimated and actual4364* airtime can be adjusted from deficit.4365*/4366#define IEEE80211_ATF_OVERHEAD 100 /* IFS + some slot time */4367#define IEEE80211_ATF_OVERHEAD_IFS 16 /* IFS only */4368static u16 ath10k_mac_update_airtime(struct ath10k *ar,4369struct ieee80211_txq *txq,4370struct sk_buff *skb)4371{4372struct ath10k_sta *arsta;4373u32 pktlen;4374u16 airtime = 0;43754376if (!txq || !txq->sta)4377return airtime;43784379if (test_bit(WMI_SERVICE_REPORT_AIRTIME, ar->wmi.svc_map))4380return airtime;43814382spin_lock_bh(&ar->data_lock);4383arsta = (struct ath10k_sta *)txq->sta->drv_priv;43844385pktlen = skb->len + 38; /* Assume MAC header 30, SNAP 8 for most case */4386if (arsta->last_tx_bitrate) {4387/* airtime in us, last_tx_bitrate in 100kbps */4388airtime = (pktlen * 8 * (1000 / 100))4389/ arsta->last_tx_bitrate;4390/* overhead for media access time and IFS */4391airtime += IEEE80211_ATF_OVERHEAD_IFS;4392} else {4393/* This is mostly for throttle excessive BC/MC frames, and the4394* airtime/rate doesn't need be exact. Airtime of BC/MC frames4395* in 2G get some discount, which helps prevent very low rate4396* frames from being blocked for too long.4397*/4398airtime = (pktlen * 8 * (1000 / 100)) / 60; /* 6M */4399airtime += IEEE80211_ATF_OVERHEAD;4400}4401spin_unlock_bh(&ar->data_lock);44024403return airtime;4404}44054406int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,4407struct ieee80211_txq *txq)4408{4409struct ath10k *ar = hw->priv;4410struct ath10k_htt *htt = &ar->htt;4411struct ath10k_txq *artxq = (void *)txq->drv_priv;4412struct ieee80211_vif *vif = txq->vif;4413struct ieee80211_sta *sta = txq->sta;4414enum ath10k_hw_txrx_mode txmode;4415enum ath10k_mac_tx_path txpath;4416struct sk_buff *skb;4417struct ieee80211_hdr *hdr;4418size_t skb_len;4419bool is_mgmt, is_presp;4420int ret;4421u16 airtime;44224423spin_lock_bh(&ar->htt.tx_lock);4424ret = ath10k_htt_tx_inc_pending(htt);4425spin_unlock_bh(&ar->htt.tx_lock);44264427if (ret)4428return ret;44294430skb = ieee80211_tx_dequeue_ni(hw, txq);4431if (!skb) {4432spin_lock_bh(&ar->htt.tx_lock);4433ath10k_htt_tx_dec_pending(htt);4434spin_unlock_bh(&ar->htt.tx_lock);44354436return -ENOENT;4437}44384439airtime = ath10k_mac_update_airtime(ar, txq, skb);4440ath10k_mac_tx_h_fill_cb(ar, vif, txq, sta, skb, airtime);44414442skb_len = skb->len;4443txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);4444txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);4445is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);44464447if (is_mgmt) {4448hdr = (struct ieee80211_hdr *)skb->data;4449is_presp = ieee80211_is_probe_resp(hdr->frame_control);44504451spin_lock_bh(&ar->htt.tx_lock);4452ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);44534454if (ret) {4455ath10k_htt_tx_dec_pending(htt);4456spin_unlock_bh(&ar->htt.tx_lock);4457return ret;4458}4459spin_unlock_bh(&ar->htt.tx_lock);4460}44614462ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, false);4463if (unlikely(ret)) {4464ath10k_warn(ar, "failed to push frame: %d\n", ret);44654466spin_lock_bh(&ar->htt.tx_lock);4467ath10k_htt_tx_dec_pending(htt);4468if (is_mgmt)4469ath10k_htt_tx_mgmt_dec_pending(htt);4470spin_unlock_bh(&ar->htt.tx_lock);44714472return ret;4473}44744475spin_lock_bh(&ar->htt.tx_lock);4476artxq->num_fw_queued++;4477spin_unlock_bh(&ar->htt.tx_lock);44784479return skb_len;4480}44814482static int ath10k_mac_schedule_txq(struct ieee80211_hw *hw, u32 ac)4483{4484struct ieee80211_txq *txq;4485int ret = 0;44864487ieee80211_txq_schedule_start(hw, ac);4488while ((txq = ieee80211_next_txq(hw, ac))) {4489while (ath10k_mac_tx_can_push(hw, txq)) {4490ret = ath10k_mac_tx_push_txq(hw, txq);4491if (ret < 0)4492break;4493}4494ieee80211_return_txq(hw, txq, false);4495ath10k_htt_tx_txq_update(hw, txq);4496if (ret == -EBUSY)4497break;4498}4499ieee80211_txq_schedule_end(hw, ac);45004501return ret;4502}45034504void ath10k_mac_tx_push_pending(struct ath10k *ar)4505{4506struct ieee80211_hw *hw = ar->hw;4507u32 ac;45084509if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)4510return;45114512if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))4513return;45144515rcu_read_lock();4516for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {4517if (ath10k_mac_schedule_txq(hw, ac) == -EBUSY)4518break;4519}4520rcu_read_unlock();4521}4522EXPORT_SYMBOL(ath10k_mac_tx_push_pending);45234524/************/4525/* Scanning */4526/************/45274528void __ath10k_scan_finish(struct ath10k *ar)4529{4530lockdep_assert_held(&ar->data_lock);45314532switch (ar->scan.state) {4533case ATH10K_SCAN_IDLE:4534break;4535case ATH10K_SCAN_RUNNING:4536case ATH10K_SCAN_ABORTING:4537if (ar->scan.is_roc && ar->scan.roc_notify)4538ieee80211_remain_on_channel_expired(ar->hw);4539fallthrough;4540case ATH10K_SCAN_STARTING:4541if (!ar->scan.is_roc) {4542struct cfg80211_scan_info info = {4543.aborted = ((ar->scan.state ==4544ATH10K_SCAN_ABORTING) ||4545(ar->scan.state ==4546ATH10K_SCAN_STARTING)),4547};45484549ieee80211_scan_completed(ar->hw, &info);4550}45514552ar->scan.state = ATH10K_SCAN_IDLE;4553ar->scan_channel = NULL;4554ar->scan.roc_freq = 0;4555ath10k_offchan_tx_purge(ar);4556cancel_delayed_work(&ar->scan.timeout);4557complete(&ar->scan.completed);4558break;4559}4560}45614562void ath10k_scan_finish(struct ath10k *ar)4563{4564spin_lock_bh(&ar->data_lock);4565__ath10k_scan_finish(ar);4566spin_unlock_bh(&ar->data_lock);4567}45684569static int ath10k_scan_stop(struct ath10k *ar)4570{4571struct wmi_stop_scan_arg arg = {4572.req_id = 1, /* FIXME */4573.req_type = WMI_SCAN_STOP_ONE,4574.u.scan_id = ATH10K_SCAN_ID,4575};4576int ret;45774578lockdep_assert_held(&ar->conf_mutex);45794580ret = ath10k_wmi_stop_scan(ar, &arg);4581if (ret) {4582ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);4583goto out;4584}45854586ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);4587if (ret == 0) {4588ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");4589ret = -ETIMEDOUT;4590} else if (ret > 0) {4591ret = 0;4592}45934594out:4595/* Scan state should be updated upon scan completion but in case4596* firmware fails to deliver the event (for whatever reason) it is4597* desired to clean up scan state anyway. Firmware may have just4598* dropped the scan completion event delivery due to transport pipe4599* being overflown with data and/or it can recover on its own before4600* next scan request is submitted.4601*/4602spin_lock_bh(&ar->data_lock);4603if (ar->scan.state != ATH10K_SCAN_IDLE)4604__ath10k_scan_finish(ar);4605spin_unlock_bh(&ar->data_lock);46064607return ret;4608}46094610static void ath10k_scan_abort(struct ath10k *ar)4611{4612int ret;46134614lockdep_assert_held(&ar->conf_mutex);46154616spin_lock_bh(&ar->data_lock);46174618switch (ar->scan.state) {4619case ATH10K_SCAN_IDLE:4620/* This can happen if timeout worker kicked in and called4621* abortion while scan completion was being processed.4622*/4623break;4624case ATH10K_SCAN_STARTING:4625case ATH10K_SCAN_ABORTING:4626ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",4627ath10k_scan_state_str(ar->scan.state),4628ar->scan.state);4629break;4630case ATH10K_SCAN_RUNNING:4631ar->scan.state = ATH10K_SCAN_ABORTING;4632spin_unlock_bh(&ar->data_lock);46334634ret = ath10k_scan_stop(ar);4635if (ret)4636ath10k_warn(ar, "failed to abort scan: %d\n", ret);46374638spin_lock_bh(&ar->data_lock);4639break;4640}46414642spin_unlock_bh(&ar->data_lock);4643}46444645void ath10k_scan_timeout_work(struct work_struct *work)4646{4647struct ath10k *ar = container_of(work, struct ath10k,4648scan.timeout.work);46494650mutex_lock(&ar->conf_mutex);4651ath10k_scan_abort(ar);4652mutex_unlock(&ar->conf_mutex);4653}46544655static int ath10k_start_scan(struct ath10k *ar,4656const struct wmi_start_scan_arg *arg)4657{4658int ret;46594660lockdep_assert_held(&ar->conf_mutex);46614662ret = ath10k_wmi_start_scan(ar, arg);4663if (ret)4664return ret;46654666ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);4667if (ret == 0) {4668ret = ath10k_scan_stop(ar);4669if (ret)4670ath10k_warn(ar, "failed to stop scan: %d\n", ret);46714672return -ETIMEDOUT;4673}46744675/* If we failed to start the scan, return error code at4676* this point. This is probably due to some issue in the4677* firmware, but no need to wedge the driver due to that...4678*/4679spin_lock_bh(&ar->data_lock);4680if (ar->scan.state == ATH10K_SCAN_IDLE) {4681spin_unlock_bh(&ar->data_lock);4682return -EINVAL;4683}4684spin_unlock_bh(&ar->data_lock);46854686return 0;4687}46884689/**********************/4690/* mac80211 callbacks */4691/**********************/46924693static void ath10k_mac_op_tx(struct ieee80211_hw *hw,4694struct ieee80211_tx_control *control,4695struct sk_buff *skb)4696{4697struct ath10k *ar = hw->priv;4698struct ath10k_htt *htt = &ar->htt;4699struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);4700struct ieee80211_vif *vif = info->control.vif;4701struct ieee80211_sta *sta = control->sta;4702struct ieee80211_txq *txq = NULL;4703enum ath10k_hw_txrx_mode txmode;4704enum ath10k_mac_tx_path txpath;4705bool is_htt;4706bool is_mgmt;4707int ret;4708u16 airtime;47094710airtime = ath10k_mac_update_airtime(ar, txq, skb);4711ath10k_mac_tx_h_fill_cb(ar, vif, txq, sta, skb, airtime);47124713txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);4714txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);4715is_htt = (txpath == ATH10K_MAC_TX_HTT ||4716txpath == ATH10K_MAC_TX_HTT_MGMT);4717is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);47184719if (is_htt) {4720bool is_presp = false;47214722spin_lock_bh(&ar->htt.tx_lock);4723if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) {4724struct ieee80211_hdr *hdr = (void *)skb->data;47254726is_presp = ieee80211_is_probe_resp(hdr->frame_control);4727}47284729ret = ath10k_htt_tx_inc_pending(htt);4730if (ret) {4731ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",4732ret);4733spin_unlock_bh(&ar->htt.tx_lock);4734ieee80211_free_txskb(ar->hw, skb);4735return;4736}47374738ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);4739if (ret) {4740ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",4741ret);4742ath10k_htt_tx_dec_pending(htt);4743spin_unlock_bh(&ar->htt.tx_lock);4744ieee80211_free_txskb(ar->hw, skb);4745return;4746}4747spin_unlock_bh(&ar->htt.tx_lock);4748}47494750ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, false);4751if (ret) {4752ath10k_warn(ar, "failed to transmit frame: %d\n", ret);4753if (is_htt) {4754spin_lock_bh(&ar->htt.tx_lock);4755ath10k_htt_tx_dec_pending(htt);4756if (is_mgmt)4757ath10k_htt_tx_mgmt_dec_pending(htt);4758spin_unlock_bh(&ar->htt.tx_lock);4759}4760return;4761}4762}47634764static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,4765struct ieee80211_txq *txq)4766{4767struct ath10k *ar = hw->priv;4768int ret;4769u8 ac = txq->ac;47704771ath10k_htt_tx_txq_update(hw, txq);4772if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)4773return;47744775spin_lock_bh(&ar->queue_lock[ac]);47764777ieee80211_txq_schedule_start(hw, ac);4778txq = ieee80211_next_txq(hw, ac);4779if (!txq)4780goto out;47814782while (ath10k_mac_tx_can_push(hw, txq)) {4783ret = ath10k_mac_tx_push_txq(hw, txq);4784if (ret < 0)4785break;4786}4787ieee80211_return_txq(hw, txq, false);4788ath10k_htt_tx_txq_update(hw, txq);4789out:4790ieee80211_txq_schedule_end(hw, ac);4791spin_unlock_bh(&ar->queue_lock[ac]);4792}47934794/* Must not be called with conf_mutex held as workers can use that also. */4795void ath10k_drain_tx(struct ath10k *ar)4796{4797lockdep_assert_not_held(&ar->conf_mutex);47984799/* make sure rcu-protected mac80211 tx path itself is drained */4800synchronize_net();48014802ath10k_offchan_tx_purge(ar);4803ath10k_mgmt_over_wmi_tx_purge(ar);48044805cancel_work_sync(&ar->offchan_tx_work);4806cancel_work_sync(&ar->wmi_mgmt_tx_work);4807}48084809void ath10k_halt(struct ath10k *ar)4810{4811struct ath10k_vif *arvif;48124813lockdep_assert_held(&ar->conf_mutex);48144815clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);4816ar->filter_flags = 0;4817ar->monitor = false;4818ar->monitor_arvif = NULL;48194820if (ar->monitor_started)4821ath10k_monitor_stop(ar);48224823ar->monitor_started = false;4824ar->tx_paused = 0;48254826ath10k_scan_finish(ar);4827ath10k_peer_cleanup_all(ar);4828ath10k_stop_radar_confirmation(ar);4829ath10k_core_stop(ar);4830ath10k_hif_power_down(ar);48314832spin_lock_bh(&ar->data_lock);4833list_for_each_entry(arvif, &ar->arvifs, list)4834ath10k_mac_vif_beacon_cleanup(arvif);4835spin_unlock_bh(&ar->data_lock);4836}48374838static int ath10k_get_antenna(struct ieee80211_hw *hw, int radio_idx,4839u32 *tx_ant, u32 *rx_ant)4840{4841struct ath10k *ar = hw->priv;48424843mutex_lock(&ar->conf_mutex);48444845*tx_ant = ar->cfg_tx_chainmask;4846*rx_ant = ar->cfg_rx_chainmask;48474848mutex_unlock(&ar->conf_mutex);48494850return 0;4851}48524853static bool ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)4854{4855/* It is not clear that allowing gaps in chainmask4856* is helpful. Probably it will not do what user4857* is hoping for, so warn in that case.4858*/4859if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)4860return true;48614862ath10k_warn(ar, "mac %s antenna chainmask is invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",4863dbg, cm);4864return false;4865}48664867static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)4868{4869int nsts = ar->vht_cap_info;48704871nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;4872nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;48734874/* If firmware does not deliver to host number of space-time4875* streams supported, assume it support up to 4 BF STS and return4876* the value for VHT CAP: nsts-1)4877*/4878if (nsts == 0)4879return 3;48804881return nsts;4882}48834884static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)4885{4886int sound_dim = ar->vht_cap_info;48874888sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;4889sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;48904891/* If the sounding dimension is not advertised by the firmware,4892* let's use a default value of 14893*/4894if (sound_dim == 0)4895return 1;48964897return sound_dim;4898}48994900static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)4901{4902struct ieee80211_sta_vht_cap vht_cap = {};4903struct ath10k_hw_params *hw = &ar->hw_params;4904u16 mcs_map;4905u32 val;4906int i;49074908vht_cap.vht_supported = 1;4909vht_cap.cap = ar->vht_cap_info;49104911if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |4912IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {4913val = ath10k_mac_get_vht_cap_bf_sts(ar);4914val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;4915val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;49164917vht_cap.cap |= val;4918}49194920if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |4921IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {4922val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);4923val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;4924val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;49254926vht_cap.cap |= val;4927}49284929mcs_map = 0;4930for (i = 0; i < 8; i++) {4931if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))4932mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);4933else4934mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);4935}49364937if (ar->cfg_tx_chainmask <= 1)4938vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;49394940vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);4941vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);49424943/* If we are supporting 160Mhz or 80+80, then the NIC may be able to do4944* a restricted NSS for 160 or 80+80 vs what it can do for 80Mhz. Give4945* user-space a clue if that is the case.4946*/4947if ((vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) &&4948(hw->vht160_mcs_rx_highest != 0 ||4949hw->vht160_mcs_tx_highest != 0)) {4950vht_cap.vht_mcs.rx_highest = cpu_to_le16(hw->vht160_mcs_rx_highest);4951vht_cap.vht_mcs.tx_highest = cpu_to_le16(hw->vht160_mcs_tx_highest);4952}49534954return vht_cap;4955}49564957static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)4958{4959int i;4960struct ieee80211_sta_ht_cap ht_cap = {};49614962if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))4963return ht_cap;49644965ht_cap.ht_supported = 1;4966ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;4967ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;4968ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;4969ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;4970ht_cap.cap |=4971WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;49724973if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)4974ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;49754976if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)4977ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;49784979if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {4980u32 smps;49814982smps = WLAN_HT_CAP_SM_PS_DYNAMIC;4983smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;49844985ht_cap.cap |= smps;4986}49874988if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))4989ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;49904991if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {4992u32 stbc;49934994stbc = ar->ht_cap_info;4995stbc &= WMI_HT_CAP_RX_STBC;4996stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;4997stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;4998stbc &= IEEE80211_HT_CAP_RX_STBC;49995000ht_cap.cap |= stbc;5001}50025003if (ar->ht_cap_info & WMI_HT_CAP_LDPC || (ar->ht_cap_info &5004WMI_HT_CAP_RX_LDPC && (ar->ht_cap_info & WMI_HT_CAP_TX_LDPC)))5005ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;50065007if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)5008ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;50095010/* max AMSDU is implicitly taken from vht_cap_info */5011if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)5012ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;50135014for (i = 0; i < ar->num_rf_chains; i++) {5015if (ar->cfg_rx_chainmask & BIT(i))5016ht_cap.mcs.rx_mask[i] = 0xFF;5017}50185019ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;50205021return ht_cap;5022}50235024static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)5025{5026struct ieee80211_supported_band *band;5027struct ieee80211_sta_vht_cap vht_cap;5028struct ieee80211_sta_ht_cap ht_cap;50295030ht_cap = ath10k_get_ht_cap(ar);5031vht_cap = ath10k_create_vht_cap(ar);50325033if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {5034band = &ar->mac.sbands[NL80211_BAND_2GHZ];5035band->ht_cap = ht_cap;5036}5037if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {5038band = &ar->mac.sbands[NL80211_BAND_5GHZ];5039band->ht_cap = ht_cap;5040band->vht_cap = vht_cap;5041}5042}50435044static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)5045{5046int ret;5047bool is_valid_tx_chain_mask, is_valid_rx_chain_mask;50485049lockdep_assert_held(&ar->conf_mutex);50505051is_valid_tx_chain_mask = ath10k_check_chain_mask(ar, tx_ant, "tx");5052is_valid_rx_chain_mask = ath10k_check_chain_mask(ar, rx_ant, "rx");50535054if (!is_valid_tx_chain_mask || !is_valid_rx_chain_mask)5055return -EINVAL;50565057ar->cfg_tx_chainmask = tx_ant;5058ar->cfg_rx_chainmask = rx_ant;50595060if ((ar->state != ATH10K_STATE_ON) &&5061(ar->state != ATH10K_STATE_RESTARTED))5062return 0;50635064ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,5065tx_ant);5066if (ret) {5067ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",5068ret, tx_ant);5069return ret;5070}50715072ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,5073rx_ant);5074if (ret) {5075ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",5076ret, rx_ant);5077return ret;5078}50795080/* Reload HT/VHT capability */5081ath10k_mac_setup_ht_vht_cap(ar);50825083return 0;5084}50855086static int ath10k_set_antenna(struct ieee80211_hw *hw, int radio_idx,5087u32 tx_ant, u32 rx_ant)5088{5089struct ath10k *ar = hw->priv;5090int ret;50915092mutex_lock(&ar->conf_mutex);5093ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);5094mutex_unlock(&ar->conf_mutex);5095return ret;5096}50975098static int __ath10k_fetch_bb_timing_dt(struct ath10k *ar,5099struct wmi_bb_timing_cfg_arg *bb_timing)5100{5101#if defined(__linux__) || (defined(__FreeBSD__) && defined(CONFIG_OF))5102struct device_node *node;5103const char *fem_name;5104int ret;51055106node = ar->dev->of_node;5107if (!node)5108return -ENOENT;51095110ret = of_property_read_string_index(node, "ext-fem-name", 0, &fem_name);5111if (ret)5112return -ENOENT;51135114/*5115* If external Front End module used in hardware, then default base band timing5116* parameter cannot be used since they were fine tuned for reference hardware,5117* so choosing different value suitable for that external FEM.5118*/5119if (!strcmp("microsemi-lx5586", fem_name)) {5120bb_timing->bb_tx_timing = 0x00;5121bb_timing->bb_xpa_timing = 0x0101;5122} else {5123return -ENOENT;5124}51255126ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot bb_tx_timing 0x%x bb_xpa_timing 0x%x\n",5127bb_timing->bb_tx_timing, bb_timing->bb_xpa_timing);5128return 0;5129#else5130return -ENOENT;5131#endif5132}51335134static int ath10k_mac_rfkill_config(struct ath10k *ar)5135{5136u32 param;5137int ret;51385139if (ar->hw_values->rfkill_pin == 0) {5140ath10k_warn(ar, "ath10k does not support hardware rfkill with this device\n");5141return -EOPNOTSUPP;5142}51435144ath10k_dbg(ar, ATH10K_DBG_MAC,5145"mac rfkill_pin %d rfkill_cfg %d rfkill_on_level %d",5146ar->hw_values->rfkill_pin, ar->hw_values->rfkill_cfg,5147ar->hw_values->rfkill_on_level);51485149param = FIELD_PREP(WMI_TLV_RFKILL_CFG_RADIO_LEVEL,5150ar->hw_values->rfkill_on_level) |5151FIELD_PREP(WMI_TLV_RFKILL_CFG_GPIO_PIN_NUM,5152ar->hw_values->rfkill_pin) |5153FIELD_PREP(WMI_TLV_RFKILL_CFG_PIN_AS_GPIO,5154ar->hw_values->rfkill_cfg);51555156ret = ath10k_wmi_pdev_set_param(ar,5157ar->wmi.pdev_param->rfkill_config,5158param);5159if (ret) {5160ath10k_warn(ar,5161"failed to set rfkill config 0x%x: %d\n",5162param, ret);5163return ret;5164}5165return 0;5166}51675168int ath10k_mac_rfkill_enable_radio(struct ath10k *ar, bool enable)5169{5170enum wmi_tlv_rfkill_enable_radio param;5171int ret;51725173if (enable)5174param = WMI_TLV_RFKILL_ENABLE_RADIO_ON;5175else5176param = WMI_TLV_RFKILL_ENABLE_RADIO_OFF;51775178ath10k_dbg(ar, ATH10K_DBG_MAC, "mac rfkill enable %d", param);51795180ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rfkill_enable,5181param);5182if (ret) {5183ath10k_warn(ar, "failed to set rfkill enable param %d: %d\n",5184param, ret);5185return ret;5186}51875188return 0;5189}51905191static int ath10k_start(struct ieee80211_hw *hw)5192{5193struct ath10k *ar = hw->priv;5194u32 param;5195int ret = 0;5196struct wmi_bb_timing_cfg_arg bb_timing = {};51975198/*5199* This makes sense only when restarting hw. It is harmless to call5200* unconditionally. This is necessary to make sure no HTT/WMI tx5201* commands will be submitted while restarting.5202*/5203ath10k_drain_tx(ar);52045205mutex_lock(&ar->conf_mutex);52065207switch (ar->state) {5208case ATH10K_STATE_OFF:5209ar->state = ATH10K_STATE_ON;5210break;5211case ATH10K_STATE_RESTARTING:5212ar->state = ATH10K_STATE_RESTARTED;5213break;5214case ATH10K_STATE_ON:5215case ATH10K_STATE_RESTARTED:5216case ATH10K_STATE_WEDGED:5217WARN_ON(1);5218ret = -EINVAL;5219goto err;5220case ATH10K_STATE_UTF:5221ret = -EBUSY;5222goto err;5223}52245225spin_lock_bh(&ar->data_lock);52265227if (ar->hw_rfkill_on) {5228ar->hw_rfkill_on = false;5229spin_unlock_bh(&ar->data_lock);5230goto err;5231}52325233spin_unlock_bh(&ar->data_lock);52345235ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL);5236if (ret) {5237ath10k_err(ar, "Could not init hif: %d\n", ret);5238goto err_off;5239}52405241ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,5242&ar->normal_mode_fw);5243if (ret) {5244ath10k_err(ar, "Could not init core: %d\n", ret);5245goto err_power_down;5246}52475248if (ar->sys_cap_info & WMI_TLV_SYS_CAP_INFO_RFKILL) {5249ret = ath10k_mac_rfkill_config(ar);5250if (ret && ret != -EOPNOTSUPP) {5251ath10k_warn(ar, "failed to configure rfkill: %d", ret);5252goto err_core_stop;5253}5254}52555256param = ar->wmi.pdev_param->pmf_qos;5257ret = ath10k_wmi_pdev_set_param(ar, param, 1);5258if (ret) {5259ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);5260goto err_core_stop;5261}52625263param = ar->wmi.pdev_param->dynamic_bw;5264ret = ath10k_wmi_pdev_set_param(ar, param, 1);5265if (ret) {5266ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);5267goto err_core_stop;5268}52695270if (test_bit(WMI_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi.svc_map)) {5271ret = ath10k_wmi_scan_prob_req_oui(ar, ar->mac_addr);5272if (ret) {5273ath10k_err(ar, "failed to set prob req oui: %i\n", ret);5274goto err_core_stop;5275}5276}52775278if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {5279ret = ath10k_wmi_adaptive_qcs(ar, true);5280if (ret) {5281ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",5282ret);5283goto err_core_stop;5284}5285}52865287if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {5288param = ar->wmi.pdev_param->burst_enable;5289ret = ath10k_wmi_pdev_set_param(ar, param, 0);5290if (ret) {5291ath10k_warn(ar, "failed to disable burst: %d\n", ret);5292goto err_core_stop;5293}5294}52955296param = ar->wmi.pdev_param->idle_ps_config;5297ret = ath10k_wmi_pdev_set_param(ar, param, 1);5298if (ret && ret != -EOPNOTSUPP) {5299ath10k_warn(ar, "failed to enable idle_ps_config: %d\n", ret);5300goto err_core_stop;5301}53025303__ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);53045305/*5306* By default FW set ARP frames ac to voice (6). In that case ARP5307* exchange is not working properly for UAPSD enabled AP. ARP requests5308* which arrives with access category 0 are processed by network stack5309* and send back with access category 0, but FW changes access category5310* to 6. Set ARP frames access category to best effort (0) solves5311* this problem.5312*/53135314param = ar->wmi.pdev_param->arp_ac_override;5315ret = ath10k_wmi_pdev_set_param(ar, param, 0);5316if (ret) {5317ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",5318ret);5319goto err_core_stop;5320}53215322if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,5323ar->running_fw->fw_file.fw_features)) {5324ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,5325WMI_CCA_DETECT_LEVEL_AUTO,5326WMI_CCA_DETECT_MARGIN_AUTO);5327if (ret) {5328ath10k_warn(ar, "failed to enable adaptive cca: %d\n",5329ret);5330goto err_core_stop;5331}5332}53335334param = ar->wmi.pdev_param->ani_enable;5335ret = ath10k_wmi_pdev_set_param(ar, param, 1);5336if (ret) {5337ath10k_warn(ar, "failed to enable ani by default: %d\n",5338ret);5339goto err_core_stop;5340}53415342ar->ani_enabled = true;53435344if (ath10k_peer_stats_enabled(ar)) {5345param = ar->wmi.pdev_param->peer_stats_update_period;5346ret = ath10k_wmi_pdev_set_param(ar, param,5347PEER_DEFAULT_STATS_UPDATE_PERIOD);5348if (ret) {5349ath10k_warn(ar,5350"failed to set peer stats period : %d\n",5351ret);5352goto err_core_stop;5353}5354}53555356param = ar->wmi.pdev_param->enable_btcoex;5357if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&5358test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,5359ar->running_fw->fw_file.fw_features) &&5360ar->coex_support) {5361ret = ath10k_wmi_pdev_set_param(ar, param, 0);5362if (ret) {5363ath10k_warn(ar,5364"failed to set btcoex param: %d\n", ret);5365goto err_core_stop;5366}5367clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);5368}53695370if (test_bit(WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT, ar->wmi.svc_map)) {5371ret = __ath10k_fetch_bb_timing_dt(ar, &bb_timing);5372if (!ret) {5373ret = ath10k_wmi_pdev_bb_timing(ar, &bb_timing);5374if (ret) {5375ath10k_warn(ar,5376"failed to set bb timings: %d\n",5377ret);5378goto err_core_stop;5379}5380}5381}53825383ar->num_started_vdevs = 0;5384ath10k_regd_update(ar);53855386ath10k_spectral_start(ar);5387ath10k_thermal_set_throttling(ar);53885389ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_IDLE;53905391mutex_unlock(&ar->conf_mutex);5392return 0;53935394err_core_stop:5395ath10k_core_stop(ar);53965397err_power_down:5398ath10k_hif_power_down(ar);53995400err_off:5401ar->state = ATH10K_STATE_OFF;54025403err:5404mutex_unlock(&ar->conf_mutex);5405return ret;5406}54075408static void ath10k_stop(struct ieee80211_hw *hw, bool suspend)5409{5410struct ath10k *ar = hw->priv;5411u32 opt;54125413ath10k_drain_tx(ar);54145415mutex_lock(&ar->conf_mutex);5416if (ar->state != ATH10K_STATE_OFF) {5417if (!ar->hw_rfkill_on) {5418/* If the current driver state is RESTARTING but not yet5419* fully RESTARTED because of incoming suspend event,5420* then ath10k_halt() is already called via5421* ath10k_core_restart() and should not be called here.5422*/5423if (ar->state != ATH10K_STATE_RESTARTING) {5424ath10k_halt(ar);5425} else {5426/* Suspending here, because when in RESTARTING5427* state, ath10k_core_stop() skips5428* ath10k_wait_for_suspend().5429*/5430opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR;5431ath10k_wait_for_suspend(ar, opt);5432}5433}5434ar->state = ATH10K_STATE_OFF;5435}5436mutex_unlock(&ar->conf_mutex);54375438cancel_work_sync(&ar->set_coverage_class_work);5439cancel_delayed_work_sync(&ar->scan.timeout);5440cancel_work_sync(&ar->restart_work);5441cancel_work_sync(&ar->recovery_check_work);5442}54435444static int ath10k_config_ps(struct ath10k *ar)5445{5446struct ath10k_vif *arvif;5447int ret = 0;54485449lockdep_assert_held(&ar->conf_mutex);54505451list_for_each_entry(arvif, &ar->arvifs, list) {5452ret = ath10k_mac_vif_setup_ps(arvif);5453if (ret) {5454ath10k_warn(ar, "failed to setup powersave: %d\n", ret);5455break;5456}5457}54585459return ret;5460}54615462static int ath10k_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)5463{5464struct ath10k *ar = hw->priv;5465struct ieee80211_conf *conf = &hw->conf;5466int ret = 0;54675468mutex_lock(&ar->conf_mutex);54695470if (changed & IEEE80211_CONF_CHANGE_PS)5471ath10k_config_ps(ar);54725473if (changed & IEEE80211_CONF_CHANGE_MONITOR) {5474ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;5475ret = ath10k_monitor_recalc(ar);5476if (ret)5477ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);5478}54795480mutex_unlock(&ar->conf_mutex);5481return ret;5482}54835484static u32 get_nss_from_chainmask(u16 chain_mask)5485{5486if ((chain_mask & 0xf) == 0xf)5487return 4;5488else if ((chain_mask & 0x7) == 0x7)5489return 3;5490else if ((chain_mask & 0x3) == 0x3)5491return 2;5492return 1;5493}54945495static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)5496{5497u32 value = 0;5498struct ath10k *ar = arvif->ar;5499int nsts;5500int sound_dim;55015502if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)5503return 0;55045505nsts = ath10k_mac_get_vht_cap_bf_sts(ar);5506if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |5507IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))5508value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);55095510sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);5511if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |5512IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))5513value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);55145515if (!value)5516return 0;55175518if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)5519value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;55205521if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)5522value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |5523WMI_VDEV_PARAM_TXBF_SU_TX_BFER);55245525if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)5526value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;55275528if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)5529value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |5530WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);55315532return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,5533ar->wmi.vdev_param->txbf, value);5534}55355536static void ath10k_update_vif_offload(struct ieee80211_hw *hw,5537struct ieee80211_vif *vif)5538{5539struct ath10k_vif *arvif = (void *)vif->drv_priv;5540struct ath10k *ar = hw->priv;5541u32 vdev_param;5542int ret;55435544if (ath10k_frame_mode != ATH10K_HW_TXRX_ETHERNET ||5545ar->wmi.vdev_param->tx_encap_type == WMI_VDEV_PARAM_UNSUPPORTED ||5546(vif->type != NL80211_IFTYPE_STATION &&5547vif->type != NL80211_IFTYPE_AP))5548vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;55495550vdev_param = ar->wmi.vdev_param->tx_encap_type;5551ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,5552ATH10K_HW_TXRX_NATIVE_WIFI);5553/* 10.X firmware does not support this VDEV parameter. Do not warn */5554if (ret && ret != -EOPNOTSUPP) {5555ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",5556arvif->vdev_id, ret);5557}5558}55595560/*5561* TODO:5562* Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,5563* because we will send mgmt frames without CCK. This requirement5564* for P2P_FIND/GO_NEG should be handled by checking CCK flag5565* in the TX packet.5566*/5567static int ath10k_add_interface(struct ieee80211_hw *hw,5568struct ieee80211_vif *vif)5569{5570struct ath10k *ar = hw->priv;5571struct ath10k_vif *arvif = (void *)vif->drv_priv;5572struct ath10k_peer *peer;5573enum wmi_sta_powersave_param param;5574int ret = 0;5575u32 value;5576int bit;5577int i;5578u32 vdev_param;55795580vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;55815582mutex_lock(&ar->conf_mutex);55835584memset(arvif, 0, sizeof(*arvif));5585ath10k_mac_txq_init(vif->txq);55865587arvif->ar = ar;5588arvif->vif = vif;55895590INIT_LIST_HEAD(&arvif->list);5591INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);5592INIT_DELAYED_WORK(&arvif->connection_loss_work,5593ath10k_mac_vif_sta_connection_loss_work);55945595for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {5596arvif->bitrate_mask.control[i].legacy = 0xffffffff;5597memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,5598sizeof(arvif->bitrate_mask.control[i].ht_mcs));5599memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,5600sizeof(arvif->bitrate_mask.control[i].vht_mcs));5601}56025603if (ar->num_peers >= ar->max_num_peers) {5604ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");5605ret = -ENOBUFS;5606goto err;5607}56085609if (ar->free_vdev_map == 0) {5610ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");5611ret = -EBUSY;5612goto err;5613}5614bit = __ffs64(ar->free_vdev_map);56155616ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",5617bit, ar->free_vdev_map);56185619arvif->vdev_id = bit;5620arvif->vdev_subtype =5621ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);56225623switch (vif->type) {5624case NL80211_IFTYPE_P2P_DEVICE:5625arvif->vdev_type = WMI_VDEV_TYPE_STA;5626arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype5627(ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);5628break;5629case NL80211_IFTYPE_UNSPECIFIED:5630case NL80211_IFTYPE_STATION:5631arvif->vdev_type = WMI_VDEV_TYPE_STA;5632if (vif->p2p)5633arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype5634(ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);5635break;5636case NL80211_IFTYPE_ADHOC:5637arvif->vdev_type = WMI_VDEV_TYPE_IBSS;5638break;5639case NL80211_IFTYPE_MESH_POINT:5640if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {5641arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype5642(ar, WMI_VDEV_SUBTYPE_MESH_11S);5643} else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {5644ret = -EINVAL;5645ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");5646goto err;5647}5648arvif->vdev_type = WMI_VDEV_TYPE_AP;5649break;5650case NL80211_IFTYPE_AP:5651arvif->vdev_type = WMI_VDEV_TYPE_AP;56525653if (vif->p2p)5654arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype5655(ar, WMI_VDEV_SUBTYPE_P2P_GO);5656break;5657case NL80211_IFTYPE_MONITOR:5658arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;5659break;5660default:5661WARN_ON(1);5662break;5663}56645665/* Using vdev_id as queue number will make it very easy to do per-vif5666* tx queue locking. This shouldn't wrap due to interface combinations5667* but do a modulo for correctness sake and prevent using offchannel tx5668* queues for regular vif tx.5669*/5670vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);5671for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)5672vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);56735674/* Some firmware revisions don't wait for beacon tx completion before5675* sending another SWBA event. This could lead to hardware using old5676* (freed) beacon data in some cases, e.g. tx credit starvation5677* combined with missed TBTT. This is very rare.5678*5679* On non-IOMMU-enabled hosts this could be a possible security issue5680* because hw could beacon some random data on the air. On5681* IOMMU-enabled hosts DMAR faults would occur in most cases and target5682* device would crash.5683*5684* Since there are no beacon tx completions (implicit nor explicit)5685* propagated to host the only workaround for this is to allocate a5686* DMA-coherent buffer for a lifetime of a vif and use it for all5687* beacon tx commands. Worst case for this approach is some beacons may5688* become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.5689*/5690if (vif->type == NL80211_IFTYPE_ADHOC ||5691vif->type == NL80211_IFTYPE_MESH_POINT ||5692vif->type == NL80211_IFTYPE_AP) {5693if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) {5694arvif->beacon_buf = kmalloc(IEEE80211_MAX_FRAME_LEN,5695GFP_KERNEL);56965697/* Using a kernel pointer in place of a dma_addr_t5698* token can lead to undefined behavior if that5699* makes it into cache management functions. Use a5700* known-invalid address token instead, which5701* avoids the warning and makes it easier to catch5702* bugs if it does end up getting used.5703*/5704arvif->beacon_paddr = DMA_MAPPING_ERROR;5705} else {5706arvif->beacon_buf =5707dma_alloc_coherent(ar->dev,5708IEEE80211_MAX_FRAME_LEN,5709&arvif->beacon_paddr,5710GFP_ATOMIC);5711}5712if (!arvif->beacon_buf) {5713ret = -ENOMEM;5714ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",5715ret);5716goto err;5717}5718}5719if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))5720arvif->nohwcrypt = true;57215722if (arvif->nohwcrypt &&5723!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {5724ret = -EINVAL;5725ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");5726goto err;5727}57285729ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",5730arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,5731arvif->beacon_buf ? "single-buf" : "per-skb");57325733ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,5734arvif->vdev_subtype, vif->addr);5735if (ret) {5736ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",5737arvif->vdev_id, ret);5738goto err;5739}57405741if (test_bit(WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,5742ar->wmi.svc_map)) {5743vdev_param = ar->wmi.vdev_param->disable_4addr_src_lrn;5744ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,5745WMI_VDEV_DISABLE_4_ADDR_SRC_LRN);5746if (ret && ret != -EOPNOTSUPP) {5747ath10k_warn(ar, "failed to disable 4addr src lrn vdev %i: %d\n",5748arvif->vdev_id, ret);5749}5750}57515752ar->free_vdev_map &= ~(1LL << arvif->vdev_id);5753spin_lock_bh(&ar->data_lock);5754list_add(&arvif->list, &ar->arvifs);5755spin_unlock_bh(&ar->data_lock);57565757/* It makes no sense to have firmware do keepalives. mac80211 already5758* takes care of this with idle connection polling.5759*/5760ret = ath10k_mac_vif_disable_keepalive(arvif);5761if (ret) {5762ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",5763arvif->vdev_id, ret);5764goto err_vdev_delete;5765}57665767arvif->def_wep_key_idx = -1;57685769ath10k_update_vif_offload(hw, vif);57705771/* Configuring number of spatial stream for monitor interface is causing5772* target assert in qca9888 and qca6174.5773*/5774if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {5775u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);57765777vdev_param = ar->wmi.vdev_param->nss;5778ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,5779nss);5780if (ret) {5781ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",5782arvif->vdev_id, ar->cfg_tx_chainmask, nss,5783ret);5784goto err_vdev_delete;5785}5786}57875788if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||5789arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {5790ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,5791vif->addr, WMI_PEER_TYPE_DEFAULT);5792if (ret) {5793ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",5794arvif->vdev_id, ret);5795goto err_vdev_delete;5796}57975798spin_lock_bh(&ar->data_lock);57995800peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);5801if (!peer) {5802ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",5803vif->addr, arvif->vdev_id);5804spin_unlock_bh(&ar->data_lock);5805ret = -ENOENT;5806goto err_peer_delete;5807}58085809arvif->peer_id = find_first_bit(peer->peer_ids,5810ATH10K_MAX_NUM_PEER_IDS);58115812spin_unlock_bh(&ar->data_lock);5813} else {5814arvif->peer_id = HTT_INVALID_PEERID;5815}58165817if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {5818ret = ath10k_mac_set_kickout(arvif);5819if (ret) {5820ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",5821arvif->vdev_id, ret);5822goto err_peer_delete;5823}5824}58255826if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {5827param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;5828value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;5829ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,5830param, value);5831if (ret) {5832ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",5833arvif->vdev_id, ret);5834goto err_peer_delete;5835}58365837ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);5838if (ret) {5839ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",5840arvif->vdev_id, ret);5841goto err_peer_delete;5842}58435844ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);5845if (ret) {5846ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",5847arvif->vdev_id, ret);5848goto err_peer_delete;5849}5850}58515852ret = ath10k_mac_set_txbf_conf(arvif);5853if (ret) {5854ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",5855arvif->vdev_id, ret);5856goto err_peer_delete;5857}58585859ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);5860if (ret) {5861ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",5862arvif->vdev_id, ret);5863goto err_peer_delete;5864}58655866arvif->txpower = vif->bss_conf.txpower;5867ret = ath10k_mac_txpower_recalc(ar);5868if (ret) {5869ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);5870goto err_peer_delete;5871}58725873if (test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map)) {5874vdev_param = ar->wmi.vdev_param->rtt_responder_role;5875ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,5876arvif->ftm_responder);58775878/* It is harmless to not set FTM role. Do not warn */5879if (ret && ret != -EOPNOTSUPP)5880ath10k_warn(ar, "failed to set vdev %i FTM Responder: %d\n",5881arvif->vdev_id, ret);5882}58835884if (vif->type == NL80211_IFTYPE_MONITOR) {5885ar->monitor_arvif = arvif;5886ret = ath10k_monitor_recalc(ar);5887if (ret) {5888ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);5889goto err_peer_delete;5890}5891}58925893spin_lock_bh(&ar->htt.tx_lock);5894if (!ar->tx_paused)5895ieee80211_wake_queue(ar->hw, arvif->vdev_id);5896spin_unlock_bh(&ar->htt.tx_lock);58975898mutex_unlock(&ar->conf_mutex);5899return 0;59005901err_peer_delete:5902if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||5903arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {5904ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);5905ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id,5906vif->addr);5907}59085909err_vdev_delete:5910ath10k_wmi_vdev_delete(ar, arvif->vdev_id);5911ar->free_vdev_map |= 1LL << arvif->vdev_id;5912spin_lock_bh(&ar->data_lock);5913list_del(&arvif->list);5914spin_unlock_bh(&ar->data_lock);59155916err:5917if (arvif->beacon_buf) {5918if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)5919kfree(arvif->beacon_buf);5920else5921dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,5922arvif->beacon_buf,5923arvif->beacon_paddr);5924arvif->beacon_buf = NULL;5925}59265927mutex_unlock(&ar->conf_mutex);59285929return ret;5930}59315932static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)5933{5934int i;59355936for (i = 0; i < BITS_PER_LONG; i++)5937ath10k_mac_vif_tx_unlock(arvif, i);5938}59395940static void ath10k_remove_interface(struct ieee80211_hw *hw,5941struct ieee80211_vif *vif)5942{5943struct ath10k *ar = hw->priv;5944struct ath10k_vif *arvif = (void *)vif->drv_priv;5945struct ath10k_peer *peer;5946int ret;5947int i;59485949cancel_work_sync(&arvif->ap_csa_work);5950cancel_delayed_work_sync(&arvif->connection_loss_work);59515952mutex_lock(&ar->conf_mutex);59535954ret = ath10k_spectral_vif_stop(arvif);5955if (ret)5956ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",5957arvif->vdev_id, ret);59585959ar->free_vdev_map |= 1LL << arvif->vdev_id;5960spin_lock_bh(&ar->data_lock);5961list_del(&arvif->list);5962spin_unlock_bh(&ar->data_lock);59635964if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||5965arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {5966ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,5967vif->addr);5968if (ret)5969ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",5970arvif->vdev_id, ret);59715972ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id,5973vif->addr);5974kfree(arvif->u.ap.noa_data);5975}59765977ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",5978arvif->vdev_id);59795980ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);5981if (ret)5982ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",5983arvif->vdev_id, ret);59845985ret = ath10k_vdev_delete_sync(ar);5986if (ret) {5987ath10k_warn(ar, "Error in receiving vdev delete response: %d\n", ret);5988goto out;5989}59905991/* Some firmware revisions don't notify host about self-peer removal5992* until after associated vdev is deleted.5993*/5994if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||5995arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {5996ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,5997vif->addr);5998if (ret)5999ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",6000arvif->vdev_id, ret);60016002spin_lock_bh(&ar->data_lock);6003ar->num_peers--;6004spin_unlock_bh(&ar->data_lock);6005}60066007spin_lock_bh(&ar->data_lock);6008for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {6009peer = ar->peer_map[i];6010if (!peer)6011continue;60126013if (peer->vif == vif) {6014ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",6015vif->addr, arvif->vdev_id);6016peer->vif = NULL;6017}6018}60196020/* Clean this up late, less opportunity for firmware to access6021* DMA memory we have deleted.6022*/6023ath10k_mac_vif_beacon_cleanup(arvif);6024spin_unlock_bh(&ar->data_lock);60256026ath10k_peer_cleanup(ar, arvif->vdev_id);6027ath10k_mac_txq_unref(ar, vif->txq);60286029if (vif->type == NL80211_IFTYPE_MONITOR) {6030ar->monitor_arvif = NULL;6031ret = ath10k_monitor_recalc(ar);6032if (ret)6033ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);6034}60356036ret = ath10k_mac_txpower_recalc(ar);6037if (ret)6038ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);60396040spin_lock_bh(&ar->htt.tx_lock);6041ath10k_mac_vif_tx_unlock_all(arvif);6042spin_unlock_bh(&ar->htt.tx_lock);60436044ath10k_mac_txq_unref(ar, vif->txq);60456046out:6047mutex_unlock(&ar->conf_mutex);6048}60496050/*6051* FIXME: Has to be verified.6052*/6053#define SUPPORTED_FILTERS \6054(FIF_ALLMULTI | \6055FIF_CONTROL | \6056FIF_PSPOLL | \6057FIF_OTHER_BSS | \6058FIF_BCN_PRBRESP_PROMISC | \6059FIF_PROBE_REQ | \6060FIF_FCSFAIL)60616062static void ath10k_configure_filter(struct ieee80211_hw *hw,6063unsigned int changed_flags,6064unsigned int *total_flags,6065u64 multicast)6066{6067struct ath10k *ar = hw->priv;6068int ret;6069unsigned int supported = SUPPORTED_FILTERS;60706071mutex_lock(&ar->conf_mutex);60726073if (ar->hw_params.mcast_frame_registration)6074supported |= FIF_MCAST_ACTION;60756076*total_flags &= supported;60776078ar->filter_flags = *total_flags;60796080ret = ath10k_monitor_recalc(ar);6081if (ret)6082ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);60836084mutex_unlock(&ar->conf_mutex);6085}60866087static void ath10k_recalculate_mgmt_rate(struct ath10k *ar,6088struct ieee80211_vif *vif,6089struct cfg80211_chan_def *def)6090{6091struct ath10k_vif *arvif = (void *)vif->drv_priv;6092const struct ieee80211_supported_band *sband;6093u8 basic_rate_idx;6094int hw_rate_code;6095u32 vdev_param;6096u16 bitrate;6097int ret;60986099lockdep_assert_held(&ar->conf_mutex);61006101sband = ar->hw->wiphy->bands[def->chan->band];6102basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;6103bitrate = sband->bitrates[basic_rate_idx].bitrate;61046105hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);6106if (hw_rate_code < 0) {6107ath10k_warn(ar, "bitrate not supported %d\n", bitrate);6108return;6109}61106111vdev_param = ar->wmi.vdev_param->mgmt_rate;6112ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,6113hw_rate_code);6114if (ret)6115ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);6116}61176118static void ath10k_bss_info_changed(struct ieee80211_hw *hw,6119struct ieee80211_vif *vif,6120struct ieee80211_bss_conf *info,6121u64 changed)6122{6123struct ath10k *ar = hw->priv;6124struct ath10k_vif *arvif = (void *)vif->drv_priv;6125struct cfg80211_chan_def def;6126u32 vdev_param, pdev_param, slottime, preamble;6127u16 bitrate, hw_value;6128u8 rate, rateidx;6129int ret = 0, mcast_rate;6130enum nl80211_band band;61316132mutex_lock(&ar->conf_mutex);61336134if (changed & BSS_CHANGED_IBSS)6135ath10k_control_ibss(arvif, vif);61366137if (changed & BSS_CHANGED_BEACON_INT) {6138arvif->beacon_interval = info->beacon_int;6139vdev_param = ar->wmi.vdev_param->beacon_interval;6140ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,6141arvif->beacon_interval);6142ath10k_dbg(ar, ATH10K_DBG_MAC,6143"mac vdev %d beacon_interval %d\n",6144arvif->vdev_id, arvif->beacon_interval);61456146if (ret)6147ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",6148arvif->vdev_id, ret);6149}61506151if (changed & BSS_CHANGED_BEACON) {6152ath10k_dbg(ar, ATH10K_DBG_MAC,6153"vdev %d set beacon tx mode to staggered\n",6154arvif->vdev_id);61556156pdev_param = ar->wmi.pdev_param->beacon_tx_mode;6157ret = ath10k_wmi_pdev_set_param(ar, pdev_param,6158WMI_BEACON_STAGGERED_MODE);6159if (ret)6160ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",6161arvif->vdev_id, ret);61626163ret = ath10k_mac_setup_bcn_tmpl(arvif);6164if (ret)6165ath10k_warn(ar, "failed to update beacon template: %d\n",6166ret);61676168if (ieee80211_vif_is_mesh(vif)) {6169/* mesh doesn't use SSID but firmware needs it */6170arvif->u.ap.ssid_len = 4;6171memcpy(arvif->u.ap.ssid, "mesh", arvif->u.ap.ssid_len);6172}6173}61746175if (changed & BSS_CHANGED_AP_PROBE_RESP) {6176ret = ath10k_mac_setup_prb_tmpl(arvif);6177if (ret)6178ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",6179arvif->vdev_id, ret);6180}61816182if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {6183arvif->dtim_period = info->dtim_period;61846185ath10k_dbg(ar, ATH10K_DBG_MAC,6186"mac vdev %d dtim_period %d\n",6187arvif->vdev_id, arvif->dtim_period);61886189vdev_param = ar->wmi.vdev_param->dtim_period;6190ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,6191arvif->dtim_period);6192if (ret)6193ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",6194arvif->vdev_id, ret);6195}61966197if (changed & BSS_CHANGED_SSID &&6198vif->type == NL80211_IFTYPE_AP) {6199arvif->u.ap.ssid_len = vif->cfg.ssid_len;6200if (vif->cfg.ssid_len)6201memcpy(arvif->u.ap.ssid, vif->cfg.ssid,6202vif->cfg.ssid_len);6203arvif->u.ap.hidden_ssid = info->hidden_ssid;6204}62056206if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))6207ether_addr_copy(arvif->bssid, info->bssid);62086209if (changed & BSS_CHANGED_FTM_RESPONDER &&6210arvif->ftm_responder != info->ftm_responder &&6211test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map)) {6212arvif->ftm_responder = info->ftm_responder;62136214vdev_param = ar->wmi.vdev_param->rtt_responder_role;6215ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,6216arvif->ftm_responder);62176218ath10k_dbg(ar, ATH10K_DBG_MAC,6219"mac vdev %d ftm_responder %d:ret %d\n",6220arvif->vdev_id, arvif->ftm_responder, ret);6221}62226223if (changed & BSS_CHANGED_BEACON_ENABLED)6224ath10k_control_beaconing(arvif, info);62256226if (changed & BSS_CHANGED_ERP_CTS_PROT) {6227arvif->use_cts_prot = info->use_cts_prot;62286229ret = ath10k_recalc_rtscts_prot(arvif);6230if (ret)6231ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",6232arvif->vdev_id, ret);62336234if (ath10k_mac_can_set_cts_prot(arvif)) {6235ret = ath10k_mac_set_cts_prot(arvif);6236if (ret)6237ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",6238arvif->vdev_id, ret);6239}6240}62416242if (changed & BSS_CHANGED_ERP_SLOT) {6243if (info->use_short_slot)6244slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */62456246else6247slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */62486249ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",6250arvif->vdev_id, slottime);62516252vdev_param = ar->wmi.vdev_param->slot_time;6253ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,6254slottime);6255if (ret)6256ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",6257arvif->vdev_id, ret);6258}62596260if (changed & BSS_CHANGED_ERP_PREAMBLE) {6261if (info->use_short_preamble)6262preamble = WMI_VDEV_PREAMBLE_SHORT;6263else6264preamble = WMI_VDEV_PREAMBLE_LONG;62656266ath10k_dbg(ar, ATH10K_DBG_MAC,6267"mac vdev %d preamble %dn",6268arvif->vdev_id, preamble);62696270vdev_param = ar->wmi.vdev_param->preamble;6271ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,6272preamble);6273if (ret)6274ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",6275arvif->vdev_id, ret);6276}62776278if (changed & BSS_CHANGED_ASSOC) {6279if (vif->cfg.assoc) {6280/* Workaround: Make sure monitor vdev is not running6281* when associating to prevent some firmware revisions6282* (e.g. 10.1 and 10.2) from crashing.6283*/6284if (ar->monitor_started)6285ath10k_monitor_stop(ar);6286ath10k_bss_assoc(hw, vif, info);6287ath10k_monitor_recalc(ar);6288} else {6289ath10k_bss_disassoc(hw, vif);6290}6291}62926293if (changed & BSS_CHANGED_TXPOWER) {6294ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",6295arvif->vdev_id, info->txpower);62966297arvif->txpower = info->txpower;6298ret = ath10k_mac_txpower_recalc(ar);6299if (ret)6300ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);6301}63026303if (changed & BSS_CHANGED_PS) {6304arvif->ps = vif->cfg.ps;63056306ret = ath10k_config_ps(ar);6307if (ret)6308ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",6309arvif->vdev_id, ret);6310}63116312if (changed & BSS_CHANGED_MCAST_RATE &&6313!ath10k_mac_vif_chan(arvif->vif, &def)) {6314band = def.chan->band;6315mcast_rate = vif->bss_conf.mcast_rate[band];6316if (mcast_rate > 0)6317rateidx = mcast_rate - 1;6318else6319rateidx = ffs(vif->bss_conf.basic_rates) - 1;63206321if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)6322rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;63236324bitrate = ath10k_wmi_legacy_rates[rateidx].bitrate;6325hw_value = ath10k_wmi_legacy_rates[rateidx].hw_value;6326if (ath10k_mac_bitrate_is_cck(bitrate))6327preamble = WMI_RATE_PREAMBLE_CCK;6328else6329preamble = WMI_RATE_PREAMBLE_OFDM;63306331rate = ATH10K_HW_RATECODE(hw_value, 0, preamble);63326333ath10k_dbg(ar, ATH10K_DBG_MAC,6334"mac vdev %d mcast_rate %x\n",6335arvif->vdev_id, rate);63366337vdev_param = ar->wmi.vdev_param->mcast_data_rate;6338ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,6339vdev_param, rate);6340if (ret)6341ath10k_warn(ar,6342"failed to set mcast rate on vdev %i: %d\n",6343arvif->vdev_id, ret);63446345vdev_param = ar->wmi.vdev_param->bcast_data_rate;6346ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,6347vdev_param, rate);6348if (ret)6349ath10k_warn(ar,6350"failed to set bcast rate on vdev %i: %d\n",6351arvif->vdev_id, ret);6352}63536354if (changed & BSS_CHANGED_BASIC_RATES &&6355!ath10k_mac_vif_chan(arvif->vif, &def))6356ath10k_recalculate_mgmt_rate(ar, vif, &def);63576358mutex_unlock(&ar->conf_mutex);6359}63606361static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, int radio_idx,6362s16 value)6363{6364struct ath10k *ar = hw->priv;63656366/* This function should never be called if setting the coverage class6367* is not supported on this hardware.6368*/6369if (!ar->hw_params.hw_ops->set_coverage_class) {6370WARN_ON_ONCE(1);6371return;6372}6373ar->hw_params.hw_ops->set_coverage_class(ar, -1, value);6374}63756376struct ath10k_mac_tdls_iter_data {6377u32 num_tdls_stations;6378struct ieee80211_vif *curr_vif;6379};63806381static void ath10k_mac_tdls_vif_stations_count_iter(void *data,6382struct ieee80211_sta *sta)6383{6384struct ath10k_mac_tdls_iter_data *iter_data = data;6385struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;6386struct ieee80211_vif *sta_vif = arsta->arvif->vif;63876388if (sta->tdls && sta_vif == iter_data->curr_vif)6389iter_data->num_tdls_stations++;6390}63916392static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,6393struct ieee80211_vif *vif)6394{6395struct ath10k_mac_tdls_iter_data data = {};63966397data.curr_vif = vif;63986399ieee80211_iterate_stations_atomic(hw,6400ath10k_mac_tdls_vif_stations_count_iter,6401&data);6402return data.num_tdls_stations;6403}64046405static int ath10k_hw_scan(struct ieee80211_hw *hw,6406struct ieee80211_vif *vif,6407struct ieee80211_scan_request *hw_req)6408{6409struct ath10k *ar = hw->priv;6410struct ath10k_vif *arvif = (void *)vif->drv_priv;6411struct cfg80211_scan_request *req = &hw_req->req;6412struct wmi_start_scan_arg *arg = NULL;6413int ret = 0;6414int i;6415u32 scan_timeout;64166417mutex_lock(&ar->conf_mutex);64186419if (ath10k_mac_tdls_vif_stations_count(hw, vif) > 0) {6420ret = -EBUSY;6421goto exit;6422}64236424spin_lock_bh(&ar->data_lock);6425switch (ar->scan.state) {6426case ATH10K_SCAN_IDLE:6427reinit_completion(&ar->scan.started);6428reinit_completion(&ar->scan.completed);6429ar->scan.state = ATH10K_SCAN_STARTING;6430ar->scan.is_roc = false;6431ar->scan.vdev_id = arvif->vdev_id;6432ret = 0;6433break;6434case ATH10K_SCAN_STARTING:6435case ATH10K_SCAN_RUNNING:6436case ATH10K_SCAN_ABORTING:6437ret = -EBUSY;6438break;6439}6440spin_unlock_bh(&ar->data_lock);64416442if (ret)6443goto exit;64446445arg = kzalloc(sizeof(*arg), GFP_KERNEL);6446if (!arg) {6447ret = -ENOMEM;6448goto exit;6449}64506451ath10k_wmi_start_scan_init(ar, arg);6452arg->vdev_id = arvif->vdev_id;6453arg->scan_id = ATH10K_SCAN_ID;64546455if (req->ie_len) {6456arg->ie_len = req->ie_len;6457memcpy(arg->ie, req->ie, arg->ie_len);6458}64596460if (req->n_ssids) {6461arg->n_ssids = req->n_ssids;6462for (i = 0; i < arg->n_ssids; i++) {6463arg->ssids[i].len = req->ssids[i].ssid_len;6464arg->ssids[i].ssid = req->ssids[i].ssid;6465}6466} else {6467arg->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;6468}64696470if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {6471arg->scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ;6472ether_addr_copy(arg->mac_addr.addr, req->mac_addr);6473ether_addr_copy(arg->mac_mask.addr, req->mac_addr_mask);6474}64756476if (req->n_channels) {6477arg->n_channels = req->n_channels;6478for (i = 0; i < arg->n_channels; i++)6479arg->channels[i] = req->channels[i]->center_freq;6480}64816482/* if duration is set, default dwell times will be overwritten */6483if (req->duration) {6484arg->dwell_time_active = req->duration;6485arg->dwell_time_passive = req->duration;6486arg->burst_duration_ms = req->duration;64876488scan_timeout = min_t(u32, arg->max_rest_time *6489(arg->n_channels - 1) + (req->duration +6490ATH10K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) *6491arg->n_channels, arg->max_scan_time);6492} else {6493scan_timeout = arg->max_scan_time;6494}64956496/* Add a 200ms margin to account for event/command processing */6497scan_timeout += 200;64986499ret = ath10k_start_scan(ar, arg);6500if (ret) {6501ath10k_warn(ar, "failed to start hw scan: %d\n", ret);6502spin_lock_bh(&ar->data_lock);6503ar->scan.state = ATH10K_SCAN_IDLE;6504spin_unlock_bh(&ar->data_lock);6505}65066507ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,6508msecs_to_jiffies(scan_timeout));65096510exit:6511kfree(arg);65126513mutex_unlock(&ar->conf_mutex);6514return ret;6515}65166517static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,6518struct ieee80211_vif *vif)6519{6520struct ath10k *ar = hw->priv;65216522mutex_lock(&ar->conf_mutex);6523ath10k_scan_abort(ar);6524mutex_unlock(&ar->conf_mutex);65256526cancel_delayed_work_sync(&ar->scan.timeout);6527}65286529static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,6530struct ath10k_vif *arvif,6531enum set_key_cmd cmd,6532struct ieee80211_key_conf *key)6533{6534u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;6535int ret;65366537/* 10.1 firmware branch requires default key index to be set to group6538* key index after installing it. Otherwise FW/HW Txes corrupted6539* frames with multi-vif APs. This is not required for main firmware6540* branch (e.g. 636).6541*6542* This is also needed for 636 fw for IBSS-RSN to work more reliably.6543*6544* FIXME: It remains unknown if this is required for multi-vif STA6545* interfaces on 10.1.6546*/65476548if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&6549arvif->vdev_type != WMI_VDEV_TYPE_IBSS)6550return;65516552if (key->cipher == WLAN_CIPHER_SUITE_WEP40)6553return;65546555if (key->cipher == WLAN_CIPHER_SUITE_WEP104)6556return;65576558if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)6559return;65606561if (cmd != SET_KEY)6562return;65636564ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,6565key->keyidx);6566if (ret)6567ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",6568arvif->vdev_id, ret);6569}65706571static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,6572struct ieee80211_vif *vif, struct ieee80211_sta *sta,6573struct ieee80211_key_conf *key)6574{6575struct ath10k *ar = hw->priv;6576struct ath10k_vif *arvif = (void *)vif->drv_priv;6577struct ath10k_sta *arsta;6578struct ath10k_peer *peer;6579const u8 *peer_addr;6580bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||6581key->cipher == WLAN_CIPHER_SUITE_WEP104;6582int ret = 0;6583int ret2;6584u32 flags = 0;6585u32 flags2;65866587/* this one needs to be done in software */6588if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||6589key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||6590key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 ||6591key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)6592return 1;65936594if (arvif->nohwcrypt)6595return 1;65966597if (key->keyidx > WMI_MAX_KEY_INDEX)6598return -ENOSPC;65996600mutex_lock(&ar->conf_mutex);66016602if (sta) {6603arsta = (struct ath10k_sta *)sta->drv_priv;6604peer_addr = sta->addr;6605spin_lock_bh(&ar->data_lock);6606arsta->ucast_cipher = key->cipher;6607spin_unlock_bh(&ar->data_lock);6608} else if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {6609peer_addr = vif->bss_conf.bssid;6610} else {6611peer_addr = vif->addr;6612}66136614key->hw_key_idx = key->keyidx;66156616if (is_wep) {6617if (cmd == SET_KEY)6618arvif->wep_keys[key->keyidx] = key;6619else6620arvif->wep_keys[key->keyidx] = NULL;6621}66226623/* the peer should not disappear in mid-way (unless FW goes awry) since6624* we already hold conf_mutex. we just make sure its there now.6625*/6626spin_lock_bh(&ar->data_lock);6627peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);6628spin_unlock_bh(&ar->data_lock);66296630if (!peer) {6631if (cmd == SET_KEY) {6632ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",6633peer_addr);6634ret = -EOPNOTSUPP;6635goto exit;6636} else {6637/* if the peer doesn't exist there is no key to disable anymore */6638goto exit;6639}6640}66416642if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)6643flags |= WMI_KEY_PAIRWISE;6644else6645flags |= WMI_KEY_GROUP;66466647if (is_wep) {6648if (cmd == DISABLE_KEY)6649ath10k_clear_vdev_key(arvif, key);66506651/* When WEP keys are uploaded it's possible that there are6652* stations associated already (e.g. when merging) without any6653* keys. Static WEP needs an explicit per-peer key upload.6654*/6655if (vif->type == NL80211_IFTYPE_ADHOC &&6656cmd == SET_KEY)6657ath10k_mac_vif_update_wep_key(arvif, key);66586659/* 802.1x never sets the def_wep_key_idx so each set_key()6660* call changes default tx key.6661*6662* Static WEP sets def_wep_key_idx via .set_default_unicast_key6663* after first set_key().6664*/6665if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)6666flags |= WMI_KEY_TX_USAGE;6667}66686669ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);6670if (ret) {6671WARN_ON(ret > 0);6672ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",6673arvif->vdev_id, peer_addr, ret);6674goto exit;6675}66766677/* mac80211 sets static WEP keys as groupwise while firmware requires6678* them to be installed twice as both pairwise and groupwise.6679*/6680if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {6681flags2 = flags;6682flags2 &= ~WMI_KEY_GROUP;6683flags2 |= WMI_KEY_PAIRWISE;66846685ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);6686if (ret) {6687WARN_ON(ret > 0);6688ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",6689arvif->vdev_id, peer_addr, ret);6690ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,6691peer_addr, flags);6692if (ret2) {6693WARN_ON(ret2 > 0);6694ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",6695arvif->vdev_id, peer_addr, ret2);6696}6697goto exit;6698}6699}67006701ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);67026703spin_lock_bh(&ar->data_lock);6704peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);6705if (peer && cmd == SET_KEY)6706peer->keys[key->keyidx] = key;6707else if (peer && cmd == DISABLE_KEY)6708peer->keys[key->keyidx] = NULL;6709else if (peer == NULL)6710/* impossible unless FW goes crazy */6711ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);6712spin_unlock_bh(&ar->data_lock);67136714if (sta && sta->tdls)6715ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,6716ar->wmi.peer_param->authorize, 1);6717else if (sta && cmd == SET_KEY && (key->flags & IEEE80211_KEY_FLAG_PAIRWISE))6718ath10k_wmi_peer_set_param(ar, arvif->vdev_id, peer_addr,6719ar->wmi.peer_param->authorize, 1);67206721exit:6722mutex_unlock(&ar->conf_mutex);6723return ret;6724}67256726static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,6727struct ieee80211_vif *vif,6728int keyidx)6729{6730struct ath10k *ar = hw->priv;6731struct ath10k_vif *arvif = (void *)vif->drv_priv;6732int ret;67336734mutex_lock(&arvif->ar->conf_mutex);67356736if (arvif->ar->state != ATH10K_STATE_ON)6737goto unlock;67386739ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",6740arvif->vdev_id, keyidx);67416742ret = ath10k_wmi_vdev_set_param(arvif->ar,6743arvif->vdev_id,6744arvif->ar->wmi.vdev_param->def_keyid,6745keyidx);67466747if (ret) {6748ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",6749arvif->vdev_id,6750ret);6751goto unlock;6752}67536754arvif->def_wep_key_idx = keyidx;67556756unlock:6757mutex_unlock(&arvif->ar->conf_mutex);6758}67596760static void ath10k_sta_rc_update_wk(struct work_struct *wk)6761{6762struct ath10k *ar;6763struct ath10k_vif *arvif;6764struct ath10k_sta *arsta;6765struct ieee80211_sta *sta;6766struct cfg80211_chan_def def;6767enum nl80211_band band;6768const u8 *ht_mcs_mask;6769const u16 *vht_mcs_mask;6770u32 changed, bw, nss, smps;6771int err;67726773arsta = container_of(wk, struct ath10k_sta, update_wk);6774sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);6775arvif = arsta->arvif;6776ar = arvif->ar;67776778if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))6779return;67806781band = def.chan->band;6782ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;6783vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;67846785spin_lock_bh(&ar->data_lock);67866787changed = arsta->changed;6788arsta->changed = 0;67896790bw = arsta->bw;6791nss = arsta->nss;6792smps = arsta->smps;67936794spin_unlock_bh(&ar->data_lock);67956796mutex_lock(&ar->conf_mutex);67976798nss = max_t(u32, 1, nss);6799nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),6800ath10k_mac_max_vht_nss(vht_mcs_mask)));68016802if (changed & IEEE80211_RC_BW_CHANGED) {6803enum wmi_phy_mode mode;68046805mode = chan_to_phymode(&def);6806ath10k_dbg(ar, ATH10K_DBG_STA, "mac update sta %pM peer bw %d phymode %d\n",6807sta->addr, bw, mode);68086809err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,6810ar->wmi.peer_param->phymode, mode);6811if (err) {6812ath10k_warn(ar, "failed to update STA %pM peer phymode %d: %d\n",6813sta->addr, mode, err);6814goto exit;6815}68166817err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,6818ar->wmi.peer_param->chan_width, bw);6819if (err)6820ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",6821sta->addr, bw, err);6822}68236824if (changed & IEEE80211_RC_NSS_CHANGED) {6825ath10k_dbg(ar, ATH10K_DBG_STA, "mac update sta %pM nss %d\n",6826sta->addr, nss);68276828err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,6829ar->wmi.peer_param->nss, nss);6830if (err)6831ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",6832sta->addr, nss, err);6833}68346835if (changed & IEEE80211_RC_SMPS_CHANGED) {6836ath10k_dbg(ar, ATH10K_DBG_STA, "mac update sta %pM smps %d\n",6837sta->addr, smps);68386839err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,6840ar->wmi.peer_param->smps_state, smps);6841if (err)6842ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",6843sta->addr, smps, err);6844}68456846if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {6847ath10k_dbg(ar, ATH10K_DBG_STA, "mac update sta %pM supp rates\n",6848sta->addr);68496850err = ath10k_station_assoc(ar, arvif->vif, sta, true);6851if (err)6852ath10k_warn(ar, "failed to reassociate station: %pM\n",6853sta->addr);6854}68556856exit:6857mutex_unlock(&ar->conf_mutex);6858}68596860static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,6861struct ieee80211_sta *sta)6862{6863struct ath10k *ar = arvif->ar;68646865lockdep_assert_held(&ar->conf_mutex);68666867if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)6868return 0;68696870if (ar->num_stations >= ar->max_num_stations)6871return -ENOBUFS;68726873ar->num_stations++;68746875return 0;6876}68776878static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,6879struct ieee80211_sta *sta)6880{6881struct ath10k *ar = arvif->ar;68826883lockdep_assert_held(&ar->conf_mutex);68846885if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)6886return;68876888ar->num_stations--;6889}68906891static int ath10k_sta_set_txpwr(struct ieee80211_hw *hw,6892struct ieee80211_vif *vif,6893struct ieee80211_sta *sta)6894{6895struct ath10k *ar = hw->priv;6896struct ath10k_vif *arvif = (void *)vif->drv_priv;6897int ret = 0;6898s16 txpwr;68996900if (sta->deflink.txpwr.type == NL80211_TX_POWER_AUTOMATIC) {6901txpwr = 0;6902} else {6903txpwr = sta->deflink.txpwr.power;6904if (!txpwr)6905return -EINVAL;6906}69076908if (txpwr > ATH10K_TX_POWER_MAX_VAL || txpwr < ATH10K_TX_POWER_MIN_VAL)6909return -EINVAL;69106911mutex_lock(&ar->conf_mutex);69126913ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,6914ar->wmi.peer_param->use_fixed_power, txpwr);6915if (ret) {6916ath10k_warn(ar, "failed to set tx power for station ret: %d\n",6917ret);6918goto out;6919}69206921out:6922mutex_unlock(&ar->conf_mutex);6923return ret;6924}69256926struct ath10k_mac_iter_tid_conf_data {6927struct ieee80211_vif *curr_vif;6928struct ath10k *ar;6929bool reset_config;6930};69316932static bool6933ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,6934enum nl80211_band band,6935const struct cfg80211_bitrate_mask *mask,6936int *vht_num_rates)6937{6938int num_rates = 0;6939int i, tmp;69406941num_rates += hweight32(mask->control[band].legacy);69426943for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)6944num_rates += hweight8(mask->control[band].ht_mcs[i]);69456946*vht_num_rates = 0;6947for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {6948tmp = hweight16(mask->control[band].vht_mcs[i]);6949num_rates += tmp;6950*vht_num_rates += tmp;6951}69526953return num_rates == 1;6954}69556956static int6957ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,6958enum nl80211_band band,6959const struct cfg80211_bitrate_mask *mask,6960u8 *rate, u8 *nss, bool vht_only)6961{6962int rate_idx;6963int i;6964u16 bitrate;6965u8 preamble;6966u8 hw_rate;69676968if (vht_only)6969goto next;69706971if (hweight32(mask->control[band].legacy) == 1) {6972rate_idx = ffs(mask->control[band].legacy) - 1;69736974if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)6975rate_idx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;69766977hw_rate = ath10k_wmi_legacy_rates[rate_idx].hw_value;6978bitrate = ath10k_wmi_legacy_rates[rate_idx].bitrate;69796980if (ath10k_mac_bitrate_is_cck(bitrate))6981preamble = WMI_RATE_PREAMBLE_CCK;6982else6983preamble = WMI_RATE_PREAMBLE_OFDM;69846985*nss = 1;6986*rate = preamble << 6 |6987(*nss - 1) << 4 |6988hw_rate << 0;69896990return 0;6991}69926993for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {6994if (hweight8(mask->control[band].ht_mcs[i]) == 1) {6995*nss = i + 1;6996*rate = WMI_RATE_PREAMBLE_HT << 6 |6997(*nss - 1) << 4 |6998(ffs(mask->control[band].ht_mcs[i]) - 1);69997000return 0;7001}7002}70037004next:7005for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {7006if (hweight16(mask->control[band].vht_mcs[i]) == 1) {7007*nss = i + 1;7008*rate = WMI_RATE_PREAMBLE_VHT << 6 |7009(*nss - 1) << 4 |7010(ffs(mask->control[band].vht_mcs[i]) - 1);70117012return 0;7013}7014}70157016return -EINVAL;7017}70187019static int ath10k_mac_validate_rate_mask(struct ath10k *ar,7020struct ieee80211_sta *sta,7021u32 rate_ctrl_flag, u8 nss)7022{7023struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap;7024struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap;70257026if (nss > sta->deflink.rx_nss) {7027ath10k_warn(ar, "Invalid nss field, configured %u limit %u\n",7028nss, sta->deflink.rx_nss);7029return -EINVAL;7030}70317032if (ATH10K_HW_PREAMBLE(rate_ctrl_flag) == WMI_RATE_PREAMBLE_VHT) {7033if (!vht_cap->vht_supported) {7034ath10k_warn(ar, "Invalid VHT rate for sta %pM\n",7035sta->addr);7036return -EINVAL;7037}7038} else if (ATH10K_HW_PREAMBLE(rate_ctrl_flag) == WMI_RATE_PREAMBLE_HT) {7039if (!ht_cap->ht_supported || vht_cap->vht_supported) {7040ath10k_warn(ar, "Invalid HT rate for sta %pM\n",7041sta->addr);7042return -EINVAL;7043}7044} else {7045if (ht_cap->ht_supported || vht_cap->vht_supported)7046return -EINVAL;7047}70487049return 0;7050}70517052static int7053ath10k_mac_tid_bitrate_config(struct ath10k *ar,7054struct ieee80211_vif *vif,7055struct ieee80211_sta *sta,7056u32 *rate_ctrl_flag, u8 *rate_ctrl,7057enum nl80211_tx_rate_setting txrate_type,7058const struct cfg80211_bitrate_mask *mask)7059{7060struct cfg80211_chan_def def;7061enum nl80211_band band;7062u8 nss, rate;7063int vht_num_rates, ret;70647065if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))7066return -EINVAL;70677068if (txrate_type == NL80211_TX_RATE_AUTOMATIC) {7069*rate_ctrl = WMI_TID_CONFIG_RATE_CONTROL_AUTO;7070*rate_ctrl_flag = 0;7071return 0;7072}70737074band = def.chan->band;70757076if (!ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask,7077&vht_num_rates)) {7078return -EINVAL;7079}70807081ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,7082&rate, &nss, false);7083if (ret) {7084ath10k_warn(ar, "failed to get single rate: %d\n",7085ret);7086return ret;7087}70887089*rate_ctrl_flag = rate;70907091if (sta && ath10k_mac_validate_rate_mask(ar, sta, *rate_ctrl_flag, nss))7092return -EINVAL;70937094if (txrate_type == NL80211_TX_RATE_FIXED)7095*rate_ctrl = WMI_TID_CONFIG_RATE_CONTROL_FIXED_RATE;7096else if (txrate_type == NL80211_TX_RATE_LIMITED &&7097(test_bit(WMI_SERVICE_EXT_PEER_TID_CONFIGS_SUPPORT,7098ar->wmi.svc_map)))7099*rate_ctrl = WMI_PEER_TID_CONFIG_RATE_UPPER_CAP;7100else7101return -EOPNOTSUPP;71027103return 0;7104}71057106static int ath10k_mac_set_tid_config(struct ath10k *ar, struct ieee80211_sta *sta,7107struct ieee80211_vif *vif, u32 changed,7108struct wmi_per_peer_per_tid_cfg_arg *arg)7109{7110struct ath10k_vif *arvif = (void *)vif->drv_priv;7111struct ath10k_sta *arsta;7112int ret;71137114if (sta) {7115if (!sta->wme)7116return -EOPNOTSUPP;71177118arsta = (struct ath10k_sta *)sta->drv_priv;71197120if (changed & BIT(NL80211_TID_CONFIG_ATTR_NOACK)) {7121if ((arsta->retry_long[arg->tid] > 0 ||7122arsta->rate_code[arg->tid] > 0 ||7123arsta->ampdu[arg->tid] ==7124WMI_TID_CONFIG_AGGR_CONTROL_ENABLE) &&7125arg->ack_policy == WMI_PEER_TID_CONFIG_NOACK) {7126changed &= ~BIT(NL80211_TID_CONFIG_ATTR_NOACK);7127arg->ack_policy = 0;7128arg->aggr_control = 0;7129arg->rate_ctrl = 0;7130arg->rcode_flags = 0;7131}7132}71337134if (changed & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) {7135if (arsta->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK ||7136arvif->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK) {7137arg->aggr_control = 0;7138changed &= ~BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG);7139}7140}71417142if (changed & (BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |7143BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE))) {7144if (arsta->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK ||7145arvif->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK) {7146arg->rate_ctrl = 0;7147arg->rcode_flags = 0;7148}7149}71507151ether_addr_copy(arg->peer_macaddr.addr, sta->addr);71527153ret = ath10k_wmi_set_per_peer_per_tid_cfg(ar, arg);7154if (ret)7155return ret;71567157/* Store the configured parameters in success case */7158if (changed & BIT(NL80211_TID_CONFIG_ATTR_NOACK)) {7159arsta->noack[arg->tid] = arg->ack_policy;7160arg->ack_policy = 0;7161arg->aggr_control = 0;7162arg->rate_ctrl = 0;7163arg->rcode_flags = 0;7164}71657166if (changed & BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG)) {7167arsta->retry_long[arg->tid] = arg->retry_count;7168arg->retry_count = 0;7169}71707171if (changed & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) {7172arsta->ampdu[arg->tid] = arg->aggr_control;7173arg->aggr_control = 0;7174}71757176if (changed & (BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |7177BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE))) {7178arsta->rate_ctrl[arg->tid] = arg->rate_ctrl;7179arg->rate_ctrl = 0;7180arg->rcode_flags = 0;7181}71827183if (changed & BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL)) {7184arsta->rtscts[arg->tid] = arg->rtscts_ctrl;7185arg->ext_tid_cfg_bitmap = 0;7186}7187} else {7188if (changed & BIT(NL80211_TID_CONFIG_ATTR_NOACK)) {7189if ((arvif->retry_long[arg->tid] ||7190arvif->rate_code[arg->tid] ||7191arvif->ampdu[arg->tid] ==7192WMI_TID_CONFIG_AGGR_CONTROL_ENABLE) &&7193arg->ack_policy == WMI_PEER_TID_CONFIG_NOACK) {7194changed &= ~BIT(NL80211_TID_CONFIG_ATTR_NOACK);7195} else {7196arvif->noack[arg->tid] = arg->ack_policy;7197arvif->ampdu[arg->tid] = arg->aggr_control;7198arvif->rate_ctrl[arg->tid] = arg->rate_ctrl;7199}7200}72017202if (changed & BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG)) {7203if (arvif->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK)7204changed &= ~BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG);7205else7206arvif->retry_long[arg->tid] = arg->retry_count;7207}72087209if (changed & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) {7210if (arvif->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK)7211changed &= ~BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL);7212else7213arvif->ampdu[arg->tid] = arg->aggr_control;7214}72157216if (changed & (BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |7217BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE))) {7218if (arvif->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK) {7219changed &= ~(BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |7220BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE));7221} else {7222arvif->rate_ctrl[arg->tid] = arg->rate_ctrl;7223arvif->rate_code[arg->tid] = arg->rcode_flags;7224}7225}72267227if (changed & BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL)) {7228arvif->rtscts[arg->tid] = arg->rtscts_ctrl;7229arg->ext_tid_cfg_bitmap = 0;7230}72317232if (changed)7233arvif->tid_conf_changed[arg->tid] |= changed;7234}72357236return 0;7237}72387239static int7240ath10k_mac_parse_tid_config(struct ath10k *ar,7241struct ieee80211_sta *sta,7242struct ieee80211_vif *vif,7243struct cfg80211_tid_cfg *tid_conf,7244struct wmi_per_peer_per_tid_cfg_arg *arg)7245{7246u32 changed = tid_conf->mask;7247int ret = 0, i = 0;72487249if (!changed)7250return -EINVAL;72517252while (i < ATH10K_TID_MAX) {7253if (!(tid_conf->tids & BIT(i))) {7254i++;7255continue;7256}72577258arg->tid = i;72597260if (changed & BIT(NL80211_TID_CONFIG_ATTR_NOACK)) {7261if (tid_conf->noack == NL80211_TID_CONFIG_ENABLE) {7262arg->ack_policy = WMI_PEER_TID_CONFIG_NOACK;7263arg->rate_ctrl =7264WMI_TID_CONFIG_RATE_CONTROL_DEFAULT_LOWEST_RATE;7265arg->aggr_control =7266WMI_TID_CONFIG_AGGR_CONTROL_DISABLE;7267} else {7268arg->ack_policy =7269WMI_PEER_TID_CONFIG_ACK;7270arg->rate_ctrl =7271WMI_TID_CONFIG_RATE_CONTROL_AUTO;7272arg->aggr_control =7273WMI_TID_CONFIG_AGGR_CONTROL_ENABLE;7274}7275}72767277if (changed & BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG))7278arg->retry_count = tid_conf->retry_long;72797280if (changed & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) {7281if (tid_conf->noack == NL80211_TID_CONFIG_ENABLE)7282arg->aggr_control = WMI_TID_CONFIG_AGGR_CONTROL_ENABLE;7283else7284arg->aggr_control = WMI_TID_CONFIG_AGGR_CONTROL_DISABLE;7285}72867287if (changed & (BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |7288BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE))) {7289ret = ath10k_mac_tid_bitrate_config(ar, vif, sta,7290&arg->rcode_flags,7291&arg->rate_ctrl,7292tid_conf->txrate_type,7293&tid_conf->txrate_mask);7294if (ret) {7295ath10k_warn(ar, "failed to configure bitrate mask %d\n",7296ret);7297arg->rcode_flags = 0;7298arg->rate_ctrl = 0;7299}7300}73017302if (changed & BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL)) {7303if (tid_conf->rtscts)7304arg->rtscts_ctrl = tid_conf->rtscts;73057306arg->ext_tid_cfg_bitmap = WMI_EXT_TID_RTS_CTS_CONFIG;7307}73087309ret = ath10k_mac_set_tid_config(ar, sta, vif, changed, arg);7310if (ret)7311return ret;7312i++;7313}73147315return ret;7316}73177318static int ath10k_mac_reset_tid_config(struct ath10k *ar,7319struct ieee80211_sta *sta,7320struct ath10k_vif *arvif,7321u8 tids)7322{7323struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;7324struct wmi_per_peer_per_tid_cfg_arg arg;7325int ret = 0, i = 0;73267327arg.vdev_id = arvif->vdev_id;7328while (i < ATH10K_TID_MAX) {7329if (!(tids & BIT(i))) {7330i++;7331continue;7332}73337334arg.tid = i;7335arg.ack_policy = WMI_PEER_TID_CONFIG_ACK;7336arg.retry_count = ATH10K_MAX_RETRY_COUNT;7337arg.rate_ctrl = WMI_TID_CONFIG_RATE_CONTROL_AUTO;7338arg.aggr_control = WMI_TID_CONFIG_AGGR_CONTROL_ENABLE;7339arg.rtscts_ctrl = WMI_TID_CONFIG_RTSCTS_CONTROL_ENABLE;7340arg.ext_tid_cfg_bitmap = WMI_EXT_TID_RTS_CTS_CONFIG;73417342ether_addr_copy(arg.peer_macaddr.addr, sta->addr);73437344ret = ath10k_wmi_set_per_peer_per_tid_cfg(ar, &arg);7345if (ret)7346return ret;73477348if (!arvif->tids_rst) {7349arsta->retry_long[i] = -1;7350arsta->noack[i] = -1;7351arsta->ampdu[i] = -1;7352arsta->rate_code[i] = -1;7353arsta->rate_ctrl[i] = 0;7354arsta->rtscts[i] = -1;7355} else {7356arvif->retry_long[i] = 0;7357arvif->noack[i] = 0;7358arvif->ampdu[i] = 0;7359arvif->rate_code[i] = 0;7360arvif->rate_ctrl[i] = 0;7361arvif->rtscts[i] = 0;7362}73637364i++;7365}73667367return ret;7368}73697370static void ath10k_sta_tid_cfg_wk(struct work_struct *wk)7371{7372struct wmi_per_peer_per_tid_cfg_arg arg = {};7373struct ieee80211_sta *sta;7374struct ath10k_sta *arsta;7375struct ath10k_vif *arvif;7376struct ath10k *ar;7377bool config_apply;7378int ret, i;7379u32 changed;7380u8 nss;73817382arsta = container_of(wk, struct ath10k_sta, tid_config_wk);7383sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);7384arvif = arsta->arvif;7385ar = arvif->ar;73867387mutex_lock(&ar->conf_mutex);73887389if (arvif->tids_rst) {7390ret = ath10k_mac_reset_tid_config(ar, sta, arvif,7391arvif->tids_rst);7392goto exit;7393}73947395ether_addr_copy(arg.peer_macaddr.addr, sta->addr);73967397for (i = 0; i < ATH10K_TID_MAX; i++) {7398config_apply = false;7399changed = arvif->tid_conf_changed[i];74007401if (changed & BIT(NL80211_TID_CONFIG_ATTR_NOACK)) {7402if (arsta->noack[i] != -1) {7403arg.ack_policy = 0;7404} else {7405config_apply = true;7406arg.ack_policy = arvif->noack[i];7407arg.aggr_control = arvif->ampdu[i];7408arg.rate_ctrl = arvif->rate_ctrl[i];7409}7410}74117412if (changed & BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG)) {7413if (arsta->retry_long[i] != -1 ||7414arsta->noack[i] == WMI_PEER_TID_CONFIG_NOACK ||7415arvif->noack[i] == WMI_PEER_TID_CONFIG_NOACK) {7416arg.retry_count = 0;7417} else {7418arg.retry_count = arvif->retry_long[i];7419config_apply = true;7420}7421}74227423if (changed & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) {7424if (arsta->ampdu[i] != -1 ||7425arsta->noack[i] == WMI_PEER_TID_CONFIG_NOACK ||7426arvif->noack[i] == WMI_PEER_TID_CONFIG_NOACK) {7427arg.aggr_control = 0;7428} else {7429arg.aggr_control = arvif->ampdu[i];7430config_apply = true;7431}7432}74337434if (changed & (BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |7435BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE))) {7436nss = ATH10K_HW_NSS(arvif->rate_code[i]);7437ret = ath10k_mac_validate_rate_mask(ar, sta,7438arvif->rate_code[i],7439nss);7440if (ret &&7441arvif->rate_ctrl[i] > WMI_TID_CONFIG_RATE_CONTROL_AUTO) {7442arg.rate_ctrl = 0;7443arg.rcode_flags = 0;7444}74457446if (arsta->rate_ctrl[i] >7447WMI_TID_CONFIG_RATE_CONTROL_AUTO ||7448arsta->noack[i] == WMI_PEER_TID_CONFIG_NOACK ||7449arvif->noack[i] == WMI_PEER_TID_CONFIG_NOACK) {7450arg.rate_ctrl = 0;7451arg.rcode_flags = 0;7452} else {7453arg.rate_ctrl = arvif->rate_ctrl[i];7454arg.rcode_flags = arvif->rate_code[i];7455config_apply = true;7456}7457}74587459if (changed & BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL)) {7460if (arsta->rtscts[i]) {7461arg.rtscts_ctrl = 0;7462arg.ext_tid_cfg_bitmap = 0;7463} else {7464arg.rtscts_ctrl = arvif->rtscts[i] - 1;7465arg.ext_tid_cfg_bitmap =7466WMI_EXT_TID_RTS_CTS_CONFIG;7467config_apply = true;7468}7469}74707471arg.tid = i;74727473if (config_apply) {7474ret = ath10k_wmi_set_per_peer_per_tid_cfg(ar, &arg);7475if (ret)7476ath10k_warn(ar, "failed to set per tid config for sta %pM: %d\n",7477sta->addr, ret);7478}74797480arg.ack_policy = 0;7481arg.retry_count = 0;7482arg.aggr_control = 0;7483arg.rate_ctrl = 0;7484arg.rcode_flags = 0;7485}74867487exit:7488mutex_unlock(&ar->conf_mutex);7489}74907491static void ath10k_mac_vif_stations_tid_conf(void *data,7492struct ieee80211_sta *sta)7493{7494struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;7495struct ath10k_mac_iter_tid_conf_data *iter_data = data;7496struct ieee80211_vif *sta_vif = arsta->arvif->vif;74977498if (sta_vif != iter_data->curr_vif || !sta->wme)7499return;75007501ieee80211_queue_work(iter_data->ar->hw, &arsta->tid_config_wk);7502}75037504static int ath10k_sta_state(struct ieee80211_hw *hw,7505struct ieee80211_vif *vif,7506struct ieee80211_sta *sta,7507enum ieee80211_sta_state old_state,7508enum ieee80211_sta_state new_state)7509{7510struct ath10k *ar = hw->priv;7511struct ath10k_vif *arvif = (void *)vif->drv_priv;7512struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;7513struct ath10k_peer *peer;7514int ret = 0;7515int i;75167517if (old_state == IEEE80211_STA_NOTEXIST &&7518new_state == IEEE80211_STA_NONE) {7519memset(arsta, 0, sizeof(*arsta));7520arsta->arvif = arvif;7521arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;7522INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);7523INIT_WORK(&arsta->tid_config_wk, ath10k_sta_tid_cfg_wk);75247525for (i = 0; i < ARRAY_SIZE(sta->txq); i++)7526ath10k_mac_txq_init(sta->txq[i]);7527}75287529/* cancel must be done outside the mutex to avoid deadlock */7530if ((old_state == IEEE80211_STA_NONE &&7531new_state == IEEE80211_STA_NOTEXIST)) {7532cancel_work_sync(&arsta->update_wk);7533cancel_work_sync(&arsta->tid_config_wk);7534}75357536mutex_lock(&ar->conf_mutex);75377538if (old_state == IEEE80211_STA_NOTEXIST &&7539new_state == IEEE80211_STA_NONE) {7540/*7541* New station addition.7542*/7543enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;7544u32 num_tdls_stations;75457546ath10k_dbg(ar, ATH10K_DBG_STA,7547"mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",7548arvif->vdev_id, sta->addr,7549ar->num_stations + 1, ar->max_num_stations,7550ar->num_peers + 1, ar->max_num_peers);75517552num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);75537554if (sta->tdls) {7555if (num_tdls_stations >= ar->max_num_tdls_vdevs) {7556ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",7557arvif->vdev_id,7558ar->max_num_tdls_vdevs);7559ret = -ELNRNG;7560goto exit;7561}7562peer_type = WMI_PEER_TYPE_TDLS;7563}75647565ret = ath10k_mac_inc_num_stations(arvif, sta);7566if (ret) {7567ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",7568ar->max_num_stations);7569goto exit;7570}75717572if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {7573arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats),7574GFP_KERNEL);7575if (!arsta->tx_stats) {7576ath10k_mac_dec_num_stations(arvif, sta);7577ret = -ENOMEM;7578goto exit;7579}7580}75817582ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,7583sta->addr, peer_type);7584if (ret) {7585ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n",7586sta->addr, arvif->vdev_id, ret);7587ath10k_mac_dec_num_stations(arvif, sta);7588kfree(arsta->tx_stats);7589goto exit;7590}75917592spin_lock_bh(&ar->data_lock);75937594peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);7595if (!peer) {7596ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",7597vif->addr, arvif->vdev_id);7598spin_unlock_bh(&ar->data_lock);7599ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);7600ath10k_mac_dec_num_stations(arvif, sta);7601kfree(arsta->tx_stats);7602ret = -ENOENT;7603goto exit;7604}76057606arsta->peer_id = find_first_bit(peer->peer_ids,7607ATH10K_MAX_NUM_PEER_IDS);76087609spin_unlock_bh(&ar->data_lock);76107611if (!sta->tdls)7612goto exit;76137614ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,7615WMI_TDLS_ENABLE_ACTIVE);7616if (ret) {7617ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",7618arvif->vdev_id, ret);7619ath10k_peer_delete(ar, arvif->vdev_id,7620sta->addr);7621ath10k_mac_dec_num_stations(arvif, sta);7622kfree(arsta->tx_stats);7623goto exit;7624}76257626ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,7627WMI_TDLS_PEER_STATE_PEERING);7628if (ret) {7629ath10k_warn(ar,7630"failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",7631sta->addr, arvif->vdev_id, ret);7632ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);7633ath10k_mac_dec_num_stations(arvif, sta);7634kfree(arsta->tx_stats);76357636if (num_tdls_stations != 0)7637goto exit;7638ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,7639WMI_TDLS_DISABLE);7640}7641} else if ((old_state == IEEE80211_STA_NONE &&7642new_state == IEEE80211_STA_NOTEXIST)) {7643/*7644* Existing station deletion.7645*/7646ath10k_dbg(ar, ATH10K_DBG_STA,7647"mac vdev %d peer delete %pM sta %p (sta gone)\n",7648arvif->vdev_id, sta->addr, sta);76497650if (sta->tdls) {7651ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id,7652sta,7653WMI_TDLS_PEER_STATE_TEARDOWN);7654if (ret)7655ath10k_warn(ar, "failed to update tdls peer state for %pM state %d: %i\n",7656sta->addr,7657WMI_TDLS_PEER_STATE_TEARDOWN, ret);7658}76597660ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);7661if (ret)7662ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",7663sta->addr, arvif->vdev_id, ret);76647665ath10k_mac_dec_num_stations(arvif, sta);76667667spin_lock_bh(&ar->data_lock);7668for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {7669peer = ar->peer_map[i];7670if (!peer)7671continue;76727673if (peer->sta == sta) {7674ath10k_warn(ar, "found sta peer %pM (ptr %p id %d) entry on vdev %i after it was supposedly removed\n",7675sta->addr, peer, i, arvif->vdev_id);7676peer->sta = NULL;76777678/* Clean up the peer object as well since we7679* must have failed to do this above.7680*/7681ath10k_peer_map_cleanup(ar, peer);7682}7683}7684spin_unlock_bh(&ar->data_lock);76857686if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {7687kfree(arsta->tx_stats);7688arsta->tx_stats = NULL;7689}76907691for (i = 0; i < ARRAY_SIZE(sta->txq); i++)7692ath10k_mac_txq_unref(ar, sta->txq[i]);76937694if (!sta->tdls)7695goto exit;76967697if (ath10k_mac_tdls_vif_stations_count(hw, vif))7698goto exit;76997700/* This was the last tdls peer in current vif */7701ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,7702WMI_TDLS_DISABLE);7703if (ret) {7704ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",7705arvif->vdev_id, ret);7706}7707} else if (old_state == IEEE80211_STA_AUTH &&7708new_state == IEEE80211_STA_ASSOC &&7709(vif->type == NL80211_IFTYPE_AP ||7710vif->type == NL80211_IFTYPE_MESH_POINT ||7711vif->type == NL80211_IFTYPE_ADHOC)) {7712/*7713* New association.7714*/7715ath10k_dbg(ar, ATH10K_DBG_STA, "mac sta %pM associated\n",7716sta->addr);77177718ret = ath10k_station_assoc(ar, vif, sta, false);7719if (ret)7720ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",7721sta->addr, arvif->vdev_id, ret);7722} else if (old_state == IEEE80211_STA_ASSOC &&7723new_state == IEEE80211_STA_AUTHORIZED &&7724sta->tdls) {7725/*7726* Tdls station authorized.7727*/7728ath10k_dbg(ar, ATH10K_DBG_STA, "mac tdls sta %pM authorized\n",7729sta->addr);77307731ret = ath10k_station_assoc(ar, vif, sta, false);7732if (ret) {7733ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",7734sta->addr, arvif->vdev_id, ret);7735goto exit;7736}77377738ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,7739WMI_TDLS_PEER_STATE_CONNECTED);7740if (ret)7741ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",7742sta->addr, arvif->vdev_id, ret);7743} else if (old_state == IEEE80211_STA_ASSOC &&7744new_state == IEEE80211_STA_AUTH &&7745(vif->type == NL80211_IFTYPE_AP ||7746vif->type == NL80211_IFTYPE_MESH_POINT ||7747vif->type == NL80211_IFTYPE_ADHOC)) {7748/*7749* Disassociation.7750*/7751ath10k_dbg(ar, ATH10K_DBG_STA, "mac sta %pM disassociated\n",7752sta->addr);77537754ret = ath10k_station_disassoc(ar, vif, sta);7755if (ret)7756ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",7757sta->addr, arvif->vdev_id, ret);7758}7759exit:7760mutex_unlock(&ar->conf_mutex);7761return ret;7762}77637764static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,7765u16 ac, bool enable)7766{7767struct ath10k_vif *arvif = (void *)vif->drv_priv;7768struct wmi_sta_uapsd_auto_trig_arg arg = {};7769u32 prio = 0, acc = 0;7770u32 value = 0;7771int ret = 0;77727773lockdep_assert_held(&ar->conf_mutex);77747775if (arvif->vdev_type != WMI_VDEV_TYPE_STA)7776return 0;77777778switch (ac) {7779case IEEE80211_AC_VO:7780value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |7781WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;7782prio = 7;7783acc = 3;7784break;7785case IEEE80211_AC_VI:7786value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |7787WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;7788prio = 5;7789acc = 2;7790break;7791case IEEE80211_AC_BE:7792value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |7793WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;7794prio = 2;7795acc = 1;7796break;7797case IEEE80211_AC_BK:7798value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |7799WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;7800prio = 0;7801acc = 0;7802break;7803}78047805if (enable)7806arvif->u.sta.uapsd |= value;7807else7808arvif->u.sta.uapsd &= ~value;78097810ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,7811WMI_STA_PS_PARAM_UAPSD,7812arvif->u.sta.uapsd);7813if (ret) {7814ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);7815goto exit;7816}78177818if (arvif->u.sta.uapsd)7819value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;7820else7821value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;78227823ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,7824WMI_STA_PS_PARAM_RX_WAKE_POLICY,7825value);7826if (ret)7827ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);78287829ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);7830if (ret) {7831ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",7832arvif->vdev_id, ret);7833return ret;7834}78357836ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);7837if (ret) {7838ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",7839arvif->vdev_id, ret);7840return ret;7841}78427843if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||7844test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {7845/* Only userspace can make an educated decision when to send7846* trigger frame. The following effectively disables u-UAPSD7847* autotrigger in firmware (which is enabled by default7848* provided the autotrigger service is available).7849*/78507851arg.wmm_ac = acc;7852arg.user_priority = prio;7853arg.service_interval = 0;7854arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;7855arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;78567857ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,7858arvif->bssid, &arg, 1);7859if (ret) {7860ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",7861ret);7862return ret;7863}7864}78657866exit:7867return ret;7868}78697870static int ath10k_conf_tx(struct ieee80211_hw *hw,7871struct ieee80211_vif *vif,7872unsigned int link_id, u16 ac,7873const struct ieee80211_tx_queue_params *params)7874{7875struct ath10k *ar = hw->priv;7876struct ath10k_vif *arvif = (void *)vif->drv_priv;7877struct wmi_wmm_params_arg *p = NULL;7878int ret;78797880mutex_lock(&ar->conf_mutex);78817882switch (ac) {7883case IEEE80211_AC_VO:7884p = &arvif->wmm_params.ac_vo;7885break;7886case IEEE80211_AC_VI:7887p = &arvif->wmm_params.ac_vi;7888break;7889case IEEE80211_AC_BE:7890p = &arvif->wmm_params.ac_be;7891break;7892case IEEE80211_AC_BK:7893p = &arvif->wmm_params.ac_bk;7894break;7895}78967897if (WARN_ON(!p)) {7898ret = -EINVAL;7899goto exit;7900}79017902p->cwmin = params->cw_min;7903p->cwmax = params->cw_max;7904p->aifs = params->aifs;79057906/*7907* The channel time duration programmed in the HW is in absolute7908* microseconds, while mac80211 gives the txop in units of7909* 32 microseconds.7910*/7911p->txop = params->txop * 32;79127913if (ar->wmi.ops->gen_vdev_wmm_conf) {7914ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,7915&arvif->wmm_params);7916if (ret) {7917ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",7918arvif->vdev_id, ret);7919goto exit;7920}7921} else {7922/* This won't work well with multi-interface cases but it's7923* better than nothing.7924*/7925ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);7926if (ret) {7927ath10k_warn(ar, "failed to set wmm params: %d\n", ret);7928goto exit;7929}7930}79317932ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);7933if (ret)7934ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);79357936exit:7937mutex_unlock(&ar->conf_mutex);7938return ret;7939}79407941static int ath10k_remain_on_channel(struct ieee80211_hw *hw,7942struct ieee80211_vif *vif,7943struct ieee80211_channel *chan,7944int duration,7945enum ieee80211_roc_type type)7946{7947struct ath10k *ar = hw->priv;7948struct ath10k_vif *arvif = (void *)vif->drv_priv;7949struct wmi_start_scan_arg *arg = NULL;7950int ret = 0;7951u32 scan_time_msec;79527953mutex_lock(&ar->conf_mutex);79547955if (ath10k_mac_tdls_vif_stations_count(hw, vif) > 0) {7956ret = -EBUSY;7957goto exit;7958}79597960spin_lock_bh(&ar->data_lock);7961switch (ar->scan.state) {7962case ATH10K_SCAN_IDLE:7963reinit_completion(&ar->scan.started);7964reinit_completion(&ar->scan.completed);7965reinit_completion(&ar->scan.on_channel);7966ar->scan.state = ATH10K_SCAN_STARTING;7967ar->scan.is_roc = true;7968ar->scan.vdev_id = arvif->vdev_id;7969ar->scan.roc_freq = chan->center_freq;7970ar->scan.roc_notify = true;7971ret = 0;7972break;7973case ATH10K_SCAN_STARTING:7974case ATH10K_SCAN_RUNNING:7975case ATH10K_SCAN_ABORTING:7976ret = -EBUSY;7977break;7978}7979spin_unlock_bh(&ar->data_lock);79807981if (ret)7982goto exit;79837984scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;79857986arg = kzalloc(sizeof(*arg), GFP_KERNEL);7987if (!arg) {7988ret = -ENOMEM;7989goto exit;7990}79917992ath10k_wmi_start_scan_init(ar, arg);7993arg->vdev_id = arvif->vdev_id;7994arg->scan_id = ATH10K_SCAN_ID;7995arg->n_channels = 1;7996arg->channels[0] = chan->center_freq;7997arg->dwell_time_active = scan_time_msec;7998arg->dwell_time_passive = scan_time_msec;7999arg->max_scan_time = scan_time_msec;8000arg->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;8001arg->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;8002arg->burst_duration_ms = duration;80038004ret = ath10k_start_scan(ar, arg);8005if (ret) {8006ath10k_warn(ar, "failed to start roc scan: %d\n", ret);8007spin_lock_bh(&ar->data_lock);8008ar->scan.state = ATH10K_SCAN_IDLE;8009spin_unlock_bh(&ar->data_lock);8010goto exit;8011}80128013ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);8014if (ret == 0) {8015ath10k_warn(ar, "failed to switch to channel for roc scan\n");80168017ret = ath10k_scan_stop(ar);8018if (ret)8019ath10k_warn(ar, "failed to stop scan: %d\n", ret);80208021ret = -ETIMEDOUT;8022goto exit;8023}80248025ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,8026msecs_to_jiffies(duration));80278028ret = 0;8029exit:8030kfree(arg);80318032mutex_unlock(&ar->conf_mutex);8033return ret;8034}80358036static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw,8037struct ieee80211_vif *vif)8038{8039struct ath10k *ar = hw->priv;80408041mutex_lock(&ar->conf_mutex);80428043spin_lock_bh(&ar->data_lock);8044ar->scan.roc_notify = false;8045spin_unlock_bh(&ar->data_lock);80468047ath10k_scan_abort(ar);80488049mutex_unlock(&ar->conf_mutex);80508051cancel_delayed_work_sync(&ar->scan.timeout);80528053return 0;8054}80558056/*8057* Both RTS and Fragmentation threshold are interface-specific8058* in ath10k, but device-specific in mac80211.8059*/80608061static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx,8062u32 value)8063{8064struct ath10k *ar = hw->priv;8065struct ath10k_vif *arvif;8066int ret = 0;80678068mutex_lock(&ar->conf_mutex);8069list_for_each_entry(arvif, &ar->arvifs, list) {8070ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",8071arvif->vdev_id, value);80728073ret = ath10k_mac_set_rts(arvif, value);8074if (ret) {8075ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",8076arvif->vdev_id, ret);8077break;8078}8079}8080mutex_unlock(&ar->conf_mutex);80818082return ret;8083}80848085static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw,8086int radio_idx, u32 value)8087{8088/* Even though there's a WMI enum for fragmentation threshold no known8089* firmware actually implements it. Moreover it is not possible to rely8090* frame fragmentation to mac80211 because firmware clears the "more8091* fragments" bit in frame control making it impossible for remote8092* devices to reassemble frames.8093*8094* Hence implement a dummy callback just to say fragmentation isn't8095* supported. This effectively prevents mac80211 from doing frame8096* fragmentation in software.8097*/8098return -EOPNOTSUPP;8099}81008101void ath10k_mac_wait_tx_complete(struct ath10k *ar)8102{8103bool skip;8104long time_left;81058106/* mac80211 doesn't care if we really xmit queued frames or not8107* we'll collect those frames either way if we stop/delete vdevs8108*/81098110if (ar->state == ATH10K_STATE_WEDGED)8111return;81128113time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({8114bool empty;81158116spin_lock_bh(&ar->htt.tx_lock);8117empty = (ar->htt.num_pending_tx == 0);8118spin_unlock_bh(&ar->htt.tx_lock);81198120skip = (ar->state == ATH10K_STATE_WEDGED) ||8121test_bit(ATH10K_FLAG_CRASH_FLUSH,8122&ar->dev_flags);81238124(empty || skip);8125}), ATH10K_FLUSH_TIMEOUT_HZ);81268127if (time_left == 0 || skip)8128ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",8129skip, ar->state, time_left);8130}81318132static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,8133u32 queues, bool drop)8134{8135struct ath10k *ar = hw->priv;8136struct ath10k_vif *arvif;8137u32 bitmap;81388139if (drop) {8140if (vif && vif->type == NL80211_IFTYPE_STATION) {8141bitmap = ~(1 << WMI_MGMT_TID);8142list_for_each_entry(arvif, &ar->arvifs, list) {8143if (arvif->vdev_type == WMI_VDEV_TYPE_STA)8144ath10k_wmi_peer_flush(ar, arvif->vdev_id,8145arvif->bssid, bitmap);8146}8147ath10k_htt_flush_tx(&ar->htt);8148}8149return;8150}81518152mutex_lock(&ar->conf_mutex);8153ath10k_mac_wait_tx_complete(ar);8154mutex_unlock(&ar->conf_mutex);8155}81568157/* TODO: Implement this function properly8158* For now it is needed to reply to Probe Requests in IBSS mode.8159* Probably we need this information from FW.8160*/8161static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)8162{8163return 1;8164}81658166static void ath10k_reconfig_complete(struct ieee80211_hw *hw,8167enum ieee80211_reconfig_type reconfig_type)8168{8169struct ath10k *ar = hw->priv;8170struct ath10k_vif *arvif;81718172if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)8173return;81748175mutex_lock(&ar->conf_mutex);81768177/* If device failed to restart it will be in a different state, e.g.8178* ATH10K_STATE_WEDGED8179*/8180if (ar->state == ATH10K_STATE_RESTARTED) {8181ath10k_info(ar, "device successfully recovered\n");8182ar->state = ATH10K_STATE_ON;8183ieee80211_wake_queues(ar->hw);81848185/* Clear recovery state. */8186complete(&ar->driver_recovery);8187atomic_set(&ar->fail_cont_count, 0);8188atomic_set(&ar->pending_recovery, 0);81898190if (ar->hw_params.hw_restart_disconnect) {8191list_for_each_entry(arvif, &ar->arvifs, list) {8192if (arvif->is_up && arvif->vdev_type == WMI_VDEV_TYPE_STA)8193ieee80211_hw_restart_disconnect(arvif->vif);8194}8195}8196}81978198mutex_unlock(&ar->conf_mutex);8199}82008201static void8202ath10k_mac_update_bss_chan_survey(struct ath10k *ar,8203struct ieee80211_channel *channel)8204{8205int ret;8206enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ;82078208lockdep_assert_held(&ar->conf_mutex);82098210if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||8211(ar->rx_channel != channel))8212return;82138214if (ar->scan.state != ATH10K_SCAN_IDLE) {8215ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");8216return;8217}82188219reinit_completion(&ar->bss_survey_done);82208221ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);8222if (ret) {8223ath10k_warn(ar, "failed to send pdev bss chan info request\n");8224return;8225}82268227ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);8228if (!ret) {8229ath10k_warn(ar, "bss channel survey timed out\n");8230return;8231}8232}82338234static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,8235struct survey_info *survey)8236{8237struct ath10k *ar = hw->priv;8238struct ieee80211_supported_band *sband;8239struct survey_info *ar_survey = &ar->survey[idx];8240int ret = 0;82418242mutex_lock(&ar->conf_mutex);82438244sband = hw->wiphy->bands[NL80211_BAND_2GHZ];8245if (sband && idx >= sband->n_channels) {8246idx -= sband->n_channels;8247sband = NULL;8248}82498250if (!sband)8251sband = hw->wiphy->bands[NL80211_BAND_5GHZ];82528253if (!sband || idx >= sband->n_channels) {8254ret = -ENOENT;8255goto exit;8256}82578258ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);82598260spin_lock_bh(&ar->data_lock);8261memcpy(survey, ar_survey, sizeof(*survey));8262spin_unlock_bh(&ar->data_lock);82638264survey->channel = &sband->channels[idx];82658266if (ar->rx_channel == survey->channel)8267survey->filled |= SURVEY_INFO_IN_USE;82688269exit:8270mutex_unlock(&ar->conf_mutex);8271return ret;8272}82738274static bool8275ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,8276enum nl80211_band band,8277const struct cfg80211_bitrate_mask *mask,8278int *nss)8279{8280struct ieee80211_supported_band *sband = &ar->mac.sbands[band];8281u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);8282u8 ht_nss_mask = 0;8283u8 vht_nss_mask = 0;8284int i;82858286if (mask->control[band].legacy)8287return false;82888289for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {8290if (mask->control[band].ht_mcs[i] == 0)8291continue;8292else if (mask->control[band].ht_mcs[i] ==8293sband->ht_cap.mcs.rx_mask[i])8294ht_nss_mask |= BIT(i);8295else8296return false;8297}82988299for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {8300if (mask->control[band].vht_mcs[i] == 0)8301continue;8302else if (mask->control[band].vht_mcs[i] ==8303ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))8304vht_nss_mask |= BIT(i);8305else8306return false;8307}83088309if (ht_nss_mask != vht_nss_mask)8310return false;83118312if (ht_nss_mask == 0)8313return false;83148315if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)8316return false;83178318*nss = fls(ht_nss_mask);83198320return true;8321}83228323static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,8324u8 rate, u8 nss, u8 sgi, u8 ldpc)8325{8326struct ath10k *ar = arvif->ar;8327u32 vdev_param;8328int ret;83298330lockdep_assert_held(&ar->conf_mutex);83318332ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02x nss %u sgi %u\n",8333arvif->vdev_id, rate, nss, sgi);83348335vdev_param = ar->wmi.vdev_param->fixed_rate;8336ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);8337if (ret) {8338ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",8339rate, ret);8340return ret;8341}83428343vdev_param = ar->wmi.vdev_param->nss;8344ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);8345if (ret) {8346ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);8347return ret;8348}83498350vdev_param = ar->wmi.vdev_param->sgi;8351ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);8352if (ret) {8353ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);8354return ret;8355}83568357vdev_param = ar->wmi.vdev_param->ldpc;8358ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);8359if (ret) {8360ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);8361return ret;8362}83638364return 0;8365}83668367static bool8368ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,8369enum nl80211_band band,8370const struct cfg80211_bitrate_mask *mask,8371bool allow_pfr)8372{8373int i;8374u16 vht_mcs;83758376/* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible8377* to express all VHT MCS rate masks. Effectively only the following8378* ranges can be used: none, 0-7, 0-8 and 0-9.8379*/8380for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {8381vht_mcs = mask->control[band].vht_mcs[i];83828383switch (vht_mcs) {8384case 0:8385case BIT(8) - 1:8386case BIT(9) - 1:8387case BIT(10) - 1:8388break;8389default:8390if (!allow_pfr)8391ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");8392return false;8393}8394}83958396return true;8397}83988399static bool ath10k_mac_set_vht_bitrate_mask_fixup(struct ath10k *ar,8400struct ath10k_vif *arvif,8401struct ieee80211_sta *sta)8402{8403int err;8404u8 rate = arvif->vht_pfr;84058406/* skip non vht and multiple rate peers */8407if (!sta->deflink.vht_cap.vht_supported || arvif->vht_num_rates != 1)8408return false;84098410err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,8411WMI_PEER_PARAM_FIXED_RATE, rate);8412if (err)8413ath10k_warn(ar, "failed to enable STA %pM peer fixed rate: %d\n",8414sta->addr, err);84158416return true;8417}84188419static void ath10k_mac_set_bitrate_mask_iter(void *data,8420struct ieee80211_sta *sta)8421{8422struct ath10k_vif *arvif = data;8423struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;8424struct ath10k *ar = arvif->ar;84258426if (arsta->arvif != arvif)8427return;84288429if (ath10k_mac_set_vht_bitrate_mask_fixup(ar, arvif, sta))8430return;84318432spin_lock_bh(&ar->data_lock);8433arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;8434spin_unlock_bh(&ar->data_lock);84358436ieee80211_queue_work(ar->hw, &arsta->update_wk);8437}84388439static void ath10k_mac_clr_bitrate_mask_iter(void *data,8440struct ieee80211_sta *sta)8441{8442struct ath10k_vif *arvif = data;8443struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;8444struct ath10k *ar = arvif->ar;8445int err;84468447/* clear vht peers only */8448if (arsta->arvif != arvif || !sta->deflink.vht_cap.vht_supported)8449return;84508451err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,8452WMI_PEER_PARAM_FIXED_RATE,8453WMI_FIXED_RATE_NONE);8454if (err)8455ath10k_warn(ar, "failed to clear STA %pM peer fixed rate: %d\n",8456sta->addr, err);8457}84588459static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,8460struct ieee80211_vif *vif,8461const struct cfg80211_bitrate_mask *mask)8462{8463struct ath10k_vif *arvif = (void *)vif->drv_priv;8464struct cfg80211_chan_def def;8465struct ath10k *ar = arvif->ar;8466enum nl80211_band band;8467const u8 *ht_mcs_mask;8468const u16 *vht_mcs_mask;8469u8 rate;8470u8 nss;8471u8 sgi;8472u8 ldpc;8473int single_nss;8474int ret;8475int vht_num_rates, allow_pfr;8476u8 vht_pfr;8477bool update_bitrate_mask = true;84788479if (ath10k_mac_vif_chan(vif, &def))8480return -EPERM;84818482band = def.chan->band;8483ht_mcs_mask = mask->control[band].ht_mcs;8484vht_mcs_mask = mask->control[band].vht_mcs;8485ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);84868487sgi = mask->control[band].gi;8488if (sgi == NL80211_TXRATE_FORCE_LGI)8489return -EINVAL;84908491allow_pfr = test_bit(ATH10K_FW_FEATURE_PEER_FIXED_RATE,8492ar->normal_mode_fw.fw_file.fw_features);8493if (allow_pfr) {8494mutex_lock(&ar->conf_mutex);8495ieee80211_iterate_stations_atomic(ar->hw,8496ath10k_mac_clr_bitrate_mask_iter,8497arvif);8498mutex_unlock(&ar->conf_mutex);8499}85008501if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask,8502&vht_num_rates)) {8503ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,8504&rate, &nss,8505false);8506if (ret) {8507ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",8508arvif->vdev_id, ret);8509return ret;8510}8511} else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,8512&single_nss)) {8513rate = WMI_FIXED_RATE_NONE;8514nss = single_nss;8515} else {8516rate = WMI_FIXED_RATE_NONE;8517nss = min(ar->num_rf_chains,8518max(ath10k_mac_max_ht_nss(ht_mcs_mask),8519ath10k_mac_max_vht_nss(vht_mcs_mask)));85208521#if defined(__FreeBSD__)8522vht_pfr = 0;8523#endif8524if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask,8525allow_pfr)) {8526u8 vht_nss;85278528if (!allow_pfr || vht_num_rates != 1)8529return -EINVAL;85308531/* Reach here, firmware supports peer fixed rate and has8532* single vht rate, and don't update vif birate_mask, as8533* the rate only for specific peer.8534*/8535ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,8536&vht_pfr,8537&vht_nss,8538true);8539update_bitrate_mask = false;8540#if defined(__linux__)8541} else {8542vht_pfr = 0;8543#endif8544}85458546mutex_lock(&ar->conf_mutex);85478548if (update_bitrate_mask)8549arvif->bitrate_mask = *mask;8550arvif->vht_num_rates = vht_num_rates;8551arvif->vht_pfr = vht_pfr;8552ieee80211_iterate_stations_atomic(ar->hw,8553ath10k_mac_set_bitrate_mask_iter,8554arvif);85558556mutex_unlock(&ar->conf_mutex);8557}85588559mutex_lock(&ar->conf_mutex);85608561ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);8562if (ret) {8563ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",8564arvif->vdev_id, ret);8565goto exit;8566}85678568exit:8569mutex_unlock(&ar->conf_mutex);85708571return ret;8572}85738574static void ath10k_sta_rc_update(struct ieee80211_hw *hw,8575struct ieee80211_vif *vif,8576struct ieee80211_link_sta *link_sta,8577u32 changed)8578{8579struct ieee80211_sta *sta = link_sta->sta;8580struct ath10k *ar = hw->priv;8581struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;8582struct ath10k_vif *arvif = (void *)vif->drv_priv;8583struct ath10k_peer *peer;8584u32 bw, smps;85858586spin_lock_bh(&ar->data_lock);85878588peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);8589if (!peer) {8590spin_unlock_bh(&ar->data_lock);8591ath10k_warn(ar, "mac sta rc update failed to find peer %pM on vdev %i\n",8592sta->addr, arvif->vdev_id);8593return;8594}85958596ath10k_dbg(ar, ATH10K_DBG_STA,8597"mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",8598sta->addr, changed, sta->deflink.bandwidth,8599sta->deflink.rx_nss,8600sta->deflink.smps_mode);86018602if (changed & IEEE80211_RC_BW_CHANGED) {8603bw = WMI_PEER_CHWIDTH_20MHZ;86048605switch (sta->deflink.bandwidth) {8606case IEEE80211_STA_RX_BW_20:8607bw = WMI_PEER_CHWIDTH_20MHZ;8608break;8609case IEEE80211_STA_RX_BW_40:8610bw = WMI_PEER_CHWIDTH_40MHZ;8611break;8612case IEEE80211_STA_RX_BW_80:8613bw = WMI_PEER_CHWIDTH_80MHZ;8614break;8615case IEEE80211_STA_RX_BW_160:8616bw = WMI_PEER_CHWIDTH_160MHZ;8617break;8618default:8619ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",8620sta->deflink.bandwidth, sta->addr);8621bw = WMI_PEER_CHWIDTH_20MHZ;8622break;8623}86248625arsta->bw = bw;8626}86278628if (changed & IEEE80211_RC_NSS_CHANGED)8629arsta->nss = sta->deflink.rx_nss;86308631if (changed & IEEE80211_RC_SMPS_CHANGED) {8632smps = WMI_PEER_SMPS_PS_NONE;86338634switch (sta->deflink.smps_mode) {8635case IEEE80211_SMPS_AUTOMATIC:8636case IEEE80211_SMPS_OFF:8637smps = WMI_PEER_SMPS_PS_NONE;8638break;8639case IEEE80211_SMPS_STATIC:8640smps = WMI_PEER_SMPS_STATIC;8641break;8642case IEEE80211_SMPS_DYNAMIC:8643smps = WMI_PEER_SMPS_DYNAMIC;8644break;8645case IEEE80211_SMPS_NUM_MODES:8646ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",8647sta->deflink.smps_mode, sta->addr);8648smps = WMI_PEER_SMPS_PS_NONE;8649break;8650}86518652arsta->smps = smps;8653}86548655arsta->changed |= changed;86568657spin_unlock_bh(&ar->data_lock);86588659ieee80211_queue_work(hw, &arsta->update_wk);8660}86618662static void ath10k_offset_tsf(struct ieee80211_hw *hw,8663struct ieee80211_vif *vif, s64 tsf_offset)8664{8665struct ath10k *ar = hw->priv;8666struct ath10k_vif *arvif = (void *)vif->drv_priv;8667u32 offset, vdev_param;8668int ret;86698670if (tsf_offset < 0) {8671vdev_param = ar->wmi.vdev_param->dec_tsf;8672offset = -tsf_offset;8673} else {8674vdev_param = ar->wmi.vdev_param->inc_tsf;8675offset = tsf_offset;8676}86778678ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,8679vdev_param, offset);86808681if (ret && ret != -EOPNOTSUPP)8682ath10k_warn(ar, "failed to set tsf offset %d cmd %d: %d\n",8683offset, vdev_param, ret);8684}86858686static int ath10k_ampdu_action(struct ieee80211_hw *hw,8687struct ieee80211_vif *vif,8688struct ieee80211_ampdu_params *params)8689{8690struct ath10k *ar = hw->priv;8691struct ath10k_vif *arvif = (void *)vif->drv_priv;8692struct ieee80211_sta *sta = params->sta;8693enum ieee80211_ampdu_mlme_action action = params->action;8694u16 tid = params->tid;86958696ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ampdu vdev_id %i sta %pM tid %u action %d\n",8697arvif->vdev_id, sta->addr, tid, action);86988699switch (action) {8700case IEEE80211_AMPDU_RX_START:8701case IEEE80211_AMPDU_RX_STOP:8702/* HTT AddBa/DelBa events trigger mac80211 Rx BA session8703* creation/removal. Do we need to verify this?8704*/8705return 0;8706case IEEE80211_AMPDU_TX_START:8707case IEEE80211_AMPDU_TX_STOP_CONT:8708case IEEE80211_AMPDU_TX_STOP_FLUSH:8709case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:8710case IEEE80211_AMPDU_TX_OPERATIONAL:8711/* Firmware offloads Tx aggregation entirely so deny mac802118712* Tx aggregation requests.8713*/8714#if defined(__FreeBSD__)8715default:8716#endif8717return -EOPNOTSUPP;8718}87198720return -EINVAL;8721}87228723static void8724ath10k_mac_update_rx_channel(struct ath10k *ar,8725struct ieee80211_chanctx_conf *ctx,8726struct ieee80211_vif_chanctx_switch *vifs,8727int n_vifs)8728{8729struct cfg80211_chan_def *def = NULL;87308731/* Both locks are required because ar->rx_channel is modified. This8732* allows readers to hold either lock.8733*/8734lockdep_assert_held(&ar->conf_mutex);8735lockdep_assert_held(&ar->data_lock);87368737WARN_ON(ctx && vifs);8738WARN_ON(vifs && !n_vifs);87398740/* FIXME: Sort of an optimization and a workaround. Peers and vifs are8741* on a linked list now. Doing a lookup peer -> vif -> chanctx for each8742* ppdu on Rx may reduce performance on low-end systems. It should be8743* possible to make tables/hashmaps to speed the lookup up (be vary of8744* cpu data cache lines though regarding sizes) but to keep the initial8745* implementation simple and less intrusive fallback to the slow lookup8746* only for multi-channel cases. Single-channel cases will remain to8747* use the old channel derival and thus performance should not be8748* affected much.8749*/8750rcu_read_lock();8751if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {8752ieee80211_iter_chan_contexts_atomic(ar->hw,8753ath10k_mac_get_any_chandef_iter,8754&def);87558756if (vifs)8757def = &vifs[0].new_ctx->def;87588759ar->rx_channel = def->chan;8760} else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||8761(ctx && (ar->state == ATH10K_STATE_RESTARTED))) {8762/* During driver restart due to firmware assert, since mac802118763* already has valid channel context for given radio, channel8764* context iteration return num_chanctx > 0. So fix rx_channel8765* when restart is in progress.8766*/8767ar->rx_channel = ctx->def.chan;8768} else {8769ar->rx_channel = NULL;8770}8771rcu_read_unlock();8772}87738774static void8775ath10k_mac_update_vif_chan(struct ath10k *ar,8776struct ieee80211_vif_chanctx_switch *vifs,8777int n_vifs)8778{8779struct ath10k_vif *arvif;8780int ret;8781int i;87828783lockdep_assert_held(&ar->conf_mutex);87848785/* First stop monitor interface. Some FW versions crash if there's a8786* lone monitor interface.8787*/8788if (ar->monitor_started)8789ath10k_monitor_stop(ar);87908791for (i = 0; i < n_vifs; i++) {8792arvif = (void *)vifs[i].vif->drv_priv;87938794ath10k_dbg(ar, ATH10K_DBG_MAC,8795"mac chanctx switch vdev_id %i freq %u->%u width %d->%d\n",8796arvif->vdev_id,8797vifs[i].old_ctx->def.chan->center_freq,8798vifs[i].new_ctx->def.chan->center_freq,8799vifs[i].old_ctx->def.width,8800vifs[i].new_ctx->def.width);88018802if (WARN_ON(!arvif->is_started))8803continue;88048805if (WARN_ON(!arvif->is_up))8806continue;88078808ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);8809if (ret) {8810ath10k_warn(ar, "failed to down vdev %d: %d\n",8811arvif->vdev_id, ret);8812continue;8813}8814}88158816/* All relevant vdevs are downed and associated channel resources8817* should be available for the channel switch now.8818*/88198820spin_lock_bh(&ar->data_lock);8821ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);8822spin_unlock_bh(&ar->data_lock);88238824for (i = 0; i < n_vifs; i++) {8825arvif = (void *)vifs[i].vif->drv_priv;88268827if (WARN_ON(!arvif->is_started))8828continue;88298830if (WARN_ON(!arvif->is_up))8831continue;88328833ret = ath10k_mac_setup_bcn_tmpl(arvif);8834if (ret)8835ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",8836ret);88378838ret = ath10k_mac_setup_prb_tmpl(arvif);8839if (ret)8840ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",8841ret);88428843ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);8844if (ret) {8845ath10k_warn(ar, "failed to restart vdev %d: %d\n",8846arvif->vdev_id, ret);8847continue;8848}88498850ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,8851arvif->bssid);8852if (ret) {8853ath10k_warn(ar, "failed to bring vdev up %d: %d\n",8854arvif->vdev_id, ret);8855continue;8856}8857}88588859ath10k_monitor_recalc(ar);8860}88618862static int8863ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,8864struct ieee80211_chanctx_conf *ctx)8865{8866struct ath10k *ar = hw->priv;88678868ath10k_dbg(ar, ATH10K_DBG_MAC,8869"mac chanctx add freq %u width %d ptr %p\n",8870ctx->def.chan->center_freq, ctx->def.width, ctx);88718872mutex_lock(&ar->conf_mutex);88738874spin_lock_bh(&ar->data_lock);8875ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);8876spin_unlock_bh(&ar->data_lock);88778878ath10k_recalc_radar_detection(ar);8879ath10k_monitor_recalc(ar);88808881mutex_unlock(&ar->conf_mutex);88828883return 0;8884}88858886static void8887ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,8888struct ieee80211_chanctx_conf *ctx)8889{8890struct ath10k *ar = hw->priv;88918892ath10k_dbg(ar, ATH10K_DBG_MAC,8893"mac chanctx remove freq %u width %d ptr %p\n",8894ctx->def.chan->center_freq, ctx->def.width, ctx);88958896mutex_lock(&ar->conf_mutex);88978898spin_lock_bh(&ar->data_lock);8899ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);8900spin_unlock_bh(&ar->data_lock);89018902ath10k_recalc_radar_detection(ar);8903ath10k_monitor_recalc(ar);89048905mutex_unlock(&ar->conf_mutex);8906}89078908struct ath10k_mac_change_chanctx_arg {8909struct ieee80211_chanctx_conf *ctx;8910struct ieee80211_vif_chanctx_switch *vifs;8911int n_vifs;8912int next_vif;8913};89148915static void8916ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,8917struct ieee80211_vif *vif)8918{8919struct ath10k_mac_change_chanctx_arg *arg = data;89208921if (rcu_access_pointer(vif->bss_conf.chanctx_conf) != arg->ctx)8922return;89238924arg->n_vifs++;8925}89268927static void8928ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,8929struct ieee80211_vif *vif)8930{8931struct ath10k_mac_change_chanctx_arg *arg = data;8932struct ieee80211_chanctx_conf *ctx;89338934ctx = rcu_access_pointer(vif->bss_conf.chanctx_conf);8935if (ctx != arg->ctx)8936return;89378938if (WARN_ON(arg->next_vif == arg->n_vifs))8939return;89408941arg->vifs[arg->next_vif].vif = vif;8942arg->vifs[arg->next_vif].old_ctx = ctx;8943arg->vifs[arg->next_vif].new_ctx = ctx;8944arg->next_vif++;8945}89468947static void8948ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,8949struct ieee80211_chanctx_conf *ctx,8950u32 changed)8951{8952struct ath10k *ar = hw->priv;8953struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };89548955mutex_lock(&ar->conf_mutex);89568957ath10k_dbg(ar, ATH10K_DBG_MAC,8958"mac chanctx change freq %u width %d ptr %p changed %x\n",8959ctx->def.chan->center_freq, ctx->def.width, ctx, changed);89608961/* This shouldn't really happen because channel switching should use8962* switch_vif_chanctx().8963*/8964if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))8965goto unlock;89668967if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {8968ieee80211_iterate_active_interfaces_atomic(8969hw,8970ATH10K_ITER_NORMAL_FLAGS,8971ath10k_mac_change_chanctx_cnt_iter,8972&arg);8973if (arg.n_vifs == 0)8974goto radar;89758976arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),8977GFP_KERNEL);8978if (!arg.vifs)8979goto radar;89808981ieee80211_iterate_active_interfaces_atomic(8982hw,8983ATH10K_ITER_NORMAL_FLAGS,8984ath10k_mac_change_chanctx_fill_iter,8985&arg);8986ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);8987kfree(arg.vifs);8988}89898990radar:8991ath10k_recalc_radar_detection(ar);89928993/* FIXME: How to configure Rx chains properly? */89948995/* No other actions are actually necessary. Firmware maintains channel8996* definitions per vdev internally and there's no host-side channel8997* context abstraction to configure, e.g. channel width.8998*/89999000unlock:9001mutex_unlock(&ar->conf_mutex);9002}90039004static int9005ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,9006struct ieee80211_vif *vif,9007struct ieee80211_bss_conf *link_conf,9008struct ieee80211_chanctx_conf *ctx)9009{9010struct ath10k *ar = hw->priv;9011struct ath10k_vif *arvif = (void *)vif->drv_priv;9012int ret;90139014mutex_lock(&ar->conf_mutex);90159016ath10k_dbg(ar, ATH10K_DBG_MAC,9017"mac chanctx assign ptr %p vdev_id %i\n",9018ctx, arvif->vdev_id);90199020if (WARN_ON(arvif->is_started)) {9021mutex_unlock(&ar->conf_mutex);9022return -EBUSY;9023}90249025ret = ath10k_vdev_start(arvif, &ctx->def);9026if (ret) {9027ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",9028arvif->vdev_id, vif->addr,9029ctx->def.chan->center_freq, ret);9030goto err;9031}90329033arvif->is_started = true;90349035ret = ath10k_mac_vif_setup_ps(arvif);9036if (ret) {9037ath10k_warn(ar, "failed to update vdev %i ps: %d\n",9038arvif->vdev_id, ret);9039goto err_stop;9040}90419042if (vif->type == NL80211_IFTYPE_MONITOR) {9043ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);9044if (ret) {9045ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",9046arvif->vdev_id, ret);9047goto err_stop;9048}90499050arvif->is_up = true;9051}90529053if (ath10k_mac_can_set_cts_prot(arvif)) {9054ret = ath10k_mac_set_cts_prot(arvif);9055if (ret)9056ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",9057arvif->vdev_id, ret);9058}90599060if (ath10k_peer_stats_enabled(ar) &&9061ar->hw_params.tx_stats_over_pktlog) {9062ar->pktlog_filter |= ATH10K_PKTLOG_PEER_STATS;9063ret = ath10k_wmi_pdev_pktlog_enable(ar,9064ar->pktlog_filter);9065if (ret) {9066ath10k_warn(ar, "failed to enable pktlog %d\n", ret);9067goto err_stop;9068}9069}90709071mutex_unlock(&ar->conf_mutex);9072return 0;90739074err_stop:9075ath10k_vdev_stop(arvif);9076arvif->is_started = false;9077ath10k_mac_vif_setup_ps(arvif);90789079err:9080mutex_unlock(&ar->conf_mutex);9081return ret;9082}90839084static void9085ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,9086struct ieee80211_vif *vif,9087struct ieee80211_bss_conf *link_conf,9088struct ieee80211_chanctx_conf *ctx)9089{9090struct ath10k *ar = hw->priv;9091struct ath10k_vif *arvif = (void *)vif->drv_priv;9092int ret;90939094mutex_lock(&ar->conf_mutex);90959096ath10k_dbg(ar, ATH10K_DBG_MAC,9097"mac chanctx unassign ptr %p vdev_id %i\n",9098ctx, arvif->vdev_id);90999100WARN_ON(!arvif->is_started);91019102if (vif->type == NL80211_IFTYPE_MONITOR) {9103WARN_ON(!arvif->is_up);91049105ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);9106if (ret)9107ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",9108arvif->vdev_id, ret);91099110arvif->is_up = false;9111}91129113ret = ath10k_vdev_stop(arvif);9114if (ret)9115ath10k_warn(ar, "failed to stop vdev %i: %d\n",9116arvif->vdev_id, ret);91179118arvif->is_started = false;91199120mutex_unlock(&ar->conf_mutex);9121}91229123static int9124ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,9125struct ieee80211_vif_chanctx_switch *vifs,9126int n_vifs,9127enum ieee80211_chanctx_switch_mode mode)9128{9129struct ath10k *ar = hw->priv;91309131mutex_lock(&ar->conf_mutex);91329133ath10k_dbg(ar, ATH10K_DBG_MAC,9134"mac chanctx switch n_vifs %d mode %d\n",9135n_vifs, mode);9136ath10k_mac_update_vif_chan(ar, vifs, n_vifs);91379138mutex_unlock(&ar->conf_mutex);9139return 0;9140}91419142static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,9143struct ieee80211_vif *vif,9144struct ieee80211_sta *sta)9145{9146struct ath10k *ar;9147struct ath10k_peer *peer;91489149ar = hw->priv;91509151list_for_each_entry(peer, &ar->peers, list)9152if (peer->sta == sta)9153peer->removed = true;9154}91559156/* HT MCS parameters with Nss = 1 */9157static const struct ath10k_index_ht_data_rate_type supported_ht_mcs_rate_nss1[] = {9158/* MCS L20 L40 S20 S40 */9159{0, { 65, 135, 72, 150} },9160{1, { 130, 270, 144, 300} },9161{2, { 195, 405, 217, 450} },9162{3, { 260, 540, 289, 600} },9163{4, { 390, 810, 433, 900} },9164{5, { 520, 1080, 578, 1200} },9165{6, { 585, 1215, 650, 1350} },9166{7, { 650, 1350, 722, 1500} }9167};91689169/* HT MCS parameters with Nss = 2 */9170static const struct ath10k_index_ht_data_rate_type supported_ht_mcs_rate_nss2[] = {9171/* MCS L20 L40 S20 S40 */9172{0, {130, 270, 144, 300} },9173{1, {260, 540, 289, 600} },9174{2, {390, 810, 433, 900} },9175{3, {520, 1080, 578, 1200} },9176{4, {780, 1620, 867, 1800} },9177{5, {1040, 2160, 1156, 2400} },9178{6, {1170, 2430, 1300, 2700} },9179{7, {1300, 2700, 1444, 3000} }9180};91819182/* MCS parameters with Nss = 1 */9183static const struct ath10k_index_vht_data_rate_type supported_vht_mcs_rate_nss1[] = {9184/* MCS L80 S80 L40 S40 L20 S20 */9185{0, {293, 325}, {135, 150}, {65, 72} },9186{1, {585, 650}, {270, 300}, {130, 144} },9187{2, {878, 975}, {405, 450}, {195, 217} },9188{3, {1170, 1300}, {540, 600}, {260, 289} },9189{4, {1755, 1950}, {810, 900}, {390, 433} },9190{5, {2340, 2600}, {1080, 1200}, {520, 578} },9191{6, {2633, 2925}, {1215, 1350}, {585, 650} },9192{7, {2925, 3250}, {1350, 1500}, {650, 722} },9193{8, {3510, 3900}, {1620, 1800}, {780, 867} },9194{9, {3900, 4333}, {1800, 2000}, {865, 960} }9195};91969197/*MCS parameters with Nss = 2 */9198static const struct ath10k_index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = {9199/* MCS L80 S80 L40 S40 L20 S20 */9200{0, {585, 650}, {270, 300}, {130, 144} },9201{1, {1170, 1300}, {540, 600}, {260, 289} },9202{2, {1755, 1950}, {810, 900}, {390, 433} },9203{3, {2340, 2600}, {1080, 1200}, {520, 578} },9204{4, {3510, 3900}, {1620, 1800}, {780, 867} },9205{5, {4680, 5200}, {2160, 2400}, {1040, 1156} },9206{6, {5265, 5850}, {2430, 2700}, {1170, 1300} },9207{7, {5850, 6500}, {2700, 3000}, {1300, 1444} },9208{8, {7020, 7800}, {3240, 3600}, {1560, 1733} },9209{9, {7800, 8667}, {3600, 4000}, {1730, 1920} }9210};92119212static void ath10k_mac_get_rate_flags_ht(struct ath10k *ar, u32 rate, u8 nss, u8 mcs,9213u8 *flags, u8 *bw)9214{9215#if defined(__linux__)9216struct ath10k_index_ht_data_rate_type *mcs_rate;9217#elif defined(__FreeBSD__)9218const struct ath10k_index_ht_data_rate_type *mcs_rate;9219#endif9220u8 index;9221size_t len_nss1 = ARRAY_SIZE(supported_ht_mcs_rate_nss1);9222size_t len_nss2 = ARRAY_SIZE(supported_ht_mcs_rate_nss2);92239224if (mcs >= (len_nss1 + len_nss2)) {9225ath10k_warn(ar, "not supported mcs %d in current rate table", mcs);9226return;9227}92289229#if defined(__linux__)9230mcs_rate = (struct ath10k_index_ht_data_rate_type *)9231#elif defined(__FreeBSD__)9232mcs_rate = (const struct ath10k_index_ht_data_rate_type *)9233#endif9234((nss == 1) ? &supported_ht_mcs_rate_nss1 :9235&supported_ht_mcs_rate_nss2);92369237if (mcs >= len_nss1)9238index = mcs - len_nss1;9239else9240index = mcs;92419242if (rate == mcs_rate[index].supported_rate[0]) {9243*bw = RATE_INFO_BW_20;9244} else if (rate == mcs_rate[index].supported_rate[1]) {9245*bw |= RATE_INFO_BW_40;9246} else if (rate == mcs_rate[index].supported_rate[2]) {9247*bw |= RATE_INFO_BW_20;9248*flags |= RATE_INFO_FLAGS_SHORT_GI;9249} else if (rate == mcs_rate[index].supported_rate[3]) {9250*bw |= RATE_INFO_BW_40;9251*flags |= RATE_INFO_FLAGS_SHORT_GI;9252} else {9253ath10k_warn(ar, "invalid ht params rate %d 100kbps nss %d mcs %d",9254rate, nss, mcs);9255}9256}92579258static void ath10k_mac_get_rate_flags_vht(struct ath10k *ar, u32 rate, u8 nss, u8 mcs,9259u8 *flags, u8 *bw)9260{9261#if defined(__linux__)9262struct ath10k_index_vht_data_rate_type *mcs_rate;92639264mcs_rate = (struct ath10k_index_vht_data_rate_type *)9265#elif defined(__FreeBSD__)9266const struct ath10k_index_vht_data_rate_type *mcs_rate;92679268mcs_rate = (const struct ath10k_index_vht_data_rate_type *)9269#endif9270((nss == 1) ? &supported_vht_mcs_rate_nss1 :9271&supported_vht_mcs_rate_nss2);92729273if (rate == mcs_rate[mcs].supported_VHT80_rate[0]) {9274*bw = RATE_INFO_BW_80;9275} else if (rate == mcs_rate[mcs].supported_VHT80_rate[1]) {9276*bw = RATE_INFO_BW_80;9277*flags |= RATE_INFO_FLAGS_SHORT_GI;9278} else if (rate == mcs_rate[mcs].supported_VHT40_rate[0]) {9279*bw = RATE_INFO_BW_40;9280} else if (rate == mcs_rate[mcs].supported_VHT40_rate[1]) {9281*bw = RATE_INFO_BW_40;9282*flags |= RATE_INFO_FLAGS_SHORT_GI;9283} else if (rate == mcs_rate[mcs].supported_VHT20_rate[0]) {9284*bw = RATE_INFO_BW_20;9285} else if (rate == mcs_rate[mcs].supported_VHT20_rate[1]) {9286*bw = RATE_INFO_BW_20;9287*flags |= RATE_INFO_FLAGS_SHORT_GI;9288} else {9289ath10k_warn(ar, "invalid vht params rate %d 100kbps nss %d mcs %d",9290rate, nss, mcs);9291}9292}92939294static void ath10k_mac_get_rate_flags(struct ath10k *ar, u32 rate,9295enum ath10k_phy_mode mode, u8 nss, u8 mcs,9296u8 *flags, u8 *bw)9297{9298if (mode == ATH10K_PHY_MODE_HT) {9299*flags = RATE_INFO_FLAGS_MCS;9300ath10k_mac_get_rate_flags_ht(ar, rate, nss, mcs, flags, bw);9301} else if (mode == ATH10K_PHY_MODE_VHT) {9302*flags = RATE_INFO_FLAGS_VHT_MCS;9303ath10k_mac_get_rate_flags_vht(ar, rate, nss, mcs, flags, bw);9304}9305}93069307static void ath10k_mac_parse_bitrate(struct ath10k *ar, u32 rate_code,9308u32 bitrate_kbps, struct rate_info *rate)9309{9310enum ath10k_phy_mode mode = ATH10K_PHY_MODE_LEGACY;9311enum wmi_rate_preamble preamble = WMI_TLV_GET_HW_RC_PREAM_V1(rate_code);9312u8 nss = WMI_TLV_GET_HW_RC_NSS_V1(rate_code) + 1;9313u8 mcs = WMI_TLV_GET_HW_RC_RATE_V1(rate_code);9314u8 flags = 0, bw = 0;93159316ath10k_dbg(ar, ATH10K_DBG_MAC, "mac parse rate code 0x%x bitrate %d kbps\n",9317rate_code, bitrate_kbps);93189319if (preamble == WMI_RATE_PREAMBLE_HT)9320mode = ATH10K_PHY_MODE_HT;9321else if (preamble == WMI_RATE_PREAMBLE_VHT)9322mode = ATH10K_PHY_MODE_VHT;93239324ath10k_mac_get_rate_flags(ar, bitrate_kbps / 100, mode, nss, mcs, &flags, &bw);93259326ath10k_dbg(ar, ATH10K_DBG_MAC,9327"mac parse bitrate preamble %d mode %d nss %d mcs %d flags %x bw %d\n",9328preamble, mode, nss, mcs, flags, bw);93299330rate->flags = flags;9331rate->bw = bw;9332rate->legacy = bitrate_kbps / 100;9333rate->nss = nss;9334rate->mcs = mcs;9335}93369337static void ath10k_mac_sta_get_peer_stats_info(struct ath10k *ar,9338struct ieee80211_sta *sta,9339struct station_info *sinfo)9340{9341struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;9342struct ath10k_peer *peer;9343unsigned long time_left;9344int ret;93459346if (!(ar->hw_params.supports_peer_stats_info &&9347arsta->arvif->vdev_type == WMI_VDEV_TYPE_STA))9348return;93499350spin_lock_bh(&ar->data_lock);9351peer = ath10k_peer_find(ar, arsta->arvif->vdev_id, sta->addr);9352spin_unlock_bh(&ar->data_lock);9353if (!peer)9354return;93559356reinit_completion(&ar->peer_stats_info_complete);93579358ret = ath10k_wmi_request_peer_stats_info(ar,9359arsta->arvif->vdev_id,9360WMI_REQUEST_ONE_PEER_STATS_INFO,9361arsta->arvif->bssid,93620);9363if (ret && ret != -EOPNOTSUPP) {9364ath10k_warn(ar, "could not request peer stats info: %d\n", ret);9365return;9366}93679368time_left = wait_for_completion_timeout(&ar->peer_stats_info_complete, 3 * HZ);9369if (time_left == 0) {9370ath10k_warn(ar, "timed out waiting peer stats info\n");9371return;9372}93739374if (arsta->rx_rate_code != 0 && arsta->rx_bitrate_kbps != 0) {9375ath10k_mac_parse_bitrate(ar, arsta->rx_rate_code,9376arsta->rx_bitrate_kbps,9377&sinfo->rxrate);93789379sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);9380arsta->rx_rate_code = 0;9381arsta->rx_bitrate_kbps = 0;9382}93839384if (arsta->tx_rate_code != 0 && arsta->tx_bitrate_kbps != 0) {9385ath10k_mac_parse_bitrate(ar, arsta->tx_rate_code,9386arsta->tx_bitrate_kbps,9387&sinfo->txrate);93889389sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);9390arsta->tx_rate_code = 0;9391arsta->tx_bitrate_kbps = 0;9392}9393}93949395static void ath10k_sta_statistics(struct ieee80211_hw *hw,9396struct ieee80211_vif *vif,9397struct ieee80211_sta *sta,9398struct station_info *sinfo)9399{9400struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;9401struct ath10k *ar = arsta->arvif->ar;94029403if (!ath10k_peer_stats_enabled(ar))9404return;94059406mutex_lock(&ar->conf_mutex);9407ath10k_debug_fw_stats_request(ar);9408mutex_unlock(&ar->conf_mutex);94099410sinfo->rx_duration = arsta->rx_duration;9411sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);94129413if (arsta->txrate.legacy || arsta->txrate.nss) {9414if (arsta->txrate.legacy) {9415sinfo->txrate.legacy = arsta->txrate.legacy;9416} else {9417sinfo->txrate.mcs = arsta->txrate.mcs;9418sinfo->txrate.nss = arsta->txrate.nss;9419sinfo->txrate.bw = arsta->txrate.bw;9420}9421sinfo->txrate.flags = arsta->txrate.flags;9422sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);9423}94249425if (ar->htt.disable_tx_comp) {9426sinfo->tx_failed = arsta->tx_failed;9427sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);9428}94299430sinfo->tx_retries = arsta->tx_retries;9431sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);94329433ath10k_mac_sta_get_peer_stats_info(ar, sta, sinfo);9434}94359436static int ath10k_mac_op_set_tid_config(struct ieee80211_hw *hw,9437struct ieee80211_vif *vif,9438struct ieee80211_sta *sta,9439struct cfg80211_tid_config *tid_config)9440{9441struct ath10k *ar = hw->priv;9442struct ath10k_vif *arvif = (void *)vif->drv_priv;9443struct ath10k_mac_iter_tid_conf_data data = {};9444struct wmi_per_peer_per_tid_cfg_arg arg = {};9445int ret, i;94469447mutex_lock(&ar->conf_mutex);9448arg.vdev_id = arvif->vdev_id;94499450arvif->tids_rst = 0;9451memset(arvif->tid_conf_changed, 0, sizeof(arvif->tid_conf_changed));94529453for (i = 0; i < tid_config->n_tid_conf; i++) {9454ret = ath10k_mac_parse_tid_config(ar, sta, vif,9455&tid_config->tid_conf[i],9456&arg);9457if (ret)9458goto exit;9459}94609461ret = 0;94629463if (sta)9464goto exit;94659466arvif->tids_rst = 0;9467data.curr_vif = vif;9468data.ar = ar;94699470ieee80211_iterate_stations_atomic(hw, ath10k_mac_vif_stations_tid_conf,9471&data);94729473exit:9474mutex_unlock(&ar->conf_mutex);9475return ret;9476}94779478static int ath10k_mac_op_reset_tid_config(struct ieee80211_hw *hw,9479struct ieee80211_vif *vif,9480struct ieee80211_sta *sta,9481u8 tids)9482{9483struct ath10k_vif *arvif = (void *)vif->drv_priv;9484struct ath10k_mac_iter_tid_conf_data data = {};9485struct ath10k *ar = hw->priv;9486int ret = 0;94879488mutex_lock(&ar->conf_mutex);94899490if (sta) {9491arvif->tids_rst = 0;9492ret = ath10k_mac_reset_tid_config(ar, sta, arvif, tids);9493goto exit;9494}94959496arvif->tids_rst = tids;9497data.curr_vif = vif;9498data.ar = ar;9499ieee80211_iterate_stations_atomic(hw, ath10k_mac_vif_stations_tid_conf,9500&data);95019502exit:9503mutex_unlock(&ar->conf_mutex);9504return ret;9505}95069507static const struct ieee80211_ops ath10k_ops = {9508.tx = ath10k_mac_op_tx,9509.wake_tx_queue = ath10k_mac_op_wake_tx_queue,9510.start = ath10k_start,9511.stop = ath10k_stop,9512.config = ath10k_config,9513.add_interface = ath10k_add_interface,9514.update_vif_offload = ath10k_update_vif_offload,9515.remove_interface = ath10k_remove_interface,9516.configure_filter = ath10k_configure_filter,9517.bss_info_changed = ath10k_bss_info_changed,9518.set_coverage_class = ath10k_mac_op_set_coverage_class,9519.hw_scan = ath10k_hw_scan,9520.cancel_hw_scan = ath10k_cancel_hw_scan,9521.set_key = ath10k_set_key,9522.set_default_unicast_key = ath10k_set_default_unicast_key,9523.sta_state = ath10k_sta_state,9524.sta_set_txpwr = ath10k_sta_set_txpwr,9525.conf_tx = ath10k_conf_tx,9526.remain_on_channel = ath10k_remain_on_channel,9527.cancel_remain_on_channel = ath10k_cancel_remain_on_channel,9528.set_rts_threshold = ath10k_set_rts_threshold,9529.set_frag_threshold = ath10k_mac_op_set_frag_threshold,9530.flush = ath10k_flush,9531.tx_last_beacon = ath10k_tx_last_beacon,9532.set_antenna = ath10k_set_antenna,9533.get_antenna = ath10k_get_antenna,9534.reconfig_complete = ath10k_reconfig_complete,9535.get_survey = ath10k_get_survey,9536.set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,9537.link_sta_rc_update = ath10k_sta_rc_update,9538.offset_tsf = ath10k_offset_tsf,9539.ampdu_action = ath10k_ampdu_action,9540.get_et_sset_count = ath10k_debug_get_et_sset_count,9541.get_et_stats = ath10k_debug_get_et_stats,9542.get_et_strings = ath10k_debug_get_et_strings,9543.add_chanctx = ath10k_mac_op_add_chanctx,9544.remove_chanctx = ath10k_mac_op_remove_chanctx,9545.change_chanctx = ath10k_mac_op_change_chanctx,9546.assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,9547.unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,9548.switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,9549.sta_pre_rcu_remove = ath10k_mac_op_sta_pre_rcu_remove,9550.sta_statistics = ath10k_sta_statistics,9551.set_tid_config = ath10k_mac_op_set_tid_config,9552.reset_tid_config = ath10k_mac_op_reset_tid_config,95539554CFG80211_TESTMODE_CMD(ath10k_tm_cmd)95559556#ifdef CONFIG_PM9557.suspend = ath10k_wow_op_suspend,9558.resume = ath10k_wow_op_resume,9559.set_wakeup = ath10k_wow_op_set_wakeup,9560#endif9561#ifdef CONFIG_MAC80211_DEBUGFS9562.sta_add_debugfs = ath10k_sta_add_debugfs,9563#endif9564.set_sar_specs = ath10k_mac_set_sar_specs,9565};95669567#define CHAN2G(_channel, _freq, _flags) { \9568.band = NL80211_BAND_2GHZ, \9569.hw_value = (_channel), \9570.center_freq = (_freq), \9571.flags = (_flags), \9572.max_antenna_gain = 0, \9573.max_power = 30, \9574}95759576#define CHAN5G(_channel, _freq, _flags) { \9577.band = NL80211_BAND_5GHZ, \9578.hw_value = (_channel), \9579.center_freq = (_freq), \9580.flags = (_flags), \9581.max_antenna_gain = 0, \9582.max_power = 30, \9583}95849585static const struct ieee80211_channel ath10k_2ghz_channels[] = {9586CHAN2G(1, 2412, 0),9587CHAN2G(2, 2417, 0),9588CHAN2G(3, 2422, 0),9589CHAN2G(4, 2427, 0),9590CHAN2G(5, 2432, 0),9591CHAN2G(6, 2437, 0),9592CHAN2G(7, 2442, 0),9593CHAN2G(8, 2447, 0),9594CHAN2G(9, 2452, 0),9595CHAN2G(10, 2457, 0),9596CHAN2G(11, 2462, 0),9597CHAN2G(12, 2467, 0),9598CHAN2G(13, 2472, 0),9599CHAN2G(14, 2484, 0),9600};96019602static const struct ieee80211_channel ath10k_5ghz_channels[] = {9603CHAN5G(36, 5180, 0),9604CHAN5G(40, 5200, 0),9605CHAN5G(44, 5220, 0),9606CHAN5G(48, 5240, 0),9607CHAN5G(52, 5260, 0),9608CHAN5G(56, 5280, 0),9609CHAN5G(60, 5300, 0),9610CHAN5G(64, 5320, 0),9611CHAN5G(100, 5500, 0),9612CHAN5G(104, 5520, 0),9613CHAN5G(108, 5540, 0),9614CHAN5G(112, 5560, 0),9615CHAN5G(116, 5580, 0),9616CHAN5G(120, 5600, 0),9617CHAN5G(124, 5620, 0),9618CHAN5G(128, 5640, 0),9619CHAN5G(132, 5660, 0),9620CHAN5G(136, 5680, 0),9621CHAN5G(140, 5700, 0),9622CHAN5G(144, 5720, 0),9623CHAN5G(149, 5745, 0),9624CHAN5G(153, 5765, 0),9625CHAN5G(157, 5785, 0),9626CHAN5G(161, 5805, 0),9627CHAN5G(165, 5825, 0),9628CHAN5G(169, 5845, 0),9629CHAN5G(173, 5865, 0),9630/* If you add more, you may need to change ATH10K_MAX_5G_CHAN */9631/* And you will definitely need to change ATH10K_NUM_CHANS in core.h */9632};96339634struct ath10k *ath10k_mac_create(size_t priv_size)9635{9636struct ieee80211_hw *hw;9637struct ieee80211_ops *ops;9638struct ath10k *ar;96399640ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);9641if (!ops)9642return NULL;96439644hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);9645if (!hw) {9646kfree(ops);9647return NULL;9648}96499650ar = hw->priv;9651ar->hw = hw;9652ar->ops = ops;96539654return ar;9655}96569657void ath10k_mac_destroy(struct ath10k *ar)9658{9659struct ieee80211_ops *ops = ar->ops;96609661ieee80211_free_hw(ar->hw);9662kfree(ops);9663}96649665static const struct ieee80211_iface_limit ath10k_if_limits[] = {9666{9667.max = 8,9668.types = BIT(NL80211_IFTYPE_STATION)9669| BIT(NL80211_IFTYPE_P2P_CLIENT)9670},9671{9672.max = 3,9673.types = BIT(NL80211_IFTYPE_P2P_GO)9674},9675{9676.max = 1,9677.types = BIT(NL80211_IFTYPE_P2P_DEVICE)9678},9679{9680.max = 7,9681.types = BIT(NL80211_IFTYPE_AP)9682#ifdef CONFIG_MAC80211_MESH9683| BIT(NL80211_IFTYPE_MESH_POINT)9684#endif9685},9686};96879688static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {9689{9690.max = 8,9691.types = BIT(NL80211_IFTYPE_AP)9692#ifdef CONFIG_MAC80211_MESH9693| BIT(NL80211_IFTYPE_MESH_POINT)9694#endif9695},9696{9697.max = 1,9698.types = BIT(NL80211_IFTYPE_STATION)9699},9700};97019702static const struct ieee80211_iface_combination ath10k_if_comb[] = {9703{9704.limits = ath10k_if_limits,9705.n_limits = ARRAY_SIZE(ath10k_if_limits),9706.max_interfaces = 8,9707.num_different_channels = 1,9708.beacon_int_infra_match = true,9709},9710};97119712static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {9713{9714.limits = ath10k_10x_if_limits,9715.n_limits = ARRAY_SIZE(ath10k_10x_if_limits),9716.max_interfaces = 8,9717.num_different_channels = 1,9718.beacon_int_infra_match = true,9719.beacon_int_min_gcd = 1,9720#ifdef CONFIG_ATH10K_DFS_CERTIFIED9721.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |9722BIT(NL80211_CHAN_WIDTH_20) |9723BIT(NL80211_CHAN_WIDTH_40) |9724BIT(NL80211_CHAN_WIDTH_80),9725#endif9726},9727};97289729static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {9730{9731.max = 2,9732.types = BIT(NL80211_IFTYPE_STATION),9733},9734{9735.max = 2,9736.types = BIT(NL80211_IFTYPE_AP) |9737#ifdef CONFIG_MAC80211_MESH9738BIT(NL80211_IFTYPE_MESH_POINT) |9739#endif9740BIT(NL80211_IFTYPE_P2P_CLIENT) |9741BIT(NL80211_IFTYPE_P2P_GO),9742},9743{9744.max = 1,9745.types = BIT(NL80211_IFTYPE_P2P_DEVICE),9746},9747};97489749static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {9750{9751.max = 2,9752.types = BIT(NL80211_IFTYPE_STATION),9753},9754{9755.max = 2,9756.types = BIT(NL80211_IFTYPE_P2P_CLIENT),9757},9758{9759.max = 1,9760.types = BIT(NL80211_IFTYPE_AP) |9761#ifdef CONFIG_MAC80211_MESH9762BIT(NL80211_IFTYPE_MESH_POINT) |9763#endif9764BIT(NL80211_IFTYPE_P2P_GO),9765},9766{9767.max = 1,9768.types = BIT(NL80211_IFTYPE_P2P_DEVICE),9769},9770};97719772static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {9773{9774.max = 1,9775.types = BIT(NL80211_IFTYPE_STATION),9776},9777{9778.max = 1,9779.types = BIT(NL80211_IFTYPE_ADHOC),9780},9781};97829783/* FIXME: This is not thoroughly tested. These combinations may over- or9784* underestimate hw/fw capabilities.9785*/9786static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {9787{9788.limits = ath10k_tlv_if_limit,9789.num_different_channels = 1,9790.max_interfaces = 4,9791.n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),9792},9793{9794.limits = ath10k_tlv_if_limit_ibss,9795.num_different_channels = 1,9796.max_interfaces = 2,9797.n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),9798},9799};98009801static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {9802{9803.limits = ath10k_tlv_if_limit,9804.num_different_channels = 1,9805.max_interfaces = 4,9806.n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),9807},9808{9809.limits = ath10k_tlv_qcs_if_limit,9810.num_different_channels = 2,9811.max_interfaces = 4,9812.n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),9813},9814{9815.limits = ath10k_tlv_if_limit_ibss,9816.num_different_channels = 1,9817.max_interfaces = 2,9818.n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),9819},9820};98219822static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {9823{9824.max = 1,9825.types = BIT(NL80211_IFTYPE_STATION),9826},9827{9828.max = 16,9829.types = BIT(NL80211_IFTYPE_AP)9830#ifdef CONFIG_MAC80211_MESH9831| BIT(NL80211_IFTYPE_MESH_POINT)9832#endif9833},9834};98359836static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {9837{9838.limits = ath10k_10_4_if_limits,9839.n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),9840.max_interfaces = 16,9841.num_different_channels = 1,9842.beacon_int_infra_match = true,9843.beacon_int_min_gcd = 1,9844#ifdef CONFIG_ATH10K_DFS_CERTIFIED9845.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |9846BIT(NL80211_CHAN_WIDTH_20) |9847BIT(NL80211_CHAN_WIDTH_40) |9848BIT(NL80211_CHAN_WIDTH_80) |9849BIT(NL80211_CHAN_WIDTH_80P80) |9850BIT(NL80211_CHAN_WIDTH_160),9851#endif9852},9853};98549855static const struct9856ieee80211_iface_combination ath10k_10_4_bcn_int_if_comb[] = {9857{9858.limits = ath10k_10_4_if_limits,9859.n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),9860.max_interfaces = 16,9861.num_different_channels = 1,9862.beacon_int_infra_match = true,9863.beacon_int_min_gcd = 100,9864#ifdef CONFIG_ATH10K_DFS_CERTIFIED9865.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |9866BIT(NL80211_CHAN_WIDTH_20) |9867BIT(NL80211_CHAN_WIDTH_40) |9868BIT(NL80211_CHAN_WIDTH_80) |9869BIT(NL80211_CHAN_WIDTH_80P80) |9870BIT(NL80211_CHAN_WIDTH_160),9871#endif9872},9873};98749875static void ath10k_get_arvif_iter(void *data, u8 *mac,9876struct ieee80211_vif *vif)9877{9878struct ath10k_vif_iter *arvif_iter = data;9879struct ath10k_vif *arvif = (void *)vif->drv_priv;98809881if (arvif->vdev_id == arvif_iter->vdev_id)9882arvif_iter->arvif = arvif;9883}98849885struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)9886{9887struct ath10k_vif_iter arvif_iter;98889889memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));9890arvif_iter.vdev_id = vdev_id;98919892ieee80211_iterate_active_interfaces_atomic(ar->hw,9893ATH10K_ITER_RESUME_FLAGS,9894ath10k_get_arvif_iter,9895&arvif_iter);9896if (!arvif_iter.arvif) {9897ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);9898return NULL;9899}99009901return arvif_iter.arvif;9902}99039904#define WRD_METHOD "WRDD"9905#define WRDD_WIFI (0x07)99069907static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_object *wrdd)9908{9909union acpi_object *mcc_pkg;9910union acpi_object *domain_type;9911union acpi_object *mcc_value;9912u32 i;99139914if (wrdd->type != ACPI_TYPE_PACKAGE ||9915wrdd->package.count < 2 ||9916wrdd->package.elements[0].type != ACPI_TYPE_INTEGER ||9917wrdd->package.elements[0].integer.value != 0) {9918ath10k_warn(ar, "ignoring malformed/unsupported wrdd structure\n");9919return 0;9920}99219922for (i = 1; i < wrdd->package.count; ++i) {9923mcc_pkg = &wrdd->package.elements[i];99249925if (mcc_pkg->type != ACPI_TYPE_PACKAGE)9926continue;9927if (mcc_pkg->package.count < 2)9928continue;9929if (mcc_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||9930mcc_pkg->package.elements[1].type != ACPI_TYPE_INTEGER)9931continue;99329933domain_type = &mcc_pkg->package.elements[0];9934if (domain_type->integer.value != WRDD_WIFI)9935continue;99369937mcc_value = &mcc_pkg->package.elements[1];9938return mcc_value->integer.value;9939}9940return 0;9941}99429943static int ath10k_mac_get_wrdd_regulatory(struct ath10k *ar, u16 *rd)9944{9945acpi_handle root_handle;9946acpi_handle handle;9947struct acpi_buffer wrdd = {ACPI_ALLOCATE_BUFFER, NULL};9948acpi_status status;9949u32 alpha2_code;9950char alpha2[3];99519952root_handle = ACPI_HANDLE(ar->dev);9953if (!root_handle)9954return -EOPNOTSUPP;99559956status = acpi_get_handle(root_handle, (acpi_string)WRD_METHOD, &handle);9957if (ACPI_FAILURE(status)) {9958ath10k_dbg(ar, ATH10K_DBG_BOOT,9959"failed to get wrd method %d\n", status);9960return -EIO;9961}99629963status = acpi_evaluate_object(handle, NULL, NULL, &wrdd);9964if (ACPI_FAILURE(status)) {9965ath10k_dbg(ar, ATH10K_DBG_BOOT,9966"failed to call wrdc %d\n", status);9967return -EIO;9968}99699970alpha2_code = ath10k_mac_wrdd_get_mcc(ar, wrdd.pointer);9971kfree(wrdd.pointer);9972if (!alpha2_code)9973return -EIO;99749975alpha2[0] = (alpha2_code >> 8) & 0xff;9976alpha2[1] = (alpha2_code >> 0) & 0xff;9977alpha2[2] = '\0';99789979ath10k_dbg(ar, ATH10K_DBG_BOOT,9980"regulatory hint from WRDD (alpha2-code): %s\n", alpha2);99819982*rd = ath_regd_find_country_by_name(alpha2);9983if (*rd == 0xffff)9984return -EIO;99859986*rd |= COUNTRY_ERD_FLAG;9987return 0;9988}99899990static int ath10k_mac_init_rd(struct ath10k *ar)9991{9992int ret;9993u16 rd;99949995ret = ath10k_mac_get_wrdd_regulatory(ar, &rd);9996if (ret) {9997ath10k_dbg(ar, ATH10K_DBG_BOOT,9998"fallback to eeprom programmed regulatory settings\n");9999rd = ar->hw_eeprom_rd;10000}1000110002ar->ath_common.regulatory.current_rd = rd;10003return 0;10004}1000510006int ath10k_mac_register(struct ath10k *ar)10007{10008static const u32 cipher_suites[] = {10009WLAN_CIPHER_SUITE_WEP40,10010WLAN_CIPHER_SUITE_WEP104,10011WLAN_CIPHER_SUITE_TKIP,10012WLAN_CIPHER_SUITE_CCMP,1001310014/* Do not add hardware supported ciphers before this line.10015* Allow software encryption for all chips. Don't forget to10016* update n_cipher_suites below.10017*/10018WLAN_CIPHER_SUITE_AES_CMAC,10019WLAN_CIPHER_SUITE_BIP_CMAC_256,10020WLAN_CIPHER_SUITE_BIP_GMAC_128,10021WLAN_CIPHER_SUITE_BIP_GMAC_256,1002210023/* Only QCA99x0 and QCA4019 variants support GCMP-128, GCMP-25610024* and CCMP-256 in hardware.10025*/10026WLAN_CIPHER_SUITE_GCMP,10027WLAN_CIPHER_SUITE_GCMP_256,10028WLAN_CIPHER_SUITE_CCMP_256,10029};10030struct ieee80211_supported_band *band;10031void *channels;10032int ret;1003310034if (!is_valid_ether_addr(ar->mac_addr)) {10035ath10k_warn(ar, "invalid MAC address; choosing random\n");10036eth_random_addr(ar->mac_addr);10037}10038SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);1003910040SET_IEEE80211_DEV(ar->hw, ar->dev);1004110042BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +10043ARRAY_SIZE(ath10k_5ghz_channels)) !=10044ATH10K_NUM_CHANS);1004510046if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {10047channels = kmemdup(ath10k_2ghz_channels,10048sizeof(ath10k_2ghz_channels),10049GFP_KERNEL);10050if (!channels) {10051ret = -ENOMEM;10052goto err_free;10053}1005410055band = &ar->mac.sbands[NL80211_BAND_2GHZ];10056band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);10057band->channels = channels;1005810059if (ar->hw_params.cck_rate_map_rev2) {10060band->n_bitrates = ath10k_g_rates_rev2_size;10061band->bitrates = ath10k_g_rates_rev2;10062} else {10063band->n_bitrates = ath10k_g_rates_size;10064band->bitrates = ath10k_g_rates;10065}1006610067ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;10068}1006910070if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {10071channels = kmemdup(ath10k_5ghz_channels,10072sizeof(ath10k_5ghz_channels),10073GFP_KERNEL);10074if (!channels) {10075ret = -ENOMEM;10076goto err_free;10077}1007810079band = &ar->mac.sbands[NL80211_BAND_5GHZ];10080band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);10081band->channels = channels;10082band->n_bitrates = ath10k_a_rates_size;10083band->bitrates = ath10k_a_rates;10084ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;10085}1008610087wiphy_read_of_freq_limits(ar->hw->wiphy);10088ath10k_mac_setup_ht_vht_cap(ar);1008910090ar->hw->wiphy->interface_modes =10091BIT(NL80211_IFTYPE_STATION) |10092BIT(NL80211_IFTYPE_AP) |10093BIT(NL80211_IFTYPE_MESH_POINT);1009410095ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;10096ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;1009710098if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))10099ar->hw->wiphy->interface_modes |=10100BIT(NL80211_IFTYPE_P2P_DEVICE) |10101BIT(NL80211_IFTYPE_P2P_CLIENT) |10102BIT(NL80211_IFTYPE_P2P_GO);1010310104ieee80211_hw_set(ar->hw, SIGNAL_DBM);1010510106if (!test_bit(ATH10K_FW_FEATURE_NO_PS,10107ar->running_fw->fw_file.fw_features)) {10108ieee80211_hw_set(ar->hw, SUPPORTS_PS);10109ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);10110}1011110112ieee80211_hw_set(ar->hw, MFP_CAPABLE);10113ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);10114ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);10115ieee80211_hw_set(ar->hw, AP_LINK_PS);10116ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);10117ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);10118ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);10119ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);10120ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);10121ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);10122ieee80211_hw_set(ar->hw, QUEUE_CONTROL);10123ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);10124ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);1012510126if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))10127ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);1012810129ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;10130ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;1013110132if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)10133ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;1013410135if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {10136ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);10137ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);10138}1013910140ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;10141ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;1014210143if (test_bit(WMI_SERVICE_NLO, ar->wmi.svc_map)) {10144ar->hw->wiphy->max_sched_scan_ssids = WMI_PNO_MAX_SUPP_NETWORKS;10145ar->hw->wiphy->max_match_sets = WMI_PNO_MAX_SUPP_NETWORKS;10146ar->hw->wiphy->max_sched_scan_ie_len = WMI_PNO_MAX_IE_LENGTH;10147ar->hw->wiphy->max_sched_scan_plans = WMI_PNO_MAX_SCHED_SCAN_PLANS;10148ar->hw->wiphy->max_sched_scan_plan_interval =10149WMI_PNO_MAX_SCHED_SCAN_PLAN_INT;10150ar->hw->wiphy->max_sched_scan_plan_iterations =10151WMI_PNO_MAX_SCHED_SCAN_PLAN_ITRNS;10152ar->hw->wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;10153}1015410155ar->hw->vif_data_size = sizeof(struct ath10k_vif);10156ar->hw->sta_data_size = sizeof(struct ath10k_sta);10157ar->hw->txq_data_size = sizeof(struct ath10k_txq);1015810159ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;1016010161if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {10162ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;1016310164/* Firmware delivers WPS/P2P Probe Requests frames to driver so10165* that userspace (e.g. wpa_supplicant/hostapd) can generate10166* correct Probe Responses. This is more of a hack advert..10167*/10168ar->hw->wiphy->probe_resp_offload |=10169NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |10170NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |10171NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;10172}1017310174if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map) ||10175test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, ar->wmi.svc_map)) {10176ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;10177if (test_bit(WMI_SERVICE_TDLS_WIDER_BANDWIDTH, ar->wmi.svc_map))10178ieee80211_hw_set(ar->hw, TDLS_WIDER_BW);10179}1018010181if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))10182ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA);1018310184if (ath10k_frame_mode == ATH10K_HW_TXRX_ETHERNET) {10185if (ar->wmi.vdev_param->tx_encap_type !=10186WMI_VDEV_PARAM_UNSUPPORTED)10187ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);10188}1018910190ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;10191ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;10192ar->hw->wiphy->max_remain_on_channel_duration = 5000;1019310194ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;10195ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |10196NL80211_FEATURE_AP_SCAN;1019710198ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;1019910200ret = ath10k_wow_init(ar);10201if (ret) {10202ath10k_warn(ar, "failed to init wow: %d\n", ret);10203goto err_free;10204}1020510206wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);10207wiphy_ext_feature_set(ar->hw->wiphy,10208NL80211_EXT_FEATURE_SET_SCAN_DWELL);10209wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_AQL);1021010211if (ar->hw_params.mcast_frame_registration)10212wiphy_ext_feature_set(ar->hw->wiphy,10213NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS);1021410215if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map) ||10216test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, ar->wmi.svc_map))10217wiphy_ext_feature_set(ar->hw->wiphy,10218NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);1021910220if (ath10k_peer_stats_enabled(ar) ||10221test_bit(WMI_SERVICE_REPORT_AIRTIME, ar->wmi.svc_map))10222wiphy_ext_feature_set(ar->hw->wiphy,10223NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);1022410225if (test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map))10226wiphy_ext_feature_set(ar->hw->wiphy,10227NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);1022810229if (test_bit(WMI_SERVICE_TX_PWR_PER_PEER, ar->wmi.svc_map))10230wiphy_ext_feature_set(ar->hw->wiphy,10231NL80211_EXT_FEATURE_STA_TX_PWR);1023210233if (test_bit(WMI_SERVICE_PEER_TID_CONFIGS_SUPPORT, ar->wmi.svc_map)) {10234ar->hw->wiphy->tid_config_support.vif |=10235BIT(NL80211_TID_CONFIG_ATTR_NOACK) |10236BIT(NL80211_TID_CONFIG_ATTR_RETRY_SHORT) |10237BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG) |10238BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL) |10239BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |10240BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE);1024110242if (test_bit(WMI_SERVICE_EXT_PEER_TID_CONFIGS_SUPPORT,10243ar->wmi.svc_map)) {10244ar->hw->wiphy->tid_config_support.vif |=10245BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL);10246}1024710248ar->hw->wiphy->tid_config_support.peer =10249ar->hw->wiphy->tid_config_support.vif;10250ar->hw->wiphy->max_data_retry_count = ATH10K_MAX_RETRY_COUNT;10251} else {10252ar->ops->set_tid_config = NULL;10253}10254/*10255* on LL hardware queues are managed entirely by the FW10256* so we only advertise to mac we can do the queues thing10257*/10258ar->hw->queues = IEEE80211_MAX_QUEUES;1025910260/* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is10261* something that vdev_ids can't reach so that we don't stop the queue10262* accidentally.10263*/10264ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;1026510266switch (ar->running_fw->fw_file.wmi_op_version) {10267case ATH10K_FW_WMI_OP_VERSION_MAIN:10268ar->hw->wiphy->iface_combinations = ath10k_if_comb;10269ar->hw->wiphy->n_iface_combinations =10270ARRAY_SIZE(ath10k_if_comb);10271ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);10272break;10273case ATH10K_FW_WMI_OP_VERSION_TLV:10274if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {10275ar->hw->wiphy->iface_combinations =10276ath10k_tlv_qcs_if_comb;10277ar->hw->wiphy->n_iface_combinations =10278ARRAY_SIZE(ath10k_tlv_qcs_if_comb);10279} else {10280ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;10281ar->hw->wiphy->n_iface_combinations =10282ARRAY_SIZE(ath10k_tlv_if_comb);10283}10284ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);10285break;10286case ATH10K_FW_WMI_OP_VERSION_10_1:10287case ATH10K_FW_WMI_OP_VERSION_10_2:10288case ATH10K_FW_WMI_OP_VERSION_10_2_4:10289ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;10290ar->hw->wiphy->n_iface_combinations =10291ARRAY_SIZE(ath10k_10x_if_comb);10292break;10293case ATH10K_FW_WMI_OP_VERSION_10_4:10294ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;10295ar->hw->wiphy->n_iface_combinations =10296ARRAY_SIZE(ath10k_10_4_if_comb);10297if (test_bit(WMI_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT,10298ar->wmi.svc_map)) {10299ar->hw->wiphy->iface_combinations =10300ath10k_10_4_bcn_int_if_comb;10301ar->hw->wiphy->n_iface_combinations =10302ARRAY_SIZE(ath10k_10_4_bcn_int_if_comb);10303}10304break;10305case ATH10K_FW_WMI_OP_VERSION_UNSET:10306case ATH10K_FW_WMI_OP_VERSION_MAX:10307WARN_ON(1);10308ret = -EINVAL;10309goto err_free;10310}1031110312if (ar->hw_params.dynamic_sar_support)10313ar->hw->wiphy->sar_capa = &ath10k_sar_capa;1031410315if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))10316ar->hw->netdev_features = NETIF_F_HW_CSUM;1031710318if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {10319/* Init ath dfs pattern detector */10320ar->ath_common.debug_mask = ATH_DBG_DFS;10321ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,10322NL80211_DFS_UNSET);1032310324if (!ar->dfs_detector)10325ath10k_warn(ar, "failed to initialise DFS pattern detector\n");10326}1032710328ret = ath10k_mac_init_rd(ar);10329if (ret) {10330ath10k_err(ar, "failed to derive regdom: %d\n", ret);10331goto err_dfs_detector_exit;10332}1033310334/* Disable set_coverage_class for chipsets that do not support it. */10335if (!ar->hw_params.hw_ops->set_coverage_class)10336ar->ops->set_coverage_class = NULL;1033710338ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,10339ath10k_reg_notifier);10340if (ret) {10341ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);10342goto err_dfs_detector_exit;10343}1034410345if (test_bit(WMI_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi.svc_map)) {10346ar->hw->wiphy->features |=10347NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;10348}1034910350ar->hw->wiphy->cipher_suites = cipher_suites;1035110352/* QCA988x and QCA6174 family chips do not support CCMP-256, GCMP-12810353* and GCMP-256 ciphers in hardware. Fetch number of ciphers supported10354* from chip specific hw_param table.10355*/10356if (!ar->hw_params.n_cipher_suites ||10357ar->hw_params.n_cipher_suites > ARRAY_SIZE(cipher_suites)) {10358ath10k_err(ar, "invalid hw_params.n_cipher_suites %d\n",10359ar->hw_params.n_cipher_suites);10360ar->hw_params.n_cipher_suites = 8;10361}10362ar->hw->wiphy->n_cipher_suites = ar->hw_params.n_cipher_suites;1036310364wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);1036510366ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;1036710368ret = ieee80211_register_hw(ar->hw);10369if (ret) {10370ath10k_err(ar, "failed to register ieee80211: %d\n", ret);10371goto err_dfs_detector_exit;10372}1037310374if (test_bit(WMI_SERVICE_PER_PACKET_SW_ENCRYPT, ar->wmi.svc_map)) {10375ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);10376ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN);10377}1037810379if (!ath_is_world_regd(&ar->ath_common.reg_world_copy) &&10380!ath_is_world_regd(&ar->ath_common.regulatory)) {10381ret = regulatory_hint(ar->hw->wiphy,10382ar->ath_common.regulatory.alpha2);10383if (ret)10384goto err_unregister;10385}1038610387return 0;1038810389err_unregister:10390ieee80211_unregister_hw(ar->hw);1039110392err_dfs_detector_exit:10393if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)10394ar->dfs_detector->exit(ar->dfs_detector);1039510396err_free:10397kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);10398kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);1039910400SET_IEEE80211_DEV(ar->hw, NULL);10401return ret;10402}1040310404void ath10k_mac_unregister(struct ath10k *ar)10405{10406ieee80211_unregister_hw(ar->hw);1040710408if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)10409ar->dfs_detector->exit(ar->dfs_detector);1041010411kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);10412kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);1041310414SET_IEEE80211_DEV(ar->hw, NULL);10415}104161041710418