1d8899132SKalle Valo // SPDX-License-Identifier: BSD-3-Clause-Clear 2d8899132SKalle Valo /* 3d8899132SKalle Valo * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4d8899132SKalle Valo * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 5d8899132SKalle Valo */ 6d8899132SKalle Valo 7d8899132SKalle Valo #include <net/mac80211.h> 8d8899132SKalle Valo #include <linux/etherdevice.h> 9d8899132SKalle Valo #include "mac.h" 10d8899132SKalle Valo #include "core.h" 11d8899132SKalle Valo #include "debug.h" 12d8899132SKalle Valo #include "wmi.h" 13d8899132SKalle Valo #include "hw.h" 14d8899132SKalle Valo #include "dp_tx.h" 15d8899132SKalle Valo #include "dp_rx.h" 16d8899132SKalle Valo #include "peer.h" 17d8899132SKalle Valo 18d8899132SKalle Valo #define CHAN2G(_channel, _freq, _flags) { \ 19d8899132SKalle Valo .band = NL80211_BAND_2GHZ, \ 20d8899132SKalle Valo .hw_value = (_channel), \ 21d8899132SKalle Valo .center_freq = (_freq), \ 22d8899132SKalle Valo .flags = (_flags), \ 23d8899132SKalle Valo .max_antenna_gain = 0, \ 24d8899132SKalle Valo .max_power = 30, \ 25d8899132SKalle Valo } 26d8899132SKalle Valo 27d8899132SKalle Valo #define CHAN5G(_channel, _freq, _flags) { \ 28d8899132SKalle Valo .band = NL80211_BAND_5GHZ, \ 29d8899132SKalle Valo .hw_value = (_channel), \ 30d8899132SKalle Valo .center_freq = (_freq), \ 31d8899132SKalle Valo .flags = (_flags), \ 32d8899132SKalle Valo .max_antenna_gain = 0, \ 33d8899132SKalle Valo .max_power = 30, \ 34d8899132SKalle Valo } 35d8899132SKalle Valo 36d8899132SKalle Valo #define CHAN6G(_channel, _freq, _flags) { \ 37d8899132SKalle Valo .band = NL80211_BAND_6GHZ, \ 38d8899132SKalle Valo .hw_value = (_channel), \ 39d8899132SKalle Valo .center_freq = (_freq), \ 40d8899132SKalle Valo .flags = (_flags), \ 41d8899132SKalle Valo .max_antenna_gain = 0, \ 42d8899132SKalle Valo .max_power = 30, \ 43d8899132SKalle Valo } 44d8899132SKalle Valo 45d8899132SKalle Valo static const struct ieee80211_channel ath12k_2ghz_channels[] = { 46d8899132SKalle Valo CHAN2G(1, 2412, 0), 47d8899132SKalle Valo CHAN2G(2, 2417, 0), 48d8899132SKalle Valo CHAN2G(3, 2422, 0), 49d8899132SKalle Valo CHAN2G(4, 2427, 0), 50d8899132SKalle Valo CHAN2G(5, 2432, 0), 51d8899132SKalle Valo CHAN2G(6, 2437, 0), 52d8899132SKalle Valo CHAN2G(7, 2442, 0), 53d8899132SKalle Valo CHAN2G(8, 2447, 0), 54d8899132SKalle Valo CHAN2G(9, 2452, 0), 55d8899132SKalle Valo CHAN2G(10, 2457, 0), 56d8899132SKalle Valo CHAN2G(11, 2462, 0), 57d8899132SKalle Valo CHAN2G(12, 2467, 0), 58d8899132SKalle Valo CHAN2G(13, 2472, 0), 59d8899132SKalle Valo CHAN2G(14, 2484, 0), 60d8899132SKalle Valo }; 61d8899132SKalle Valo 62d8899132SKalle Valo static const struct ieee80211_channel ath12k_5ghz_channels[] = { 63d8899132SKalle Valo CHAN5G(36, 5180, 0), 64d8899132SKalle Valo CHAN5G(40, 5200, 0), 65d8899132SKalle Valo CHAN5G(44, 5220, 0), 66d8899132SKalle Valo CHAN5G(48, 5240, 0), 67d8899132SKalle Valo CHAN5G(52, 5260, 0), 68d8899132SKalle Valo CHAN5G(56, 5280, 0), 69d8899132SKalle Valo CHAN5G(60, 5300, 0), 70d8899132SKalle Valo CHAN5G(64, 5320, 0), 71d8899132SKalle Valo CHAN5G(100, 5500, 0), 72d8899132SKalle Valo CHAN5G(104, 5520, 0), 73d8899132SKalle Valo CHAN5G(108, 5540, 0), 74d8899132SKalle Valo CHAN5G(112, 5560, 0), 75d8899132SKalle Valo CHAN5G(116, 5580, 0), 76d8899132SKalle Valo CHAN5G(120, 5600, 0), 77d8899132SKalle Valo CHAN5G(124, 5620, 0), 78d8899132SKalle Valo CHAN5G(128, 5640, 0), 79d8899132SKalle Valo CHAN5G(132, 5660, 0), 80d8899132SKalle Valo CHAN5G(136, 5680, 0), 81d8899132SKalle Valo CHAN5G(140, 5700, 0), 82d8899132SKalle Valo CHAN5G(144, 5720, 0), 83d8899132SKalle Valo CHAN5G(149, 5745, 0), 84d8899132SKalle Valo CHAN5G(153, 5765, 0), 85d8899132SKalle Valo CHAN5G(157, 5785, 0), 86d8899132SKalle Valo CHAN5G(161, 5805, 0), 87d8899132SKalle Valo CHAN5G(165, 5825, 0), 88d8899132SKalle Valo CHAN5G(169, 5845, 0), 89d8899132SKalle Valo CHAN5G(173, 5865, 0), 90d8899132SKalle Valo }; 91d8899132SKalle Valo 92d8899132SKalle Valo static const struct ieee80211_channel ath12k_6ghz_channels[] = { 93d8899132SKalle Valo CHAN6G(1, 5955, 0), 94d8899132SKalle Valo CHAN6G(5, 5975, 0), 95d8899132SKalle Valo CHAN6G(9, 5995, 0), 96d8899132SKalle Valo CHAN6G(13, 6015, 0), 97d8899132SKalle Valo CHAN6G(17, 6035, 0), 98d8899132SKalle Valo CHAN6G(21, 6055, 0), 99d8899132SKalle Valo CHAN6G(25, 6075, 0), 100d8899132SKalle Valo CHAN6G(29, 6095, 0), 101d8899132SKalle Valo CHAN6G(33, 6115, 0), 102d8899132SKalle Valo CHAN6G(37, 6135, 0), 103d8899132SKalle Valo CHAN6G(41, 6155, 0), 104d8899132SKalle Valo CHAN6G(45, 6175, 0), 105d8899132SKalle Valo CHAN6G(49, 6195, 0), 106d8899132SKalle Valo CHAN6G(53, 6215, 0), 107d8899132SKalle Valo CHAN6G(57, 6235, 0), 108d8899132SKalle Valo CHAN6G(61, 6255, 0), 109d8899132SKalle Valo CHAN6G(65, 6275, 0), 110d8899132SKalle Valo CHAN6G(69, 6295, 0), 111d8899132SKalle Valo CHAN6G(73, 6315, 0), 112d8899132SKalle Valo CHAN6G(77, 6335, 0), 113d8899132SKalle Valo CHAN6G(81, 6355, 0), 114d8899132SKalle Valo CHAN6G(85, 6375, 0), 115d8899132SKalle Valo CHAN6G(89, 6395, 0), 116d8899132SKalle Valo CHAN6G(93, 6415, 0), 117d8899132SKalle Valo CHAN6G(97, 6435, 0), 118d8899132SKalle Valo CHAN6G(101, 6455, 0), 119d8899132SKalle Valo CHAN6G(105, 6475, 0), 120d8899132SKalle Valo CHAN6G(109, 6495, 0), 121d8899132SKalle Valo CHAN6G(113, 6515, 0), 122d8899132SKalle Valo CHAN6G(117, 6535, 0), 123d8899132SKalle Valo CHAN6G(121, 6555, 0), 124d8899132SKalle Valo CHAN6G(125, 6575, 0), 125d8899132SKalle Valo CHAN6G(129, 6595, 0), 126d8899132SKalle Valo CHAN6G(133, 6615, 0), 127d8899132SKalle Valo CHAN6G(137, 6635, 0), 128d8899132SKalle Valo CHAN6G(141, 6655, 0), 129d8899132SKalle Valo CHAN6G(145, 6675, 0), 130d8899132SKalle Valo CHAN6G(149, 6695, 0), 131d8899132SKalle Valo CHAN6G(153, 6715, 0), 132d8899132SKalle Valo CHAN6G(157, 6735, 0), 133d8899132SKalle Valo CHAN6G(161, 6755, 0), 134d8899132SKalle Valo CHAN6G(165, 6775, 0), 135d8899132SKalle Valo CHAN6G(169, 6795, 0), 136d8899132SKalle Valo CHAN6G(173, 6815, 0), 137d8899132SKalle Valo CHAN6G(177, 6835, 0), 138d8899132SKalle Valo CHAN6G(181, 6855, 0), 139d8899132SKalle Valo CHAN6G(185, 6875, 0), 140d8899132SKalle Valo CHAN6G(189, 6895, 0), 141d8899132SKalle Valo CHAN6G(193, 6915, 0), 142d8899132SKalle Valo CHAN6G(197, 6935, 0), 143d8899132SKalle Valo CHAN6G(201, 6955, 0), 144d8899132SKalle Valo CHAN6G(205, 6975, 0), 145d8899132SKalle Valo CHAN6G(209, 6995, 0), 146d8899132SKalle Valo CHAN6G(213, 7015, 0), 147d8899132SKalle Valo CHAN6G(217, 7035, 0), 148d8899132SKalle Valo CHAN6G(221, 7055, 0), 149d8899132SKalle Valo CHAN6G(225, 7075, 0), 150d8899132SKalle Valo CHAN6G(229, 7095, 0), 151d8899132SKalle Valo CHAN6G(233, 7115, 0), 152d8899132SKalle Valo }; 153d8899132SKalle Valo 154d8899132SKalle Valo static struct ieee80211_rate ath12k_legacy_rates[] = { 155d8899132SKalle Valo { .bitrate = 10, 156d8899132SKalle Valo .hw_value = ATH12K_HW_RATE_CCK_LP_1M }, 157d8899132SKalle Valo { .bitrate = 20, 158d8899132SKalle Valo .hw_value = ATH12K_HW_RATE_CCK_LP_2M, 159d8899132SKalle Valo .hw_value_short = ATH12K_HW_RATE_CCK_SP_2M, 160d8899132SKalle Valo .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 161d8899132SKalle Valo { .bitrate = 55, 162d8899132SKalle Valo .hw_value = ATH12K_HW_RATE_CCK_LP_5_5M, 163d8899132SKalle Valo .hw_value_short = ATH12K_HW_RATE_CCK_SP_5_5M, 164d8899132SKalle Valo .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 165d8899132SKalle Valo { .bitrate = 110, 166d8899132SKalle Valo .hw_value = ATH12K_HW_RATE_CCK_LP_11M, 167d8899132SKalle Valo .hw_value_short = ATH12K_HW_RATE_CCK_SP_11M, 168d8899132SKalle Valo .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 169d8899132SKalle Valo 170d8899132SKalle Valo { .bitrate = 60, .hw_value = ATH12K_HW_RATE_OFDM_6M }, 171d8899132SKalle Valo { .bitrate = 90, .hw_value = ATH12K_HW_RATE_OFDM_9M }, 172d8899132SKalle Valo { .bitrate = 120, .hw_value = ATH12K_HW_RATE_OFDM_12M }, 173d8899132SKalle Valo { .bitrate = 180, .hw_value = ATH12K_HW_RATE_OFDM_18M }, 174d8899132SKalle Valo { .bitrate = 240, .hw_value = ATH12K_HW_RATE_OFDM_24M }, 175d8899132SKalle Valo { .bitrate = 360, .hw_value = ATH12K_HW_RATE_OFDM_36M }, 176d8899132SKalle Valo { .bitrate = 480, .hw_value = ATH12K_HW_RATE_OFDM_48M }, 177d8899132SKalle Valo { .bitrate = 540, .hw_value = ATH12K_HW_RATE_OFDM_54M }, 178d8899132SKalle Valo }; 179d8899132SKalle Valo 180d8899132SKalle Valo static const int 181d8899132SKalle Valo ath12k_phymodes[NUM_NL80211_BANDS][ATH12K_CHAN_WIDTH_NUM] = { 182d8899132SKalle Valo [NL80211_BAND_2GHZ] = { 183d8899132SKalle Valo [NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN, 184d8899132SKalle Valo [NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN, 185d8899132SKalle Valo [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20_2G, 186d8899132SKalle Valo [NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20_2G, 187d8899132SKalle Valo [NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40_2G, 188d8899132SKalle Valo [NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80_2G, 189d8899132SKalle Valo [NL80211_CHAN_WIDTH_80P80] = MODE_UNKNOWN, 190d8899132SKalle Valo [NL80211_CHAN_WIDTH_160] = MODE_UNKNOWN, 191d8899132SKalle Valo }, 192d8899132SKalle Valo [NL80211_BAND_5GHZ] = { 193d8899132SKalle Valo [NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN, 194d8899132SKalle Valo [NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN, 195d8899132SKalle Valo [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20, 196d8899132SKalle Valo [NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20, 197d8899132SKalle Valo [NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40, 198d8899132SKalle Valo [NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80, 199d8899132SKalle Valo [NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160, 200d8899132SKalle Valo [NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80, 201d8899132SKalle Valo }, 202d8899132SKalle Valo [NL80211_BAND_6GHZ] = { 203d8899132SKalle Valo [NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN, 204d8899132SKalle Valo [NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN, 205d8899132SKalle Valo [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20, 206d8899132SKalle Valo [NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20, 207d8899132SKalle Valo [NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40, 208d8899132SKalle Valo [NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80, 209d8899132SKalle Valo [NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160, 210d8899132SKalle Valo [NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80, 211d8899132SKalle Valo }, 212d8899132SKalle Valo 213d8899132SKalle Valo }; 214d8899132SKalle Valo 215d8899132SKalle Valo const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default = { 216d8899132SKalle Valo .rx_filter = HTT_RX_FILTER_TLV_FLAGS_MPDU_START | 217d8899132SKalle Valo HTT_RX_FILTER_TLV_FLAGS_PPDU_END | 218d8899132SKalle Valo HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE, 219d8899132SKalle Valo .pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0, 220d8899132SKalle Valo .pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1, 221d8899132SKalle Valo .pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2, 222d8899132SKalle Valo .pkt_filter_flags3 = HTT_RX_FP_DATA_FILTER_FLASG3 | 223d8899132SKalle Valo HTT_RX_FP_CTRL_FILTER_FLASG3 224d8899132SKalle Valo }; 225d8899132SKalle Valo 226d8899132SKalle Valo #define ATH12K_MAC_FIRST_OFDM_RATE_IDX 4 227d8899132SKalle Valo #define ath12k_g_rates ath12k_legacy_rates 228d8899132SKalle Valo #define ath12k_g_rates_size (ARRAY_SIZE(ath12k_legacy_rates)) 229d8899132SKalle Valo #define ath12k_a_rates (ath12k_legacy_rates + 4) 230d8899132SKalle Valo #define ath12k_a_rates_size (ARRAY_SIZE(ath12k_legacy_rates) - 4) 231d8899132SKalle Valo 232d8899132SKalle Valo #define ATH12K_MAC_SCAN_TIMEOUT_MSECS 200 /* in msecs */ 233d8899132SKalle Valo 234d8899132SKalle Valo static const u32 ath12k_smps_map[] = { 235d8899132SKalle Valo [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC, 236d8899132SKalle Valo [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC, 237d8899132SKalle Valo [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE, 238d8899132SKalle Valo [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE, 239d8899132SKalle Valo }; 240d8899132SKalle Valo 241d8899132SKalle Valo static int ath12k_start_vdev_delay(struct ieee80211_hw *hw, 242d8899132SKalle Valo struct ieee80211_vif *vif); 243d8899132SKalle Valo 244d8899132SKalle Valo static const char *ath12k_mac_phymode_str(enum wmi_phy_mode mode) 245d8899132SKalle Valo { 246d8899132SKalle Valo switch (mode) { 247d8899132SKalle Valo case MODE_11A: 248d8899132SKalle Valo return "11a"; 249d8899132SKalle Valo case MODE_11G: 250d8899132SKalle Valo return "11g"; 251d8899132SKalle Valo case MODE_11B: 252d8899132SKalle Valo return "11b"; 253d8899132SKalle Valo case MODE_11GONLY: 254d8899132SKalle Valo return "11gonly"; 255d8899132SKalle Valo case MODE_11NA_HT20: 256d8899132SKalle Valo return "11na-ht20"; 257d8899132SKalle Valo case MODE_11NG_HT20: 258d8899132SKalle Valo return "11ng-ht20"; 259d8899132SKalle Valo case MODE_11NA_HT40: 260d8899132SKalle Valo return "11na-ht40"; 261d8899132SKalle Valo case MODE_11NG_HT40: 262d8899132SKalle Valo return "11ng-ht40"; 263d8899132SKalle Valo case MODE_11AC_VHT20: 264d8899132SKalle Valo return "11ac-vht20"; 265d8899132SKalle Valo case MODE_11AC_VHT40: 266d8899132SKalle Valo return "11ac-vht40"; 267d8899132SKalle Valo case MODE_11AC_VHT80: 268d8899132SKalle Valo return "11ac-vht80"; 269d8899132SKalle Valo case MODE_11AC_VHT160: 270d8899132SKalle Valo return "11ac-vht160"; 271d8899132SKalle Valo case MODE_11AC_VHT80_80: 272d8899132SKalle Valo return "11ac-vht80+80"; 273d8899132SKalle Valo case MODE_11AC_VHT20_2G: 274d8899132SKalle Valo return "11ac-vht20-2g"; 275d8899132SKalle Valo case MODE_11AC_VHT40_2G: 276d8899132SKalle Valo return "11ac-vht40-2g"; 277d8899132SKalle Valo case MODE_11AC_VHT80_2G: 278d8899132SKalle Valo return "11ac-vht80-2g"; 279d8899132SKalle Valo case MODE_11AX_HE20: 280d8899132SKalle Valo return "11ax-he20"; 281d8899132SKalle Valo case MODE_11AX_HE40: 282d8899132SKalle Valo return "11ax-he40"; 283d8899132SKalle Valo case MODE_11AX_HE80: 284d8899132SKalle Valo return "11ax-he80"; 285d8899132SKalle Valo case MODE_11AX_HE80_80: 286d8899132SKalle Valo return "11ax-he80+80"; 287d8899132SKalle Valo case MODE_11AX_HE160: 288d8899132SKalle Valo return "11ax-he160"; 289d8899132SKalle Valo case MODE_11AX_HE20_2G: 290d8899132SKalle Valo return "11ax-he20-2g"; 291d8899132SKalle Valo case MODE_11AX_HE40_2G: 292d8899132SKalle Valo return "11ax-he40-2g"; 293d8899132SKalle Valo case MODE_11AX_HE80_2G: 294d8899132SKalle Valo return "11ax-he80-2g"; 295d8899132SKalle Valo case MODE_UNKNOWN: 296d8899132SKalle Valo /* skip */ 297d8899132SKalle Valo break; 298d8899132SKalle Valo 299d8899132SKalle Valo /* no default handler to allow compiler to check that the 300d8899132SKalle Valo * enum is fully handled 301d8899132SKalle Valo */ 302d8899132SKalle Valo } 303d8899132SKalle Valo 304d8899132SKalle Valo return "<unknown>"; 305d8899132SKalle Valo } 306d8899132SKalle Valo 307d8899132SKalle Valo enum rate_info_bw 308d8899132SKalle Valo ath12k_mac_bw_to_mac80211_bw(enum ath12k_supported_bw bw) 309d8899132SKalle Valo { 310d8899132SKalle Valo u8 ret = RATE_INFO_BW_20; 311d8899132SKalle Valo 312d8899132SKalle Valo switch (bw) { 313d8899132SKalle Valo case ATH12K_BW_20: 314d8899132SKalle Valo ret = RATE_INFO_BW_20; 315d8899132SKalle Valo break; 316d8899132SKalle Valo case ATH12K_BW_40: 317d8899132SKalle Valo ret = RATE_INFO_BW_40; 318d8899132SKalle Valo break; 319d8899132SKalle Valo case ATH12K_BW_80: 320d8899132SKalle Valo ret = RATE_INFO_BW_80; 321d8899132SKalle Valo break; 322d8899132SKalle Valo case ATH12K_BW_160: 323d8899132SKalle Valo ret = RATE_INFO_BW_160; 324d8899132SKalle Valo break; 325d8899132SKalle Valo } 326d8899132SKalle Valo 327d8899132SKalle Valo return ret; 328d8899132SKalle Valo } 329d8899132SKalle Valo 330d8899132SKalle Valo enum ath12k_supported_bw ath12k_mac_mac80211_bw_to_ath12k_bw(enum rate_info_bw bw) 331d8899132SKalle Valo { 332d8899132SKalle Valo switch (bw) { 333d8899132SKalle Valo case RATE_INFO_BW_20: 334d8899132SKalle Valo return ATH12K_BW_20; 335d8899132SKalle Valo case RATE_INFO_BW_40: 336d8899132SKalle Valo return ATH12K_BW_40; 337d8899132SKalle Valo case RATE_INFO_BW_80: 338d8899132SKalle Valo return ATH12K_BW_80; 339d8899132SKalle Valo case RATE_INFO_BW_160: 340d8899132SKalle Valo return ATH12K_BW_160; 341d8899132SKalle Valo default: 342d8899132SKalle Valo return ATH12K_BW_20; 343d8899132SKalle Valo } 344d8899132SKalle Valo } 345d8899132SKalle Valo 346d8899132SKalle Valo int ath12k_mac_hw_ratecode_to_legacy_rate(u8 hw_rc, u8 preamble, u8 *rateidx, 347d8899132SKalle Valo u16 *rate) 348d8899132SKalle Valo { 349d8899132SKalle Valo /* As default, it is OFDM rates */ 350d8899132SKalle Valo int i = ATH12K_MAC_FIRST_OFDM_RATE_IDX; 351d8899132SKalle Valo int max_rates_idx = ath12k_g_rates_size; 352d8899132SKalle Valo 353d8899132SKalle Valo if (preamble == WMI_RATE_PREAMBLE_CCK) { 354d8899132SKalle Valo hw_rc &= ~ATH12K_HW_RATECODE_CCK_SHORT_PREAM_MASK; 355d8899132SKalle Valo i = 0; 356d8899132SKalle Valo max_rates_idx = ATH12K_MAC_FIRST_OFDM_RATE_IDX; 357d8899132SKalle Valo } 358d8899132SKalle Valo 359d8899132SKalle Valo while (i < max_rates_idx) { 360d8899132SKalle Valo if (hw_rc == ath12k_legacy_rates[i].hw_value) { 361d8899132SKalle Valo *rateidx = i; 362d8899132SKalle Valo *rate = ath12k_legacy_rates[i].bitrate; 363d8899132SKalle Valo return 0; 364d8899132SKalle Valo } 365d8899132SKalle Valo i++; 366d8899132SKalle Valo } 367d8899132SKalle Valo 368d8899132SKalle Valo return -EINVAL; 369d8899132SKalle Valo } 370d8899132SKalle Valo 371d8899132SKalle Valo u8 ath12k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband, 372d8899132SKalle Valo u32 bitrate) 373d8899132SKalle Valo { 374d8899132SKalle Valo int i; 375d8899132SKalle Valo 376d8899132SKalle Valo for (i = 0; i < sband->n_bitrates; i++) 377d8899132SKalle Valo if (sband->bitrates[i].bitrate == bitrate) 378d8899132SKalle Valo return i; 379d8899132SKalle Valo 380d8899132SKalle Valo return 0; 381d8899132SKalle Valo } 382d8899132SKalle Valo 383d8899132SKalle Valo static u32 384d8899132SKalle Valo ath12k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) 385d8899132SKalle Valo { 386d8899132SKalle Valo int nss; 387d8899132SKalle Valo 388d8899132SKalle Valo for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--) 389d8899132SKalle Valo if (ht_mcs_mask[nss]) 390d8899132SKalle Valo return nss + 1; 391d8899132SKalle Valo 392d8899132SKalle Valo return 1; 393d8899132SKalle Valo } 394d8899132SKalle Valo 395d8899132SKalle Valo static u32 396d8899132SKalle Valo ath12k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX]) 397d8899132SKalle Valo { 398d8899132SKalle Valo int nss; 399d8899132SKalle Valo 400d8899132SKalle Valo for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--) 401d8899132SKalle Valo if (vht_mcs_mask[nss]) 402d8899132SKalle Valo return nss + 1; 403d8899132SKalle Valo 404d8899132SKalle Valo return 1; 405d8899132SKalle Valo } 406d8899132SKalle Valo 407d8899132SKalle Valo static u8 ath12k_parse_mpdudensity(u8 mpdudensity) 408d8899132SKalle Valo { 409d8899132SKalle Valo /* From IEEE Std 802.11-2020 defined values for "Minimum MPDU Start Spacing": 410d8899132SKalle Valo * 0 for no restriction 411d8899132SKalle Valo * 1 for 1/4 us 412d8899132SKalle Valo * 2 for 1/2 us 413d8899132SKalle Valo * 3 for 1 us 414d8899132SKalle Valo * 4 for 2 us 415d8899132SKalle Valo * 5 for 4 us 416d8899132SKalle Valo * 6 for 8 us 417d8899132SKalle Valo * 7 for 16 us 418d8899132SKalle Valo */ 419d8899132SKalle Valo switch (mpdudensity) { 420d8899132SKalle Valo case 0: 421d8899132SKalle Valo return 0; 422d8899132SKalle Valo case 1: 423d8899132SKalle Valo case 2: 424d8899132SKalle Valo case 3: 425d8899132SKalle Valo /* Our lower layer calculations limit our precision to 426d8899132SKalle Valo * 1 microsecond 427d8899132SKalle Valo */ 428d8899132SKalle Valo return 1; 429d8899132SKalle Valo case 4: 430d8899132SKalle Valo return 2; 431d8899132SKalle Valo case 5: 432d8899132SKalle Valo return 4; 433d8899132SKalle Valo case 6: 434d8899132SKalle Valo return 8; 435d8899132SKalle Valo case 7: 436d8899132SKalle Valo return 16; 437d8899132SKalle Valo default: 438d8899132SKalle Valo return 0; 439d8899132SKalle Valo } 440d8899132SKalle Valo } 441d8899132SKalle Valo 442d8899132SKalle Valo static int ath12k_mac_vif_chan(struct ieee80211_vif *vif, 443d8899132SKalle Valo struct cfg80211_chan_def *def) 444d8899132SKalle Valo { 445d8899132SKalle Valo struct ieee80211_chanctx_conf *conf; 446d8899132SKalle Valo 447d8899132SKalle Valo rcu_read_lock(); 448d8899132SKalle Valo conf = rcu_dereference(vif->bss_conf.chanctx_conf); 449d8899132SKalle Valo if (!conf) { 450d8899132SKalle Valo rcu_read_unlock(); 451d8899132SKalle Valo return -ENOENT; 452d8899132SKalle Valo } 453d8899132SKalle Valo 454d8899132SKalle Valo *def = conf->def; 455d8899132SKalle Valo rcu_read_unlock(); 456d8899132SKalle Valo 457d8899132SKalle Valo return 0; 458d8899132SKalle Valo } 459d8899132SKalle Valo 460d8899132SKalle Valo static bool ath12k_mac_bitrate_is_cck(int bitrate) 461d8899132SKalle Valo { 462d8899132SKalle Valo switch (bitrate) { 463d8899132SKalle Valo case 10: 464d8899132SKalle Valo case 20: 465d8899132SKalle Valo case 55: 466d8899132SKalle Valo case 110: 467d8899132SKalle Valo return true; 468d8899132SKalle Valo } 469d8899132SKalle Valo 470d8899132SKalle Valo return false; 471d8899132SKalle Valo } 472d8899132SKalle Valo 473d8899132SKalle Valo u8 ath12k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband, 474d8899132SKalle Valo u8 hw_rate, bool cck) 475d8899132SKalle Valo { 476d8899132SKalle Valo const struct ieee80211_rate *rate; 477d8899132SKalle Valo int i; 478d8899132SKalle Valo 479d8899132SKalle Valo for (i = 0; i < sband->n_bitrates; i++) { 480d8899132SKalle Valo rate = &sband->bitrates[i]; 481d8899132SKalle Valo 482d8899132SKalle Valo if (ath12k_mac_bitrate_is_cck(rate->bitrate) != cck) 483d8899132SKalle Valo continue; 484d8899132SKalle Valo 485d8899132SKalle Valo if (rate->hw_value == hw_rate) 486d8899132SKalle Valo return i; 487d8899132SKalle Valo else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE && 488d8899132SKalle Valo rate->hw_value_short == hw_rate) 489d8899132SKalle Valo return i; 490d8899132SKalle Valo } 491d8899132SKalle Valo 492d8899132SKalle Valo return 0; 493d8899132SKalle Valo } 494d8899132SKalle Valo 495d8899132SKalle Valo static u8 ath12k_mac_bitrate_to_rate(int bitrate) 496d8899132SKalle Valo { 497d8899132SKalle Valo return DIV_ROUND_UP(bitrate, 5) | 498d8899132SKalle Valo (ath12k_mac_bitrate_is_cck(bitrate) ? BIT(7) : 0); 499d8899132SKalle Valo } 500d8899132SKalle Valo 501d8899132SKalle Valo static void ath12k_get_arvif_iter(void *data, u8 *mac, 502d8899132SKalle Valo struct ieee80211_vif *vif) 503d8899132SKalle Valo { 504d8899132SKalle Valo struct ath12k_vif_iter *arvif_iter = data; 505d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 506d8899132SKalle Valo 507d8899132SKalle Valo if (arvif->vdev_id == arvif_iter->vdev_id) 508d8899132SKalle Valo arvif_iter->arvif = arvif; 509d8899132SKalle Valo } 510d8899132SKalle Valo 511d8899132SKalle Valo struct ath12k_vif *ath12k_mac_get_arvif(struct ath12k *ar, u32 vdev_id) 512d8899132SKalle Valo { 513d8899132SKalle Valo struct ath12k_vif_iter arvif_iter = {}; 514d8899132SKalle Valo u32 flags; 515d8899132SKalle Valo 516d8899132SKalle Valo arvif_iter.vdev_id = vdev_id; 517d8899132SKalle Valo 518d8899132SKalle Valo flags = IEEE80211_IFACE_ITER_RESUME_ALL; 519d8899132SKalle Valo ieee80211_iterate_active_interfaces_atomic(ar->hw, 520d8899132SKalle Valo flags, 521d8899132SKalle Valo ath12k_get_arvif_iter, 522d8899132SKalle Valo &arvif_iter); 523d8899132SKalle Valo if (!arvif_iter.arvif) { 524d8899132SKalle Valo ath12k_warn(ar->ab, "No VIF found for vdev %d\n", vdev_id); 525d8899132SKalle Valo return NULL; 526d8899132SKalle Valo } 527d8899132SKalle Valo 528d8899132SKalle Valo return arvif_iter.arvif; 529d8899132SKalle Valo } 530d8899132SKalle Valo 531d8899132SKalle Valo struct ath12k_vif *ath12k_mac_get_arvif_by_vdev_id(struct ath12k_base *ab, 532d8899132SKalle Valo u32 vdev_id) 533d8899132SKalle Valo { 534d8899132SKalle Valo int i; 535d8899132SKalle Valo struct ath12k_pdev *pdev; 536d8899132SKalle Valo struct ath12k_vif *arvif; 537d8899132SKalle Valo 538d8899132SKalle Valo for (i = 0; i < ab->num_radios; i++) { 539d8899132SKalle Valo pdev = rcu_dereference(ab->pdevs_active[i]); 540d8899132SKalle Valo if (pdev && pdev->ar) { 541d8899132SKalle Valo arvif = ath12k_mac_get_arvif(pdev->ar, vdev_id); 542d8899132SKalle Valo if (arvif) 543d8899132SKalle Valo return arvif; 544d8899132SKalle Valo } 545d8899132SKalle Valo } 546d8899132SKalle Valo 547d8899132SKalle Valo return NULL; 548d8899132SKalle Valo } 549d8899132SKalle Valo 550d8899132SKalle Valo struct ath12k *ath12k_mac_get_ar_by_vdev_id(struct ath12k_base *ab, u32 vdev_id) 551d8899132SKalle Valo { 552d8899132SKalle Valo int i; 553d8899132SKalle Valo struct ath12k_pdev *pdev; 554d8899132SKalle Valo 555d8899132SKalle Valo for (i = 0; i < ab->num_radios; i++) { 556d8899132SKalle Valo pdev = rcu_dereference(ab->pdevs_active[i]); 557d8899132SKalle Valo if (pdev && pdev->ar) { 558d8899132SKalle Valo if (pdev->ar->allocated_vdev_map & (1LL << vdev_id)) 559d8899132SKalle Valo return pdev->ar; 560d8899132SKalle Valo } 561d8899132SKalle Valo } 562d8899132SKalle Valo 563d8899132SKalle Valo return NULL; 564d8899132SKalle Valo } 565d8899132SKalle Valo 566d8899132SKalle Valo struct ath12k *ath12k_mac_get_ar_by_pdev_id(struct ath12k_base *ab, u32 pdev_id) 567d8899132SKalle Valo { 568d8899132SKalle Valo int i; 569d8899132SKalle Valo struct ath12k_pdev *pdev; 570d8899132SKalle Valo 571d8899132SKalle Valo if (ab->hw_params->single_pdev_only) { 572d8899132SKalle Valo pdev = rcu_dereference(ab->pdevs_active[0]); 573d8899132SKalle Valo return pdev ? pdev->ar : NULL; 574d8899132SKalle Valo } 575d8899132SKalle Valo 576d8899132SKalle Valo if (WARN_ON(pdev_id > ab->num_radios)) 577d8899132SKalle Valo return NULL; 578d8899132SKalle Valo 579d8899132SKalle Valo for (i = 0; i < ab->num_radios; i++) { 580d8899132SKalle Valo pdev = rcu_dereference(ab->pdevs_active[i]); 581d8899132SKalle Valo 582d8899132SKalle Valo if (pdev && pdev->pdev_id == pdev_id) 583d8899132SKalle Valo return (pdev->ar ? pdev->ar : NULL); 584d8899132SKalle Valo } 585d8899132SKalle Valo 586d8899132SKalle Valo return NULL; 587d8899132SKalle Valo } 588d8899132SKalle Valo 589d8899132SKalle Valo static void ath12k_pdev_caps_update(struct ath12k *ar) 590d8899132SKalle Valo { 591d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 592d8899132SKalle Valo 593d8899132SKalle Valo ar->max_tx_power = ab->target_caps.hw_max_tx_power; 594d8899132SKalle Valo 595d8899132SKalle Valo /* FIXME: Set min_tx_power to ab->target_caps.hw_min_tx_power. 596d8899132SKalle Valo * But since the received value in svcrdy is same as hw_max_tx_power, 597d8899132SKalle Valo * we can set ar->min_tx_power to 0 currently until 598d8899132SKalle Valo * this is fixed in firmware 599d8899132SKalle Valo */ 600d8899132SKalle Valo ar->min_tx_power = 0; 601d8899132SKalle Valo 602d8899132SKalle Valo ar->txpower_limit_2g = ar->max_tx_power; 603d8899132SKalle Valo ar->txpower_limit_5g = ar->max_tx_power; 604d8899132SKalle Valo ar->txpower_scale = WMI_HOST_TP_SCALE_MAX; 605d8899132SKalle Valo } 606d8899132SKalle Valo 607d8899132SKalle Valo static int ath12k_mac_txpower_recalc(struct ath12k *ar) 608d8899132SKalle Valo { 609d8899132SKalle Valo struct ath12k_pdev *pdev = ar->pdev; 610d8899132SKalle Valo struct ath12k_vif *arvif; 611d8899132SKalle Valo int ret, txpower = -1; 612d8899132SKalle Valo u32 param; 613d8899132SKalle Valo 614d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 615d8899132SKalle Valo 616d8899132SKalle Valo list_for_each_entry(arvif, &ar->arvifs, list) { 617d8899132SKalle Valo if (arvif->txpower <= 0) 618d8899132SKalle Valo continue; 619d8899132SKalle Valo 620d8899132SKalle Valo if (txpower == -1) 621d8899132SKalle Valo txpower = arvif->txpower; 622d8899132SKalle Valo else 623d8899132SKalle Valo txpower = min(txpower, arvif->txpower); 624d8899132SKalle Valo } 625d8899132SKalle Valo 626d8899132SKalle Valo if (txpower == -1) 627d8899132SKalle Valo return 0; 628d8899132SKalle Valo 629d8899132SKalle Valo /* txpwr is set as 2 units per dBm in FW*/ 630d8899132SKalle Valo txpower = min_t(u32, max_t(u32, ar->min_tx_power, txpower), 631d8899132SKalle Valo ar->max_tx_power) * 2; 632d8899132SKalle Valo 633d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "txpower to set in hw %d\n", 634d8899132SKalle Valo txpower / 2); 635d8899132SKalle Valo 636d8899132SKalle Valo if ((pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) && 637d8899132SKalle Valo ar->txpower_limit_2g != txpower) { 638d8899132SKalle Valo param = WMI_PDEV_PARAM_TXPOWER_LIMIT2G; 639d8899132SKalle Valo ret = ath12k_wmi_pdev_set_param(ar, param, 640d8899132SKalle Valo txpower, ar->pdev->pdev_id); 641d8899132SKalle Valo if (ret) 642d8899132SKalle Valo goto fail; 643d8899132SKalle Valo ar->txpower_limit_2g = txpower; 644d8899132SKalle Valo } 645d8899132SKalle Valo 646d8899132SKalle Valo if ((pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) && 647d8899132SKalle Valo ar->txpower_limit_5g != txpower) { 648d8899132SKalle Valo param = WMI_PDEV_PARAM_TXPOWER_LIMIT5G; 649d8899132SKalle Valo ret = ath12k_wmi_pdev_set_param(ar, param, 650d8899132SKalle Valo txpower, ar->pdev->pdev_id); 651d8899132SKalle Valo if (ret) 652d8899132SKalle Valo goto fail; 653d8899132SKalle Valo ar->txpower_limit_5g = txpower; 654d8899132SKalle Valo } 655d8899132SKalle Valo 656d8899132SKalle Valo return 0; 657d8899132SKalle Valo 658d8899132SKalle Valo fail: 659d8899132SKalle Valo ath12k_warn(ar->ab, "failed to recalc txpower limit %d using pdev param %d: %d\n", 660d8899132SKalle Valo txpower / 2, param, ret); 661d8899132SKalle Valo return ret; 662d8899132SKalle Valo } 663d8899132SKalle Valo 664d8899132SKalle Valo static int ath12k_recalc_rtscts_prot(struct ath12k_vif *arvif) 665d8899132SKalle Valo { 666d8899132SKalle Valo struct ath12k *ar = arvif->ar; 667d8899132SKalle Valo u32 vdev_param, rts_cts; 668d8899132SKalle Valo int ret; 669d8899132SKalle Valo 670d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 671d8899132SKalle Valo 672d8899132SKalle Valo vdev_param = WMI_VDEV_PARAM_ENABLE_RTSCTS; 673d8899132SKalle Valo 674d8899132SKalle Valo /* Enable RTS/CTS protection for sw retries (when legacy stations 675d8899132SKalle Valo * are in BSS) or by default only for second rate series. 676d8899132SKalle Valo * TODO: Check if we need to enable CTS 2 Self in any case 677d8899132SKalle Valo */ 678d8899132SKalle Valo rts_cts = WMI_USE_RTS_CTS; 679d8899132SKalle Valo 680d8899132SKalle Valo if (arvif->num_legacy_stations > 0) 681d8899132SKalle Valo rts_cts |= WMI_RTSCTS_ACROSS_SW_RETRIES << 4; 682d8899132SKalle Valo else 683d8899132SKalle Valo rts_cts |= WMI_RTSCTS_FOR_SECOND_RATESERIES << 4; 684d8899132SKalle Valo 685d8899132SKalle Valo /* Need not send duplicate param value to firmware */ 686d8899132SKalle Valo if (arvif->rtscts_prot_mode == rts_cts) 687d8899132SKalle Valo return 0; 688d8899132SKalle Valo 689d8899132SKalle Valo arvif->rtscts_prot_mode = rts_cts; 690d8899132SKalle Valo 691d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vdev %d recalc rts/cts prot %d\n", 692d8899132SKalle Valo arvif->vdev_id, rts_cts); 693d8899132SKalle Valo 694d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 695d8899132SKalle Valo vdev_param, rts_cts); 696d8899132SKalle Valo if (ret) 697d8899132SKalle Valo ath12k_warn(ar->ab, "failed to recalculate rts/cts prot for vdev %d: %d\n", 698d8899132SKalle Valo arvif->vdev_id, ret); 699d8899132SKalle Valo 700d8899132SKalle Valo return ret; 701d8899132SKalle Valo } 702d8899132SKalle Valo 703d8899132SKalle Valo static int ath12k_mac_set_kickout(struct ath12k_vif *arvif) 704d8899132SKalle Valo { 705d8899132SKalle Valo struct ath12k *ar = arvif->ar; 706d8899132SKalle Valo u32 param; 707d8899132SKalle Valo int ret; 708d8899132SKalle Valo 709d8899132SKalle Valo ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_STA_KICKOUT_TH, 710d8899132SKalle Valo ATH12K_KICKOUT_THRESHOLD, 711d8899132SKalle Valo ar->pdev->pdev_id); 712d8899132SKalle Valo if (ret) { 713d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set kickout threshold on vdev %i: %d\n", 714d8899132SKalle Valo arvif->vdev_id, ret); 715d8899132SKalle Valo return ret; 716d8899132SKalle Valo } 717d8899132SKalle Valo 718d8899132SKalle Valo param = WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS; 719d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, 720d8899132SKalle Valo ATH12K_KEEPALIVE_MIN_IDLE); 721d8899132SKalle Valo if (ret) { 722d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set keepalive minimum idle time on vdev %i: %d\n", 723d8899132SKalle Valo arvif->vdev_id, ret); 724d8899132SKalle Valo return ret; 725d8899132SKalle Valo } 726d8899132SKalle Valo 727d8899132SKalle Valo param = WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS; 728d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, 729d8899132SKalle Valo ATH12K_KEEPALIVE_MAX_IDLE); 730d8899132SKalle Valo if (ret) { 731d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set keepalive maximum idle time on vdev %i: %d\n", 732d8899132SKalle Valo arvif->vdev_id, ret); 733d8899132SKalle Valo return ret; 734d8899132SKalle Valo } 735d8899132SKalle Valo 736d8899132SKalle Valo param = WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS; 737d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, 738d8899132SKalle Valo ATH12K_KEEPALIVE_MAX_UNRESPONSIVE); 739d8899132SKalle Valo if (ret) { 740d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n", 741d8899132SKalle Valo arvif->vdev_id, ret); 742d8899132SKalle Valo return ret; 743d8899132SKalle Valo } 744d8899132SKalle Valo 745d8899132SKalle Valo return 0; 746d8899132SKalle Valo } 747d8899132SKalle Valo 748d8899132SKalle Valo void ath12k_mac_peer_cleanup_all(struct ath12k *ar) 749d8899132SKalle Valo { 750d8899132SKalle Valo struct ath12k_peer *peer, *tmp; 751d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 752d8899132SKalle Valo 753d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 754d8899132SKalle Valo 755d8899132SKalle Valo spin_lock_bh(&ab->base_lock); 756d8899132SKalle Valo list_for_each_entry_safe(peer, tmp, &ab->peers, list) { 757d8899132SKalle Valo ath12k_dp_rx_peer_tid_cleanup(ar, peer); 758d8899132SKalle Valo list_del(&peer->list); 759d8899132SKalle Valo kfree(peer); 760d8899132SKalle Valo } 761d8899132SKalle Valo spin_unlock_bh(&ab->base_lock); 762d8899132SKalle Valo 763d8899132SKalle Valo ar->num_peers = 0; 764d8899132SKalle Valo ar->num_stations = 0; 765d8899132SKalle Valo } 766d8899132SKalle Valo 767d8899132SKalle Valo static int ath12k_mac_vdev_setup_sync(struct ath12k *ar) 768d8899132SKalle Valo { 769d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 770d8899132SKalle Valo 771d8899132SKalle Valo if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) 772d8899132SKalle Valo return -ESHUTDOWN; 773d8899132SKalle Valo 774d8899132SKalle Valo if (!wait_for_completion_timeout(&ar->vdev_setup_done, 775d8899132SKalle Valo ATH12K_VDEV_SETUP_TIMEOUT_HZ)) 776d8899132SKalle Valo return -ETIMEDOUT; 777d8899132SKalle Valo 778d8899132SKalle Valo return ar->last_wmi_vdev_start_status ? -EINVAL : 0; 779d8899132SKalle Valo } 780d8899132SKalle Valo 781d8899132SKalle Valo static int ath12k_monitor_vdev_up(struct ath12k *ar, int vdev_id) 782d8899132SKalle Valo { 783d8899132SKalle Valo int ret; 784d8899132SKalle Valo 785d8899132SKalle Valo ret = ath12k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr); 786d8899132SKalle Valo if (ret) { 787d8899132SKalle Valo ath12k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n", 788d8899132SKalle Valo vdev_id, ret); 789d8899132SKalle Valo return ret; 790d8899132SKalle Valo } 791d8899132SKalle Valo 792d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor vdev %i started\n", 793d8899132SKalle Valo vdev_id); 794d8899132SKalle Valo return 0; 795d8899132SKalle Valo } 796d8899132SKalle Valo 797d8899132SKalle Valo static int ath12k_mac_monitor_vdev_start(struct ath12k *ar, int vdev_id, 798d8899132SKalle Valo struct cfg80211_chan_def *chandef) 799d8899132SKalle Valo { 800d8899132SKalle Valo struct ieee80211_channel *channel; 801d8899132SKalle Valo struct wmi_vdev_start_req_arg arg = {}; 802d8899132SKalle Valo int ret; 803d8899132SKalle Valo 804d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 805d8899132SKalle Valo 806d8899132SKalle Valo channel = chandef->chan; 807d8899132SKalle Valo arg.vdev_id = vdev_id; 808d8899132SKalle Valo arg.freq = channel->center_freq; 809d8899132SKalle Valo arg.band_center_freq1 = chandef->center_freq1; 810d8899132SKalle Valo arg.band_center_freq2 = chandef->center_freq2; 811d8899132SKalle Valo arg.mode = ath12k_phymodes[chandef->chan->band][chandef->width]; 812d8899132SKalle Valo arg.chan_radar = !!(channel->flags & IEEE80211_CHAN_RADAR); 813d8899132SKalle Valo 814d8899132SKalle Valo arg.min_power = 0; 815d8899132SKalle Valo arg.max_power = channel->max_power; 816d8899132SKalle Valo arg.max_reg_power = channel->max_reg_power; 817d8899132SKalle Valo arg.max_antenna_gain = channel->max_antenna_gain; 818d8899132SKalle Valo 819d8899132SKalle Valo arg.pref_tx_streams = ar->num_tx_chains; 820d8899132SKalle Valo arg.pref_rx_streams = ar->num_rx_chains; 821d8899132SKalle Valo 822d8899132SKalle Valo arg.passive |= !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR); 823d8899132SKalle Valo 824d8899132SKalle Valo reinit_completion(&ar->vdev_setup_done); 825d8899132SKalle Valo reinit_completion(&ar->vdev_delete_done); 826d8899132SKalle Valo 827d8899132SKalle Valo ret = ath12k_wmi_vdev_start(ar, &arg, false); 828d8899132SKalle Valo if (ret) { 829d8899132SKalle Valo ath12k_warn(ar->ab, "failed to request monitor vdev %i start: %d\n", 830d8899132SKalle Valo vdev_id, ret); 831d8899132SKalle Valo return ret; 832d8899132SKalle Valo } 833d8899132SKalle Valo 834d8899132SKalle Valo ret = ath12k_mac_vdev_setup_sync(ar); 835d8899132SKalle Valo if (ret) { 836d8899132SKalle Valo ath12k_warn(ar->ab, "failed to synchronize setup for monitor vdev %i start: %d\n", 837d8899132SKalle Valo vdev_id, ret); 838d8899132SKalle Valo return ret; 839d8899132SKalle Valo } 840d8899132SKalle Valo 841d8899132SKalle Valo ret = ath12k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr); 842d8899132SKalle Valo if (ret) { 843d8899132SKalle Valo ath12k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n", 844d8899132SKalle Valo vdev_id, ret); 845d8899132SKalle Valo goto vdev_stop; 846d8899132SKalle Valo } 847d8899132SKalle Valo 848d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor vdev %i started\n", 849d8899132SKalle Valo vdev_id); 850d8899132SKalle Valo return 0; 851d8899132SKalle Valo 852d8899132SKalle Valo vdev_stop: 853d8899132SKalle Valo ret = ath12k_wmi_vdev_stop(ar, vdev_id); 854d8899132SKalle Valo if (ret) 855d8899132SKalle Valo ath12k_warn(ar->ab, "failed to stop monitor vdev %i after start failure: %d\n", 856d8899132SKalle Valo vdev_id, ret); 857d8899132SKalle Valo return ret; 858d8899132SKalle Valo } 859d8899132SKalle Valo 860d8899132SKalle Valo static int ath12k_mac_monitor_vdev_stop(struct ath12k *ar) 861d8899132SKalle Valo { 862d8899132SKalle Valo int ret; 863d8899132SKalle Valo 864d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 865d8899132SKalle Valo 866d8899132SKalle Valo reinit_completion(&ar->vdev_setup_done); 867d8899132SKalle Valo 868d8899132SKalle Valo ret = ath12k_wmi_vdev_stop(ar, ar->monitor_vdev_id); 869d8899132SKalle Valo if (ret) 870d8899132SKalle Valo ath12k_warn(ar->ab, "failed to request monitor vdev %i stop: %d\n", 871d8899132SKalle Valo ar->monitor_vdev_id, ret); 872d8899132SKalle Valo 873d8899132SKalle Valo ret = ath12k_mac_vdev_setup_sync(ar); 874d8899132SKalle Valo if (ret) 875d8899132SKalle Valo ath12k_warn(ar->ab, "failed to synchronize monitor vdev %i stop: %d\n", 876d8899132SKalle Valo ar->monitor_vdev_id, ret); 877d8899132SKalle Valo 878d8899132SKalle Valo ret = ath12k_wmi_vdev_down(ar, ar->monitor_vdev_id); 879d8899132SKalle Valo if (ret) 880d8899132SKalle Valo ath12k_warn(ar->ab, "failed to put down monitor vdev %i: %d\n", 881d8899132SKalle Valo ar->monitor_vdev_id, ret); 882d8899132SKalle Valo 883d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor vdev %i stopped\n", 884d8899132SKalle Valo ar->monitor_vdev_id); 885d8899132SKalle Valo return ret; 886d8899132SKalle Valo } 887d8899132SKalle Valo 888d8899132SKalle Valo static int ath12k_mac_monitor_vdev_create(struct ath12k *ar) 889d8899132SKalle Valo { 890d8899132SKalle Valo struct ath12k_pdev *pdev = ar->pdev; 891d8899132SKalle Valo struct ath12k_wmi_vdev_create_arg arg = {}; 892d8899132SKalle Valo int bit, ret; 893d8899132SKalle Valo u8 tmp_addr[6]; 894d8899132SKalle Valo u16 nss; 895d8899132SKalle Valo 896d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 897d8899132SKalle Valo 898d8899132SKalle Valo if (ar->monitor_vdev_created) 899d8899132SKalle Valo return 0; 900d8899132SKalle Valo 901d8899132SKalle Valo if (ar->ab->free_vdev_map == 0) { 902d8899132SKalle Valo ath12k_warn(ar->ab, "failed to find free vdev id for monitor vdev\n"); 903d8899132SKalle Valo return -ENOMEM; 904d8899132SKalle Valo } 905d8899132SKalle Valo 906d8899132SKalle Valo bit = __ffs64(ar->ab->free_vdev_map); 907d8899132SKalle Valo 908d8899132SKalle Valo ar->monitor_vdev_id = bit; 909d8899132SKalle Valo 910d8899132SKalle Valo arg.if_id = ar->monitor_vdev_id; 911d8899132SKalle Valo arg.type = WMI_VDEV_TYPE_MONITOR; 912d8899132SKalle Valo arg.subtype = WMI_VDEV_SUBTYPE_NONE; 913d8899132SKalle Valo arg.pdev_id = pdev->pdev_id; 914d8899132SKalle Valo arg.if_stats_id = ATH12K_INVAL_VDEV_STATS_ID; 915d8899132SKalle Valo 916d8899132SKalle Valo if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) { 917d8899132SKalle Valo arg.chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains; 918d8899132SKalle Valo arg.chains[NL80211_BAND_2GHZ].rx = ar->num_rx_chains; 919d8899132SKalle Valo } 920d8899132SKalle Valo 921d8899132SKalle Valo if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) { 922d8899132SKalle Valo arg.chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains; 923d8899132SKalle Valo arg.chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains; 924d8899132SKalle Valo } 925d8899132SKalle Valo 926d8899132SKalle Valo ret = ath12k_wmi_vdev_create(ar, tmp_addr, &arg); 927d8899132SKalle Valo if (ret) { 928d8899132SKalle Valo ath12k_warn(ar->ab, "failed to request monitor vdev %i creation: %d\n", 929d8899132SKalle Valo ar->monitor_vdev_id, ret); 930d8899132SKalle Valo ar->monitor_vdev_id = -1; 931d8899132SKalle Valo return ret; 932d8899132SKalle Valo } 933d8899132SKalle Valo 934d8899132SKalle Valo nss = hweight32(ar->cfg_tx_chainmask) ? : 1; 935d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, ar->monitor_vdev_id, 936d8899132SKalle Valo WMI_VDEV_PARAM_NSS, nss); 937d8899132SKalle Valo if (ret) { 938d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set vdev %d chainmask 0x%x, nss %d :%d\n", 939d8899132SKalle Valo ar->monitor_vdev_id, ar->cfg_tx_chainmask, nss, ret); 940d8899132SKalle Valo return ret; 941d8899132SKalle Valo } 942d8899132SKalle Valo 943d8899132SKalle Valo ret = ath12k_mac_txpower_recalc(ar); 944d8899132SKalle Valo if (ret) 945d8899132SKalle Valo return ret; 946d8899132SKalle Valo 947d8899132SKalle Valo ar->allocated_vdev_map |= 1LL << ar->monitor_vdev_id; 948d8899132SKalle Valo ar->ab->free_vdev_map &= ~(1LL << ar->monitor_vdev_id); 949d8899132SKalle Valo ar->num_created_vdevs++; 950d8899132SKalle Valo ar->monitor_vdev_created = true; 951d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor vdev %d created\n", 952d8899132SKalle Valo ar->monitor_vdev_id); 953d8899132SKalle Valo 954d8899132SKalle Valo return 0; 955d8899132SKalle Valo } 956d8899132SKalle Valo 957d8899132SKalle Valo static int ath12k_mac_monitor_vdev_delete(struct ath12k *ar) 958d8899132SKalle Valo { 959d8899132SKalle Valo int ret; 960d8899132SKalle Valo unsigned long time_left; 961d8899132SKalle Valo 962d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 963d8899132SKalle Valo 964d8899132SKalle Valo if (!ar->monitor_vdev_created) 965d8899132SKalle Valo return 0; 966d8899132SKalle Valo 967d8899132SKalle Valo reinit_completion(&ar->vdev_delete_done); 968d8899132SKalle Valo 969d8899132SKalle Valo ret = ath12k_wmi_vdev_delete(ar, ar->monitor_vdev_id); 970d8899132SKalle Valo if (ret) { 971d8899132SKalle Valo ath12k_warn(ar->ab, "failed to request wmi monitor vdev %i removal: %d\n", 972d8899132SKalle Valo ar->monitor_vdev_id, ret); 973d8899132SKalle Valo return ret; 974d8899132SKalle Valo } 975d8899132SKalle Valo 976d8899132SKalle Valo time_left = wait_for_completion_timeout(&ar->vdev_delete_done, 977d8899132SKalle Valo ATH12K_VDEV_DELETE_TIMEOUT_HZ); 978d8899132SKalle Valo if (time_left == 0) { 979d8899132SKalle Valo ath12k_warn(ar->ab, "Timeout in receiving vdev delete response\n"); 980d8899132SKalle Valo } else { 981d8899132SKalle Valo ar->allocated_vdev_map &= ~(1LL << ar->monitor_vdev_id); 982d8899132SKalle Valo ar->ab->free_vdev_map |= 1LL << (ar->monitor_vdev_id); 983d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor vdev %d deleted\n", 984d8899132SKalle Valo ar->monitor_vdev_id); 985d8899132SKalle Valo ar->num_created_vdevs--; 986d8899132SKalle Valo ar->monitor_vdev_id = -1; 987d8899132SKalle Valo ar->monitor_vdev_created = false; 988d8899132SKalle Valo } 989d8899132SKalle Valo 990d8899132SKalle Valo return ret; 991d8899132SKalle Valo } 992d8899132SKalle Valo 993d8899132SKalle Valo static void 994d8899132SKalle Valo ath12k_mac_get_any_chandef_iter(struct ieee80211_hw *hw, 995d8899132SKalle Valo struct ieee80211_chanctx_conf *conf, 996d8899132SKalle Valo void *data) 997d8899132SKalle Valo { 998d8899132SKalle Valo struct cfg80211_chan_def **def = data; 999d8899132SKalle Valo 1000d8899132SKalle Valo *def = &conf->def; 1001d8899132SKalle Valo } 1002d8899132SKalle Valo 1003d8899132SKalle Valo static int ath12k_mac_monitor_start(struct ath12k *ar) 1004d8899132SKalle Valo { 1005d8899132SKalle Valo struct cfg80211_chan_def *chandef = NULL; 1006d8899132SKalle Valo int ret; 1007d8899132SKalle Valo 1008d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 1009d8899132SKalle Valo 1010d8899132SKalle Valo if (ar->monitor_started) 1011d8899132SKalle Valo return 0; 1012d8899132SKalle Valo 1013d8899132SKalle Valo ieee80211_iter_chan_contexts_atomic(ar->hw, 1014d8899132SKalle Valo ath12k_mac_get_any_chandef_iter, 1015d8899132SKalle Valo &chandef); 1016d8899132SKalle Valo if (!chandef) 1017d8899132SKalle Valo return 0; 1018d8899132SKalle Valo 1019d8899132SKalle Valo ret = ath12k_mac_monitor_vdev_start(ar, ar->monitor_vdev_id, chandef); 1020d8899132SKalle Valo if (ret) { 1021d8899132SKalle Valo ath12k_warn(ar->ab, "failed to start monitor vdev: %d\n", ret); 1022d8899132SKalle Valo ath12k_mac_monitor_vdev_delete(ar); 1023d8899132SKalle Valo return ret; 1024d8899132SKalle Valo } 1025d8899132SKalle Valo 1026d8899132SKalle Valo ar->monitor_started = true; 1027d8899132SKalle Valo ar->num_started_vdevs++; 1028d8899132SKalle Valo ret = ath12k_dp_tx_htt_monitor_mode_ring_config(ar, false); 1029d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor started ret %d\n", ret); 1030d8899132SKalle Valo 1031d8899132SKalle Valo return ret; 1032d8899132SKalle Valo } 1033d8899132SKalle Valo 1034d8899132SKalle Valo static int ath12k_mac_monitor_stop(struct ath12k *ar) 1035d8899132SKalle Valo { 1036d8899132SKalle Valo int ret; 1037d8899132SKalle Valo 1038d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 1039d8899132SKalle Valo 1040d8899132SKalle Valo if (!ar->monitor_started) 1041d8899132SKalle Valo return 0; 1042d8899132SKalle Valo 1043d8899132SKalle Valo ret = ath12k_mac_monitor_vdev_stop(ar); 1044d8899132SKalle Valo if (ret) { 1045d8899132SKalle Valo ath12k_warn(ar->ab, "failed to stop monitor vdev: %d\n", ret); 1046d8899132SKalle Valo return ret; 1047d8899132SKalle Valo } 1048d8899132SKalle Valo 1049d8899132SKalle Valo ar->monitor_started = false; 1050d8899132SKalle Valo ar->num_started_vdevs--; 1051d8899132SKalle Valo ret = ath12k_dp_tx_htt_monitor_mode_ring_config(ar, true); 1052d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor stopped ret %d\n", ret); 1053d8899132SKalle Valo return ret; 1054d8899132SKalle Valo } 1055d8899132SKalle Valo 1056d8899132SKalle Valo static int ath12k_mac_op_config(struct ieee80211_hw *hw, u32 changed) 1057d8899132SKalle Valo { 1058d8899132SKalle Valo struct ath12k *ar = hw->priv; 1059d8899132SKalle Valo struct ieee80211_conf *conf = &hw->conf; 1060*d1335f0dSThiraviyam Mariyappan int ret = 0; 1061d8899132SKalle Valo 1062d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 1063d8899132SKalle Valo 1064d8899132SKalle Valo if (changed & IEEE80211_CONF_CHANGE_MONITOR) { 1065d8899132SKalle Valo ar->monitor_conf_enabled = conf->flags & IEEE80211_CONF_MONITOR; 1066d8899132SKalle Valo if (ar->monitor_conf_enabled) { 1067d8899132SKalle Valo if (ar->monitor_vdev_created) 1068d8899132SKalle Valo goto exit; 1069d8899132SKalle Valo ret = ath12k_mac_monitor_vdev_create(ar); 1070d8899132SKalle Valo if (ret) 1071d8899132SKalle Valo goto exit; 1072d8899132SKalle Valo ret = ath12k_mac_monitor_start(ar); 1073d8899132SKalle Valo if (ret) 1074d8899132SKalle Valo goto err_mon_del; 1075d8899132SKalle Valo } else { 1076d8899132SKalle Valo if (!ar->monitor_vdev_created) 1077d8899132SKalle Valo goto exit; 1078d8899132SKalle Valo ret = ath12k_mac_monitor_stop(ar); 1079d8899132SKalle Valo if (ret) 1080d8899132SKalle Valo goto exit; 1081d8899132SKalle Valo ath12k_mac_monitor_vdev_delete(ar); 1082d8899132SKalle Valo } 1083d8899132SKalle Valo } 1084d8899132SKalle Valo 1085d8899132SKalle Valo exit: 1086d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 1087d8899132SKalle Valo return ret; 1088d8899132SKalle Valo 1089d8899132SKalle Valo err_mon_del: 1090d8899132SKalle Valo ath12k_mac_monitor_vdev_delete(ar); 1091d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 1092*d1335f0dSThiraviyam Mariyappan return ret; 1093d8899132SKalle Valo } 1094d8899132SKalle Valo 1095d8899132SKalle Valo static int ath12k_mac_setup_bcn_tmpl(struct ath12k_vif *arvif) 1096d8899132SKalle Valo { 1097d8899132SKalle Valo struct ath12k *ar = arvif->ar; 1098d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 1099d8899132SKalle Valo struct ieee80211_hw *hw = ar->hw; 1100d8899132SKalle Valo struct ieee80211_vif *vif = arvif->vif; 1101d8899132SKalle Valo struct ieee80211_mutable_offsets offs = {}; 1102d8899132SKalle Valo struct sk_buff *bcn; 1103d8899132SKalle Valo struct ieee80211_mgmt *mgmt; 1104d8899132SKalle Valo u8 *ies; 1105d8899132SKalle Valo int ret; 1106d8899132SKalle Valo 1107d8899132SKalle Valo if (arvif->vdev_type != WMI_VDEV_TYPE_AP) 1108d8899132SKalle Valo return 0; 1109d8899132SKalle Valo 1110d8899132SKalle Valo bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0); 1111d8899132SKalle Valo if (!bcn) { 1112d8899132SKalle Valo ath12k_warn(ab, "failed to get beacon template from mac80211\n"); 1113d8899132SKalle Valo return -EPERM; 1114d8899132SKalle Valo } 1115d8899132SKalle Valo 1116d8899132SKalle Valo ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn); 1117d8899132SKalle Valo ies += sizeof(mgmt->u.beacon); 1118d8899132SKalle Valo 1119d8899132SKalle Valo if (cfg80211_find_ie(WLAN_EID_RSN, ies, (skb_tail_pointer(bcn) - ies))) 1120d8899132SKalle Valo arvif->rsnie_present = true; 1121d8899132SKalle Valo 1122d8899132SKalle Valo if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, 1123d8899132SKalle Valo WLAN_OUI_TYPE_MICROSOFT_WPA, 1124d8899132SKalle Valo ies, (skb_tail_pointer(bcn) - ies))) 1125d8899132SKalle Valo arvif->wpaie_present = true; 1126d8899132SKalle Valo 1127d8899132SKalle Valo ret = ath12k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); 1128d8899132SKalle Valo 1129d8899132SKalle Valo kfree_skb(bcn); 1130d8899132SKalle Valo 1131d8899132SKalle Valo if (ret) 1132d8899132SKalle Valo ath12k_warn(ab, "failed to submit beacon template command: %d\n", 1133d8899132SKalle Valo ret); 1134d8899132SKalle Valo 1135d8899132SKalle Valo return ret; 1136d8899132SKalle Valo } 1137d8899132SKalle Valo 1138d8899132SKalle Valo static void ath12k_control_beaconing(struct ath12k_vif *arvif, 1139d8899132SKalle Valo struct ieee80211_bss_conf *info) 1140d8899132SKalle Valo { 1141d8899132SKalle Valo struct ath12k *ar = arvif->ar; 1142d8899132SKalle Valo int ret; 1143d8899132SKalle Valo 1144d8899132SKalle Valo lockdep_assert_held(&arvif->ar->conf_mutex); 1145d8899132SKalle Valo 1146d8899132SKalle Valo if (!info->enable_beacon) { 1147d8899132SKalle Valo ret = ath12k_wmi_vdev_down(ar, arvif->vdev_id); 1148d8899132SKalle Valo if (ret) 1149d8899132SKalle Valo ath12k_warn(ar->ab, "failed to down vdev_id %i: %d\n", 1150d8899132SKalle Valo arvif->vdev_id, ret); 1151d8899132SKalle Valo 1152d8899132SKalle Valo arvif->is_up = false; 1153d8899132SKalle Valo return; 1154d8899132SKalle Valo } 1155d8899132SKalle Valo 1156d8899132SKalle Valo /* Install the beacon template to the FW */ 1157d8899132SKalle Valo ret = ath12k_mac_setup_bcn_tmpl(arvif); 1158d8899132SKalle Valo if (ret) { 1159d8899132SKalle Valo ath12k_warn(ar->ab, "failed to update bcn tmpl during vdev up: %d\n", 1160d8899132SKalle Valo ret); 1161d8899132SKalle Valo return; 1162d8899132SKalle Valo } 1163d8899132SKalle Valo 1164d8899132SKalle Valo arvif->aid = 0; 1165d8899132SKalle Valo 1166d8899132SKalle Valo ether_addr_copy(arvif->bssid, info->bssid); 1167d8899132SKalle Valo 1168d8899132SKalle Valo ret = ath12k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, 1169d8899132SKalle Valo arvif->bssid); 1170d8899132SKalle Valo if (ret) { 1171d8899132SKalle Valo ath12k_warn(ar->ab, "failed to bring up vdev %d: %i\n", 1172d8899132SKalle Valo arvif->vdev_id, ret); 1173d8899132SKalle Valo return; 1174d8899132SKalle Valo } 1175d8899132SKalle Valo 1176d8899132SKalle Valo arvif->is_up = true; 1177d8899132SKalle Valo 1178d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id); 1179d8899132SKalle Valo } 1180d8899132SKalle Valo 1181d8899132SKalle Valo static void ath12k_peer_assoc_h_basic(struct ath12k *ar, 1182d8899132SKalle Valo struct ieee80211_vif *vif, 1183d8899132SKalle Valo struct ieee80211_sta *sta, 1184d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg *arg) 1185d8899132SKalle Valo { 1186d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 1187d8899132SKalle Valo u32 aid; 1188d8899132SKalle Valo 1189d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 1190d8899132SKalle Valo 1191d8899132SKalle Valo if (vif->type == NL80211_IFTYPE_STATION) 1192d8899132SKalle Valo aid = vif->cfg.aid; 1193d8899132SKalle Valo else 1194d8899132SKalle Valo aid = sta->aid; 1195d8899132SKalle Valo 1196d8899132SKalle Valo ether_addr_copy(arg->peer_mac, sta->addr); 1197d8899132SKalle Valo arg->vdev_id = arvif->vdev_id; 1198d8899132SKalle Valo arg->peer_associd = aid; 1199d8899132SKalle Valo arg->auth_flag = true; 1200d8899132SKalle Valo /* TODO: STA WAR in ath10k for listen interval required? */ 1201d8899132SKalle Valo arg->peer_listen_intval = ar->hw->conf.listen_interval; 1202d8899132SKalle Valo arg->peer_nss = 1; 1203d8899132SKalle Valo arg->peer_caps = vif->bss_conf.assoc_capability; 1204d8899132SKalle Valo } 1205d8899132SKalle Valo 1206d8899132SKalle Valo static void ath12k_peer_assoc_h_crypto(struct ath12k *ar, 1207d8899132SKalle Valo struct ieee80211_vif *vif, 1208d8899132SKalle Valo struct ieee80211_sta *sta, 1209d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg *arg) 1210d8899132SKalle Valo { 1211d8899132SKalle Valo struct ieee80211_bss_conf *info = &vif->bss_conf; 1212d8899132SKalle Valo struct cfg80211_chan_def def; 1213d8899132SKalle Valo struct cfg80211_bss *bss; 1214d8899132SKalle Valo struct ath12k_vif *arvif = (struct ath12k_vif *)vif->drv_priv; 1215d8899132SKalle Valo const u8 *rsnie = NULL; 1216d8899132SKalle Valo const u8 *wpaie = NULL; 1217d8899132SKalle Valo 1218d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 1219d8899132SKalle Valo 1220d8899132SKalle Valo if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) 1221d8899132SKalle Valo return; 1222d8899132SKalle Valo 1223d8899132SKalle Valo bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0, 1224d8899132SKalle Valo IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); 1225d8899132SKalle Valo 1226d8899132SKalle Valo if (arvif->rsnie_present || arvif->wpaie_present) { 1227d8899132SKalle Valo arg->need_ptk_4_way = true; 1228d8899132SKalle Valo if (arvif->wpaie_present) 1229d8899132SKalle Valo arg->need_gtk_2_way = true; 1230d8899132SKalle Valo } else if (bss) { 1231d8899132SKalle Valo const struct cfg80211_bss_ies *ies; 1232d8899132SKalle Valo 1233d8899132SKalle Valo rcu_read_lock(); 1234d8899132SKalle Valo rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN); 1235d8899132SKalle Valo 1236d8899132SKalle Valo ies = rcu_dereference(bss->ies); 1237d8899132SKalle Valo 1238d8899132SKalle Valo wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, 1239d8899132SKalle Valo WLAN_OUI_TYPE_MICROSOFT_WPA, 1240d8899132SKalle Valo ies->data, 1241d8899132SKalle Valo ies->len); 1242d8899132SKalle Valo rcu_read_unlock(); 1243d8899132SKalle Valo cfg80211_put_bss(ar->hw->wiphy, bss); 1244d8899132SKalle Valo } 1245d8899132SKalle Valo 1246d8899132SKalle Valo /* FIXME: base on RSN IE/WPA IE is a correct idea? */ 1247d8899132SKalle Valo if (rsnie || wpaie) { 1248d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_WMI, 1249d8899132SKalle Valo "%s: rsn ie found\n", __func__); 1250d8899132SKalle Valo arg->need_ptk_4_way = true; 1251d8899132SKalle Valo } 1252d8899132SKalle Valo 1253d8899132SKalle Valo if (wpaie) { 1254d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_WMI, 1255d8899132SKalle Valo "%s: wpa ie found\n", __func__); 1256d8899132SKalle Valo arg->need_gtk_2_way = true; 1257d8899132SKalle Valo } 1258d8899132SKalle Valo 1259d8899132SKalle Valo if (sta->mfp) { 1260d8899132SKalle Valo /* TODO: Need to check if FW supports PMF? */ 1261d8899132SKalle Valo arg->is_pmf_enabled = true; 1262d8899132SKalle Valo } 1263d8899132SKalle Valo 1264d8899132SKalle Valo /* TODO: safe_mode_enabled (bypass 4-way handshake) flag req? */ 1265d8899132SKalle Valo } 1266d8899132SKalle Valo 1267d8899132SKalle Valo static void ath12k_peer_assoc_h_rates(struct ath12k *ar, 1268d8899132SKalle Valo struct ieee80211_vif *vif, 1269d8899132SKalle Valo struct ieee80211_sta *sta, 1270d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg *arg) 1271d8899132SKalle Valo { 1272d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 1273d8899132SKalle Valo struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates; 1274d8899132SKalle Valo struct cfg80211_chan_def def; 1275d8899132SKalle Valo const struct ieee80211_supported_band *sband; 1276d8899132SKalle Valo const struct ieee80211_rate *rates; 1277d8899132SKalle Valo enum nl80211_band band; 1278d8899132SKalle Valo u32 ratemask; 1279d8899132SKalle Valo u8 rate; 1280d8899132SKalle Valo int i; 1281d8899132SKalle Valo 1282d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 1283d8899132SKalle Valo 1284d8899132SKalle Valo if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) 1285d8899132SKalle Valo return; 1286d8899132SKalle Valo 1287d8899132SKalle Valo band = def.chan->band; 1288d8899132SKalle Valo sband = ar->hw->wiphy->bands[band]; 1289d8899132SKalle Valo ratemask = sta->deflink.supp_rates[band]; 1290d8899132SKalle Valo ratemask &= arvif->bitrate_mask.control[band].legacy; 1291d8899132SKalle Valo rates = sband->bitrates; 1292d8899132SKalle Valo 1293d8899132SKalle Valo rateset->num_rates = 0; 1294d8899132SKalle Valo 1295d8899132SKalle Valo for (i = 0; i < 32; i++, ratemask >>= 1, rates++) { 1296d8899132SKalle Valo if (!(ratemask & 1)) 1297d8899132SKalle Valo continue; 1298d8899132SKalle Valo 1299d8899132SKalle Valo rate = ath12k_mac_bitrate_to_rate(rates->bitrate); 1300d8899132SKalle Valo rateset->rates[rateset->num_rates] = rate; 1301d8899132SKalle Valo rateset->num_rates++; 1302d8899132SKalle Valo } 1303d8899132SKalle Valo } 1304d8899132SKalle Valo 1305d8899132SKalle Valo static bool 1306d8899132SKalle Valo ath12k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) 1307d8899132SKalle Valo { 1308d8899132SKalle Valo int nss; 1309d8899132SKalle Valo 1310d8899132SKalle Valo for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++) 1311d8899132SKalle Valo if (ht_mcs_mask[nss]) 1312d8899132SKalle Valo return false; 1313d8899132SKalle Valo 1314d8899132SKalle Valo return true; 1315d8899132SKalle Valo } 1316d8899132SKalle Valo 1317d8899132SKalle Valo static bool 1318d8899132SKalle Valo ath12k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX]) 1319d8899132SKalle Valo { 1320d8899132SKalle Valo int nss; 1321d8899132SKalle Valo 1322d8899132SKalle Valo for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) 1323d8899132SKalle Valo if (vht_mcs_mask[nss]) 1324d8899132SKalle Valo return false; 1325d8899132SKalle Valo 1326d8899132SKalle Valo return true; 1327d8899132SKalle Valo } 1328d8899132SKalle Valo 1329d8899132SKalle Valo static void ath12k_peer_assoc_h_ht(struct ath12k *ar, 1330d8899132SKalle Valo struct ieee80211_vif *vif, 1331d8899132SKalle Valo struct ieee80211_sta *sta, 1332d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg *arg) 1333d8899132SKalle Valo { 1334d8899132SKalle Valo const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; 1335d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 1336d8899132SKalle Valo struct cfg80211_chan_def def; 1337d8899132SKalle Valo enum nl80211_band band; 1338d8899132SKalle Valo const u8 *ht_mcs_mask; 1339d8899132SKalle Valo int i, n; 1340d8899132SKalle Valo u8 max_nss; 1341d8899132SKalle Valo u32 stbc; 1342d8899132SKalle Valo 1343d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 1344d8899132SKalle Valo 1345d8899132SKalle Valo if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) 1346d8899132SKalle Valo return; 1347d8899132SKalle Valo 1348d8899132SKalle Valo if (!ht_cap->ht_supported) 1349d8899132SKalle Valo return; 1350d8899132SKalle Valo 1351d8899132SKalle Valo band = def.chan->band; 1352d8899132SKalle Valo ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs; 1353d8899132SKalle Valo 1354d8899132SKalle Valo if (ath12k_peer_assoc_h_ht_masked(ht_mcs_mask)) 1355d8899132SKalle Valo return; 1356d8899132SKalle Valo 1357d8899132SKalle Valo arg->ht_flag = true; 1358d8899132SKalle Valo 1359d8899132SKalle Valo arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + 1360d8899132SKalle Valo ht_cap->ampdu_factor)) - 1; 1361d8899132SKalle Valo 1362d8899132SKalle Valo arg->peer_mpdu_density = 1363d8899132SKalle Valo ath12k_parse_mpdudensity(ht_cap->ampdu_density); 1364d8899132SKalle Valo 1365d8899132SKalle Valo arg->peer_ht_caps = ht_cap->cap; 1366d8899132SKalle Valo arg->peer_rate_caps |= WMI_HOST_RC_HT_FLAG; 1367d8899132SKalle Valo 1368d8899132SKalle Valo if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING) 1369d8899132SKalle Valo arg->ldpc_flag = true; 1370d8899132SKalle Valo 1371d8899132SKalle Valo if (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) { 1372d8899132SKalle Valo arg->bw_40 = true; 1373d8899132SKalle Valo arg->peer_rate_caps |= WMI_HOST_RC_CW40_FLAG; 1374d8899132SKalle Valo } 1375d8899132SKalle Valo 1376d8899132SKalle Valo if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) { 1377d8899132SKalle Valo if (ht_cap->cap & (IEEE80211_HT_CAP_SGI_20 | 1378d8899132SKalle Valo IEEE80211_HT_CAP_SGI_40)) 1379d8899132SKalle Valo arg->peer_rate_caps |= WMI_HOST_RC_SGI_FLAG; 1380d8899132SKalle Valo } 1381d8899132SKalle Valo 1382d8899132SKalle Valo if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) { 1383d8899132SKalle Valo arg->peer_rate_caps |= WMI_HOST_RC_TX_STBC_FLAG; 1384d8899132SKalle Valo arg->stbc_flag = true; 1385d8899132SKalle Valo } 1386d8899132SKalle Valo 1387d8899132SKalle Valo if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) { 1388d8899132SKalle Valo stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC; 1389d8899132SKalle Valo stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT; 1390d8899132SKalle Valo stbc = stbc << WMI_HOST_RC_RX_STBC_FLAG_S; 1391d8899132SKalle Valo arg->peer_rate_caps |= stbc; 1392d8899132SKalle Valo arg->stbc_flag = true; 1393d8899132SKalle Valo } 1394d8899132SKalle Valo 1395d8899132SKalle Valo if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2]) 1396d8899132SKalle Valo arg->peer_rate_caps |= WMI_HOST_RC_TS_FLAG; 1397d8899132SKalle Valo else if (ht_cap->mcs.rx_mask[1]) 1398d8899132SKalle Valo arg->peer_rate_caps |= WMI_HOST_RC_DS_FLAG; 1399d8899132SKalle Valo 1400d8899132SKalle Valo for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++) 1401d8899132SKalle Valo if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) && 1402d8899132SKalle Valo (ht_mcs_mask[i / 8] & BIT(i % 8))) { 1403d8899132SKalle Valo max_nss = (i / 8) + 1; 1404d8899132SKalle Valo arg->peer_ht_rates.rates[n++] = i; 1405d8899132SKalle Valo } 1406d8899132SKalle Valo 1407d8899132SKalle Valo /* This is a workaround for HT-enabled STAs which break the spec 1408d8899132SKalle Valo * and have no HT capabilities RX mask (no HT RX MCS map). 1409d8899132SKalle Valo * 1410d8899132SKalle Valo * As per spec, in section 20.3.5 Modulation and coding scheme (MCS), 1411d8899132SKalle Valo * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs. 1412d8899132SKalle Valo * 1413d8899132SKalle Valo * Firmware asserts if such situation occurs. 1414d8899132SKalle Valo */ 1415d8899132SKalle Valo if (n == 0) { 1416d8899132SKalle Valo arg->peer_ht_rates.num_rates = 8; 1417d8899132SKalle Valo for (i = 0; i < arg->peer_ht_rates.num_rates; i++) 1418d8899132SKalle Valo arg->peer_ht_rates.rates[i] = i; 1419d8899132SKalle Valo } else { 1420d8899132SKalle Valo arg->peer_ht_rates.num_rates = n; 1421d8899132SKalle Valo arg->peer_nss = min(sta->deflink.rx_nss, max_nss); 1422d8899132SKalle Valo } 1423d8899132SKalle Valo 1424d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n", 1425d8899132SKalle Valo arg->peer_mac, 1426d8899132SKalle Valo arg->peer_ht_rates.num_rates, 1427d8899132SKalle Valo arg->peer_nss); 1428d8899132SKalle Valo } 1429d8899132SKalle Valo 1430d8899132SKalle Valo static int ath12k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss) 1431d8899132SKalle Valo { 1432d8899132SKalle Valo switch ((mcs_map >> (2 * nss)) & 0x3) { 1433d8899132SKalle Valo case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1; 1434d8899132SKalle Valo case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1; 1435d8899132SKalle Valo case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1; 1436d8899132SKalle Valo } 1437d8899132SKalle Valo return 0; 1438d8899132SKalle Valo } 1439d8899132SKalle Valo 1440d8899132SKalle Valo static u16 1441d8899132SKalle Valo ath12k_peer_assoc_h_vht_limit(u16 tx_mcs_set, 1442d8899132SKalle Valo const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX]) 1443d8899132SKalle Valo { 1444d8899132SKalle Valo int idx_limit; 1445d8899132SKalle Valo int nss; 1446d8899132SKalle Valo u16 mcs_map; 1447d8899132SKalle Valo u16 mcs; 1448d8899132SKalle Valo 1449d8899132SKalle Valo for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) { 1450d8899132SKalle Valo mcs_map = ath12k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) & 1451d8899132SKalle Valo vht_mcs_limit[nss]; 1452d8899132SKalle Valo 1453d8899132SKalle Valo if (mcs_map) 1454d8899132SKalle Valo idx_limit = fls(mcs_map) - 1; 1455d8899132SKalle Valo else 1456d8899132SKalle Valo idx_limit = -1; 1457d8899132SKalle Valo 1458d8899132SKalle Valo switch (idx_limit) { 1459d8899132SKalle Valo case 0: 1460d8899132SKalle Valo case 1: 1461d8899132SKalle Valo case 2: 1462d8899132SKalle Valo case 3: 1463d8899132SKalle Valo case 4: 1464d8899132SKalle Valo case 5: 1465d8899132SKalle Valo case 6: 1466d8899132SKalle Valo case 7: 1467d8899132SKalle Valo mcs = IEEE80211_VHT_MCS_SUPPORT_0_7; 1468d8899132SKalle Valo break; 1469d8899132SKalle Valo case 8: 1470d8899132SKalle Valo mcs = IEEE80211_VHT_MCS_SUPPORT_0_8; 1471d8899132SKalle Valo break; 1472d8899132SKalle Valo case 9: 1473d8899132SKalle Valo mcs = IEEE80211_VHT_MCS_SUPPORT_0_9; 1474d8899132SKalle Valo break; 1475d8899132SKalle Valo default: 1476d8899132SKalle Valo WARN_ON(1); 1477d8899132SKalle Valo fallthrough; 1478d8899132SKalle Valo case -1: 1479d8899132SKalle Valo mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED; 1480d8899132SKalle Valo break; 1481d8899132SKalle Valo } 1482d8899132SKalle Valo 1483d8899132SKalle Valo tx_mcs_set &= ~(0x3 << (nss * 2)); 1484d8899132SKalle Valo tx_mcs_set |= mcs << (nss * 2); 1485d8899132SKalle Valo } 1486d8899132SKalle Valo 1487d8899132SKalle Valo return tx_mcs_set; 1488d8899132SKalle Valo } 1489d8899132SKalle Valo 1490d8899132SKalle Valo static void ath12k_peer_assoc_h_vht(struct ath12k *ar, 1491d8899132SKalle Valo struct ieee80211_vif *vif, 1492d8899132SKalle Valo struct ieee80211_sta *sta, 1493d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg *arg) 1494d8899132SKalle Valo { 1495d8899132SKalle Valo const struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; 1496d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 1497d8899132SKalle Valo struct cfg80211_chan_def def; 1498d8899132SKalle Valo enum nl80211_band band; 1499d8899132SKalle Valo const u16 *vht_mcs_mask; 1500d8899132SKalle Valo u16 tx_mcs_map; 1501d8899132SKalle Valo u8 ampdu_factor; 1502d8899132SKalle Valo u8 max_nss, vht_mcs; 1503d8899132SKalle Valo int i; 1504d8899132SKalle Valo 1505d8899132SKalle Valo if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) 1506d8899132SKalle Valo return; 1507d8899132SKalle Valo 1508d8899132SKalle Valo if (!vht_cap->vht_supported) 1509d8899132SKalle Valo return; 1510d8899132SKalle Valo 1511d8899132SKalle Valo band = def.chan->band; 1512d8899132SKalle Valo vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs; 1513d8899132SKalle Valo 1514d8899132SKalle Valo if (ath12k_peer_assoc_h_vht_masked(vht_mcs_mask)) 1515d8899132SKalle Valo return; 1516d8899132SKalle Valo 1517d8899132SKalle Valo arg->vht_flag = true; 1518d8899132SKalle Valo 1519d8899132SKalle Valo /* TODO: similar flags required? */ 1520d8899132SKalle Valo arg->vht_capable = true; 1521d8899132SKalle Valo 1522d8899132SKalle Valo if (def.chan->band == NL80211_BAND_2GHZ) 1523d8899132SKalle Valo arg->vht_ng_flag = true; 1524d8899132SKalle Valo 1525d8899132SKalle Valo arg->peer_vht_caps = vht_cap->cap; 1526d8899132SKalle Valo 1527d8899132SKalle Valo ampdu_factor = (vht_cap->cap & 1528d8899132SKalle Valo IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >> 1529d8899132SKalle Valo IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; 1530d8899132SKalle Valo 1531d8899132SKalle Valo /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to 1532d8899132SKalle Valo * zero in VHT IE. Using it would result in degraded throughput. 1533d8899132SKalle Valo * arg->peer_max_mpdu at this point contains HT max_mpdu so keep 1534d8899132SKalle Valo * it if VHT max_mpdu is smaller. 1535d8899132SKalle Valo */ 1536d8899132SKalle Valo arg->peer_max_mpdu = max(arg->peer_max_mpdu, 1537d8899132SKalle Valo (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR + 1538d8899132SKalle Valo ampdu_factor)) - 1); 1539d8899132SKalle Valo 1540d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) 1541d8899132SKalle Valo arg->bw_80 = true; 1542d8899132SKalle Valo 1543d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) 1544d8899132SKalle Valo arg->bw_160 = true; 1545d8899132SKalle Valo 1546d8899132SKalle Valo /* Calculate peer NSS capability from VHT capabilities if STA 1547d8899132SKalle Valo * supports VHT. 1548d8899132SKalle Valo */ 1549d8899132SKalle Valo for (i = 0, max_nss = 0, vht_mcs = 0; i < NL80211_VHT_NSS_MAX; i++) { 1550d8899132SKalle Valo vht_mcs = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) >> 1551d8899132SKalle Valo (2 * i) & 3; 1552d8899132SKalle Valo 1553d8899132SKalle Valo if (vht_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED && 1554d8899132SKalle Valo vht_mcs_mask[i]) 1555d8899132SKalle Valo max_nss = i + 1; 1556d8899132SKalle Valo } 1557d8899132SKalle Valo arg->peer_nss = min(sta->deflink.rx_nss, max_nss); 1558d8899132SKalle Valo arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest); 1559d8899132SKalle Valo arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map); 1560d8899132SKalle Valo arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); 1561d8899132SKalle Valo 1562d8899132SKalle Valo tx_mcs_map = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); 1563d8899132SKalle Valo arg->tx_mcs_set = ath12k_peer_assoc_h_vht_limit(tx_mcs_map, vht_mcs_mask); 1564d8899132SKalle Valo 1565d8899132SKalle Valo /* In QCN9274 platform, VHT MCS rate 10 and 11 is enabled by default. 1566d8899132SKalle Valo * VHT MCS rate 10 and 11 is not supported in 11ac standard. 1567d8899132SKalle Valo * so explicitly disable the VHT MCS rate 10 and 11 in 11ac mode. 1568d8899132SKalle Valo */ 1569d8899132SKalle Valo arg->tx_mcs_set &= ~IEEE80211_VHT_MCS_SUPPORT_0_11_MASK; 1570d8899132SKalle Valo arg->tx_mcs_set |= IEEE80211_DISABLE_VHT_MCS_SUPPORT_0_11; 1571d8899132SKalle Valo 1572d8899132SKalle Valo if ((arg->tx_mcs_set & IEEE80211_VHT_MCS_NOT_SUPPORTED) == 1573d8899132SKalle Valo IEEE80211_VHT_MCS_NOT_SUPPORTED) 1574d8899132SKalle Valo arg->peer_vht_caps &= ~IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; 1575d8899132SKalle Valo 1576d8899132SKalle Valo /* TODO: Check */ 1577d8899132SKalle Valo arg->tx_max_mcs_nss = 0xFF; 1578d8899132SKalle Valo 1579d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n", 1580d8899132SKalle Valo sta->addr, arg->peer_max_mpdu, arg->peer_flags); 1581d8899132SKalle Valo 1582d8899132SKalle Valo /* TODO: rxnss_override */ 1583d8899132SKalle Valo } 1584d8899132SKalle Valo 1585d8899132SKalle Valo static void ath12k_peer_assoc_h_he(struct ath12k *ar, 1586d8899132SKalle Valo struct ieee80211_vif *vif, 1587d8899132SKalle Valo struct ieee80211_sta *sta, 1588d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg *arg) 1589d8899132SKalle Valo { 1590d8899132SKalle Valo const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; 1591d8899132SKalle Valo int i; 1592d8899132SKalle Valo u8 ampdu_factor, rx_mcs_80, rx_mcs_160, max_nss; 1593d8899132SKalle Valo u16 mcs_160_map, mcs_80_map; 1594d8899132SKalle Valo bool support_160; 1595d8899132SKalle Valo u16 v; 1596d8899132SKalle Valo 1597d8899132SKalle Valo if (!he_cap->has_he) 1598d8899132SKalle Valo return; 1599d8899132SKalle Valo 1600d8899132SKalle Valo arg->he_flag = true; 1601d8899132SKalle Valo 1602d8899132SKalle Valo support_160 = !!(he_cap->he_cap_elem.phy_cap_info[0] & 1603d8899132SKalle Valo IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G); 1604d8899132SKalle Valo 1605d8899132SKalle Valo /* Supported HE-MCS and NSS Set of peer he_cap is intersection with self he_cp */ 1606d8899132SKalle Valo mcs_160_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); 1607d8899132SKalle Valo mcs_80_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); 1608d8899132SKalle Valo 1609d8899132SKalle Valo if (support_160) { 1610d8899132SKalle Valo for (i = 7; i >= 0; i--) { 1611d8899132SKalle Valo u8 mcs_160 = (mcs_160_map >> (2 * i)) & 3; 1612d8899132SKalle Valo 1613d8899132SKalle Valo if (mcs_160 != IEEE80211_HE_MCS_NOT_SUPPORTED) { 1614d8899132SKalle Valo rx_mcs_160 = i + 1; 1615d8899132SKalle Valo break; 1616d8899132SKalle Valo } 1617d8899132SKalle Valo } 1618d8899132SKalle Valo } 1619d8899132SKalle Valo 1620d8899132SKalle Valo for (i = 7; i >= 0; i--) { 1621d8899132SKalle Valo u8 mcs_80 = (mcs_80_map >> (2 * i)) & 3; 1622d8899132SKalle Valo 1623d8899132SKalle Valo if (mcs_80 != IEEE80211_HE_MCS_NOT_SUPPORTED) { 1624d8899132SKalle Valo rx_mcs_80 = i + 1; 1625d8899132SKalle Valo break; 1626d8899132SKalle Valo } 1627d8899132SKalle Valo } 1628d8899132SKalle Valo 1629d8899132SKalle Valo if (support_160) 1630d8899132SKalle Valo max_nss = min(rx_mcs_80, rx_mcs_160); 1631d8899132SKalle Valo else 1632d8899132SKalle Valo max_nss = rx_mcs_80; 1633d8899132SKalle Valo 1634d8899132SKalle Valo arg->peer_nss = min(sta->deflink.rx_nss, max_nss); 1635d8899132SKalle Valo 1636d8899132SKalle Valo memcpy(&arg->peer_he_cap_macinfo, he_cap->he_cap_elem.mac_cap_info, 1637d8899132SKalle Valo sizeof(arg->peer_he_cap_macinfo)); 1638d8899132SKalle Valo memcpy(&arg->peer_he_cap_phyinfo, he_cap->he_cap_elem.phy_cap_info, 1639d8899132SKalle Valo sizeof(arg->peer_he_cap_phyinfo)); 1640d8899132SKalle Valo arg->peer_he_ops = vif->bss_conf.he_oper.params; 1641d8899132SKalle Valo 1642d8899132SKalle Valo /* the top most byte is used to indicate BSS color info */ 1643d8899132SKalle Valo arg->peer_he_ops &= 0xffffff; 1644d8899132SKalle Valo 1645d8899132SKalle Valo /* As per section 26.6.1 IEEE Std 802.11ax‐2022, if the Max AMPDU 1646d8899132SKalle Valo * Exponent Extension in HE cap is zero, use the arg->peer_max_mpdu 1647d8899132SKalle Valo * as calculated while parsing VHT caps(if VHT caps is present) 1648d8899132SKalle Valo * or HT caps (if VHT caps is not present). 1649d8899132SKalle Valo * 1650d8899132SKalle Valo * For non-zero value of Max AMPDU Exponent Extension in HE MAC caps, 1651d8899132SKalle Valo * if a HE STA sends VHT cap and HE cap IE in assoc request then, use 1652d8899132SKalle Valo * MAX_AMPDU_LEN_FACTOR as 20 to calculate max_ampdu length. 1653d8899132SKalle Valo * If a HE STA that does not send VHT cap, but HE and HT cap in assoc 1654d8899132SKalle Valo * request, then use MAX_AMPDU_LEN_FACTOR as 16 to calculate max_ampdu 1655d8899132SKalle Valo * length. 1656d8899132SKalle Valo */ 1657d8899132SKalle Valo ampdu_factor = (he_cap->he_cap_elem.mac_cap_info[3] & 1658d8899132SKalle Valo IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) >> 1659d8899132SKalle Valo IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK; 1660d8899132SKalle Valo 1661d8899132SKalle Valo if (ampdu_factor) { 1662d8899132SKalle Valo if (sta->deflink.vht_cap.vht_supported) 1663d8899132SKalle Valo arg->peer_max_mpdu = (1 << (IEEE80211_HE_VHT_MAX_AMPDU_FACTOR + 1664d8899132SKalle Valo ampdu_factor)) - 1; 1665d8899132SKalle Valo else if (sta->deflink.ht_cap.ht_supported) 1666d8899132SKalle Valo arg->peer_max_mpdu = (1 << (IEEE80211_HE_HT_MAX_AMPDU_FACTOR + 1667d8899132SKalle Valo ampdu_factor)) - 1; 1668d8899132SKalle Valo } 1669d8899132SKalle Valo 1670d8899132SKalle Valo if (he_cap->he_cap_elem.phy_cap_info[6] & 1671d8899132SKalle Valo IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) { 1672d8899132SKalle Valo int bit = 7; 1673d8899132SKalle Valo int nss, ru; 1674d8899132SKalle Valo 1675d8899132SKalle Valo arg->peer_ppet.numss_m1 = he_cap->ppe_thres[0] & 1676d8899132SKalle Valo IEEE80211_PPE_THRES_NSS_MASK; 1677d8899132SKalle Valo arg->peer_ppet.ru_bit_mask = 1678d8899132SKalle Valo (he_cap->ppe_thres[0] & 1679d8899132SKalle Valo IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK) >> 1680d8899132SKalle Valo IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS; 1681d8899132SKalle Valo 1682d8899132SKalle Valo for (nss = 0; nss <= arg->peer_ppet.numss_m1; nss++) { 1683d8899132SKalle Valo for (ru = 0; ru < 4; ru++) { 1684d8899132SKalle Valo u32 val = 0; 1685d8899132SKalle Valo int i; 1686d8899132SKalle Valo 1687d8899132SKalle Valo if ((arg->peer_ppet.ru_bit_mask & BIT(ru)) == 0) 1688d8899132SKalle Valo continue; 1689d8899132SKalle Valo for (i = 0; i < 6; i++) { 1690d8899132SKalle Valo val >>= 1; 1691d8899132SKalle Valo val |= ((he_cap->ppe_thres[bit / 8] >> 1692d8899132SKalle Valo (bit % 8)) & 0x1) << 5; 1693d8899132SKalle Valo bit++; 1694d8899132SKalle Valo } 1695d8899132SKalle Valo arg->peer_ppet.ppet16_ppet8_ru3_ru0[nss] |= 1696d8899132SKalle Valo val << (ru * 6); 1697d8899132SKalle Valo } 1698d8899132SKalle Valo } 1699d8899132SKalle Valo } 1700d8899132SKalle Valo 1701d8899132SKalle Valo if (he_cap->he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_RES) 1702d8899132SKalle Valo arg->twt_responder = true; 1703d8899132SKalle Valo if (he_cap->he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_REQ) 1704d8899132SKalle Valo arg->twt_requester = true; 1705d8899132SKalle Valo 1706d8899132SKalle Valo switch (sta->deflink.bandwidth) { 1707d8899132SKalle Valo case IEEE80211_STA_RX_BW_160: 1708d8899132SKalle Valo if (he_cap->he_cap_elem.phy_cap_info[0] & 1709d8899132SKalle Valo IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) { 1710d8899132SKalle Valo v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80p80); 1711d8899132SKalle Valo arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v; 1712d8899132SKalle Valo 1713d8899132SKalle Valo v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80p80); 1714d8899132SKalle Valo arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v; 1715d8899132SKalle Valo 1716d8899132SKalle Valo arg->peer_he_mcs_count++; 1717d8899132SKalle Valo } 1718d8899132SKalle Valo v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); 1719d8899132SKalle Valo arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; 1720d8899132SKalle Valo 1721d8899132SKalle Valo v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); 1722d8899132SKalle Valo arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; 1723d8899132SKalle Valo 1724d8899132SKalle Valo arg->peer_he_mcs_count++; 1725d8899132SKalle Valo fallthrough; 1726d8899132SKalle Valo 1727d8899132SKalle Valo default: 1728d8899132SKalle Valo v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); 1729d8899132SKalle Valo arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; 1730d8899132SKalle Valo 1731d8899132SKalle Valo v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); 1732d8899132SKalle Valo arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; 1733d8899132SKalle Valo 1734d8899132SKalle Valo arg->peer_he_mcs_count++; 1735d8899132SKalle Valo break; 1736d8899132SKalle Valo } 1737d8899132SKalle Valo } 1738d8899132SKalle Valo 1739d8899132SKalle Valo static void ath12k_peer_assoc_h_smps(struct ieee80211_sta *sta, 1740d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg *arg) 1741d8899132SKalle Valo { 1742d8899132SKalle Valo const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; 1743d8899132SKalle Valo int smps; 1744d8899132SKalle Valo 1745d8899132SKalle Valo if (!ht_cap->ht_supported) 1746d8899132SKalle Valo return; 1747d8899132SKalle Valo 1748d8899132SKalle Valo smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS; 1749d8899132SKalle Valo smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT; 1750d8899132SKalle Valo 1751d8899132SKalle Valo switch (smps) { 1752d8899132SKalle Valo case WLAN_HT_CAP_SM_PS_STATIC: 1753d8899132SKalle Valo arg->static_mimops_flag = true; 1754d8899132SKalle Valo break; 1755d8899132SKalle Valo case WLAN_HT_CAP_SM_PS_DYNAMIC: 1756d8899132SKalle Valo arg->dynamic_mimops_flag = true; 1757d8899132SKalle Valo break; 1758d8899132SKalle Valo case WLAN_HT_CAP_SM_PS_DISABLED: 1759d8899132SKalle Valo arg->spatial_mux_flag = true; 1760d8899132SKalle Valo break; 1761d8899132SKalle Valo default: 1762d8899132SKalle Valo break; 1763d8899132SKalle Valo } 1764d8899132SKalle Valo } 1765d8899132SKalle Valo 1766d8899132SKalle Valo static void ath12k_peer_assoc_h_qos(struct ath12k *ar, 1767d8899132SKalle Valo struct ieee80211_vif *vif, 1768d8899132SKalle Valo struct ieee80211_sta *sta, 1769d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg *arg) 1770d8899132SKalle Valo { 1771d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 1772d8899132SKalle Valo 1773d8899132SKalle Valo switch (arvif->vdev_type) { 1774d8899132SKalle Valo case WMI_VDEV_TYPE_AP: 1775d8899132SKalle Valo if (sta->wme) { 1776d8899132SKalle Valo /* TODO: Check WME vs QoS */ 1777d8899132SKalle Valo arg->is_wme_set = true; 1778d8899132SKalle Valo arg->qos_flag = true; 1779d8899132SKalle Valo } 1780d8899132SKalle Valo 1781d8899132SKalle Valo if (sta->wme && sta->uapsd_queues) { 1782d8899132SKalle Valo /* TODO: Check WME vs QoS */ 1783d8899132SKalle Valo arg->is_wme_set = true; 1784d8899132SKalle Valo arg->apsd_flag = true; 1785d8899132SKalle Valo arg->peer_rate_caps |= WMI_HOST_RC_UAPSD_FLAG; 1786d8899132SKalle Valo } 1787d8899132SKalle Valo break; 1788d8899132SKalle Valo case WMI_VDEV_TYPE_STA: 1789d8899132SKalle Valo if (sta->wme) { 1790d8899132SKalle Valo arg->is_wme_set = true; 1791d8899132SKalle Valo arg->qos_flag = true; 1792d8899132SKalle Valo } 1793d8899132SKalle Valo break; 1794d8899132SKalle Valo default: 1795d8899132SKalle Valo break; 1796d8899132SKalle Valo } 1797d8899132SKalle Valo 1798d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac peer %pM qos %d\n", 1799d8899132SKalle Valo sta->addr, arg->qos_flag); 1800d8899132SKalle Valo } 1801d8899132SKalle Valo 1802d8899132SKalle Valo static int ath12k_peer_assoc_qos_ap(struct ath12k *ar, 1803d8899132SKalle Valo struct ath12k_vif *arvif, 1804d8899132SKalle Valo struct ieee80211_sta *sta) 1805d8899132SKalle Valo { 1806d8899132SKalle Valo struct ath12k_wmi_ap_ps_arg arg; 1807d8899132SKalle Valo u32 max_sp; 1808d8899132SKalle Valo u32 uapsd; 1809d8899132SKalle Valo int ret; 1810d8899132SKalle Valo 1811d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 1812d8899132SKalle Valo 1813d8899132SKalle Valo arg.vdev_id = arvif->vdev_id; 1814d8899132SKalle Valo 1815d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n", 1816d8899132SKalle Valo sta->uapsd_queues, sta->max_sp); 1817d8899132SKalle Valo 1818d8899132SKalle Valo uapsd = 0; 1819d8899132SKalle Valo if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) 1820d8899132SKalle Valo uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN | 1821d8899132SKalle Valo WMI_AP_PS_UAPSD_AC3_TRIGGER_EN; 1822d8899132SKalle Valo if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) 1823d8899132SKalle Valo uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN | 1824d8899132SKalle Valo WMI_AP_PS_UAPSD_AC2_TRIGGER_EN; 1825d8899132SKalle Valo if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) 1826d8899132SKalle Valo uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN | 1827d8899132SKalle Valo WMI_AP_PS_UAPSD_AC1_TRIGGER_EN; 1828d8899132SKalle Valo if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) 1829d8899132SKalle Valo uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN | 1830d8899132SKalle Valo WMI_AP_PS_UAPSD_AC0_TRIGGER_EN; 1831d8899132SKalle Valo 1832d8899132SKalle Valo max_sp = 0; 1833d8899132SKalle Valo if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP) 1834d8899132SKalle Valo max_sp = sta->max_sp; 1835d8899132SKalle Valo 1836d8899132SKalle Valo arg.param = WMI_AP_PS_PEER_PARAM_UAPSD; 1837d8899132SKalle Valo arg.value = uapsd; 1838d8899132SKalle Valo ret = ath12k_wmi_send_set_ap_ps_param_cmd(ar, sta->addr, &arg); 1839d8899132SKalle Valo if (ret) 1840d8899132SKalle Valo goto err; 1841d8899132SKalle Valo 1842d8899132SKalle Valo arg.param = WMI_AP_PS_PEER_PARAM_MAX_SP; 1843d8899132SKalle Valo arg.value = max_sp; 1844d8899132SKalle Valo ret = ath12k_wmi_send_set_ap_ps_param_cmd(ar, sta->addr, &arg); 1845d8899132SKalle Valo if (ret) 1846d8899132SKalle Valo goto err; 1847d8899132SKalle Valo 1848d8899132SKalle Valo /* TODO: revisit during testing */ 1849d8899132SKalle Valo arg.param = WMI_AP_PS_PEER_PARAM_SIFS_RESP_FRMTYPE; 1850d8899132SKalle Valo arg.value = DISABLE_SIFS_RESPONSE_TRIGGER; 1851d8899132SKalle Valo ret = ath12k_wmi_send_set_ap_ps_param_cmd(ar, sta->addr, &arg); 1852d8899132SKalle Valo if (ret) 1853d8899132SKalle Valo goto err; 1854d8899132SKalle Valo 1855d8899132SKalle Valo arg.param = WMI_AP_PS_PEER_PARAM_SIFS_RESP_UAPSD; 1856d8899132SKalle Valo arg.value = DISABLE_SIFS_RESPONSE_TRIGGER; 1857d8899132SKalle Valo ret = ath12k_wmi_send_set_ap_ps_param_cmd(ar, sta->addr, &arg); 1858d8899132SKalle Valo if (ret) 1859d8899132SKalle Valo goto err; 1860d8899132SKalle Valo 1861d8899132SKalle Valo return 0; 1862d8899132SKalle Valo 1863d8899132SKalle Valo err: 1864d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set ap ps peer param %d for vdev %i: %d\n", 1865d8899132SKalle Valo arg.param, arvif->vdev_id, ret); 1866d8899132SKalle Valo return ret; 1867d8899132SKalle Valo } 1868d8899132SKalle Valo 1869d8899132SKalle Valo static bool ath12k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta) 1870d8899132SKalle Valo { 1871d8899132SKalle Valo return sta->deflink.supp_rates[NL80211_BAND_2GHZ] >> 1872d8899132SKalle Valo ATH12K_MAC_FIRST_OFDM_RATE_IDX; 1873d8899132SKalle Valo } 1874d8899132SKalle Valo 1875d8899132SKalle Valo static enum wmi_phy_mode ath12k_mac_get_phymode_vht(struct ath12k *ar, 1876d8899132SKalle Valo struct ieee80211_sta *sta) 1877d8899132SKalle Valo { 1878d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) { 1879d8899132SKalle Valo switch (sta->deflink.vht_cap.cap & 1880d8899132SKalle Valo IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) { 1881d8899132SKalle Valo case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ: 1882d8899132SKalle Valo return MODE_11AC_VHT160; 1883d8899132SKalle Valo case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ: 1884d8899132SKalle Valo return MODE_11AC_VHT80_80; 1885d8899132SKalle Valo default: 1886d8899132SKalle Valo /* not sure if this is a valid case? */ 1887d8899132SKalle Valo return MODE_11AC_VHT160; 1888d8899132SKalle Valo } 1889d8899132SKalle Valo } 1890d8899132SKalle Valo 1891d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) 1892d8899132SKalle Valo return MODE_11AC_VHT80; 1893d8899132SKalle Valo 1894d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) 1895d8899132SKalle Valo return MODE_11AC_VHT40; 1896d8899132SKalle Valo 1897d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) 1898d8899132SKalle Valo return MODE_11AC_VHT20; 1899d8899132SKalle Valo 1900d8899132SKalle Valo return MODE_UNKNOWN; 1901d8899132SKalle Valo } 1902d8899132SKalle Valo 1903d8899132SKalle Valo static enum wmi_phy_mode ath12k_mac_get_phymode_he(struct ath12k *ar, 1904d8899132SKalle Valo struct ieee80211_sta *sta) 1905d8899132SKalle Valo { 1906d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) { 1907d8899132SKalle Valo if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] & 1908d8899132SKalle Valo IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) 1909d8899132SKalle Valo return MODE_11AX_HE160; 1910d8899132SKalle Valo else if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] & 1911d8899132SKalle Valo IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) 1912d8899132SKalle Valo return MODE_11AX_HE80_80; 1913d8899132SKalle Valo /* not sure if this is a valid case? */ 1914d8899132SKalle Valo return MODE_11AX_HE160; 1915d8899132SKalle Valo } 1916d8899132SKalle Valo 1917d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) 1918d8899132SKalle Valo return MODE_11AX_HE80; 1919d8899132SKalle Valo 1920d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) 1921d8899132SKalle Valo return MODE_11AX_HE40; 1922d8899132SKalle Valo 1923d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) 1924d8899132SKalle Valo return MODE_11AX_HE20; 1925d8899132SKalle Valo 1926d8899132SKalle Valo return MODE_UNKNOWN; 1927d8899132SKalle Valo } 1928d8899132SKalle Valo 1929d8899132SKalle Valo static void ath12k_peer_assoc_h_phymode(struct ath12k *ar, 1930d8899132SKalle Valo struct ieee80211_vif *vif, 1931d8899132SKalle Valo struct ieee80211_sta *sta, 1932d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg *arg) 1933d8899132SKalle Valo { 1934d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 1935d8899132SKalle Valo struct cfg80211_chan_def def; 1936d8899132SKalle Valo enum nl80211_band band; 1937d8899132SKalle Valo const u8 *ht_mcs_mask; 1938d8899132SKalle Valo const u16 *vht_mcs_mask; 1939d8899132SKalle Valo enum wmi_phy_mode phymode = MODE_UNKNOWN; 1940d8899132SKalle Valo 1941d8899132SKalle Valo if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) 1942d8899132SKalle Valo return; 1943d8899132SKalle Valo 1944d8899132SKalle Valo band = def.chan->band; 1945d8899132SKalle Valo ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs; 1946d8899132SKalle Valo vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs; 1947d8899132SKalle Valo 1948d8899132SKalle Valo switch (band) { 1949d8899132SKalle Valo case NL80211_BAND_2GHZ: 1950d8899132SKalle Valo if (sta->deflink.he_cap.has_he) { 1951d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) 1952d8899132SKalle Valo phymode = MODE_11AX_HE80_2G; 1953d8899132SKalle Valo else if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) 1954d8899132SKalle Valo phymode = MODE_11AX_HE40_2G; 1955d8899132SKalle Valo else 1956d8899132SKalle Valo phymode = MODE_11AX_HE20_2G; 1957d8899132SKalle Valo } else if (sta->deflink.vht_cap.vht_supported && 1958d8899132SKalle Valo !ath12k_peer_assoc_h_vht_masked(vht_mcs_mask)) { 1959d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) 1960d8899132SKalle Valo phymode = MODE_11AC_VHT40; 1961d8899132SKalle Valo else 1962d8899132SKalle Valo phymode = MODE_11AC_VHT20; 1963d8899132SKalle Valo } else if (sta->deflink.ht_cap.ht_supported && 1964d8899132SKalle Valo !ath12k_peer_assoc_h_ht_masked(ht_mcs_mask)) { 1965d8899132SKalle Valo if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) 1966d8899132SKalle Valo phymode = MODE_11NG_HT40; 1967d8899132SKalle Valo else 1968d8899132SKalle Valo phymode = MODE_11NG_HT20; 1969d8899132SKalle Valo } else if (ath12k_mac_sta_has_ofdm_only(sta)) { 1970d8899132SKalle Valo phymode = MODE_11G; 1971d8899132SKalle Valo } else { 1972d8899132SKalle Valo phymode = MODE_11B; 1973d8899132SKalle Valo } 1974d8899132SKalle Valo break; 1975d8899132SKalle Valo case NL80211_BAND_5GHZ: 1976d8899132SKalle Valo case NL80211_BAND_6GHZ: 1977d8899132SKalle Valo /* Check HE first */ 1978d8899132SKalle Valo if (sta->deflink.he_cap.has_he) { 1979d8899132SKalle Valo phymode = ath12k_mac_get_phymode_he(ar, sta); 1980d8899132SKalle Valo } else if (sta->deflink.vht_cap.vht_supported && 1981d8899132SKalle Valo !ath12k_peer_assoc_h_vht_masked(vht_mcs_mask)) { 1982d8899132SKalle Valo phymode = ath12k_mac_get_phymode_vht(ar, sta); 1983d8899132SKalle Valo } else if (sta->deflink.ht_cap.ht_supported && 1984d8899132SKalle Valo !ath12k_peer_assoc_h_ht_masked(ht_mcs_mask)) { 1985d8899132SKalle Valo if (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) 1986d8899132SKalle Valo phymode = MODE_11NA_HT40; 1987d8899132SKalle Valo else 1988d8899132SKalle Valo phymode = MODE_11NA_HT20; 1989d8899132SKalle Valo } else { 1990d8899132SKalle Valo phymode = MODE_11A; 1991d8899132SKalle Valo } 1992d8899132SKalle Valo break; 1993d8899132SKalle Valo default: 1994d8899132SKalle Valo break; 1995d8899132SKalle Valo } 1996d8899132SKalle Valo 1997d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac peer %pM phymode %s\n", 1998d8899132SKalle Valo sta->addr, ath12k_mac_phymode_str(phymode)); 1999d8899132SKalle Valo 2000d8899132SKalle Valo arg->peer_phymode = phymode; 2001d8899132SKalle Valo WARN_ON(phymode == MODE_UNKNOWN); 2002d8899132SKalle Valo } 2003d8899132SKalle Valo 2004d8899132SKalle Valo static void ath12k_peer_assoc_prepare(struct ath12k *ar, 2005d8899132SKalle Valo struct ieee80211_vif *vif, 2006d8899132SKalle Valo struct ieee80211_sta *sta, 2007d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg *arg, 2008d8899132SKalle Valo bool reassoc) 2009d8899132SKalle Valo { 2010d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 2011d8899132SKalle Valo 2012d8899132SKalle Valo memset(arg, 0, sizeof(*arg)); 2013d8899132SKalle Valo 2014d8899132SKalle Valo reinit_completion(&ar->peer_assoc_done); 2015d8899132SKalle Valo 2016d8899132SKalle Valo arg->peer_new_assoc = !reassoc; 2017d8899132SKalle Valo ath12k_peer_assoc_h_basic(ar, vif, sta, arg); 2018d8899132SKalle Valo ath12k_peer_assoc_h_crypto(ar, vif, sta, arg); 2019d8899132SKalle Valo ath12k_peer_assoc_h_rates(ar, vif, sta, arg); 2020d8899132SKalle Valo ath12k_peer_assoc_h_ht(ar, vif, sta, arg); 2021d8899132SKalle Valo ath12k_peer_assoc_h_vht(ar, vif, sta, arg); 2022d8899132SKalle Valo ath12k_peer_assoc_h_he(ar, vif, sta, arg); 2023d8899132SKalle Valo ath12k_peer_assoc_h_qos(ar, vif, sta, arg); 2024d8899132SKalle Valo ath12k_peer_assoc_h_phymode(ar, vif, sta, arg); 2025d8899132SKalle Valo ath12k_peer_assoc_h_smps(sta, arg); 2026d8899132SKalle Valo 2027d8899132SKalle Valo /* TODO: amsdu_disable req? */ 2028d8899132SKalle Valo } 2029d8899132SKalle Valo 2030d8899132SKalle Valo static int ath12k_setup_peer_smps(struct ath12k *ar, struct ath12k_vif *arvif, 2031d8899132SKalle Valo const u8 *addr, 2032d8899132SKalle Valo const struct ieee80211_sta_ht_cap *ht_cap) 2033d8899132SKalle Valo { 2034d8899132SKalle Valo int smps; 2035d8899132SKalle Valo 2036d8899132SKalle Valo if (!ht_cap->ht_supported) 2037d8899132SKalle Valo return 0; 2038d8899132SKalle Valo 2039d8899132SKalle Valo smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS; 2040d8899132SKalle Valo smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT; 2041d8899132SKalle Valo 2042d8899132SKalle Valo if (smps >= ARRAY_SIZE(ath12k_smps_map)) 2043d8899132SKalle Valo return -EINVAL; 2044d8899132SKalle Valo 2045d8899132SKalle Valo return ath12k_wmi_set_peer_param(ar, addr, arvif->vdev_id, 2046d8899132SKalle Valo WMI_PEER_MIMO_PS_STATE, 2047d8899132SKalle Valo ath12k_smps_map[smps]); 2048d8899132SKalle Valo } 2049d8899132SKalle Valo 2050d8899132SKalle Valo static void ath12k_bss_assoc(struct ieee80211_hw *hw, 2051d8899132SKalle Valo struct ieee80211_vif *vif, 2052d8899132SKalle Valo struct ieee80211_bss_conf *bss_conf) 2053d8899132SKalle Valo { 2054d8899132SKalle Valo struct ath12k *ar = hw->priv; 2055d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 2056d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg peer_arg; 2057d8899132SKalle Valo struct ieee80211_sta *ap_sta; 2058d8899132SKalle Valo struct ath12k_peer *peer; 2059d8899132SKalle Valo bool is_auth = false; 2060d8899132SKalle Valo int ret; 2061d8899132SKalle Valo 2062d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 2063d8899132SKalle Valo 2064d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n", 2065d8899132SKalle Valo arvif->vdev_id, arvif->bssid, arvif->aid); 2066d8899132SKalle Valo 2067d8899132SKalle Valo rcu_read_lock(); 2068d8899132SKalle Valo 2069d8899132SKalle Valo ap_sta = ieee80211_find_sta(vif, bss_conf->bssid); 2070d8899132SKalle Valo if (!ap_sta) { 2071d8899132SKalle Valo ath12k_warn(ar->ab, "failed to find station entry for bss %pM vdev %i\n", 2072d8899132SKalle Valo bss_conf->bssid, arvif->vdev_id); 2073d8899132SKalle Valo rcu_read_unlock(); 2074d8899132SKalle Valo return; 2075d8899132SKalle Valo } 2076d8899132SKalle Valo 2077d8899132SKalle Valo ath12k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg, false); 2078d8899132SKalle Valo 2079d8899132SKalle Valo rcu_read_unlock(); 2080d8899132SKalle Valo 2081d8899132SKalle Valo ret = ath12k_wmi_send_peer_assoc_cmd(ar, &peer_arg); 2082d8899132SKalle Valo if (ret) { 2083d8899132SKalle Valo ath12k_warn(ar->ab, "failed to run peer assoc for %pM vdev %i: %d\n", 2084d8899132SKalle Valo bss_conf->bssid, arvif->vdev_id, ret); 2085d8899132SKalle Valo return; 2086d8899132SKalle Valo } 2087d8899132SKalle Valo 2088d8899132SKalle Valo if (!wait_for_completion_timeout(&ar->peer_assoc_done, 1 * HZ)) { 2089d8899132SKalle Valo ath12k_warn(ar->ab, "failed to get peer assoc conf event for %pM vdev %i\n", 2090d8899132SKalle Valo bss_conf->bssid, arvif->vdev_id); 2091d8899132SKalle Valo return; 2092d8899132SKalle Valo } 2093d8899132SKalle Valo 2094d8899132SKalle Valo ret = ath12k_setup_peer_smps(ar, arvif, bss_conf->bssid, 2095d8899132SKalle Valo &ap_sta->deflink.ht_cap); 2096d8899132SKalle Valo if (ret) { 2097d8899132SKalle Valo ath12k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n", 2098d8899132SKalle Valo arvif->vdev_id, ret); 2099d8899132SKalle Valo return; 2100d8899132SKalle Valo } 2101d8899132SKalle Valo 2102d8899132SKalle Valo WARN_ON(arvif->is_up); 2103d8899132SKalle Valo 2104d8899132SKalle Valo arvif->aid = vif->cfg.aid; 2105d8899132SKalle Valo ether_addr_copy(arvif->bssid, bss_conf->bssid); 2106d8899132SKalle Valo 2107d8899132SKalle Valo ret = ath12k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid); 2108d8899132SKalle Valo if (ret) { 2109d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set vdev %d up: %d\n", 2110d8899132SKalle Valo arvif->vdev_id, ret); 2111d8899132SKalle Valo return; 2112d8899132SKalle Valo } 2113d8899132SKalle Valo 2114d8899132SKalle Valo arvif->is_up = true; 2115d8899132SKalle Valo 2116d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 2117d8899132SKalle Valo "mac vdev %d up (associated) bssid %pM aid %d\n", 2118d8899132SKalle Valo arvif->vdev_id, bss_conf->bssid, vif->cfg.aid); 2119d8899132SKalle Valo 2120d8899132SKalle Valo spin_lock_bh(&ar->ab->base_lock); 2121d8899132SKalle Valo 2122d8899132SKalle Valo peer = ath12k_peer_find(ar->ab, arvif->vdev_id, arvif->bssid); 2123d8899132SKalle Valo if (peer && peer->is_authorized) 2124d8899132SKalle Valo is_auth = true; 2125d8899132SKalle Valo 2126d8899132SKalle Valo spin_unlock_bh(&ar->ab->base_lock); 2127d8899132SKalle Valo 2128d8899132SKalle Valo /* Authorize BSS Peer */ 2129d8899132SKalle Valo if (is_auth) { 2130d8899132SKalle Valo ret = ath12k_wmi_set_peer_param(ar, arvif->bssid, 2131d8899132SKalle Valo arvif->vdev_id, 2132d8899132SKalle Valo WMI_PEER_AUTHORIZE, 2133d8899132SKalle Valo 1); 2134d8899132SKalle Valo if (ret) 2135d8899132SKalle Valo ath12k_warn(ar->ab, "Unable to authorize BSS peer: %d\n", ret); 2136d8899132SKalle Valo } 2137d8899132SKalle Valo 2138d8899132SKalle Valo ret = ath12k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id, 2139d8899132SKalle Valo &bss_conf->he_obss_pd); 2140d8899132SKalle Valo if (ret) 2141d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set vdev %i OBSS PD parameters: %d\n", 2142d8899132SKalle Valo arvif->vdev_id, ret); 2143d8899132SKalle Valo } 2144d8899132SKalle Valo 2145d8899132SKalle Valo static void ath12k_bss_disassoc(struct ieee80211_hw *hw, 2146d8899132SKalle Valo struct ieee80211_vif *vif) 2147d8899132SKalle Valo { 2148d8899132SKalle Valo struct ath12k *ar = hw->priv; 2149d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 2150d8899132SKalle Valo int ret; 2151d8899132SKalle Valo 2152d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 2153d8899132SKalle Valo 2154d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n", 2155d8899132SKalle Valo arvif->vdev_id, arvif->bssid); 2156d8899132SKalle Valo 2157d8899132SKalle Valo ret = ath12k_wmi_vdev_down(ar, arvif->vdev_id); 2158d8899132SKalle Valo if (ret) 2159d8899132SKalle Valo ath12k_warn(ar->ab, "failed to down vdev %i: %d\n", 2160d8899132SKalle Valo arvif->vdev_id, ret); 2161d8899132SKalle Valo 2162d8899132SKalle Valo arvif->is_up = false; 2163d8899132SKalle Valo 2164d8899132SKalle Valo /* TODO: cancel connection_loss_work */ 2165d8899132SKalle Valo } 2166d8899132SKalle Valo 2167d8899132SKalle Valo static u32 ath12k_mac_get_rate_hw_value(int bitrate) 2168d8899132SKalle Valo { 2169d8899132SKalle Valo u32 preamble; 2170d8899132SKalle Valo u16 hw_value; 2171d8899132SKalle Valo int rate; 2172d8899132SKalle Valo size_t i; 2173d8899132SKalle Valo 2174d8899132SKalle Valo if (ath12k_mac_bitrate_is_cck(bitrate)) 2175d8899132SKalle Valo preamble = WMI_RATE_PREAMBLE_CCK; 2176d8899132SKalle Valo else 2177d8899132SKalle Valo preamble = WMI_RATE_PREAMBLE_OFDM; 2178d8899132SKalle Valo 2179d8899132SKalle Valo for (i = 0; i < ARRAY_SIZE(ath12k_legacy_rates); i++) { 2180d8899132SKalle Valo if (ath12k_legacy_rates[i].bitrate != bitrate) 2181d8899132SKalle Valo continue; 2182d8899132SKalle Valo 2183d8899132SKalle Valo hw_value = ath12k_legacy_rates[i].hw_value; 2184d8899132SKalle Valo rate = ATH12K_HW_RATE_CODE(hw_value, 0, preamble); 2185d8899132SKalle Valo 2186d8899132SKalle Valo return rate; 2187d8899132SKalle Valo } 2188d8899132SKalle Valo 2189d8899132SKalle Valo return -EINVAL; 2190d8899132SKalle Valo } 2191d8899132SKalle Valo 2192d8899132SKalle Valo static void ath12k_recalculate_mgmt_rate(struct ath12k *ar, 2193d8899132SKalle Valo struct ieee80211_vif *vif, 2194d8899132SKalle Valo struct cfg80211_chan_def *def) 2195d8899132SKalle Valo { 2196d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 2197d8899132SKalle Valo const struct ieee80211_supported_band *sband; 2198d8899132SKalle Valo u8 basic_rate_idx; 2199d8899132SKalle Valo int hw_rate_code; 2200d8899132SKalle Valo u32 vdev_param; 2201d8899132SKalle Valo u16 bitrate; 2202d8899132SKalle Valo int ret; 2203d8899132SKalle Valo 2204d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 2205d8899132SKalle Valo 2206d8899132SKalle Valo sband = ar->hw->wiphy->bands[def->chan->band]; 2207d8899132SKalle Valo basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1; 2208d8899132SKalle Valo bitrate = sband->bitrates[basic_rate_idx].bitrate; 2209d8899132SKalle Valo 2210d8899132SKalle Valo hw_rate_code = ath12k_mac_get_rate_hw_value(bitrate); 2211d8899132SKalle Valo if (hw_rate_code < 0) { 2212d8899132SKalle Valo ath12k_warn(ar->ab, "bitrate not supported %d\n", bitrate); 2213d8899132SKalle Valo return; 2214d8899132SKalle Valo } 2215d8899132SKalle Valo 2216d8899132SKalle Valo vdev_param = WMI_VDEV_PARAM_MGMT_RATE; 2217d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, vdev_param, 2218d8899132SKalle Valo hw_rate_code); 2219d8899132SKalle Valo if (ret) 2220d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set mgmt tx rate %d\n", ret); 2221d8899132SKalle Valo 2222d8899132SKalle Valo vdev_param = WMI_VDEV_PARAM_BEACON_RATE; 2223d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, vdev_param, 2224d8899132SKalle Valo hw_rate_code); 2225d8899132SKalle Valo if (ret) 2226d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set beacon tx rate %d\n", ret); 2227d8899132SKalle Valo } 2228d8899132SKalle Valo 2229d8899132SKalle Valo static int ath12k_mac_fils_discovery(struct ath12k_vif *arvif, 2230d8899132SKalle Valo struct ieee80211_bss_conf *info) 2231d8899132SKalle Valo { 2232d8899132SKalle Valo struct ath12k *ar = arvif->ar; 2233d8899132SKalle Valo struct sk_buff *tmpl; 2234d8899132SKalle Valo int ret; 2235d8899132SKalle Valo u32 interval; 2236d8899132SKalle Valo bool unsol_bcast_probe_resp_enabled = false; 2237d8899132SKalle Valo 2238d8899132SKalle Valo if (info->fils_discovery.max_interval) { 2239d8899132SKalle Valo interval = info->fils_discovery.max_interval; 2240d8899132SKalle Valo 2241d8899132SKalle Valo tmpl = ieee80211_get_fils_discovery_tmpl(ar->hw, arvif->vif); 2242d8899132SKalle Valo if (tmpl) 2243d8899132SKalle Valo ret = ath12k_wmi_fils_discovery_tmpl(ar, arvif->vdev_id, 2244d8899132SKalle Valo tmpl); 2245d8899132SKalle Valo } else if (info->unsol_bcast_probe_resp_interval) { 2246d8899132SKalle Valo unsol_bcast_probe_resp_enabled = 1; 2247d8899132SKalle Valo interval = info->unsol_bcast_probe_resp_interval; 2248d8899132SKalle Valo 2249d8899132SKalle Valo tmpl = ieee80211_get_unsol_bcast_probe_resp_tmpl(ar->hw, 2250d8899132SKalle Valo arvif->vif); 2251d8899132SKalle Valo if (tmpl) 2252d8899132SKalle Valo ret = ath12k_wmi_probe_resp_tmpl(ar, arvif->vdev_id, 2253d8899132SKalle Valo tmpl); 2254d8899132SKalle Valo } else { /* Disable */ 2255d8899132SKalle Valo return ath12k_wmi_fils_discovery(ar, arvif->vdev_id, 0, false); 2256d8899132SKalle Valo } 2257d8899132SKalle Valo 2258d8899132SKalle Valo if (!tmpl) { 2259d8899132SKalle Valo ath12k_warn(ar->ab, 2260d8899132SKalle Valo "mac vdev %i failed to retrieve %s template\n", 2261d8899132SKalle Valo arvif->vdev_id, (unsol_bcast_probe_resp_enabled ? 2262d8899132SKalle Valo "unsolicited broadcast probe response" : 2263d8899132SKalle Valo "FILS discovery")); 2264d8899132SKalle Valo return -EPERM; 2265d8899132SKalle Valo } 2266d8899132SKalle Valo kfree_skb(tmpl); 2267d8899132SKalle Valo 2268d8899132SKalle Valo if (!ret) 2269d8899132SKalle Valo ret = ath12k_wmi_fils_discovery(ar, arvif->vdev_id, interval, 2270d8899132SKalle Valo unsol_bcast_probe_resp_enabled); 2271d8899132SKalle Valo 2272d8899132SKalle Valo return ret; 2273d8899132SKalle Valo } 2274d8899132SKalle Valo 2275d8899132SKalle Valo static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw, 2276d8899132SKalle Valo struct ieee80211_vif *vif, 2277d8899132SKalle Valo struct ieee80211_bss_conf *info, 2278d8899132SKalle Valo u64 changed) 2279d8899132SKalle Valo { 2280d8899132SKalle Valo struct ath12k *ar = hw->priv; 2281d8899132SKalle Valo struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 2282d8899132SKalle Valo struct cfg80211_chan_def def; 2283d8899132SKalle Valo u32 param_id, param_value; 2284d8899132SKalle Valo enum nl80211_band band; 2285d8899132SKalle Valo u32 vdev_param; 2286d8899132SKalle Valo int mcast_rate; 2287d8899132SKalle Valo u32 preamble; 2288d8899132SKalle Valo u16 hw_value; 2289d8899132SKalle Valo u16 bitrate; 2290d8899132SKalle Valo int ret; 2291d8899132SKalle Valo u8 rateidx; 2292d8899132SKalle Valo u32 rate; 2293d8899132SKalle Valo 2294d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 2295d8899132SKalle Valo 2296d8899132SKalle Valo if (changed & BSS_CHANGED_BEACON_INT) { 2297d8899132SKalle Valo arvif->beacon_interval = info->beacon_int; 2298d8899132SKalle Valo 2299d8899132SKalle Valo param_id = WMI_VDEV_PARAM_BEACON_INTERVAL; 2300d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 2301d8899132SKalle Valo param_id, 2302d8899132SKalle Valo arvif->beacon_interval); 2303d8899132SKalle Valo if (ret) 2304d8899132SKalle Valo ath12k_warn(ar->ab, "Failed to set beacon interval for VDEV: %d\n", 2305d8899132SKalle Valo arvif->vdev_id); 2306d8899132SKalle Valo else 2307d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 2308d8899132SKalle Valo "Beacon interval: %d set for VDEV: %d\n", 2309d8899132SKalle Valo arvif->beacon_interval, arvif->vdev_id); 2310d8899132SKalle Valo } 2311d8899132SKalle Valo 2312d8899132SKalle Valo if (changed & BSS_CHANGED_BEACON) { 2313d8899132SKalle Valo param_id = WMI_PDEV_PARAM_BEACON_TX_MODE; 2314d8899132SKalle Valo param_value = WMI_BEACON_STAGGERED_MODE; 2315d8899132SKalle Valo ret = ath12k_wmi_pdev_set_param(ar, param_id, 2316d8899132SKalle Valo param_value, ar->pdev->pdev_id); 2317d8899132SKalle Valo if (ret) 2318d8899132SKalle Valo ath12k_warn(ar->ab, "Failed to set beacon mode for VDEV: %d\n", 2319d8899132SKalle Valo arvif->vdev_id); 2320d8899132SKalle Valo else 2321d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 2322d8899132SKalle Valo "Set staggered beacon mode for VDEV: %d\n", 2323d8899132SKalle Valo arvif->vdev_id); 2324d8899132SKalle Valo 2325d8899132SKalle Valo ret = ath12k_mac_setup_bcn_tmpl(arvif); 2326d8899132SKalle Valo if (ret) 2327d8899132SKalle Valo ath12k_warn(ar->ab, "failed to update bcn template: %d\n", 2328d8899132SKalle Valo ret); 2329d8899132SKalle Valo } 2330d8899132SKalle Valo 2331d8899132SKalle Valo if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) { 2332d8899132SKalle Valo arvif->dtim_period = info->dtim_period; 2333d8899132SKalle Valo 2334d8899132SKalle Valo param_id = WMI_VDEV_PARAM_DTIM_PERIOD; 2335d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 2336d8899132SKalle Valo param_id, 2337d8899132SKalle Valo arvif->dtim_period); 2338d8899132SKalle Valo 2339d8899132SKalle Valo if (ret) 2340d8899132SKalle Valo ath12k_warn(ar->ab, "Failed to set dtim period for VDEV %d: %i\n", 2341d8899132SKalle Valo arvif->vdev_id, ret); 2342d8899132SKalle Valo else 2343d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 2344d8899132SKalle Valo "DTIM period: %d set for VDEV: %d\n", 2345d8899132SKalle Valo arvif->dtim_period, arvif->vdev_id); 2346d8899132SKalle Valo } 2347d8899132SKalle Valo 2348d8899132SKalle Valo if (changed & BSS_CHANGED_SSID && 2349d8899132SKalle Valo vif->type == NL80211_IFTYPE_AP) { 2350d8899132SKalle Valo arvif->u.ap.ssid_len = vif->cfg.ssid_len; 2351d8899132SKalle Valo if (vif->cfg.ssid_len) 2352d8899132SKalle Valo memcpy(arvif->u.ap.ssid, vif->cfg.ssid, vif->cfg.ssid_len); 2353d8899132SKalle Valo arvif->u.ap.hidden_ssid = info->hidden_ssid; 2354d8899132SKalle Valo } 2355d8899132SKalle Valo 2356d8899132SKalle Valo if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid)) 2357d8899132SKalle Valo ether_addr_copy(arvif->bssid, info->bssid); 2358d8899132SKalle Valo 2359d8899132SKalle Valo if (changed & BSS_CHANGED_BEACON_ENABLED) { 2360d8899132SKalle Valo ath12k_control_beaconing(arvif, info); 2361d8899132SKalle Valo 2362d8899132SKalle Valo if (arvif->is_up && vif->bss_conf.he_support && 2363d8899132SKalle Valo vif->bss_conf.he_oper.params) { 2364d8899132SKalle Valo /* TODO: Extend to support 1024 BA Bitmap size */ 2365d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 2366d8899132SKalle Valo WMI_VDEV_PARAM_BA_MODE, 2367d8899132SKalle Valo WMI_BA_MODE_BUFFER_SIZE_256); 2368d8899132SKalle Valo if (ret) 2369d8899132SKalle Valo ath12k_warn(ar->ab, 2370d8899132SKalle Valo "failed to set BA BUFFER SIZE 256 for vdev: %d\n", 2371d8899132SKalle Valo arvif->vdev_id); 2372d8899132SKalle Valo 2373d8899132SKalle Valo param_id = WMI_VDEV_PARAM_HEOPS_0_31; 2374d8899132SKalle Valo param_value = vif->bss_conf.he_oper.params; 2375d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 2376d8899132SKalle Valo param_id, param_value); 2377d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 2378d8899132SKalle Valo "he oper param: %x set for VDEV: %d\n", 2379d8899132SKalle Valo param_value, arvif->vdev_id); 2380d8899132SKalle Valo 2381d8899132SKalle Valo if (ret) 2382d8899132SKalle Valo ath12k_warn(ar->ab, "Failed to set he oper params %x for VDEV %d: %i\n", 2383d8899132SKalle Valo param_value, arvif->vdev_id, ret); 2384d8899132SKalle Valo } 2385d8899132SKalle Valo } 2386d8899132SKalle Valo 2387d8899132SKalle Valo if (changed & BSS_CHANGED_ERP_CTS_PROT) { 2388d8899132SKalle Valo u32 cts_prot; 2389d8899132SKalle Valo 2390d8899132SKalle Valo cts_prot = !!(info->use_cts_prot); 2391d8899132SKalle Valo param_id = WMI_VDEV_PARAM_PROTECTION_MODE; 2392d8899132SKalle Valo 2393d8899132SKalle Valo if (arvif->is_started) { 2394d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 2395d8899132SKalle Valo param_id, cts_prot); 2396d8899132SKalle Valo if (ret) 2397d8899132SKalle Valo ath12k_warn(ar->ab, "Failed to set CTS prot for VDEV: %d\n", 2398d8899132SKalle Valo arvif->vdev_id); 2399d8899132SKalle Valo else 2400d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "Set CTS prot: %d for VDEV: %d\n", 2401d8899132SKalle Valo cts_prot, arvif->vdev_id); 2402d8899132SKalle Valo } else { 2403d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "defer protection mode setup, vdev is not ready yet\n"); 2404d8899132SKalle Valo } 2405d8899132SKalle Valo } 2406d8899132SKalle Valo 2407d8899132SKalle Valo if (changed & BSS_CHANGED_ERP_SLOT) { 2408d8899132SKalle Valo u32 slottime; 2409d8899132SKalle Valo 2410d8899132SKalle Valo if (info->use_short_slot) 2411d8899132SKalle Valo slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */ 2412d8899132SKalle Valo 2413d8899132SKalle Valo else 2414d8899132SKalle Valo slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */ 2415d8899132SKalle Valo 2416d8899132SKalle Valo param_id = WMI_VDEV_PARAM_SLOT_TIME; 2417d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 2418d8899132SKalle Valo param_id, slottime); 2419d8899132SKalle Valo if (ret) 2420d8899132SKalle Valo ath12k_warn(ar->ab, "Failed to set erp slot for VDEV: %d\n", 2421d8899132SKalle Valo arvif->vdev_id); 2422d8899132SKalle Valo else 2423d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 2424d8899132SKalle Valo "Set slottime: %d for VDEV: %d\n", 2425d8899132SKalle Valo slottime, arvif->vdev_id); 2426d8899132SKalle Valo } 2427d8899132SKalle Valo 2428d8899132SKalle Valo if (changed & BSS_CHANGED_ERP_PREAMBLE) { 2429d8899132SKalle Valo u32 preamble; 2430d8899132SKalle Valo 2431d8899132SKalle Valo if (info->use_short_preamble) 2432d8899132SKalle Valo preamble = WMI_VDEV_PREAMBLE_SHORT; 2433d8899132SKalle Valo else 2434d8899132SKalle Valo preamble = WMI_VDEV_PREAMBLE_LONG; 2435d8899132SKalle Valo 2436d8899132SKalle Valo param_id = WMI_VDEV_PARAM_PREAMBLE; 2437d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 2438d8899132SKalle Valo param_id, preamble); 2439d8899132SKalle Valo if (ret) 2440d8899132SKalle Valo ath12k_warn(ar->ab, "Failed to set preamble for VDEV: %d\n", 2441d8899132SKalle Valo arvif->vdev_id); 2442d8899132SKalle Valo else 2443d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 2444d8899132SKalle Valo "Set preamble: %d for VDEV: %d\n", 2445d8899132SKalle Valo preamble, arvif->vdev_id); 2446d8899132SKalle Valo } 2447d8899132SKalle Valo 2448d8899132SKalle Valo if (changed & BSS_CHANGED_ASSOC) { 2449d8899132SKalle Valo if (vif->cfg.assoc) 2450d8899132SKalle Valo ath12k_bss_assoc(hw, vif, info); 2451d8899132SKalle Valo else 2452d8899132SKalle Valo ath12k_bss_disassoc(hw, vif); 2453d8899132SKalle Valo } 2454d8899132SKalle Valo 2455d8899132SKalle Valo if (changed & BSS_CHANGED_TXPOWER) { 2456d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vdev_id %i txpower %d\n", 2457d8899132SKalle Valo arvif->vdev_id, info->txpower); 2458d8899132SKalle Valo 2459d8899132SKalle Valo arvif->txpower = info->txpower; 2460d8899132SKalle Valo ath12k_mac_txpower_recalc(ar); 2461d8899132SKalle Valo } 2462d8899132SKalle Valo 2463d8899132SKalle Valo if (changed & BSS_CHANGED_MCAST_RATE && 2464d8899132SKalle Valo !ath12k_mac_vif_chan(arvif->vif, &def)) { 2465d8899132SKalle Valo band = def.chan->band; 2466d8899132SKalle Valo mcast_rate = vif->bss_conf.mcast_rate[band]; 2467d8899132SKalle Valo 2468d8899132SKalle Valo if (mcast_rate > 0) 2469d8899132SKalle Valo rateidx = mcast_rate - 1; 2470d8899132SKalle Valo else 2471d8899132SKalle Valo rateidx = ffs(vif->bss_conf.basic_rates) - 1; 2472d8899132SKalle Valo 2473d8899132SKalle Valo if (ar->pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) 2474d8899132SKalle Valo rateidx += ATH12K_MAC_FIRST_OFDM_RATE_IDX; 2475d8899132SKalle Valo 2476d8899132SKalle Valo bitrate = ath12k_legacy_rates[rateidx].bitrate; 2477d8899132SKalle Valo hw_value = ath12k_legacy_rates[rateidx].hw_value; 2478d8899132SKalle Valo 2479d8899132SKalle Valo if (ath12k_mac_bitrate_is_cck(bitrate)) 2480d8899132SKalle Valo preamble = WMI_RATE_PREAMBLE_CCK; 2481d8899132SKalle Valo else 2482d8899132SKalle Valo preamble = WMI_RATE_PREAMBLE_OFDM; 2483d8899132SKalle Valo 2484d8899132SKalle Valo rate = ATH12K_HW_RATE_CODE(hw_value, 0, preamble); 2485d8899132SKalle Valo 2486d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 2487d8899132SKalle Valo "mac vdev %d mcast_rate %x\n", 2488d8899132SKalle Valo arvif->vdev_id, rate); 2489d8899132SKalle Valo 2490d8899132SKalle Valo vdev_param = WMI_VDEV_PARAM_MCAST_DATA_RATE; 2491d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 2492d8899132SKalle Valo vdev_param, rate); 2493d8899132SKalle Valo if (ret) 2494d8899132SKalle Valo ath12k_warn(ar->ab, 2495d8899132SKalle Valo "failed to set mcast rate on vdev %i: %d\n", 2496d8899132SKalle Valo arvif->vdev_id, ret); 2497d8899132SKalle Valo 2498d8899132SKalle Valo vdev_param = WMI_VDEV_PARAM_BCAST_DATA_RATE; 2499d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 2500d8899132SKalle Valo vdev_param, rate); 2501d8899132SKalle Valo if (ret) 2502d8899132SKalle Valo ath12k_warn(ar->ab, 2503d8899132SKalle Valo "failed to set bcast rate on vdev %i: %d\n", 2504d8899132SKalle Valo arvif->vdev_id, ret); 2505d8899132SKalle Valo } 2506d8899132SKalle Valo 2507d8899132SKalle Valo if (changed & BSS_CHANGED_BASIC_RATES && 2508d8899132SKalle Valo !ath12k_mac_vif_chan(arvif->vif, &def)) 2509d8899132SKalle Valo ath12k_recalculate_mgmt_rate(ar, vif, &def); 2510d8899132SKalle Valo 2511d8899132SKalle Valo if (changed & BSS_CHANGED_TWT) { 2512d8899132SKalle Valo if (info->twt_requester || info->twt_responder) 2513d8899132SKalle Valo ath12k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id); 2514d8899132SKalle Valo else 2515d8899132SKalle Valo ath12k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id); 2516d8899132SKalle Valo } 2517d8899132SKalle Valo 2518d8899132SKalle Valo if (changed & BSS_CHANGED_HE_OBSS_PD) 2519d8899132SKalle Valo ath12k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id, 2520d8899132SKalle Valo &info->he_obss_pd); 2521d8899132SKalle Valo 2522d8899132SKalle Valo if (changed & BSS_CHANGED_HE_BSS_COLOR) { 2523d8899132SKalle Valo if (vif->type == NL80211_IFTYPE_AP) { 2524d8899132SKalle Valo ret = ath12k_wmi_obss_color_cfg_cmd(ar, 2525d8899132SKalle Valo arvif->vdev_id, 2526d8899132SKalle Valo info->he_bss_color.color, 2527d8899132SKalle Valo ATH12K_BSS_COLOR_AP_PERIODS, 2528d8899132SKalle Valo info->he_bss_color.enabled); 2529d8899132SKalle Valo if (ret) 2530d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n", 2531d8899132SKalle Valo arvif->vdev_id, ret); 2532d8899132SKalle Valo } else if (vif->type == NL80211_IFTYPE_STATION) { 2533d8899132SKalle Valo ret = ath12k_wmi_send_bss_color_change_enable_cmd(ar, 2534d8899132SKalle Valo arvif->vdev_id, 2535d8899132SKalle Valo 1); 2536d8899132SKalle Valo if (ret) 2537d8899132SKalle Valo ath12k_warn(ar->ab, "failed to enable bss color change on vdev %i: %d\n", 2538d8899132SKalle Valo arvif->vdev_id, ret); 2539d8899132SKalle Valo ret = ath12k_wmi_obss_color_cfg_cmd(ar, 2540d8899132SKalle Valo arvif->vdev_id, 2541d8899132SKalle Valo 0, 2542d8899132SKalle Valo ATH12K_BSS_COLOR_STA_PERIODS, 2543d8899132SKalle Valo 1); 2544d8899132SKalle Valo if (ret) 2545d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n", 2546d8899132SKalle Valo arvif->vdev_id, ret); 2547d8899132SKalle Valo } 2548d8899132SKalle Valo } 2549d8899132SKalle Valo 2550d8899132SKalle Valo if (changed & BSS_CHANGED_FILS_DISCOVERY || 2551d8899132SKalle Valo changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP) 2552d8899132SKalle Valo ath12k_mac_fils_discovery(arvif, info); 2553d8899132SKalle Valo 2554d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 2555d8899132SKalle Valo } 2556d8899132SKalle Valo 2557d8899132SKalle Valo void __ath12k_mac_scan_finish(struct ath12k *ar) 2558d8899132SKalle Valo { 2559d8899132SKalle Valo lockdep_assert_held(&ar->data_lock); 2560d8899132SKalle Valo 2561d8899132SKalle Valo switch (ar->scan.state) { 2562d8899132SKalle Valo case ATH12K_SCAN_IDLE: 2563d8899132SKalle Valo break; 2564d8899132SKalle Valo case ATH12K_SCAN_RUNNING: 2565d8899132SKalle Valo case ATH12K_SCAN_ABORTING: 2566d8899132SKalle Valo if (!ar->scan.is_roc) { 2567d8899132SKalle Valo struct cfg80211_scan_info info = { 2568d8899132SKalle Valo .aborted = (ar->scan.state == 2569d8899132SKalle Valo ATH12K_SCAN_ABORTING), 2570d8899132SKalle Valo }; 2571d8899132SKalle Valo 2572d8899132SKalle Valo ieee80211_scan_completed(ar->hw, &info); 2573d8899132SKalle Valo } else if (ar->scan.roc_notify) { 2574d8899132SKalle Valo ieee80211_remain_on_channel_expired(ar->hw); 2575d8899132SKalle Valo } 2576d8899132SKalle Valo fallthrough; 2577d8899132SKalle Valo case ATH12K_SCAN_STARTING: 2578d8899132SKalle Valo ar->scan.state = ATH12K_SCAN_IDLE; 2579d8899132SKalle Valo ar->scan_channel = NULL; 2580d8899132SKalle Valo ar->scan.roc_freq = 0; 2581d8899132SKalle Valo cancel_delayed_work(&ar->scan.timeout); 2582d8899132SKalle Valo complete(&ar->scan.completed); 2583d8899132SKalle Valo break; 2584d8899132SKalle Valo } 2585d8899132SKalle Valo } 2586d8899132SKalle Valo 2587d8899132SKalle Valo void ath12k_mac_scan_finish(struct ath12k *ar) 2588d8899132SKalle Valo { 2589d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 2590d8899132SKalle Valo __ath12k_mac_scan_finish(ar); 2591d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 2592d8899132SKalle Valo } 2593d8899132SKalle Valo 2594d8899132SKalle Valo static int ath12k_scan_stop(struct ath12k *ar) 2595d8899132SKalle Valo { 2596d8899132SKalle Valo struct ath12k_wmi_scan_cancel_arg arg = { 2597d8899132SKalle Valo .req_type = WLAN_SCAN_CANCEL_SINGLE, 2598d8899132SKalle Valo .scan_id = ATH12K_SCAN_ID, 2599d8899132SKalle Valo }; 2600d8899132SKalle Valo int ret; 2601d8899132SKalle Valo 2602d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 2603d8899132SKalle Valo 2604d8899132SKalle Valo /* TODO: Fill other STOP Params */ 2605d8899132SKalle Valo arg.pdev_id = ar->pdev->pdev_id; 2606d8899132SKalle Valo 2607d8899132SKalle Valo ret = ath12k_wmi_send_scan_stop_cmd(ar, &arg); 2608d8899132SKalle Valo if (ret) { 2609d8899132SKalle Valo ath12k_warn(ar->ab, "failed to stop wmi scan: %d\n", ret); 2610d8899132SKalle Valo goto out; 2611d8899132SKalle Valo } 2612d8899132SKalle Valo 2613d8899132SKalle Valo ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ); 2614d8899132SKalle Valo if (ret == 0) { 2615d8899132SKalle Valo ath12k_warn(ar->ab, 2616d8899132SKalle Valo "failed to receive scan abort comple: timed out\n"); 2617d8899132SKalle Valo ret = -ETIMEDOUT; 2618d8899132SKalle Valo } else if (ret > 0) { 2619d8899132SKalle Valo ret = 0; 2620d8899132SKalle Valo } 2621d8899132SKalle Valo 2622d8899132SKalle Valo out: 2623d8899132SKalle Valo /* Scan state should be updated upon scan completion but in case 2624d8899132SKalle Valo * firmware fails to deliver the event (for whatever reason) it is 2625d8899132SKalle Valo * desired to clean up scan state anyway. Firmware may have just 2626d8899132SKalle Valo * dropped the scan completion event delivery due to transport pipe 2627d8899132SKalle Valo * being overflown with data and/or it can recover on its own before 2628d8899132SKalle Valo * next scan request is submitted. 2629d8899132SKalle Valo */ 2630d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 2631d8899132SKalle Valo if (ar->scan.state != ATH12K_SCAN_IDLE) 2632d8899132SKalle Valo __ath12k_mac_scan_finish(ar); 2633d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 2634d8899132SKalle Valo 2635d8899132SKalle Valo return ret; 2636d8899132SKalle Valo } 2637d8899132SKalle Valo 2638d8899132SKalle Valo static void ath12k_scan_abort(struct ath12k *ar) 2639d8899132SKalle Valo { 2640d8899132SKalle Valo int ret; 2641d8899132SKalle Valo 2642d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 2643d8899132SKalle Valo 2644d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 2645d8899132SKalle Valo 2646d8899132SKalle Valo switch (ar->scan.state) { 2647d8899132SKalle Valo case ATH12K_SCAN_IDLE: 2648d8899132SKalle Valo /* This can happen if timeout worker kicked in and called 2649d8899132SKalle Valo * abortion while scan completion was being processed. 2650d8899132SKalle Valo */ 2651d8899132SKalle Valo break; 2652d8899132SKalle Valo case ATH12K_SCAN_STARTING: 2653d8899132SKalle Valo case ATH12K_SCAN_ABORTING: 2654d8899132SKalle Valo ath12k_warn(ar->ab, "refusing scan abortion due to invalid scan state: %d\n", 2655d8899132SKalle Valo ar->scan.state); 2656d8899132SKalle Valo break; 2657d8899132SKalle Valo case ATH12K_SCAN_RUNNING: 2658d8899132SKalle Valo ar->scan.state = ATH12K_SCAN_ABORTING; 2659d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 2660d8899132SKalle Valo 2661d8899132SKalle Valo ret = ath12k_scan_stop(ar); 2662d8899132SKalle Valo if (ret) 2663d8899132SKalle Valo ath12k_warn(ar->ab, "failed to abort scan: %d\n", ret); 2664d8899132SKalle Valo 2665d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 2666d8899132SKalle Valo break; 2667d8899132SKalle Valo } 2668d8899132SKalle Valo 2669d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 2670d8899132SKalle Valo } 2671d8899132SKalle Valo 2672d8899132SKalle Valo static void ath12k_scan_timeout_work(struct work_struct *work) 2673d8899132SKalle Valo { 2674d8899132SKalle Valo struct ath12k *ar = container_of(work, struct ath12k, 2675d8899132SKalle Valo scan.timeout.work); 2676d8899132SKalle Valo 2677d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 2678d8899132SKalle Valo ath12k_scan_abort(ar); 2679d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 2680d8899132SKalle Valo } 2681d8899132SKalle Valo 2682d8899132SKalle Valo static int ath12k_start_scan(struct ath12k *ar, 2683d8899132SKalle Valo struct ath12k_wmi_scan_req_arg *arg) 2684d8899132SKalle Valo { 2685d8899132SKalle Valo int ret; 2686d8899132SKalle Valo 2687d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 2688d8899132SKalle Valo 2689d8899132SKalle Valo ret = ath12k_wmi_send_scan_start_cmd(ar, arg); 2690d8899132SKalle Valo if (ret) 2691d8899132SKalle Valo return ret; 2692d8899132SKalle Valo 2693d8899132SKalle Valo ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ); 2694d8899132SKalle Valo if (ret == 0) { 2695d8899132SKalle Valo ret = ath12k_scan_stop(ar); 2696d8899132SKalle Valo if (ret) 2697d8899132SKalle Valo ath12k_warn(ar->ab, "failed to stop scan: %d\n", ret); 2698d8899132SKalle Valo 2699d8899132SKalle Valo return -ETIMEDOUT; 2700d8899132SKalle Valo } 2701d8899132SKalle Valo 2702d8899132SKalle Valo /* If we failed to start the scan, return error code at 2703d8899132SKalle Valo * this point. This is probably due to some issue in the 2704d8899132SKalle Valo * firmware, but no need to wedge the driver due to that... 2705d8899132SKalle Valo */ 2706d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 2707d8899132SKalle Valo if (ar->scan.state == ATH12K_SCAN_IDLE) { 2708d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 2709d8899132SKalle Valo return -EINVAL; 2710d8899132SKalle Valo } 2711d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 2712d8899132SKalle Valo 2713d8899132SKalle Valo return 0; 2714d8899132SKalle Valo } 2715d8899132SKalle Valo 2716d8899132SKalle Valo static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, 2717d8899132SKalle Valo struct ieee80211_vif *vif, 2718d8899132SKalle Valo struct ieee80211_scan_request *hw_req) 2719d8899132SKalle Valo { 2720d8899132SKalle Valo struct ath12k *ar = hw->priv; 2721d8899132SKalle Valo struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 2722d8899132SKalle Valo struct cfg80211_scan_request *req = &hw_req->req; 2723d8899132SKalle Valo struct ath12k_wmi_scan_req_arg arg = {}; 2724d8899132SKalle Valo int ret; 2725d8899132SKalle Valo int i; 2726d8899132SKalle Valo 2727d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 2728d8899132SKalle Valo 2729d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 2730d8899132SKalle Valo switch (ar->scan.state) { 2731d8899132SKalle Valo case ATH12K_SCAN_IDLE: 2732d8899132SKalle Valo reinit_completion(&ar->scan.started); 2733d8899132SKalle Valo reinit_completion(&ar->scan.completed); 2734d8899132SKalle Valo ar->scan.state = ATH12K_SCAN_STARTING; 2735d8899132SKalle Valo ar->scan.is_roc = false; 2736d8899132SKalle Valo ar->scan.vdev_id = arvif->vdev_id; 2737d8899132SKalle Valo ret = 0; 2738d8899132SKalle Valo break; 2739d8899132SKalle Valo case ATH12K_SCAN_STARTING: 2740d8899132SKalle Valo case ATH12K_SCAN_RUNNING: 2741d8899132SKalle Valo case ATH12K_SCAN_ABORTING: 2742d8899132SKalle Valo ret = -EBUSY; 2743d8899132SKalle Valo break; 2744d8899132SKalle Valo } 2745d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 2746d8899132SKalle Valo 2747d8899132SKalle Valo if (ret) 2748d8899132SKalle Valo goto exit; 2749d8899132SKalle Valo 2750d8899132SKalle Valo ath12k_wmi_start_scan_init(ar, &arg); 2751d8899132SKalle Valo arg.vdev_id = arvif->vdev_id; 2752d8899132SKalle Valo arg.scan_id = ATH12K_SCAN_ID; 2753d8899132SKalle Valo 2754d8899132SKalle Valo if (req->ie_len) { 2755d8899132SKalle Valo arg.extraie.len = req->ie_len; 2756d8899132SKalle Valo arg.extraie.ptr = kzalloc(req->ie_len, GFP_KERNEL); 2757d8899132SKalle Valo memcpy(arg.extraie.ptr, req->ie, req->ie_len); 2758d8899132SKalle Valo } 2759d8899132SKalle Valo 2760d8899132SKalle Valo if (req->n_ssids) { 2761d8899132SKalle Valo arg.num_ssids = req->n_ssids; 2762d8899132SKalle Valo for (i = 0; i < arg.num_ssids; i++) 2763d8899132SKalle Valo arg.ssid[i] = req->ssids[i]; 2764d8899132SKalle Valo } else { 2765d8899132SKalle Valo arg.scan_flags |= WMI_SCAN_FLAG_PASSIVE; 2766d8899132SKalle Valo } 2767d8899132SKalle Valo 2768d8899132SKalle Valo if (req->n_channels) { 2769d8899132SKalle Valo arg.num_chan = req->n_channels; 2770d8899132SKalle Valo for (i = 0; i < arg.num_chan; i++) 2771d8899132SKalle Valo arg.chan_list[i] = req->channels[i]->center_freq; 2772d8899132SKalle Valo } 2773d8899132SKalle Valo 2774d8899132SKalle Valo ret = ath12k_start_scan(ar, &arg); 2775d8899132SKalle Valo if (ret) { 2776d8899132SKalle Valo ath12k_warn(ar->ab, "failed to start hw scan: %d\n", ret); 2777d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 2778d8899132SKalle Valo ar->scan.state = ATH12K_SCAN_IDLE; 2779d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 2780d8899132SKalle Valo } 2781d8899132SKalle Valo 2782d8899132SKalle Valo /* Add a margin to account for event/command processing */ 2783d8899132SKalle Valo ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout, 2784d8899132SKalle Valo msecs_to_jiffies(arg.max_scan_time + 2785d8899132SKalle Valo ATH12K_MAC_SCAN_TIMEOUT_MSECS)); 2786d8899132SKalle Valo 2787d8899132SKalle Valo exit: 2788d8899132SKalle Valo if (req->ie_len) 2789d8899132SKalle Valo kfree(arg.extraie.ptr); 2790d8899132SKalle Valo 2791d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 2792d8899132SKalle Valo return ret; 2793d8899132SKalle Valo } 2794d8899132SKalle Valo 2795d8899132SKalle Valo static void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw, 2796d8899132SKalle Valo struct ieee80211_vif *vif) 2797d8899132SKalle Valo { 2798d8899132SKalle Valo struct ath12k *ar = hw->priv; 2799d8899132SKalle Valo 2800d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 2801d8899132SKalle Valo ath12k_scan_abort(ar); 2802d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 2803d8899132SKalle Valo 2804d8899132SKalle Valo cancel_delayed_work_sync(&ar->scan.timeout); 2805d8899132SKalle Valo } 2806d8899132SKalle Valo 2807d8899132SKalle Valo static int ath12k_install_key(struct ath12k_vif *arvif, 2808d8899132SKalle Valo struct ieee80211_key_conf *key, 2809d8899132SKalle Valo enum set_key_cmd cmd, 2810d8899132SKalle Valo const u8 *macaddr, u32 flags) 2811d8899132SKalle Valo { 2812d8899132SKalle Valo int ret; 2813d8899132SKalle Valo struct ath12k *ar = arvif->ar; 2814d8899132SKalle Valo struct wmi_vdev_install_key_arg arg = { 2815d8899132SKalle Valo .vdev_id = arvif->vdev_id, 2816d8899132SKalle Valo .key_idx = key->keyidx, 2817d8899132SKalle Valo .key_len = key->keylen, 2818d8899132SKalle Valo .key_data = key->key, 2819d8899132SKalle Valo .key_flags = flags, 2820d8899132SKalle Valo .macaddr = macaddr, 2821d8899132SKalle Valo }; 2822d8899132SKalle Valo 2823d8899132SKalle Valo lockdep_assert_held(&arvif->ar->conf_mutex); 2824d8899132SKalle Valo 2825d8899132SKalle Valo reinit_completion(&ar->install_key_done); 2826d8899132SKalle Valo 2827d8899132SKalle Valo if (test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) 2828d8899132SKalle Valo return 0; 2829d8899132SKalle Valo 2830d8899132SKalle Valo if (cmd == DISABLE_KEY) { 2831d8899132SKalle Valo /* TODO: Check if FW expects value other than NONE for del */ 2832d8899132SKalle Valo /* arg.key_cipher = WMI_CIPHER_NONE; */ 2833d8899132SKalle Valo arg.key_len = 0; 2834d8899132SKalle Valo arg.key_data = NULL; 2835d8899132SKalle Valo goto install; 2836d8899132SKalle Valo } 2837d8899132SKalle Valo 2838d8899132SKalle Valo switch (key->cipher) { 2839d8899132SKalle Valo case WLAN_CIPHER_SUITE_CCMP: 2840d8899132SKalle Valo arg.key_cipher = WMI_CIPHER_AES_CCM; 2841d8899132SKalle Valo /* TODO: Re-check if flag is valid */ 2842d8899132SKalle Valo key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT; 2843d8899132SKalle Valo break; 2844d8899132SKalle Valo case WLAN_CIPHER_SUITE_TKIP: 2845d8899132SKalle Valo arg.key_cipher = WMI_CIPHER_TKIP; 2846d8899132SKalle Valo arg.key_txmic_len = 8; 2847d8899132SKalle Valo arg.key_rxmic_len = 8; 2848d8899132SKalle Valo break; 2849d8899132SKalle Valo case WLAN_CIPHER_SUITE_CCMP_256: 2850d8899132SKalle Valo arg.key_cipher = WMI_CIPHER_AES_CCM; 2851d8899132SKalle Valo break; 2852d8899132SKalle Valo case WLAN_CIPHER_SUITE_GCMP: 2853d8899132SKalle Valo case WLAN_CIPHER_SUITE_GCMP_256: 2854d8899132SKalle Valo arg.key_cipher = WMI_CIPHER_AES_GCM; 2855d8899132SKalle Valo break; 2856d8899132SKalle Valo default: 2857d8899132SKalle Valo ath12k_warn(ar->ab, "cipher %d is not supported\n", key->cipher); 2858d8899132SKalle Valo return -EOPNOTSUPP; 2859d8899132SKalle Valo } 2860d8899132SKalle Valo 2861d8899132SKalle Valo if (test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) 2862d8899132SKalle Valo key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV | 2863d8899132SKalle Valo IEEE80211_KEY_FLAG_RESERVE_TAILROOM; 2864d8899132SKalle Valo 2865d8899132SKalle Valo install: 2866d8899132SKalle Valo ret = ath12k_wmi_vdev_install_key(arvif->ar, &arg); 2867d8899132SKalle Valo 2868d8899132SKalle Valo if (ret) 2869d8899132SKalle Valo return ret; 2870d8899132SKalle Valo 2871d8899132SKalle Valo if (!wait_for_completion_timeout(&ar->install_key_done, 1 * HZ)) 2872d8899132SKalle Valo return -ETIMEDOUT; 2873d8899132SKalle Valo 2874d8899132SKalle Valo if (ether_addr_equal(macaddr, arvif->vif->addr)) 2875d8899132SKalle Valo arvif->key_cipher = key->cipher; 2876d8899132SKalle Valo 2877d8899132SKalle Valo return ar->install_key_status ? -EINVAL : 0; 2878d8899132SKalle Valo } 2879d8899132SKalle Valo 2880d8899132SKalle Valo static int ath12k_clear_peer_keys(struct ath12k_vif *arvif, 2881d8899132SKalle Valo const u8 *addr) 2882d8899132SKalle Valo { 2883d8899132SKalle Valo struct ath12k *ar = arvif->ar; 2884d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 2885d8899132SKalle Valo struct ath12k_peer *peer; 2886d8899132SKalle Valo int first_errno = 0; 2887d8899132SKalle Valo int ret; 2888d8899132SKalle Valo int i; 2889d8899132SKalle Valo u32 flags = 0; 2890d8899132SKalle Valo 2891d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 2892d8899132SKalle Valo 2893d8899132SKalle Valo spin_lock_bh(&ab->base_lock); 2894d8899132SKalle Valo peer = ath12k_peer_find(ab, arvif->vdev_id, addr); 2895d8899132SKalle Valo spin_unlock_bh(&ab->base_lock); 2896d8899132SKalle Valo 2897d8899132SKalle Valo if (!peer) 2898d8899132SKalle Valo return -ENOENT; 2899d8899132SKalle Valo 2900d8899132SKalle Valo for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { 2901d8899132SKalle Valo if (!peer->keys[i]) 2902d8899132SKalle Valo continue; 2903d8899132SKalle Valo 2904d8899132SKalle Valo /* key flags are not required to delete the key */ 2905d8899132SKalle Valo ret = ath12k_install_key(arvif, peer->keys[i], 2906d8899132SKalle Valo DISABLE_KEY, addr, flags); 2907d8899132SKalle Valo if (ret < 0 && first_errno == 0) 2908d8899132SKalle Valo first_errno = ret; 2909d8899132SKalle Valo 2910d8899132SKalle Valo if (ret < 0) 2911d8899132SKalle Valo ath12k_warn(ab, "failed to remove peer key %d: %d\n", 2912d8899132SKalle Valo i, ret); 2913d8899132SKalle Valo 2914d8899132SKalle Valo spin_lock_bh(&ab->base_lock); 2915d8899132SKalle Valo peer->keys[i] = NULL; 2916d8899132SKalle Valo spin_unlock_bh(&ab->base_lock); 2917d8899132SKalle Valo } 2918d8899132SKalle Valo 2919d8899132SKalle Valo return first_errno; 2920d8899132SKalle Valo } 2921d8899132SKalle Valo 2922d8899132SKalle Valo static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 2923d8899132SKalle Valo struct ieee80211_vif *vif, struct ieee80211_sta *sta, 2924d8899132SKalle Valo struct ieee80211_key_conf *key) 2925d8899132SKalle Valo { 2926d8899132SKalle Valo struct ath12k *ar = hw->priv; 2927d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 2928d8899132SKalle Valo struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 2929d8899132SKalle Valo struct ath12k_peer *peer; 2930d8899132SKalle Valo struct ath12k_sta *arsta; 2931d8899132SKalle Valo const u8 *peer_addr; 2932d8899132SKalle Valo int ret = 0; 2933d8899132SKalle Valo u32 flags = 0; 2934d8899132SKalle Valo 2935d8899132SKalle Valo /* BIP needs to be done in software */ 2936d8899132SKalle Valo if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC || 2937d8899132SKalle Valo key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || 2938d8899132SKalle Valo key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 || 2939d8899132SKalle Valo key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256) 2940d8899132SKalle Valo return 1; 2941d8899132SKalle Valo 2942d8899132SKalle Valo if (test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) 2943d8899132SKalle Valo return 1; 2944d8899132SKalle Valo 2945d8899132SKalle Valo if (key->keyidx > WMI_MAX_KEY_INDEX) 2946d8899132SKalle Valo return -ENOSPC; 2947d8899132SKalle Valo 2948d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 2949d8899132SKalle Valo 2950d8899132SKalle Valo if (sta) 2951d8899132SKalle Valo peer_addr = sta->addr; 2952d8899132SKalle Valo else if (arvif->vdev_type == WMI_VDEV_TYPE_STA) 2953d8899132SKalle Valo peer_addr = vif->bss_conf.bssid; 2954d8899132SKalle Valo else 2955d8899132SKalle Valo peer_addr = vif->addr; 2956d8899132SKalle Valo 2957d8899132SKalle Valo key->hw_key_idx = key->keyidx; 2958d8899132SKalle Valo 2959d8899132SKalle Valo /* the peer should not disappear in mid-way (unless FW goes awry) since 2960d8899132SKalle Valo * we already hold conf_mutex. we just make sure its there now. 2961d8899132SKalle Valo */ 2962d8899132SKalle Valo spin_lock_bh(&ab->base_lock); 2963d8899132SKalle Valo peer = ath12k_peer_find(ab, arvif->vdev_id, peer_addr); 2964d8899132SKalle Valo spin_unlock_bh(&ab->base_lock); 2965d8899132SKalle Valo 2966d8899132SKalle Valo if (!peer) { 2967d8899132SKalle Valo if (cmd == SET_KEY) { 2968d8899132SKalle Valo ath12k_warn(ab, "cannot install key for non-existent peer %pM\n", 2969d8899132SKalle Valo peer_addr); 2970d8899132SKalle Valo ret = -EOPNOTSUPP; 2971d8899132SKalle Valo goto exit; 2972d8899132SKalle Valo } else { 2973d8899132SKalle Valo /* if the peer doesn't exist there is no key to disable 2974d8899132SKalle Valo * anymore 2975d8899132SKalle Valo */ 2976d8899132SKalle Valo goto exit; 2977d8899132SKalle Valo } 2978d8899132SKalle Valo } 2979d8899132SKalle Valo 2980d8899132SKalle Valo if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) 2981d8899132SKalle Valo flags |= WMI_KEY_PAIRWISE; 2982d8899132SKalle Valo else 2983d8899132SKalle Valo flags |= WMI_KEY_GROUP; 2984d8899132SKalle Valo 2985d8899132SKalle Valo ret = ath12k_install_key(arvif, key, cmd, peer_addr, flags); 2986d8899132SKalle Valo if (ret) { 2987d8899132SKalle Valo ath12k_warn(ab, "ath12k_install_key failed (%d)\n", ret); 2988d8899132SKalle Valo goto exit; 2989d8899132SKalle Valo } 2990d8899132SKalle Valo 2991d8899132SKalle Valo ret = ath12k_dp_rx_peer_pn_replay_config(arvif, peer_addr, cmd, key); 2992d8899132SKalle Valo if (ret) { 2993d8899132SKalle Valo ath12k_warn(ab, "failed to offload PN replay detection %d\n", ret); 2994d8899132SKalle Valo goto exit; 2995d8899132SKalle Valo } 2996d8899132SKalle Valo 2997d8899132SKalle Valo spin_lock_bh(&ab->base_lock); 2998d8899132SKalle Valo peer = ath12k_peer_find(ab, arvif->vdev_id, peer_addr); 2999d8899132SKalle Valo if (peer && cmd == SET_KEY) { 3000d8899132SKalle Valo peer->keys[key->keyidx] = key; 3001d8899132SKalle Valo if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { 3002d8899132SKalle Valo peer->ucast_keyidx = key->keyidx; 3003d8899132SKalle Valo peer->sec_type = ath12k_dp_tx_get_encrypt_type(key->cipher); 3004d8899132SKalle Valo } else { 3005d8899132SKalle Valo peer->mcast_keyidx = key->keyidx; 3006d8899132SKalle Valo peer->sec_type_grp = ath12k_dp_tx_get_encrypt_type(key->cipher); 3007d8899132SKalle Valo } 3008d8899132SKalle Valo } else if (peer && cmd == DISABLE_KEY) { 3009d8899132SKalle Valo peer->keys[key->keyidx] = NULL; 3010d8899132SKalle Valo if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) 3011d8899132SKalle Valo peer->ucast_keyidx = 0; 3012d8899132SKalle Valo else 3013d8899132SKalle Valo peer->mcast_keyidx = 0; 3014d8899132SKalle Valo } else if (!peer) 3015d8899132SKalle Valo /* impossible unless FW goes crazy */ 3016d8899132SKalle Valo ath12k_warn(ab, "peer %pM disappeared!\n", peer_addr); 3017d8899132SKalle Valo 3018d8899132SKalle Valo if (sta) { 3019d8899132SKalle Valo arsta = (struct ath12k_sta *)sta->drv_priv; 3020d8899132SKalle Valo 3021d8899132SKalle Valo switch (key->cipher) { 3022d8899132SKalle Valo case WLAN_CIPHER_SUITE_TKIP: 3023d8899132SKalle Valo case WLAN_CIPHER_SUITE_CCMP: 3024d8899132SKalle Valo case WLAN_CIPHER_SUITE_CCMP_256: 3025d8899132SKalle Valo case WLAN_CIPHER_SUITE_GCMP: 3026d8899132SKalle Valo case WLAN_CIPHER_SUITE_GCMP_256: 3027d8899132SKalle Valo if (cmd == SET_KEY) 3028d8899132SKalle Valo arsta->pn_type = HAL_PN_TYPE_WPA; 3029d8899132SKalle Valo else 3030d8899132SKalle Valo arsta->pn_type = HAL_PN_TYPE_NONE; 3031d8899132SKalle Valo break; 3032d8899132SKalle Valo default: 3033d8899132SKalle Valo arsta->pn_type = HAL_PN_TYPE_NONE; 3034d8899132SKalle Valo break; 3035d8899132SKalle Valo } 3036d8899132SKalle Valo } 3037d8899132SKalle Valo 3038d8899132SKalle Valo spin_unlock_bh(&ab->base_lock); 3039d8899132SKalle Valo 3040d8899132SKalle Valo exit: 3041d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 3042d8899132SKalle Valo return ret; 3043d8899132SKalle Valo } 3044d8899132SKalle Valo 3045d8899132SKalle Valo static int 3046d8899132SKalle Valo ath12k_mac_bitrate_mask_num_vht_rates(struct ath12k *ar, 3047d8899132SKalle Valo enum nl80211_band band, 3048d8899132SKalle Valo const struct cfg80211_bitrate_mask *mask) 3049d8899132SKalle Valo { 3050d8899132SKalle Valo int num_rates = 0; 3051d8899132SKalle Valo int i; 3052d8899132SKalle Valo 3053d8899132SKalle Valo for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) 3054d8899132SKalle Valo num_rates += hweight16(mask->control[band].vht_mcs[i]); 3055d8899132SKalle Valo 3056d8899132SKalle Valo return num_rates; 3057d8899132SKalle Valo } 3058d8899132SKalle Valo 3059d8899132SKalle Valo static int 3060d8899132SKalle Valo ath12k_mac_set_peer_vht_fixed_rate(struct ath12k_vif *arvif, 3061d8899132SKalle Valo struct ieee80211_sta *sta, 3062d8899132SKalle Valo const struct cfg80211_bitrate_mask *mask, 3063d8899132SKalle Valo enum nl80211_band band) 3064d8899132SKalle Valo { 3065d8899132SKalle Valo struct ath12k *ar = arvif->ar; 3066d8899132SKalle Valo u8 vht_rate, nss; 3067d8899132SKalle Valo u32 rate_code; 3068d8899132SKalle Valo int ret, i; 3069d8899132SKalle Valo 3070d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 3071d8899132SKalle Valo 3072d8899132SKalle Valo nss = 0; 3073d8899132SKalle Valo 3074d8899132SKalle Valo for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) { 3075d8899132SKalle Valo if (hweight16(mask->control[band].vht_mcs[i]) == 1) { 3076d8899132SKalle Valo nss = i + 1; 3077d8899132SKalle Valo vht_rate = ffs(mask->control[band].vht_mcs[i]) - 1; 3078d8899132SKalle Valo } 3079d8899132SKalle Valo } 3080d8899132SKalle Valo 3081d8899132SKalle Valo if (!nss) { 3082d8899132SKalle Valo ath12k_warn(ar->ab, "No single VHT Fixed rate found to set for %pM", 3083d8899132SKalle Valo sta->addr); 3084d8899132SKalle Valo return -EINVAL; 3085d8899132SKalle Valo } 3086d8899132SKalle Valo 3087d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 3088d8899132SKalle Valo "Setting Fixed VHT Rate for peer %pM. Device will not switch to any other selected rates", 3089d8899132SKalle Valo sta->addr); 3090d8899132SKalle Valo 3091d8899132SKalle Valo rate_code = ATH12K_HW_RATE_CODE(vht_rate, nss - 1, 3092d8899132SKalle Valo WMI_RATE_PREAMBLE_VHT); 3093d8899132SKalle Valo ret = ath12k_wmi_set_peer_param(ar, sta->addr, 3094d8899132SKalle Valo arvif->vdev_id, 3095d8899132SKalle Valo WMI_PEER_PARAM_FIXED_RATE, 3096d8899132SKalle Valo rate_code); 3097d8899132SKalle Valo if (ret) 3098d8899132SKalle Valo ath12k_warn(ar->ab, 3099d8899132SKalle Valo "failed to update STA %pM Fixed Rate %d: %d\n", 3100d8899132SKalle Valo sta->addr, rate_code, ret); 3101d8899132SKalle Valo 3102d8899132SKalle Valo return ret; 3103d8899132SKalle Valo } 3104d8899132SKalle Valo 3105d8899132SKalle Valo static int ath12k_station_assoc(struct ath12k *ar, 3106d8899132SKalle Valo struct ieee80211_vif *vif, 3107d8899132SKalle Valo struct ieee80211_sta *sta, 3108d8899132SKalle Valo bool reassoc) 3109d8899132SKalle Valo { 3110d8899132SKalle Valo struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 3111d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg peer_arg; 3112d8899132SKalle Valo int ret; 3113d8899132SKalle Valo struct cfg80211_chan_def def; 3114d8899132SKalle Valo enum nl80211_band band; 3115d8899132SKalle Valo struct cfg80211_bitrate_mask *mask; 3116d8899132SKalle Valo u8 num_vht_rates; 3117d8899132SKalle Valo 3118d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 3119d8899132SKalle Valo 3120d8899132SKalle Valo if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) 3121d8899132SKalle Valo return -EPERM; 3122d8899132SKalle Valo 3123d8899132SKalle Valo band = def.chan->band; 3124d8899132SKalle Valo mask = &arvif->bitrate_mask; 3125d8899132SKalle Valo 3126d8899132SKalle Valo ath12k_peer_assoc_prepare(ar, vif, sta, &peer_arg, reassoc); 3127d8899132SKalle Valo 3128d8899132SKalle Valo ret = ath12k_wmi_send_peer_assoc_cmd(ar, &peer_arg); 3129d8899132SKalle Valo if (ret) { 3130d8899132SKalle Valo ath12k_warn(ar->ab, "failed to run peer assoc for STA %pM vdev %i: %d\n", 3131d8899132SKalle Valo sta->addr, arvif->vdev_id, ret); 3132d8899132SKalle Valo return ret; 3133d8899132SKalle Valo } 3134d8899132SKalle Valo 3135d8899132SKalle Valo if (!wait_for_completion_timeout(&ar->peer_assoc_done, 1 * HZ)) { 3136d8899132SKalle Valo ath12k_warn(ar->ab, "failed to get peer assoc conf event for %pM vdev %i\n", 3137d8899132SKalle Valo sta->addr, arvif->vdev_id); 3138d8899132SKalle Valo return -ETIMEDOUT; 3139d8899132SKalle Valo } 3140d8899132SKalle Valo 3141d8899132SKalle Valo num_vht_rates = ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask); 3142d8899132SKalle Valo 3143d8899132SKalle Valo /* If single VHT rate is configured (by set_bitrate_mask()), 3144d8899132SKalle Valo * peer_assoc will disable VHT. This is now enabled by a peer specific 3145d8899132SKalle Valo * fixed param. 3146d8899132SKalle Valo * Note that all other rates and NSS will be disabled for this peer. 3147d8899132SKalle Valo */ 3148d8899132SKalle Valo if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) { 3149d8899132SKalle Valo ret = ath12k_mac_set_peer_vht_fixed_rate(arvif, sta, mask, 3150d8899132SKalle Valo band); 3151d8899132SKalle Valo if (ret) 3152d8899132SKalle Valo return ret; 3153d8899132SKalle Valo } 3154d8899132SKalle Valo 3155d8899132SKalle Valo /* Re-assoc is run only to update supported rates for given station. It 3156d8899132SKalle Valo * doesn't make much sense to reconfigure the peer completely. 3157d8899132SKalle Valo */ 3158d8899132SKalle Valo if (reassoc) 3159d8899132SKalle Valo return 0; 3160d8899132SKalle Valo 3161d8899132SKalle Valo ret = ath12k_setup_peer_smps(ar, arvif, sta->addr, 3162d8899132SKalle Valo &sta->deflink.ht_cap); 3163d8899132SKalle Valo if (ret) { 3164d8899132SKalle Valo ath12k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n", 3165d8899132SKalle Valo arvif->vdev_id, ret); 3166d8899132SKalle Valo return ret; 3167d8899132SKalle Valo } 3168d8899132SKalle Valo 3169d8899132SKalle Valo if (!sta->wme) { 3170d8899132SKalle Valo arvif->num_legacy_stations++; 3171d8899132SKalle Valo ret = ath12k_recalc_rtscts_prot(arvif); 3172d8899132SKalle Valo if (ret) 3173d8899132SKalle Valo return ret; 3174d8899132SKalle Valo } 3175d8899132SKalle Valo 3176d8899132SKalle Valo if (sta->wme && sta->uapsd_queues) { 3177d8899132SKalle Valo ret = ath12k_peer_assoc_qos_ap(ar, arvif, sta); 3178d8899132SKalle Valo if (ret) { 3179d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set qos params for STA %pM for vdev %i: %d\n", 3180d8899132SKalle Valo sta->addr, arvif->vdev_id, ret); 3181d8899132SKalle Valo return ret; 3182d8899132SKalle Valo } 3183d8899132SKalle Valo } 3184d8899132SKalle Valo 3185d8899132SKalle Valo return 0; 3186d8899132SKalle Valo } 3187d8899132SKalle Valo 3188d8899132SKalle Valo static int ath12k_station_disassoc(struct ath12k *ar, 3189d8899132SKalle Valo struct ieee80211_vif *vif, 3190d8899132SKalle Valo struct ieee80211_sta *sta) 3191d8899132SKalle Valo { 3192d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 3193d8899132SKalle Valo int ret; 3194d8899132SKalle Valo 3195d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 3196d8899132SKalle Valo 3197d8899132SKalle Valo if (!sta->wme) { 3198d8899132SKalle Valo arvif->num_legacy_stations--; 3199d8899132SKalle Valo ret = ath12k_recalc_rtscts_prot(arvif); 3200d8899132SKalle Valo if (ret) 3201d8899132SKalle Valo return ret; 3202d8899132SKalle Valo } 3203d8899132SKalle Valo 3204d8899132SKalle Valo ret = ath12k_clear_peer_keys(arvif, sta->addr); 3205d8899132SKalle Valo if (ret) { 3206d8899132SKalle Valo ath12k_warn(ar->ab, "failed to clear all peer keys for vdev %i: %d\n", 3207d8899132SKalle Valo arvif->vdev_id, ret); 3208d8899132SKalle Valo return ret; 3209d8899132SKalle Valo } 3210d8899132SKalle Valo return 0; 3211d8899132SKalle Valo } 3212d8899132SKalle Valo 3213d8899132SKalle Valo static void ath12k_sta_rc_update_wk(struct work_struct *wk) 3214d8899132SKalle Valo { 3215d8899132SKalle Valo struct ath12k *ar; 3216d8899132SKalle Valo struct ath12k_vif *arvif; 3217d8899132SKalle Valo struct ath12k_sta *arsta; 3218d8899132SKalle Valo struct ieee80211_sta *sta; 3219d8899132SKalle Valo struct cfg80211_chan_def def; 3220d8899132SKalle Valo enum nl80211_band band; 3221d8899132SKalle Valo const u8 *ht_mcs_mask; 3222d8899132SKalle Valo const u16 *vht_mcs_mask; 3223d8899132SKalle Valo u32 changed, bw, nss, smps; 3224d8899132SKalle Valo int err, num_vht_rates; 3225d8899132SKalle Valo const struct cfg80211_bitrate_mask *mask; 3226d8899132SKalle Valo struct ath12k_wmi_peer_assoc_arg peer_arg; 3227d8899132SKalle Valo 3228d8899132SKalle Valo arsta = container_of(wk, struct ath12k_sta, update_wk); 3229d8899132SKalle Valo sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv); 3230d8899132SKalle Valo arvif = arsta->arvif; 3231d8899132SKalle Valo ar = arvif->ar; 3232d8899132SKalle Valo 3233d8899132SKalle Valo if (WARN_ON(ath12k_mac_vif_chan(arvif->vif, &def))) 3234d8899132SKalle Valo return; 3235d8899132SKalle Valo 3236d8899132SKalle Valo band = def.chan->band; 3237d8899132SKalle Valo ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs; 3238d8899132SKalle Valo vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs; 3239d8899132SKalle Valo 3240d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 3241d8899132SKalle Valo 3242d8899132SKalle Valo changed = arsta->changed; 3243d8899132SKalle Valo arsta->changed = 0; 3244d8899132SKalle Valo 3245d8899132SKalle Valo bw = arsta->bw; 3246d8899132SKalle Valo nss = arsta->nss; 3247d8899132SKalle Valo smps = arsta->smps; 3248d8899132SKalle Valo 3249d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 3250d8899132SKalle Valo 3251d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 3252d8899132SKalle Valo 3253d8899132SKalle Valo nss = max_t(u32, 1, nss); 3254d8899132SKalle Valo nss = min(nss, max(ath12k_mac_max_ht_nss(ht_mcs_mask), 3255d8899132SKalle Valo ath12k_mac_max_vht_nss(vht_mcs_mask))); 3256d8899132SKalle Valo 3257d8899132SKalle Valo if (changed & IEEE80211_RC_BW_CHANGED) { 3258d8899132SKalle Valo err = ath12k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id, 3259d8899132SKalle Valo WMI_PEER_CHWIDTH, bw); 3260d8899132SKalle Valo if (err) 3261d8899132SKalle Valo ath12k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n", 3262d8899132SKalle Valo sta->addr, bw, err); 3263d8899132SKalle Valo } 3264d8899132SKalle Valo 3265d8899132SKalle Valo if (changed & IEEE80211_RC_NSS_CHANGED) { 3266d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac update sta %pM nss %d\n", 3267d8899132SKalle Valo sta->addr, nss); 3268d8899132SKalle Valo 3269d8899132SKalle Valo err = ath12k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id, 3270d8899132SKalle Valo WMI_PEER_NSS, nss); 3271d8899132SKalle Valo if (err) 3272d8899132SKalle Valo ath12k_warn(ar->ab, "failed to update STA %pM nss %d: %d\n", 3273d8899132SKalle Valo sta->addr, nss, err); 3274d8899132SKalle Valo } 3275d8899132SKalle Valo 3276d8899132SKalle Valo if (changed & IEEE80211_RC_SMPS_CHANGED) { 3277d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac update sta %pM smps %d\n", 3278d8899132SKalle Valo sta->addr, smps); 3279d8899132SKalle Valo 3280d8899132SKalle Valo err = ath12k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id, 3281d8899132SKalle Valo WMI_PEER_MIMO_PS_STATE, smps); 3282d8899132SKalle Valo if (err) 3283d8899132SKalle Valo ath12k_warn(ar->ab, "failed to update STA %pM smps %d: %d\n", 3284d8899132SKalle Valo sta->addr, smps, err); 3285d8899132SKalle Valo } 3286d8899132SKalle Valo 3287d8899132SKalle Valo if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { 3288d8899132SKalle Valo mask = &arvif->bitrate_mask; 3289d8899132SKalle Valo num_vht_rates = ath12k_mac_bitrate_mask_num_vht_rates(ar, band, 3290d8899132SKalle Valo mask); 3291d8899132SKalle Valo 3292d8899132SKalle Valo /* Peer_assoc_prepare will reject vht rates in 3293d8899132SKalle Valo * bitrate_mask if its not available in range format and 3294d8899132SKalle Valo * sets vht tx_rateset as unsupported. So multiple VHT MCS 3295d8899132SKalle Valo * setting(eg. MCS 4,5,6) per peer is not supported here. 3296d8899132SKalle Valo * But, Single rate in VHT mask can be set as per-peer 3297d8899132SKalle Valo * fixed rate. But even if any HT rates are configured in 3298d8899132SKalle Valo * the bitrate mask, device will not switch to those rates 3299d8899132SKalle Valo * when per-peer Fixed rate is set. 3300d8899132SKalle Valo * TODO: Check RATEMASK_CMDID to support auto rates selection 3301d8899132SKalle Valo * across HT/VHT and for multiple VHT MCS support. 3302d8899132SKalle Valo */ 3303d8899132SKalle Valo if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) { 3304d8899132SKalle Valo ath12k_mac_set_peer_vht_fixed_rate(arvif, sta, mask, 3305d8899132SKalle Valo band); 3306d8899132SKalle Valo } else { 3307d8899132SKalle Valo /* If the peer is non-VHT or no fixed VHT rate 3308d8899132SKalle Valo * is provided in the new bitrate mask we set the 3309d8899132SKalle Valo * other rates using peer_assoc command. 3310d8899132SKalle Valo */ 3311d8899132SKalle Valo ath12k_peer_assoc_prepare(ar, arvif->vif, sta, 3312d8899132SKalle Valo &peer_arg, true); 3313d8899132SKalle Valo 3314d8899132SKalle Valo err = ath12k_wmi_send_peer_assoc_cmd(ar, &peer_arg); 3315d8899132SKalle Valo if (err) 3316d8899132SKalle Valo ath12k_warn(ar->ab, "failed to run peer assoc for STA %pM vdev %i: %d\n", 3317d8899132SKalle Valo sta->addr, arvif->vdev_id, err); 3318d8899132SKalle Valo 3319d8899132SKalle Valo if (!wait_for_completion_timeout(&ar->peer_assoc_done, 1 * HZ)) 3320d8899132SKalle Valo ath12k_warn(ar->ab, "failed to get peer assoc conf event for %pM vdev %i\n", 3321d8899132SKalle Valo sta->addr, arvif->vdev_id); 3322d8899132SKalle Valo } 3323d8899132SKalle Valo } 3324d8899132SKalle Valo 3325d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 3326d8899132SKalle Valo } 3327d8899132SKalle Valo 3328d8899132SKalle Valo static int ath12k_mac_inc_num_stations(struct ath12k_vif *arvif, 3329d8899132SKalle Valo struct ieee80211_sta *sta) 3330d8899132SKalle Valo { 3331d8899132SKalle Valo struct ath12k *ar = arvif->ar; 3332d8899132SKalle Valo 3333d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 3334d8899132SKalle Valo 3335d8899132SKalle Valo if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls) 3336d8899132SKalle Valo return 0; 3337d8899132SKalle Valo 3338d8899132SKalle Valo if (ar->num_stations >= ar->max_num_stations) 3339d8899132SKalle Valo return -ENOBUFS; 3340d8899132SKalle Valo 3341d8899132SKalle Valo ar->num_stations++; 3342d8899132SKalle Valo 3343d8899132SKalle Valo return 0; 3344d8899132SKalle Valo } 3345d8899132SKalle Valo 3346d8899132SKalle Valo static void ath12k_mac_dec_num_stations(struct ath12k_vif *arvif, 3347d8899132SKalle Valo struct ieee80211_sta *sta) 3348d8899132SKalle Valo { 3349d8899132SKalle Valo struct ath12k *ar = arvif->ar; 3350d8899132SKalle Valo 3351d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 3352d8899132SKalle Valo 3353d8899132SKalle Valo if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls) 3354d8899132SKalle Valo return; 3355d8899132SKalle Valo 3356d8899132SKalle Valo ar->num_stations--; 3357d8899132SKalle Valo } 3358d8899132SKalle Valo 3359d8899132SKalle Valo static int ath12k_mac_station_add(struct ath12k *ar, 3360d8899132SKalle Valo struct ieee80211_vif *vif, 3361d8899132SKalle Valo struct ieee80211_sta *sta) 3362d8899132SKalle Valo { 3363d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 3364d8899132SKalle Valo struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 3365d8899132SKalle Valo struct ath12k_sta *arsta = (struct ath12k_sta *)sta->drv_priv; 3366d8899132SKalle Valo struct ath12k_wmi_peer_create_arg peer_param; 3367d8899132SKalle Valo int ret; 3368d8899132SKalle Valo 3369d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 3370d8899132SKalle Valo 3371d8899132SKalle Valo ret = ath12k_mac_inc_num_stations(arvif, sta); 3372d8899132SKalle Valo if (ret) { 3373d8899132SKalle Valo ath12k_warn(ab, "refusing to associate station: too many connected already (%d)\n", 3374d8899132SKalle Valo ar->max_num_stations); 3375d8899132SKalle Valo goto exit; 3376d8899132SKalle Valo } 3377d8899132SKalle Valo 3378d8899132SKalle Valo arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL); 3379d8899132SKalle Valo if (!arsta->rx_stats) { 3380d8899132SKalle Valo ret = -ENOMEM; 3381d8899132SKalle Valo goto dec_num_station; 3382d8899132SKalle Valo } 3383d8899132SKalle Valo 3384d8899132SKalle Valo peer_param.vdev_id = arvif->vdev_id; 3385d8899132SKalle Valo peer_param.peer_addr = sta->addr; 3386d8899132SKalle Valo peer_param.peer_type = WMI_PEER_TYPE_DEFAULT; 3387d8899132SKalle Valo 3388d8899132SKalle Valo ret = ath12k_peer_create(ar, arvif, sta, &peer_param); 3389d8899132SKalle Valo if (ret) { 3390d8899132SKalle Valo ath12k_warn(ab, "Failed to add peer: %pM for VDEV: %d\n", 3391d8899132SKalle Valo sta->addr, arvif->vdev_id); 3392d8899132SKalle Valo goto free_peer; 3393d8899132SKalle Valo } 3394d8899132SKalle Valo 3395d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, "Added peer: %pM for VDEV: %d\n", 3396d8899132SKalle Valo sta->addr, arvif->vdev_id); 3397d8899132SKalle Valo 3398d8899132SKalle Valo if (ieee80211_vif_is_mesh(vif)) { 3399d8899132SKalle Valo ret = ath12k_wmi_set_peer_param(ar, sta->addr, 3400d8899132SKalle Valo arvif->vdev_id, 3401d8899132SKalle Valo WMI_PEER_USE_4ADDR, 1); 3402d8899132SKalle Valo if (ret) { 3403d8899132SKalle Valo ath12k_warn(ab, "failed to STA %pM 4addr capability: %d\n", 3404d8899132SKalle Valo sta->addr, ret); 3405d8899132SKalle Valo goto free_peer; 3406d8899132SKalle Valo } 3407d8899132SKalle Valo } 3408d8899132SKalle Valo 3409d8899132SKalle Valo ret = ath12k_dp_peer_setup(ar, arvif->vdev_id, sta->addr); 3410d8899132SKalle Valo if (ret) { 3411d8899132SKalle Valo ath12k_warn(ab, "failed to setup dp for peer %pM on vdev %i (%d)\n", 3412d8899132SKalle Valo sta->addr, arvif->vdev_id, ret); 3413d8899132SKalle Valo goto free_peer; 3414d8899132SKalle Valo } 3415d8899132SKalle Valo 3416d8899132SKalle Valo if (ab->hw_params->vdev_start_delay && 3417d8899132SKalle Valo !arvif->is_started && 3418d8899132SKalle Valo arvif->vdev_type != WMI_VDEV_TYPE_AP) { 3419d8899132SKalle Valo ret = ath12k_start_vdev_delay(ar->hw, vif); 3420d8899132SKalle Valo if (ret) { 3421d8899132SKalle Valo ath12k_warn(ab, "failed to delay vdev start: %d\n", ret); 3422d8899132SKalle Valo goto free_peer; 3423d8899132SKalle Valo } 3424d8899132SKalle Valo } 3425d8899132SKalle Valo 3426d8899132SKalle Valo return 0; 3427d8899132SKalle Valo 3428d8899132SKalle Valo free_peer: 3429d8899132SKalle Valo ath12k_peer_delete(ar, arvif->vdev_id, sta->addr); 3430d8899132SKalle Valo dec_num_station: 3431d8899132SKalle Valo ath12k_mac_dec_num_stations(arvif, sta); 3432d8899132SKalle Valo exit: 3433d8899132SKalle Valo return ret; 3434d8899132SKalle Valo } 3435d8899132SKalle Valo 3436d8899132SKalle Valo static int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, 3437d8899132SKalle Valo struct ieee80211_vif *vif, 3438d8899132SKalle Valo struct ieee80211_sta *sta, 3439d8899132SKalle Valo enum ieee80211_sta_state old_state, 3440d8899132SKalle Valo enum ieee80211_sta_state new_state) 3441d8899132SKalle Valo { 3442d8899132SKalle Valo struct ath12k *ar = hw->priv; 3443d8899132SKalle Valo struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 3444d8899132SKalle Valo struct ath12k_sta *arsta = (struct ath12k_sta *)sta->drv_priv; 3445d8899132SKalle Valo struct ath12k_peer *peer; 3446d8899132SKalle Valo int ret = 0; 3447d8899132SKalle Valo 3448d8899132SKalle Valo /* cancel must be done outside the mutex to avoid deadlock */ 3449d8899132SKalle Valo if ((old_state == IEEE80211_STA_NONE && 3450d8899132SKalle Valo new_state == IEEE80211_STA_NOTEXIST)) 3451d8899132SKalle Valo cancel_work_sync(&arsta->update_wk); 3452d8899132SKalle Valo 3453d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 3454d8899132SKalle Valo 3455d8899132SKalle Valo if (old_state == IEEE80211_STA_NOTEXIST && 3456d8899132SKalle Valo new_state == IEEE80211_STA_NONE) { 3457d8899132SKalle Valo memset(arsta, 0, sizeof(*arsta)); 3458d8899132SKalle Valo arsta->arvif = arvif; 3459d8899132SKalle Valo INIT_WORK(&arsta->update_wk, ath12k_sta_rc_update_wk); 3460d8899132SKalle Valo 3461d8899132SKalle Valo ret = ath12k_mac_station_add(ar, vif, sta); 3462d8899132SKalle Valo if (ret) 3463d8899132SKalle Valo ath12k_warn(ar->ab, "Failed to add station: %pM for VDEV: %d\n", 3464d8899132SKalle Valo sta->addr, arvif->vdev_id); 3465d8899132SKalle Valo } else if ((old_state == IEEE80211_STA_NONE && 3466d8899132SKalle Valo new_state == IEEE80211_STA_NOTEXIST)) { 3467d8899132SKalle Valo ath12k_dp_peer_cleanup(ar, arvif->vdev_id, sta->addr); 3468d8899132SKalle Valo 3469d8899132SKalle Valo ret = ath12k_peer_delete(ar, arvif->vdev_id, sta->addr); 3470d8899132SKalle Valo if (ret) 3471d8899132SKalle Valo ath12k_warn(ar->ab, "Failed to delete peer: %pM for VDEV: %d\n", 3472d8899132SKalle Valo sta->addr, arvif->vdev_id); 3473d8899132SKalle Valo else 3474d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "Removed peer: %pM for VDEV: %d\n", 3475d8899132SKalle Valo sta->addr, arvif->vdev_id); 3476d8899132SKalle Valo 3477d8899132SKalle Valo ath12k_mac_dec_num_stations(arvif, sta); 3478d8899132SKalle Valo spin_lock_bh(&ar->ab->base_lock); 3479d8899132SKalle Valo peer = ath12k_peer_find(ar->ab, arvif->vdev_id, sta->addr); 3480d8899132SKalle Valo if (peer && peer->sta == sta) { 3481d8899132SKalle Valo ath12k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n", 3482d8899132SKalle Valo vif->addr, arvif->vdev_id); 3483d8899132SKalle Valo peer->sta = NULL; 3484d8899132SKalle Valo list_del(&peer->list); 3485d8899132SKalle Valo kfree(peer); 3486d8899132SKalle Valo ar->num_peers--; 3487d8899132SKalle Valo } 3488d8899132SKalle Valo spin_unlock_bh(&ar->ab->base_lock); 3489d8899132SKalle Valo 3490d8899132SKalle Valo kfree(arsta->rx_stats); 3491d8899132SKalle Valo arsta->rx_stats = NULL; 3492d8899132SKalle Valo } else if (old_state == IEEE80211_STA_AUTH && 3493d8899132SKalle Valo new_state == IEEE80211_STA_ASSOC && 3494d8899132SKalle Valo (vif->type == NL80211_IFTYPE_AP || 3495d8899132SKalle Valo vif->type == NL80211_IFTYPE_MESH_POINT || 3496d8899132SKalle Valo vif->type == NL80211_IFTYPE_ADHOC)) { 3497d8899132SKalle Valo ret = ath12k_station_assoc(ar, vif, sta, false); 3498d8899132SKalle Valo if (ret) 3499d8899132SKalle Valo ath12k_warn(ar->ab, "Failed to associate station: %pM\n", 3500d8899132SKalle Valo sta->addr); 3501d8899132SKalle Valo } else if (old_state == IEEE80211_STA_ASSOC && 3502d8899132SKalle Valo new_state == IEEE80211_STA_AUTHORIZED) { 3503d8899132SKalle Valo spin_lock_bh(&ar->ab->base_lock); 3504d8899132SKalle Valo 3505d8899132SKalle Valo peer = ath12k_peer_find(ar->ab, arvif->vdev_id, sta->addr); 3506d8899132SKalle Valo if (peer) 3507d8899132SKalle Valo peer->is_authorized = true; 3508d8899132SKalle Valo 3509d8899132SKalle Valo spin_unlock_bh(&ar->ab->base_lock); 3510d8899132SKalle Valo 3511d8899132SKalle Valo if (vif->type == NL80211_IFTYPE_STATION && arvif->is_up) { 3512d8899132SKalle Valo ret = ath12k_wmi_set_peer_param(ar, sta->addr, 3513d8899132SKalle Valo arvif->vdev_id, 3514d8899132SKalle Valo WMI_PEER_AUTHORIZE, 3515d8899132SKalle Valo 1); 3516d8899132SKalle Valo if (ret) 3517d8899132SKalle Valo ath12k_warn(ar->ab, "Unable to authorize peer %pM vdev %d: %d\n", 3518d8899132SKalle Valo sta->addr, arvif->vdev_id, ret); 3519d8899132SKalle Valo } 3520d8899132SKalle Valo } else if (old_state == IEEE80211_STA_AUTHORIZED && 3521d8899132SKalle Valo new_state == IEEE80211_STA_ASSOC) { 3522d8899132SKalle Valo spin_lock_bh(&ar->ab->base_lock); 3523d8899132SKalle Valo 3524d8899132SKalle Valo peer = ath12k_peer_find(ar->ab, arvif->vdev_id, sta->addr); 3525d8899132SKalle Valo if (peer) 3526d8899132SKalle Valo peer->is_authorized = false; 3527d8899132SKalle Valo 3528d8899132SKalle Valo spin_unlock_bh(&ar->ab->base_lock); 3529d8899132SKalle Valo } else if (old_state == IEEE80211_STA_ASSOC && 3530d8899132SKalle Valo new_state == IEEE80211_STA_AUTH && 3531d8899132SKalle Valo (vif->type == NL80211_IFTYPE_AP || 3532d8899132SKalle Valo vif->type == NL80211_IFTYPE_MESH_POINT || 3533d8899132SKalle Valo vif->type == NL80211_IFTYPE_ADHOC)) { 3534d8899132SKalle Valo ret = ath12k_station_disassoc(ar, vif, sta); 3535d8899132SKalle Valo if (ret) 3536d8899132SKalle Valo ath12k_warn(ar->ab, "Failed to disassociate station: %pM\n", 3537d8899132SKalle Valo sta->addr); 3538d8899132SKalle Valo } 3539d8899132SKalle Valo 3540d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 3541d8899132SKalle Valo return ret; 3542d8899132SKalle Valo } 3543d8899132SKalle Valo 3544d8899132SKalle Valo static int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, 3545d8899132SKalle Valo struct ieee80211_vif *vif, 3546d8899132SKalle Valo struct ieee80211_sta *sta) 3547d8899132SKalle Valo { 3548d8899132SKalle Valo struct ath12k *ar = hw->priv; 3549d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 3550d8899132SKalle Valo int ret; 3551d8899132SKalle Valo s16 txpwr; 3552d8899132SKalle Valo 3553d8899132SKalle Valo if (sta->deflink.txpwr.type == NL80211_TX_POWER_AUTOMATIC) { 3554d8899132SKalle Valo txpwr = 0; 3555d8899132SKalle Valo } else { 3556d8899132SKalle Valo txpwr = sta->deflink.txpwr.power; 3557d8899132SKalle Valo if (!txpwr) 3558d8899132SKalle Valo return -EINVAL; 3559d8899132SKalle Valo } 3560d8899132SKalle Valo 3561d8899132SKalle Valo if (txpwr > ATH12K_TX_POWER_MAX_VAL || txpwr < ATH12K_TX_POWER_MIN_VAL) 3562d8899132SKalle Valo return -EINVAL; 3563d8899132SKalle Valo 3564d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 3565d8899132SKalle Valo 3566d8899132SKalle Valo ret = ath12k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id, 3567d8899132SKalle Valo WMI_PEER_USE_FIXED_PWR, txpwr); 3568d8899132SKalle Valo if (ret) { 3569d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set tx power for station ret: %d\n", 3570d8899132SKalle Valo ret); 3571d8899132SKalle Valo goto out; 3572d8899132SKalle Valo } 3573d8899132SKalle Valo 3574d8899132SKalle Valo out: 3575d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 3576d8899132SKalle Valo return ret; 3577d8899132SKalle Valo } 3578d8899132SKalle Valo 3579d8899132SKalle Valo static void ath12k_mac_op_sta_rc_update(struct ieee80211_hw *hw, 3580d8899132SKalle Valo struct ieee80211_vif *vif, 3581d8899132SKalle Valo struct ieee80211_sta *sta, 3582d8899132SKalle Valo u32 changed) 3583d8899132SKalle Valo { 3584d8899132SKalle Valo struct ath12k *ar = hw->priv; 3585d8899132SKalle Valo struct ath12k_sta *arsta = (struct ath12k_sta *)sta->drv_priv; 3586d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 3587d8899132SKalle Valo struct ath12k_peer *peer; 3588d8899132SKalle Valo u32 bw, smps; 3589d8899132SKalle Valo 3590d8899132SKalle Valo spin_lock_bh(&ar->ab->base_lock); 3591d8899132SKalle Valo 3592d8899132SKalle Valo peer = ath12k_peer_find(ar->ab, arvif->vdev_id, sta->addr); 3593d8899132SKalle Valo if (!peer) { 3594d8899132SKalle Valo spin_unlock_bh(&ar->ab->base_lock); 3595d8899132SKalle Valo ath12k_warn(ar->ab, "mac sta rc update failed to find peer %pM on vdev %i\n", 3596d8899132SKalle Valo sta->addr, arvif->vdev_id); 3597d8899132SKalle Valo return; 3598d8899132SKalle Valo } 3599d8899132SKalle Valo 3600d8899132SKalle Valo spin_unlock_bh(&ar->ab->base_lock); 3601d8899132SKalle Valo 3602d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 3603d8899132SKalle Valo "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n", 3604d8899132SKalle Valo sta->addr, changed, sta->deflink.bandwidth, sta->deflink.rx_nss, 3605d8899132SKalle Valo sta->deflink.smps_mode); 3606d8899132SKalle Valo 3607d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 3608d8899132SKalle Valo 3609d8899132SKalle Valo if (changed & IEEE80211_RC_BW_CHANGED) { 3610d8899132SKalle Valo bw = WMI_PEER_CHWIDTH_20MHZ; 3611d8899132SKalle Valo 3612d8899132SKalle Valo switch (sta->deflink.bandwidth) { 3613d8899132SKalle Valo case IEEE80211_STA_RX_BW_20: 3614d8899132SKalle Valo bw = WMI_PEER_CHWIDTH_20MHZ; 3615d8899132SKalle Valo break; 3616d8899132SKalle Valo case IEEE80211_STA_RX_BW_40: 3617d8899132SKalle Valo bw = WMI_PEER_CHWIDTH_40MHZ; 3618d8899132SKalle Valo break; 3619d8899132SKalle Valo case IEEE80211_STA_RX_BW_80: 3620d8899132SKalle Valo bw = WMI_PEER_CHWIDTH_80MHZ; 3621d8899132SKalle Valo break; 3622d8899132SKalle Valo case IEEE80211_STA_RX_BW_160: 3623d8899132SKalle Valo bw = WMI_PEER_CHWIDTH_160MHZ; 3624d8899132SKalle Valo break; 3625d8899132SKalle Valo default: 3626d8899132SKalle Valo ath12k_warn(ar->ab, "Invalid bandwidth %d in rc update for %pM\n", 3627d8899132SKalle Valo sta->deflink.bandwidth, sta->addr); 3628d8899132SKalle Valo bw = WMI_PEER_CHWIDTH_20MHZ; 3629d8899132SKalle Valo break; 3630d8899132SKalle Valo } 3631d8899132SKalle Valo 3632d8899132SKalle Valo arsta->bw = bw; 3633d8899132SKalle Valo } 3634d8899132SKalle Valo 3635d8899132SKalle Valo if (changed & IEEE80211_RC_NSS_CHANGED) 3636d8899132SKalle Valo arsta->nss = sta->deflink.rx_nss; 3637d8899132SKalle Valo 3638d8899132SKalle Valo if (changed & IEEE80211_RC_SMPS_CHANGED) { 3639d8899132SKalle Valo smps = WMI_PEER_SMPS_PS_NONE; 3640d8899132SKalle Valo 3641d8899132SKalle Valo switch (sta->deflink.smps_mode) { 3642d8899132SKalle Valo case IEEE80211_SMPS_AUTOMATIC: 3643d8899132SKalle Valo case IEEE80211_SMPS_OFF: 3644d8899132SKalle Valo smps = WMI_PEER_SMPS_PS_NONE; 3645d8899132SKalle Valo break; 3646d8899132SKalle Valo case IEEE80211_SMPS_STATIC: 3647d8899132SKalle Valo smps = WMI_PEER_SMPS_STATIC; 3648d8899132SKalle Valo break; 3649d8899132SKalle Valo case IEEE80211_SMPS_DYNAMIC: 3650d8899132SKalle Valo smps = WMI_PEER_SMPS_DYNAMIC; 3651d8899132SKalle Valo break; 3652d8899132SKalle Valo default: 3653d8899132SKalle Valo ath12k_warn(ar->ab, "Invalid smps %d in sta rc update for %pM\n", 3654d8899132SKalle Valo sta->deflink.smps_mode, sta->addr); 3655d8899132SKalle Valo smps = WMI_PEER_SMPS_PS_NONE; 3656d8899132SKalle Valo break; 3657d8899132SKalle Valo } 3658d8899132SKalle Valo 3659d8899132SKalle Valo arsta->smps = smps; 3660d8899132SKalle Valo } 3661d8899132SKalle Valo 3662d8899132SKalle Valo arsta->changed |= changed; 3663d8899132SKalle Valo 3664d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 3665d8899132SKalle Valo 3666d8899132SKalle Valo ieee80211_queue_work(hw, &arsta->update_wk); 3667d8899132SKalle Valo } 3668d8899132SKalle Valo 3669d8899132SKalle Valo static int ath12k_conf_tx_uapsd(struct ath12k *ar, struct ieee80211_vif *vif, 3670d8899132SKalle Valo u16 ac, bool enable) 3671d8899132SKalle Valo { 3672d8899132SKalle Valo struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 3673d8899132SKalle Valo u32 value; 3674d8899132SKalle Valo int ret; 3675d8899132SKalle Valo 3676d8899132SKalle Valo if (arvif->vdev_type != WMI_VDEV_TYPE_STA) 3677d8899132SKalle Valo return 0; 3678d8899132SKalle Valo 3679d8899132SKalle Valo switch (ac) { 3680d8899132SKalle Valo case IEEE80211_AC_VO: 3681d8899132SKalle Valo value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN | 3682d8899132SKalle Valo WMI_STA_PS_UAPSD_AC3_TRIGGER_EN; 3683d8899132SKalle Valo break; 3684d8899132SKalle Valo case IEEE80211_AC_VI: 3685d8899132SKalle Valo value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN | 3686d8899132SKalle Valo WMI_STA_PS_UAPSD_AC2_TRIGGER_EN; 3687d8899132SKalle Valo break; 3688d8899132SKalle Valo case IEEE80211_AC_BE: 3689d8899132SKalle Valo value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN | 3690d8899132SKalle Valo WMI_STA_PS_UAPSD_AC1_TRIGGER_EN; 3691d8899132SKalle Valo break; 3692d8899132SKalle Valo case IEEE80211_AC_BK: 3693d8899132SKalle Valo value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN | 3694d8899132SKalle Valo WMI_STA_PS_UAPSD_AC0_TRIGGER_EN; 3695d8899132SKalle Valo break; 3696d8899132SKalle Valo } 3697d8899132SKalle Valo 3698d8899132SKalle Valo if (enable) 3699d8899132SKalle Valo arvif->u.sta.uapsd |= value; 3700d8899132SKalle Valo else 3701d8899132SKalle Valo arvif->u.sta.uapsd &= ~value; 3702d8899132SKalle Valo 3703d8899132SKalle Valo ret = ath12k_wmi_set_sta_ps_param(ar, arvif->vdev_id, 3704d8899132SKalle Valo WMI_STA_PS_PARAM_UAPSD, 3705d8899132SKalle Valo arvif->u.sta.uapsd); 3706d8899132SKalle Valo if (ret) { 3707d8899132SKalle Valo ath12k_warn(ar->ab, "could not set uapsd params %d\n", ret); 3708d8899132SKalle Valo goto exit; 3709d8899132SKalle Valo } 3710d8899132SKalle Valo 3711d8899132SKalle Valo if (arvif->u.sta.uapsd) 3712d8899132SKalle Valo value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD; 3713d8899132SKalle Valo else 3714d8899132SKalle Valo value = WMI_STA_PS_RX_WAKE_POLICY_WAKE; 3715d8899132SKalle Valo 3716d8899132SKalle Valo ret = ath12k_wmi_set_sta_ps_param(ar, arvif->vdev_id, 3717d8899132SKalle Valo WMI_STA_PS_PARAM_RX_WAKE_POLICY, 3718d8899132SKalle Valo value); 3719d8899132SKalle Valo if (ret) 3720d8899132SKalle Valo ath12k_warn(ar->ab, "could not set rx wake param %d\n", ret); 3721d8899132SKalle Valo 3722d8899132SKalle Valo exit: 3723d8899132SKalle Valo return ret; 3724d8899132SKalle Valo } 3725d8899132SKalle Valo 3726d8899132SKalle Valo static int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw, 3727d8899132SKalle Valo struct ieee80211_vif *vif, 3728d8899132SKalle Valo unsigned int link_id, u16 ac, 3729d8899132SKalle Valo const struct ieee80211_tx_queue_params *params) 3730d8899132SKalle Valo { 3731d8899132SKalle Valo struct ath12k *ar = hw->priv; 3732d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 3733d8899132SKalle Valo struct wmi_wmm_params_arg *p = NULL; 3734d8899132SKalle Valo int ret; 3735d8899132SKalle Valo 3736d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 3737d8899132SKalle Valo 3738d8899132SKalle Valo switch (ac) { 3739d8899132SKalle Valo case IEEE80211_AC_VO: 3740d8899132SKalle Valo p = &arvif->wmm_params.ac_vo; 3741d8899132SKalle Valo break; 3742d8899132SKalle Valo case IEEE80211_AC_VI: 3743d8899132SKalle Valo p = &arvif->wmm_params.ac_vi; 3744d8899132SKalle Valo break; 3745d8899132SKalle Valo case IEEE80211_AC_BE: 3746d8899132SKalle Valo p = &arvif->wmm_params.ac_be; 3747d8899132SKalle Valo break; 3748d8899132SKalle Valo case IEEE80211_AC_BK: 3749d8899132SKalle Valo p = &arvif->wmm_params.ac_bk; 3750d8899132SKalle Valo break; 3751d8899132SKalle Valo } 3752d8899132SKalle Valo 3753d8899132SKalle Valo if (WARN_ON(!p)) { 3754d8899132SKalle Valo ret = -EINVAL; 3755d8899132SKalle Valo goto exit; 3756d8899132SKalle Valo } 3757d8899132SKalle Valo 3758d8899132SKalle Valo p->cwmin = params->cw_min; 3759d8899132SKalle Valo p->cwmax = params->cw_max; 3760d8899132SKalle Valo p->aifs = params->aifs; 3761d8899132SKalle Valo p->txop = params->txop; 3762d8899132SKalle Valo 3763d8899132SKalle Valo ret = ath12k_wmi_send_wmm_update_cmd(ar, arvif->vdev_id, 3764d8899132SKalle Valo &arvif->wmm_params); 3765d8899132SKalle Valo if (ret) { 3766d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set wmm params: %d\n", ret); 3767d8899132SKalle Valo goto exit; 3768d8899132SKalle Valo } 3769d8899132SKalle Valo 3770d8899132SKalle Valo ret = ath12k_conf_tx_uapsd(ar, vif, ac, params->uapsd); 3771d8899132SKalle Valo 3772d8899132SKalle Valo if (ret) 3773d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set sta uapsd: %d\n", ret); 3774d8899132SKalle Valo 3775d8899132SKalle Valo exit: 3776d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 3777d8899132SKalle Valo return ret; 3778d8899132SKalle Valo } 3779d8899132SKalle Valo 3780d8899132SKalle Valo static struct ieee80211_sta_ht_cap 3781d8899132SKalle Valo ath12k_create_ht_cap(struct ath12k *ar, u32 ar_ht_cap, u32 rate_cap_rx_chainmask) 3782d8899132SKalle Valo { 3783d8899132SKalle Valo int i; 3784d8899132SKalle Valo struct ieee80211_sta_ht_cap ht_cap = {0}; 3785d8899132SKalle Valo u32 ar_vht_cap = ar->pdev->cap.vht_cap; 3786d8899132SKalle Valo 3787d8899132SKalle Valo if (!(ar_ht_cap & WMI_HT_CAP_ENABLED)) 3788d8899132SKalle Valo return ht_cap; 3789d8899132SKalle Valo 3790d8899132SKalle Valo ht_cap.ht_supported = 1; 3791d8899132SKalle Valo ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 3792d8899132SKalle Valo ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; 3793d8899132SKalle Valo ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 3794d8899132SKalle Valo ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40; 3795d8899132SKalle Valo ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT; 3796d8899132SKalle Valo 3797d8899132SKalle Valo if (ar_ht_cap & WMI_HT_CAP_HT20_SGI) 3798d8899132SKalle Valo ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; 3799d8899132SKalle Valo 3800d8899132SKalle Valo if (ar_ht_cap & WMI_HT_CAP_HT40_SGI) 3801d8899132SKalle Valo ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; 3802d8899132SKalle Valo 3803d8899132SKalle Valo if (ar_ht_cap & WMI_HT_CAP_DYNAMIC_SMPS) { 3804d8899132SKalle Valo u32 smps; 3805d8899132SKalle Valo 3806d8899132SKalle Valo smps = WLAN_HT_CAP_SM_PS_DYNAMIC; 3807d8899132SKalle Valo smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT; 3808d8899132SKalle Valo 3809d8899132SKalle Valo ht_cap.cap |= smps; 3810d8899132SKalle Valo } 3811d8899132SKalle Valo 3812d8899132SKalle Valo if (ar_ht_cap & WMI_HT_CAP_TX_STBC) 3813d8899132SKalle Valo ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; 3814d8899132SKalle Valo 3815d8899132SKalle Valo if (ar_ht_cap & WMI_HT_CAP_RX_STBC) { 3816d8899132SKalle Valo u32 stbc; 3817d8899132SKalle Valo 3818d8899132SKalle Valo stbc = ar_ht_cap; 3819d8899132SKalle Valo stbc &= WMI_HT_CAP_RX_STBC; 3820d8899132SKalle Valo stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT; 3821d8899132SKalle Valo stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT; 3822d8899132SKalle Valo stbc &= IEEE80211_HT_CAP_RX_STBC; 3823d8899132SKalle Valo 3824d8899132SKalle Valo ht_cap.cap |= stbc; 3825d8899132SKalle Valo } 3826d8899132SKalle Valo 3827d8899132SKalle Valo if (ar_ht_cap & WMI_HT_CAP_RX_LDPC) 3828d8899132SKalle Valo ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; 3829d8899132SKalle Valo 3830d8899132SKalle Valo if (ar_ht_cap & WMI_HT_CAP_L_SIG_TXOP_PROT) 3831d8899132SKalle Valo ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT; 3832d8899132SKalle Valo 3833d8899132SKalle Valo if (ar_vht_cap & WMI_VHT_CAP_MAX_MPDU_LEN_MASK) 3834d8899132SKalle Valo ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU; 3835d8899132SKalle Valo 3836d8899132SKalle Valo for (i = 0; i < ar->num_rx_chains; i++) { 3837d8899132SKalle Valo if (rate_cap_rx_chainmask & BIT(i)) 3838d8899132SKalle Valo ht_cap.mcs.rx_mask[i] = 0xFF; 3839d8899132SKalle Valo } 3840d8899132SKalle Valo 3841d8899132SKalle Valo ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; 3842d8899132SKalle Valo 3843d8899132SKalle Valo return ht_cap; 3844d8899132SKalle Valo } 3845d8899132SKalle Valo 3846d8899132SKalle Valo static int ath12k_mac_set_txbf_conf(struct ath12k_vif *arvif) 3847d8899132SKalle Valo { 3848d8899132SKalle Valo u32 value = 0; 3849d8899132SKalle Valo struct ath12k *ar = arvif->ar; 3850d8899132SKalle Valo int nsts; 3851d8899132SKalle Valo int sound_dim; 3852d8899132SKalle Valo u32 vht_cap = ar->pdev->cap.vht_cap; 3853d8899132SKalle Valo u32 vdev_param = WMI_VDEV_PARAM_TXBF; 3854d8899132SKalle Valo 3855d8899132SKalle Valo if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) { 3856d8899132SKalle Valo nsts = vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; 3857d8899132SKalle Valo nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; 3858d8899132SKalle Valo value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET); 3859d8899132SKalle Valo } 3860d8899132SKalle Valo 3861d8899132SKalle Valo if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { 3862d8899132SKalle Valo sound_dim = vht_cap & 3863d8899132SKalle Valo IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK; 3864d8899132SKalle Valo sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; 3865d8899132SKalle Valo if (sound_dim > (ar->num_tx_chains - 1)) 3866d8899132SKalle Valo sound_dim = ar->num_tx_chains - 1; 3867d8899132SKalle Valo value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET); 3868d8899132SKalle Valo } 3869d8899132SKalle Valo 3870d8899132SKalle Valo if (!value) 3871d8899132SKalle Valo return 0; 3872d8899132SKalle Valo 3873d8899132SKalle Valo if (vht_cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) { 3874d8899132SKalle Valo value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER; 3875d8899132SKalle Valo 3876d8899132SKalle Valo if ((vht_cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) && 3877d8899132SKalle Valo arvif->vdev_type == WMI_VDEV_TYPE_AP) 3878d8899132SKalle Valo value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER; 3879d8899132SKalle Valo } 3880d8899132SKalle Valo 3881d8899132SKalle Valo if (vht_cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) { 3882d8899132SKalle Valo value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE; 3883d8899132SKalle Valo 3884d8899132SKalle Valo if ((vht_cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) && 3885d8899132SKalle Valo arvif->vdev_type == WMI_VDEV_TYPE_STA) 3886d8899132SKalle Valo value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE; 3887d8899132SKalle Valo } 3888d8899132SKalle Valo 3889d8899132SKalle Valo return ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 3890d8899132SKalle Valo vdev_param, value); 3891d8899132SKalle Valo } 3892d8899132SKalle Valo 3893d8899132SKalle Valo static void ath12k_set_vht_txbf_cap(struct ath12k *ar, u32 *vht_cap) 3894d8899132SKalle Valo { 3895d8899132SKalle Valo bool subfer, subfee; 3896d8899132SKalle Valo int sound_dim = 0; 3897d8899132SKalle Valo 3898d8899132SKalle Valo subfer = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)); 3899d8899132SKalle Valo subfee = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)); 3900d8899132SKalle Valo 3901d8899132SKalle Valo if (ar->num_tx_chains < 2) { 3902d8899132SKalle Valo *vht_cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE); 3903d8899132SKalle Valo subfer = false; 3904d8899132SKalle Valo } 3905d8899132SKalle Valo 3906d8899132SKalle Valo /* If SU Beaformer is not set, then disable MU Beamformer Capability */ 3907d8899132SKalle Valo if (!subfer) 3908d8899132SKalle Valo *vht_cap &= ~(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE); 3909d8899132SKalle Valo 3910d8899132SKalle Valo /* If SU Beaformee is not set, then disable MU Beamformee Capability */ 3911d8899132SKalle Valo if (!subfee) 3912d8899132SKalle Valo *vht_cap &= ~(IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); 3913d8899132SKalle Valo 3914d8899132SKalle Valo sound_dim = u32_get_bits(*vht_cap, 3915d8899132SKalle Valo IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK); 3916d8899132SKalle Valo *vht_cap = u32_replace_bits(*vht_cap, 0, 3917d8899132SKalle Valo IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK); 3918d8899132SKalle Valo 3919d8899132SKalle Valo /* TODO: Need to check invalid STS and Sound_dim values set by FW? */ 3920d8899132SKalle Valo 3921d8899132SKalle Valo /* Enable Sounding Dimension Field only if SU BF is enabled */ 3922d8899132SKalle Valo if (subfer) { 3923d8899132SKalle Valo if (sound_dim > (ar->num_tx_chains - 1)) 3924d8899132SKalle Valo sound_dim = ar->num_tx_chains - 1; 3925d8899132SKalle Valo 3926d8899132SKalle Valo *vht_cap = u32_replace_bits(*vht_cap, sound_dim, 3927d8899132SKalle Valo IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK); 3928d8899132SKalle Valo } 3929d8899132SKalle Valo 3930d8899132SKalle Valo /* Use the STS advertised by FW unless SU Beamformee is not supported*/ 3931d8899132SKalle Valo if (!subfee) 3932d8899132SKalle Valo *vht_cap &= ~(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK); 3933d8899132SKalle Valo } 3934d8899132SKalle Valo 3935d8899132SKalle Valo static struct ieee80211_sta_vht_cap 3936d8899132SKalle Valo ath12k_create_vht_cap(struct ath12k *ar, u32 rate_cap_tx_chainmask, 3937d8899132SKalle Valo u32 rate_cap_rx_chainmask) 3938d8899132SKalle Valo { 3939d8899132SKalle Valo struct ieee80211_sta_vht_cap vht_cap = {0}; 3940d8899132SKalle Valo u16 txmcs_map, rxmcs_map; 3941d8899132SKalle Valo int i; 3942d8899132SKalle Valo 3943d8899132SKalle Valo vht_cap.vht_supported = 1; 3944d8899132SKalle Valo vht_cap.cap = ar->pdev->cap.vht_cap; 3945d8899132SKalle Valo 3946d8899132SKalle Valo ath12k_set_vht_txbf_cap(ar, &vht_cap.cap); 3947d8899132SKalle Valo 3948d8899132SKalle Valo /* TODO: Enable back VHT160 mode once association issues are fixed */ 3949d8899132SKalle Valo /* Disabling VHT160 and VHT80+80 modes */ 3950d8899132SKalle Valo vht_cap.cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; 3951d8899132SKalle Valo vht_cap.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160; 3952d8899132SKalle Valo 3953d8899132SKalle Valo rxmcs_map = 0; 3954d8899132SKalle Valo txmcs_map = 0; 3955d8899132SKalle Valo for (i = 0; i < 8; i++) { 3956d8899132SKalle Valo if (i < ar->num_tx_chains && rate_cap_tx_chainmask & BIT(i)) 3957d8899132SKalle Valo txmcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); 3958d8899132SKalle Valo else 3959d8899132SKalle Valo txmcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); 3960d8899132SKalle Valo 3961d8899132SKalle Valo if (i < ar->num_rx_chains && rate_cap_rx_chainmask & BIT(i)) 3962d8899132SKalle Valo rxmcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); 3963d8899132SKalle Valo else 3964d8899132SKalle Valo rxmcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); 3965d8899132SKalle Valo } 3966d8899132SKalle Valo 3967d8899132SKalle Valo if (rate_cap_tx_chainmask <= 1) 3968d8899132SKalle Valo vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC; 3969d8899132SKalle Valo 3970d8899132SKalle Valo vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(rxmcs_map); 3971d8899132SKalle Valo vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(txmcs_map); 3972d8899132SKalle Valo 3973d8899132SKalle Valo return vht_cap; 3974d8899132SKalle Valo } 3975d8899132SKalle Valo 3976d8899132SKalle Valo static void ath12k_mac_setup_ht_vht_cap(struct ath12k *ar, 3977d8899132SKalle Valo struct ath12k_pdev_cap *cap, 3978d8899132SKalle Valo u32 *ht_cap_info) 3979d8899132SKalle Valo { 3980d8899132SKalle Valo struct ieee80211_supported_band *band; 3981d8899132SKalle Valo u32 rate_cap_tx_chainmask; 3982d8899132SKalle Valo u32 rate_cap_rx_chainmask; 3983d8899132SKalle Valo u32 ht_cap; 3984d8899132SKalle Valo 3985d8899132SKalle Valo rate_cap_tx_chainmask = ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift; 3986d8899132SKalle Valo rate_cap_rx_chainmask = ar->cfg_rx_chainmask >> cap->rx_chain_mask_shift; 3987d8899132SKalle Valo 3988d8899132SKalle Valo if (cap->supported_bands & WMI_HOST_WLAN_2G_CAP) { 3989d8899132SKalle Valo band = &ar->mac.sbands[NL80211_BAND_2GHZ]; 3990d8899132SKalle Valo ht_cap = cap->band[NL80211_BAND_2GHZ].ht_cap_info; 3991d8899132SKalle Valo if (ht_cap_info) 3992d8899132SKalle Valo *ht_cap_info = ht_cap; 3993d8899132SKalle Valo band->ht_cap = ath12k_create_ht_cap(ar, ht_cap, 3994d8899132SKalle Valo rate_cap_rx_chainmask); 3995d8899132SKalle Valo } 3996d8899132SKalle Valo 3997d8899132SKalle Valo if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && 3998d8899132SKalle Valo (ar->ab->hw_params->single_pdev_only || 3999d8899132SKalle Valo !ar->supports_6ghz)) { 4000d8899132SKalle Valo band = &ar->mac.sbands[NL80211_BAND_5GHZ]; 4001d8899132SKalle Valo ht_cap = cap->band[NL80211_BAND_5GHZ].ht_cap_info; 4002d8899132SKalle Valo if (ht_cap_info) 4003d8899132SKalle Valo *ht_cap_info = ht_cap; 4004d8899132SKalle Valo band->ht_cap = ath12k_create_ht_cap(ar, ht_cap, 4005d8899132SKalle Valo rate_cap_rx_chainmask); 4006d8899132SKalle Valo band->vht_cap = ath12k_create_vht_cap(ar, rate_cap_tx_chainmask, 4007d8899132SKalle Valo rate_cap_rx_chainmask); 4008d8899132SKalle Valo } 4009d8899132SKalle Valo } 4010d8899132SKalle Valo 4011d8899132SKalle Valo static int ath12k_check_chain_mask(struct ath12k *ar, u32 ant, bool is_tx_ant) 4012d8899132SKalle Valo { 4013d8899132SKalle Valo /* TODO: Check the request chainmask against the supported 4014d8899132SKalle Valo * chainmask table which is advertised in extented_service_ready event 4015d8899132SKalle Valo */ 4016d8899132SKalle Valo 4017d8899132SKalle Valo return 0; 4018d8899132SKalle Valo } 4019d8899132SKalle Valo 4020d8899132SKalle Valo static void ath12k_gen_ppe_thresh(struct ath12k_wmi_ppe_threshold_arg *fw_ppet, 4021d8899132SKalle Valo u8 *he_ppet) 4022d8899132SKalle Valo { 4023d8899132SKalle Valo int nss, ru; 4024d8899132SKalle Valo u8 bit = 7; 4025d8899132SKalle Valo 4026d8899132SKalle Valo he_ppet[0] = fw_ppet->numss_m1 & IEEE80211_PPE_THRES_NSS_MASK; 4027d8899132SKalle Valo he_ppet[0] |= (fw_ppet->ru_bit_mask << 4028d8899132SKalle Valo IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS) & 4029d8899132SKalle Valo IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK; 4030d8899132SKalle Valo for (nss = 0; nss <= fw_ppet->numss_m1; nss++) { 4031d8899132SKalle Valo for (ru = 0; ru < 4; ru++) { 4032d8899132SKalle Valo u8 val; 4033d8899132SKalle Valo int i; 4034d8899132SKalle Valo 4035d8899132SKalle Valo if ((fw_ppet->ru_bit_mask & BIT(ru)) == 0) 4036d8899132SKalle Valo continue; 4037d8899132SKalle Valo val = (fw_ppet->ppet16_ppet8_ru3_ru0[nss] >> (ru * 6)) & 4038d8899132SKalle Valo 0x3f; 4039d8899132SKalle Valo val = ((val >> 3) & 0x7) | ((val & 0x7) << 3); 4040d8899132SKalle Valo for (i = 5; i >= 0; i--) { 4041d8899132SKalle Valo he_ppet[bit / 8] |= 4042d8899132SKalle Valo ((val >> i) & 0x1) << ((bit % 8)); 4043d8899132SKalle Valo bit++; 4044d8899132SKalle Valo } 4045d8899132SKalle Valo } 4046d8899132SKalle Valo } 4047d8899132SKalle Valo } 4048d8899132SKalle Valo 4049d8899132SKalle Valo static void 4050d8899132SKalle Valo ath12k_mac_filter_he_cap_mesh(struct ieee80211_he_cap_elem *he_cap_elem) 4051d8899132SKalle Valo { 4052d8899132SKalle Valo u8 m; 4053d8899132SKalle Valo 4054d8899132SKalle Valo m = IEEE80211_HE_MAC_CAP0_TWT_RES | 4055d8899132SKalle Valo IEEE80211_HE_MAC_CAP0_TWT_REQ; 4056d8899132SKalle Valo he_cap_elem->mac_cap_info[0] &= ~m; 4057d8899132SKalle Valo 4058d8899132SKalle Valo m = IEEE80211_HE_MAC_CAP2_TRS | 4059d8899132SKalle Valo IEEE80211_HE_MAC_CAP2_BCAST_TWT | 4060d8899132SKalle Valo IEEE80211_HE_MAC_CAP2_MU_CASCADING; 4061d8899132SKalle Valo he_cap_elem->mac_cap_info[2] &= ~m; 4062d8899132SKalle Valo 4063d8899132SKalle Valo m = IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED | 4064d8899132SKalle Valo IEEE80211_HE_MAC_CAP2_BCAST_TWT | 4065d8899132SKalle Valo IEEE80211_HE_MAC_CAP2_MU_CASCADING; 4066d8899132SKalle Valo he_cap_elem->mac_cap_info[3] &= ~m; 4067d8899132SKalle Valo 4068d8899132SKalle Valo m = IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG | 4069d8899132SKalle Valo IEEE80211_HE_MAC_CAP4_BQR; 4070d8899132SKalle Valo he_cap_elem->mac_cap_info[4] &= ~m; 4071d8899132SKalle Valo 4072d8899132SKalle Valo m = IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION | 4073d8899132SKalle Valo IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU | 4074d8899132SKalle Valo IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING | 4075d8899132SKalle Valo IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX; 4076d8899132SKalle Valo he_cap_elem->mac_cap_info[5] &= ~m; 4077d8899132SKalle Valo 4078d8899132SKalle Valo m = IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO | 4079d8899132SKalle Valo IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO; 4080d8899132SKalle Valo he_cap_elem->phy_cap_info[2] &= ~m; 4081d8899132SKalle Valo 4082d8899132SKalle Valo m = IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU | 4083d8899132SKalle Valo IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK | 4084d8899132SKalle Valo IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK; 4085d8899132SKalle Valo he_cap_elem->phy_cap_info[3] &= ~m; 4086d8899132SKalle Valo 4087d8899132SKalle Valo m = IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER; 4088d8899132SKalle Valo he_cap_elem->phy_cap_info[4] &= ~m; 4089d8899132SKalle Valo 4090d8899132SKalle Valo m = IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK; 4091d8899132SKalle Valo he_cap_elem->phy_cap_info[5] &= ~m; 4092d8899132SKalle Valo 4093d8899132SKalle Valo m = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | 4094d8899132SKalle Valo IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB | 4095d8899132SKalle Valo IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB | 4096d8899132SKalle Valo IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO; 4097d8899132SKalle Valo he_cap_elem->phy_cap_info[6] &= ~m; 4098d8899132SKalle Valo 4099d8899132SKalle Valo m = IEEE80211_HE_PHY_CAP7_PSR_BASED_SR | 4100d8899132SKalle Valo IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP | 4101d8899132SKalle Valo IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ | 4102d8899132SKalle Valo IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ; 4103d8899132SKalle Valo he_cap_elem->phy_cap_info[7] &= ~m; 4104d8899132SKalle Valo 4105d8899132SKalle Valo m = IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI | 4106d8899132SKalle Valo IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G | 4107d8899132SKalle Valo IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU | 4108d8899132SKalle Valo IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU; 4109d8899132SKalle Valo he_cap_elem->phy_cap_info[8] &= ~m; 4110d8899132SKalle Valo 4111d8899132SKalle Valo m = IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM | 4112d8899132SKalle Valo IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK | 4113d8899132SKalle Valo IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU | 4114d8899132SKalle Valo IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU | 4115d8899132SKalle Valo IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | 4116d8899132SKalle Valo IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB; 4117d8899132SKalle Valo he_cap_elem->phy_cap_info[9] &= ~m; 4118d8899132SKalle Valo } 4119d8899132SKalle Valo 4120d8899132SKalle Valo static __le16 ath12k_mac_setup_he_6ghz_cap(struct ath12k_pdev_cap *pcap, 4121d8899132SKalle Valo struct ath12k_band_cap *bcap) 4122d8899132SKalle Valo { 4123d8899132SKalle Valo u8 val; 4124d8899132SKalle Valo 4125d8899132SKalle Valo bcap->he_6ghz_capa = IEEE80211_HT_MPDU_DENSITY_NONE; 4126d8899132SKalle Valo if (bcap->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) 4127d8899132SKalle Valo bcap->he_6ghz_capa |= 4128d8899132SKalle Valo u32_encode_bits(WLAN_HT_CAP_SM_PS_DYNAMIC, 4129d8899132SKalle Valo IEEE80211_HE_6GHZ_CAP_SM_PS); 4130d8899132SKalle Valo else 4131d8899132SKalle Valo bcap->he_6ghz_capa |= 4132d8899132SKalle Valo u32_encode_bits(WLAN_HT_CAP_SM_PS_DISABLED, 4133d8899132SKalle Valo IEEE80211_HE_6GHZ_CAP_SM_PS); 4134d8899132SKalle Valo val = u32_get_bits(pcap->vht_cap, 4135d8899132SKalle Valo IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK); 4136d8899132SKalle Valo bcap->he_6ghz_capa |= 4137d8899132SKalle Valo u32_encode_bits(val, IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP); 4138d8899132SKalle Valo val = u32_get_bits(pcap->vht_cap, 4139d8899132SKalle Valo IEEE80211_VHT_CAP_MAX_MPDU_MASK); 4140d8899132SKalle Valo bcap->he_6ghz_capa |= 4141d8899132SKalle Valo u32_encode_bits(val, IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN); 4142d8899132SKalle Valo if (pcap->vht_cap & IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN) 4143d8899132SKalle Valo bcap->he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS; 4144d8899132SKalle Valo if (pcap->vht_cap & IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN) 4145d8899132SKalle Valo bcap->he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS; 4146d8899132SKalle Valo 4147d8899132SKalle Valo return cpu_to_le16(bcap->he_6ghz_capa); 4148d8899132SKalle Valo } 4149d8899132SKalle Valo 4150d8899132SKalle Valo static int ath12k_mac_copy_he_cap(struct ath12k *ar, 4151d8899132SKalle Valo struct ath12k_pdev_cap *cap, 4152d8899132SKalle Valo struct ieee80211_sband_iftype_data *data, 4153d8899132SKalle Valo int band) 4154d8899132SKalle Valo { 4155d8899132SKalle Valo int i, idx = 0; 4156d8899132SKalle Valo 4157d8899132SKalle Valo for (i = 0; i < NUM_NL80211_IFTYPES; i++) { 4158d8899132SKalle Valo struct ieee80211_sta_he_cap *he_cap = &data[idx].he_cap; 4159d8899132SKalle Valo struct ath12k_band_cap *band_cap = &cap->band[band]; 4160d8899132SKalle Valo struct ieee80211_he_cap_elem *he_cap_elem = 4161d8899132SKalle Valo &he_cap->he_cap_elem; 4162d8899132SKalle Valo 4163d8899132SKalle Valo switch (i) { 4164d8899132SKalle Valo case NL80211_IFTYPE_STATION: 4165d8899132SKalle Valo case NL80211_IFTYPE_AP: 4166d8899132SKalle Valo case NL80211_IFTYPE_MESH_POINT: 4167d8899132SKalle Valo break; 4168d8899132SKalle Valo 4169d8899132SKalle Valo default: 4170d8899132SKalle Valo continue; 4171d8899132SKalle Valo } 4172d8899132SKalle Valo 4173d8899132SKalle Valo data[idx].types_mask = BIT(i); 4174d8899132SKalle Valo he_cap->has_he = true; 4175d8899132SKalle Valo memcpy(he_cap_elem->mac_cap_info, band_cap->he_cap_info, 4176d8899132SKalle Valo sizeof(he_cap_elem->mac_cap_info)); 4177d8899132SKalle Valo memcpy(he_cap_elem->phy_cap_info, band_cap->he_cap_phy_info, 4178d8899132SKalle Valo sizeof(he_cap_elem->phy_cap_info)); 4179d8899132SKalle Valo 4180d8899132SKalle Valo he_cap_elem->mac_cap_info[1] &= 4181d8899132SKalle Valo IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK; 4182d8899132SKalle Valo 4183d8899132SKalle Valo he_cap_elem->phy_cap_info[5] &= 4184d8899132SKalle Valo ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK; 4185d8899132SKalle Valo he_cap_elem->phy_cap_info[5] &= 4186d8899132SKalle Valo ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK; 4187d8899132SKalle Valo he_cap_elem->phy_cap_info[5] |= ar->num_tx_chains - 1; 4188d8899132SKalle Valo 4189d8899132SKalle Valo switch (i) { 4190d8899132SKalle Valo case NL80211_IFTYPE_AP: 4191d8899132SKalle Valo he_cap_elem->phy_cap_info[3] &= 4192d8899132SKalle Valo ~IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK; 4193d8899132SKalle Valo he_cap_elem->phy_cap_info[9] |= 4194d8899132SKalle Valo IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU; 4195d8899132SKalle Valo break; 4196d8899132SKalle Valo case NL80211_IFTYPE_STATION: 4197d8899132SKalle Valo he_cap_elem->mac_cap_info[0] &= 4198d8899132SKalle Valo ~IEEE80211_HE_MAC_CAP0_TWT_RES; 4199d8899132SKalle Valo he_cap_elem->mac_cap_info[0] |= 4200d8899132SKalle Valo IEEE80211_HE_MAC_CAP0_TWT_REQ; 4201d8899132SKalle Valo he_cap_elem->phy_cap_info[9] |= 4202d8899132SKalle Valo IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU; 4203d8899132SKalle Valo break; 4204d8899132SKalle Valo case NL80211_IFTYPE_MESH_POINT: 4205d8899132SKalle Valo ath12k_mac_filter_he_cap_mesh(he_cap_elem); 4206d8899132SKalle Valo break; 4207d8899132SKalle Valo } 4208d8899132SKalle Valo 4209d8899132SKalle Valo he_cap->he_mcs_nss_supp.rx_mcs_80 = 4210d8899132SKalle Valo cpu_to_le16(band_cap->he_mcs & 0xffff); 4211d8899132SKalle Valo he_cap->he_mcs_nss_supp.tx_mcs_80 = 4212d8899132SKalle Valo cpu_to_le16(band_cap->he_mcs & 0xffff); 4213d8899132SKalle Valo he_cap->he_mcs_nss_supp.rx_mcs_160 = 4214d8899132SKalle Valo cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); 4215d8899132SKalle Valo he_cap->he_mcs_nss_supp.tx_mcs_160 = 4216d8899132SKalle Valo cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); 4217d8899132SKalle Valo he_cap->he_mcs_nss_supp.rx_mcs_80p80 = 4218d8899132SKalle Valo cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); 4219d8899132SKalle Valo he_cap->he_mcs_nss_supp.tx_mcs_80p80 = 4220d8899132SKalle Valo cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); 4221d8899132SKalle Valo 4222d8899132SKalle Valo memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres)); 4223d8899132SKalle Valo if (he_cap_elem->phy_cap_info[6] & 4224d8899132SKalle Valo IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) 4225d8899132SKalle Valo ath12k_gen_ppe_thresh(&band_cap->he_ppet, 4226d8899132SKalle Valo he_cap->ppe_thres); 4227d8899132SKalle Valo 4228d8899132SKalle Valo if (band == NL80211_BAND_6GHZ) { 4229d8899132SKalle Valo data[idx].he_6ghz_capa.capa = 4230d8899132SKalle Valo ath12k_mac_setup_he_6ghz_cap(cap, band_cap); 4231d8899132SKalle Valo } 4232d8899132SKalle Valo idx++; 4233d8899132SKalle Valo } 4234d8899132SKalle Valo 4235d8899132SKalle Valo return idx; 4236d8899132SKalle Valo } 4237d8899132SKalle Valo 4238d8899132SKalle Valo static void ath12k_mac_setup_he_cap(struct ath12k *ar, 4239d8899132SKalle Valo struct ath12k_pdev_cap *cap) 4240d8899132SKalle Valo { 4241d8899132SKalle Valo struct ieee80211_supported_band *band; 4242d8899132SKalle Valo int count; 4243d8899132SKalle Valo 4244d8899132SKalle Valo if (cap->supported_bands & WMI_HOST_WLAN_2G_CAP) { 4245d8899132SKalle Valo count = ath12k_mac_copy_he_cap(ar, cap, 4246d8899132SKalle Valo ar->mac.iftype[NL80211_BAND_2GHZ], 4247d8899132SKalle Valo NL80211_BAND_2GHZ); 4248d8899132SKalle Valo band = &ar->mac.sbands[NL80211_BAND_2GHZ]; 4249d8899132SKalle Valo band->iftype_data = ar->mac.iftype[NL80211_BAND_2GHZ]; 4250d8899132SKalle Valo band->n_iftype_data = count; 4251d8899132SKalle Valo } 4252d8899132SKalle Valo 4253d8899132SKalle Valo if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) { 4254d8899132SKalle Valo count = ath12k_mac_copy_he_cap(ar, cap, 4255d8899132SKalle Valo ar->mac.iftype[NL80211_BAND_5GHZ], 4256d8899132SKalle Valo NL80211_BAND_5GHZ); 4257d8899132SKalle Valo band = &ar->mac.sbands[NL80211_BAND_5GHZ]; 4258d8899132SKalle Valo band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ]; 4259d8899132SKalle Valo band->n_iftype_data = count; 4260d8899132SKalle Valo } 4261d8899132SKalle Valo 4262d8899132SKalle Valo if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && 4263d8899132SKalle Valo ar->supports_6ghz) { 4264d8899132SKalle Valo count = ath12k_mac_copy_he_cap(ar, cap, 4265d8899132SKalle Valo ar->mac.iftype[NL80211_BAND_6GHZ], 4266d8899132SKalle Valo NL80211_BAND_6GHZ); 4267d8899132SKalle Valo band = &ar->mac.sbands[NL80211_BAND_6GHZ]; 4268d8899132SKalle Valo band->iftype_data = ar->mac.iftype[NL80211_BAND_6GHZ]; 4269d8899132SKalle Valo band->n_iftype_data = count; 4270d8899132SKalle Valo } 4271d8899132SKalle Valo } 4272d8899132SKalle Valo 4273d8899132SKalle Valo static int __ath12k_set_antenna(struct ath12k *ar, u32 tx_ant, u32 rx_ant) 4274d8899132SKalle Valo { 4275d8899132SKalle Valo int ret; 4276d8899132SKalle Valo 4277d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 4278d8899132SKalle Valo 4279d8899132SKalle Valo if (ath12k_check_chain_mask(ar, tx_ant, true)) 4280d8899132SKalle Valo return -EINVAL; 4281d8899132SKalle Valo 4282d8899132SKalle Valo if (ath12k_check_chain_mask(ar, rx_ant, false)) 4283d8899132SKalle Valo return -EINVAL; 4284d8899132SKalle Valo 4285d8899132SKalle Valo ar->cfg_tx_chainmask = tx_ant; 4286d8899132SKalle Valo ar->cfg_rx_chainmask = rx_ant; 4287d8899132SKalle Valo 4288d8899132SKalle Valo if (ar->state != ATH12K_STATE_ON && 4289d8899132SKalle Valo ar->state != ATH12K_STATE_RESTARTED) 4290d8899132SKalle Valo return 0; 4291d8899132SKalle Valo 4292d8899132SKalle Valo ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_TX_CHAIN_MASK, 4293d8899132SKalle Valo tx_ant, ar->pdev->pdev_id); 4294d8899132SKalle Valo if (ret) { 4295d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set tx-chainmask: %d, req 0x%x\n", 4296d8899132SKalle Valo ret, tx_ant); 4297d8899132SKalle Valo return ret; 4298d8899132SKalle Valo } 4299d8899132SKalle Valo 4300d8899132SKalle Valo ar->num_tx_chains = hweight32(tx_ant); 4301d8899132SKalle Valo 4302d8899132SKalle Valo ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_RX_CHAIN_MASK, 4303d8899132SKalle Valo rx_ant, ar->pdev->pdev_id); 4304d8899132SKalle Valo if (ret) { 4305d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set rx-chainmask: %d, req 0x%x\n", 4306d8899132SKalle Valo ret, rx_ant); 4307d8899132SKalle Valo return ret; 4308d8899132SKalle Valo } 4309d8899132SKalle Valo 4310d8899132SKalle Valo ar->num_rx_chains = hweight32(rx_ant); 4311d8899132SKalle Valo 4312d8899132SKalle Valo /* Reload HT/VHT/HE capability */ 4313d8899132SKalle Valo ath12k_mac_setup_ht_vht_cap(ar, &ar->pdev->cap, NULL); 4314d8899132SKalle Valo ath12k_mac_setup_he_cap(ar, &ar->pdev->cap); 4315d8899132SKalle Valo 4316d8899132SKalle Valo return 0; 4317d8899132SKalle Valo } 4318d8899132SKalle Valo 4319d8899132SKalle Valo int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx) 4320d8899132SKalle Valo { 4321d8899132SKalle Valo struct sk_buff *msdu = skb; 4322d8899132SKalle Valo struct ieee80211_tx_info *info; 4323d8899132SKalle Valo struct ath12k *ar = ctx; 4324d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 4325d8899132SKalle Valo 4326d8899132SKalle Valo spin_lock_bh(&ar->txmgmt_idr_lock); 4327d8899132SKalle Valo idr_remove(&ar->txmgmt_idr, buf_id); 4328d8899132SKalle Valo spin_unlock_bh(&ar->txmgmt_idr_lock); 4329d8899132SKalle Valo dma_unmap_single(ab->dev, ATH12K_SKB_CB(msdu)->paddr, msdu->len, 4330d8899132SKalle Valo DMA_TO_DEVICE); 4331d8899132SKalle Valo 4332d8899132SKalle Valo info = IEEE80211_SKB_CB(msdu); 4333d8899132SKalle Valo memset(&info->status, 0, sizeof(info->status)); 4334d8899132SKalle Valo 4335d8899132SKalle Valo ieee80211_free_txskb(ar->hw, msdu); 4336d8899132SKalle Valo 4337d8899132SKalle Valo return 0; 4338d8899132SKalle Valo } 4339d8899132SKalle Valo 4340d8899132SKalle Valo static int ath12k_mac_vif_txmgmt_idr_remove(int buf_id, void *skb, void *ctx) 4341d8899132SKalle Valo { 4342d8899132SKalle Valo struct ieee80211_vif *vif = ctx; 4343d8899132SKalle Valo struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); 4344d8899132SKalle Valo struct sk_buff *msdu = skb; 4345d8899132SKalle Valo struct ath12k *ar = skb_cb->ar; 4346d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 4347d8899132SKalle Valo 4348d8899132SKalle Valo if (skb_cb->vif == vif) { 4349d8899132SKalle Valo spin_lock_bh(&ar->txmgmt_idr_lock); 4350d8899132SKalle Valo idr_remove(&ar->txmgmt_idr, buf_id); 4351d8899132SKalle Valo spin_unlock_bh(&ar->txmgmt_idr_lock); 4352d8899132SKalle Valo dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, 4353d8899132SKalle Valo DMA_TO_DEVICE); 4354d8899132SKalle Valo } 4355d8899132SKalle Valo 4356d8899132SKalle Valo return 0; 4357d8899132SKalle Valo } 4358d8899132SKalle Valo 4359d8899132SKalle Valo static int ath12k_mac_mgmt_tx_wmi(struct ath12k *ar, struct ath12k_vif *arvif, 4360d8899132SKalle Valo struct sk_buff *skb) 4361d8899132SKalle Valo { 4362d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 4363d8899132SKalle Valo struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 4364d8899132SKalle Valo struct ieee80211_tx_info *info; 4365d8899132SKalle Valo dma_addr_t paddr; 4366d8899132SKalle Valo int buf_id; 4367d8899132SKalle Valo int ret; 4368d8899132SKalle Valo 4369d8899132SKalle Valo spin_lock_bh(&ar->txmgmt_idr_lock); 4370d8899132SKalle Valo buf_id = idr_alloc(&ar->txmgmt_idr, skb, 0, 4371d8899132SKalle Valo ATH12K_TX_MGMT_NUM_PENDING_MAX, GFP_ATOMIC); 4372d8899132SKalle Valo spin_unlock_bh(&ar->txmgmt_idr_lock); 4373d8899132SKalle Valo if (buf_id < 0) 4374d8899132SKalle Valo return -ENOSPC; 4375d8899132SKalle Valo 4376d8899132SKalle Valo info = IEEE80211_SKB_CB(skb); 4377d8899132SKalle Valo if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) { 4378d8899132SKalle Valo if ((ieee80211_is_action(hdr->frame_control) || 4379d8899132SKalle Valo ieee80211_is_deauth(hdr->frame_control) || 4380d8899132SKalle Valo ieee80211_is_disassoc(hdr->frame_control)) && 4381d8899132SKalle Valo ieee80211_has_protected(hdr->frame_control)) { 4382d8899132SKalle Valo skb_put(skb, IEEE80211_CCMP_MIC_LEN); 4383d8899132SKalle Valo } 4384d8899132SKalle Valo } 4385d8899132SKalle Valo 4386d8899132SKalle Valo paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); 4387d8899132SKalle Valo if (dma_mapping_error(ab->dev, paddr)) { 4388d8899132SKalle Valo ath12k_warn(ab, "failed to DMA map mgmt Tx buffer\n"); 4389d8899132SKalle Valo ret = -EIO; 4390d8899132SKalle Valo goto err_free_idr; 4391d8899132SKalle Valo } 4392d8899132SKalle Valo 4393d8899132SKalle Valo ATH12K_SKB_CB(skb)->paddr = paddr; 4394d8899132SKalle Valo 4395d8899132SKalle Valo ret = ath12k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb); 4396d8899132SKalle Valo if (ret) { 4397d8899132SKalle Valo ath12k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret); 4398d8899132SKalle Valo goto err_unmap_buf; 4399d8899132SKalle Valo } 4400d8899132SKalle Valo 4401d8899132SKalle Valo return 0; 4402d8899132SKalle Valo 4403d8899132SKalle Valo err_unmap_buf: 4404d8899132SKalle Valo dma_unmap_single(ab->dev, ATH12K_SKB_CB(skb)->paddr, 4405d8899132SKalle Valo skb->len, DMA_TO_DEVICE); 4406d8899132SKalle Valo err_free_idr: 4407d8899132SKalle Valo spin_lock_bh(&ar->txmgmt_idr_lock); 4408d8899132SKalle Valo idr_remove(&ar->txmgmt_idr, buf_id); 4409d8899132SKalle Valo spin_unlock_bh(&ar->txmgmt_idr_lock); 4410d8899132SKalle Valo 4411d8899132SKalle Valo return ret; 4412d8899132SKalle Valo } 4413d8899132SKalle Valo 4414d8899132SKalle Valo static void ath12k_mgmt_over_wmi_tx_purge(struct ath12k *ar) 4415d8899132SKalle Valo { 4416d8899132SKalle Valo struct sk_buff *skb; 4417d8899132SKalle Valo 4418d8899132SKalle Valo while ((skb = skb_dequeue(&ar->wmi_mgmt_tx_queue)) != NULL) 4419d8899132SKalle Valo ieee80211_free_txskb(ar->hw, skb); 4420d8899132SKalle Valo } 4421d8899132SKalle Valo 4422d8899132SKalle Valo static void ath12k_mgmt_over_wmi_tx_work(struct work_struct *work) 4423d8899132SKalle Valo { 4424d8899132SKalle Valo struct ath12k *ar = container_of(work, struct ath12k, wmi_mgmt_tx_work); 4425d8899132SKalle Valo struct ath12k_skb_cb *skb_cb; 4426d8899132SKalle Valo struct ath12k_vif *arvif; 4427d8899132SKalle Valo struct sk_buff *skb; 4428d8899132SKalle Valo int ret; 4429d8899132SKalle Valo 4430d8899132SKalle Valo while ((skb = skb_dequeue(&ar->wmi_mgmt_tx_queue)) != NULL) { 4431d8899132SKalle Valo skb_cb = ATH12K_SKB_CB(skb); 4432d8899132SKalle Valo if (!skb_cb->vif) { 4433d8899132SKalle Valo ath12k_warn(ar->ab, "no vif found for mgmt frame\n"); 4434d8899132SKalle Valo ieee80211_free_txskb(ar->hw, skb); 4435d8899132SKalle Valo continue; 4436d8899132SKalle Valo } 4437d8899132SKalle Valo 4438d8899132SKalle Valo arvif = ath12k_vif_to_arvif(skb_cb->vif); 4439d8899132SKalle Valo if (ar->allocated_vdev_map & (1LL << arvif->vdev_id) && 4440d8899132SKalle Valo arvif->is_started) { 4441d8899132SKalle Valo ret = ath12k_mac_mgmt_tx_wmi(ar, arvif, skb); 4442d8899132SKalle Valo if (ret) { 4443d8899132SKalle Valo ath12k_warn(ar->ab, "failed to tx mgmt frame, vdev_id %d :%d\n", 4444d8899132SKalle Valo arvif->vdev_id, ret); 4445d8899132SKalle Valo ieee80211_free_txskb(ar->hw, skb); 4446d8899132SKalle Valo } else { 4447d8899132SKalle Valo atomic_inc(&ar->num_pending_mgmt_tx); 4448d8899132SKalle Valo } 4449d8899132SKalle Valo } else { 4450d8899132SKalle Valo ath12k_warn(ar->ab, 4451d8899132SKalle Valo "dropping mgmt frame for vdev %d, is_started %d\n", 4452d8899132SKalle Valo arvif->vdev_id, 4453d8899132SKalle Valo arvif->is_started); 4454d8899132SKalle Valo ieee80211_free_txskb(ar->hw, skb); 4455d8899132SKalle Valo } 4456d8899132SKalle Valo } 4457d8899132SKalle Valo } 4458d8899132SKalle Valo 4459d8899132SKalle Valo static int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb, 4460d8899132SKalle Valo bool is_prb_rsp) 4461d8899132SKalle Valo { 4462d8899132SKalle Valo struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; 4463d8899132SKalle Valo 4464d8899132SKalle Valo if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) 4465d8899132SKalle Valo return -ESHUTDOWN; 4466d8899132SKalle Valo 4467d8899132SKalle Valo /* Drop probe response packets when the pending management tx 4468d8899132SKalle Valo * count has reached a certain threshold, so as to prioritize 4469d8899132SKalle Valo * other mgmt packets like auth and assoc to be sent on time 4470d8899132SKalle Valo * for establishing successful connections. 4471d8899132SKalle Valo */ 4472d8899132SKalle Valo if (is_prb_rsp && 4473d8899132SKalle Valo atomic_read(&ar->num_pending_mgmt_tx) > ATH12K_PRB_RSP_DROP_THRESHOLD) { 4474d8899132SKalle Valo ath12k_warn(ar->ab, 4475d8899132SKalle Valo "dropping probe response as pending queue is almost full\n"); 4476d8899132SKalle Valo return -ENOSPC; 4477d8899132SKalle Valo } 4478d8899132SKalle Valo 4479d8899132SKalle Valo if (skb_queue_len(q) == ATH12K_TX_MGMT_NUM_PENDING_MAX) { 4480d8899132SKalle Valo ath12k_warn(ar->ab, "mgmt tx queue is full\n"); 4481d8899132SKalle Valo return -ENOSPC; 4482d8899132SKalle Valo } 4483d8899132SKalle Valo 4484d8899132SKalle Valo skb_queue_tail(q, skb); 4485d8899132SKalle Valo ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work); 4486d8899132SKalle Valo 4487d8899132SKalle Valo return 0; 4488d8899132SKalle Valo } 4489d8899132SKalle Valo 4490d8899132SKalle Valo static void ath12k_mac_op_tx(struct ieee80211_hw *hw, 4491d8899132SKalle Valo struct ieee80211_tx_control *control, 4492d8899132SKalle Valo struct sk_buff *skb) 4493d8899132SKalle Valo { 4494d8899132SKalle Valo struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); 4495d8899132SKalle Valo struct ath12k *ar = hw->priv; 4496d8899132SKalle Valo struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 4497d8899132SKalle Valo struct ieee80211_vif *vif = info->control.vif; 4498d8899132SKalle Valo struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 4499d8899132SKalle Valo struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 4500d8899132SKalle Valo struct ieee80211_key_conf *key = info->control.hw_key; 4501d8899132SKalle Valo u32 info_flags = info->flags; 4502d8899132SKalle Valo bool is_prb_rsp; 4503d8899132SKalle Valo int ret; 4504d8899132SKalle Valo 4505d8899132SKalle Valo memset(skb_cb, 0, sizeof(*skb_cb)); 4506d8899132SKalle Valo skb_cb->vif = vif; 4507d8899132SKalle Valo 4508d8899132SKalle Valo if (key) { 4509d8899132SKalle Valo skb_cb->cipher = key->cipher; 4510d8899132SKalle Valo skb_cb->flags |= ATH12K_SKB_CIPHER_SET; 4511d8899132SKalle Valo } 4512d8899132SKalle Valo 4513d8899132SKalle Valo if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { 4514d8899132SKalle Valo skb_cb->flags |= ATH12K_SKB_HW_80211_ENCAP; 4515d8899132SKalle Valo } else if (ieee80211_is_mgmt(hdr->frame_control)) { 4516d8899132SKalle Valo is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); 4517d8899132SKalle Valo ret = ath12k_mac_mgmt_tx(ar, skb, is_prb_rsp); 4518d8899132SKalle Valo if (ret) { 4519d8899132SKalle Valo ath12k_warn(ar->ab, "failed to queue management frame %d\n", 4520d8899132SKalle Valo ret); 4521d8899132SKalle Valo ieee80211_free_txskb(ar->hw, skb); 4522d8899132SKalle Valo } 4523d8899132SKalle Valo return; 4524d8899132SKalle Valo } 4525d8899132SKalle Valo 4526d8899132SKalle Valo ret = ath12k_dp_tx(ar, arvif, skb); 4527d8899132SKalle Valo if (ret) { 4528d8899132SKalle Valo ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret); 4529d8899132SKalle Valo ieee80211_free_txskb(ar->hw, skb); 4530d8899132SKalle Valo } 4531d8899132SKalle Valo } 4532d8899132SKalle Valo 4533d8899132SKalle Valo void ath12k_mac_drain_tx(struct ath12k *ar) 4534d8899132SKalle Valo { 4535d8899132SKalle Valo /* make sure rcu-protected mac80211 tx path itself is drained */ 4536d8899132SKalle Valo synchronize_net(); 4537d8899132SKalle Valo 4538d8899132SKalle Valo cancel_work_sync(&ar->wmi_mgmt_tx_work); 4539d8899132SKalle Valo ath12k_mgmt_over_wmi_tx_purge(ar); 4540d8899132SKalle Valo } 4541d8899132SKalle Valo 4542d8899132SKalle Valo static int ath12k_mac_config_mon_status_default(struct ath12k *ar, bool enable) 4543d8899132SKalle Valo { 4544d8899132SKalle Valo return -ENOTSUPP; 4545d8899132SKalle Valo /* TODO: Need to support new monitor mode */ 4546d8899132SKalle Valo } 4547d8899132SKalle Valo 4548d8899132SKalle Valo static void ath12k_mac_wait_reconfigure(struct ath12k_base *ab) 4549d8899132SKalle Valo { 4550d8899132SKalle Valo int recovery_start_count; 4551d8899132SKalle Valo 4552d8899132SKalle Valo if (!ab->is_reset) 4553d8899132SKalle Valo return; 4554d8899132SKalle Valo 4555d8899132SKalle Valo recovery_start_count = atomic_inc_return(&ab->recovery_start_count); 4556d8899132SKalle Valo 4557d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, "recovery start count %d\n", recovery_start_count); 4558d8899132SKalle Valo 4559d8899132SKalle Valo if (recovery_start_count == ab->num_radios) { 4560d8899132SKalle Valo complete(&ab->recovery_start); 4561d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, "recovery started success\n"); 4562d8899132SKalle Valo } 4563d8899132SKalle Valo 4564d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, "waiting reconfigure...\n"); 4565d8899132SKalle Valo 4566d8899132SKalle Valo wait_for_completion_timeout(&ab->reconfigure_complete, 4567d8899132SKalle Valo ATH12K_RECONFIGURE_TIMEOUT_HZ); 4568d8899132SKalle Valo } 4569d8899132SKalle Valo 4570d8899132SKalle Valo static int ath12k_mac_op_start(struct ieee80211_hw *hw) 4571d8899132SKalle Valo { 4572d8899132SKalle Valo struct ath12k *ar = hw->priv; 4573d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 4574d8899132SKalle Valo struct ath12k_pdev *pdev = ar->pdev; 4575d8899132SKalle Valo int ret; 4576d8899132SKalle Valo 4577d8899132SKalle Valo ath12k_mac_drain_tx(ar); 4578d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 4579d8899132SKalle Valo 4580d8899132SKalle Valo switch (ar->state) { 4581d8899132SKalle Valo case ATH12K_STATE_OFF: 4582d8899132SKalle Valo ar->state = ATH12K_STATE_ON; 4583d8899132SKalle Valo break; 4584d8899132SKalle Valo case ATH12K_STATE_RESTARTING: 4585d8899132SKalle Valo ar->state = ATH12K_STATE_RESTARTED; 4586d8899132SKalle Valo ath12k_mac_wait_reconfigure(ab); 4587d8899132SKalle Valo break; 4588d8899132SKalle Valo case ATH12K_STATE_RESTARTED: 4589d8899132SKalle Valo case ATH12K_STATE_WEDGED: 4590d8899132SKalle Valo case ATH12K_STATE_ON: 4591d8899132SKalle Valo WARN_ON(1); 4592d8899132SKalle Valo ret = -EINVAL; 4593d8899132SKalle Valo goto err; 4594d8899132SKalle Valo } 4595d8899132SKalle Valo 4596d8899132SKalle Valo ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS, 4597d8899132SKalle Valo 1, pdev->pdev_id); 4598d8899132SKalle Valo 4599d8899132SKalle Valo if (ret) { 4600d8899132SKalle Valo ath12k_err(ar->ab, "failed to enable PMF QOS: (%d\n", ret); 4601d8899132SKalle Valo goto err; 4602d8899132SKalle Valo } 4603d8899132SKalle Valo 4604d8899132SKalle Valo ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_DYNAMIC_BW, 1, 4605d8899132SKalle Valo pdev->pdev_id); 4606d8899132SKalle Valo if (ret) { 4607d8899132SKalle Valo ath12k_err(ar->ab, "failed to enable dynamic bw: %d\n", ret); 4608d8899132SKalle Valo goto err; 4609d8899132SKalle Valo } 4610d8899132SKalle Valo 4611d8899132SKalle Valo ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 4612d8899132SKalle Valo 0, pdev->pdev_id); 4613d8899132SKalle Valo if (ret) { 4614d8899132SKalle Valo ath12k_err(ab, "failed to set ac override for ARP: %d\n", 4615d8899132SKalle Valo ret); 4616d8899132SKalle Valo goto err; 4617d8899132SKalle Valo } 4618d8899132SKalle Valo 4619d8899132SKalle Valo ret = ath12k_wmi_send_dfs_phyerr_offload_enable_cmd(ar, pdev->pdev_id); 4620d8899132SKalle Valo if (ret) { 4621d8899132SKalle Valo ath12k_err(ab, "failed to offload radar detection: %d\n", 4622d8899132SKalle Valo ret); 4623d8899132SKalle Valo goto err; 4624d8899132SKalle Valo } 4625d8899132SKalle Valo 4626d8899132SKalle Valo ret = ath12k_dp_tx_htt_h2t_ppdu_stats_req(ar, 4627d8899132SKalle Valo HTT_PPDU_STATS_TAG_DEFAULT); 4628d8899132SKalle Valo if (ret) { 4629d8899132SKalle Valo ath12k_err(ab, "failed to req ppdu stats: %d\n", ret); 4630d8899132SKalle Valo goto err; 4631d8899132SKalle Valo } 4632d8899132SKalle Valo 4633d8899132SKalle Valo ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_MESH_MCAST_ENABLE, 4634d8899132SKalle Valo 1, pdev->pdev_id); 4635d8899132SKalle Valo 4636d8899132SKalle Valo if (ret) { 4637d8899132SKalle Valo ath12k_err(ar->ab, "failed to enable MESH MCAST ENABLE: (%d\n", ret); 4638d8899132SKalle Valo goto err; 4639d8899132SKalle Valo } 4640d8899132SKalle Valo 4641d8899132SKalle Valo __ath12k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask); 4642d8899132SKalle Valo 4643d8899132SKalle Valo /* TODO: Do we need to enable ANI? */ 4644d8899132SKalle Valo 4645d8899132SKalle Valo ath12k_reg_update_chan_list(ar); 4646d8899132SKalle Valo 4647d8899132SKalle Valo ar->num_started_vdevs = 0; 4648d8899132SKalle Valo ar->num_created_vdevs = 0; 4649d8899132SKalle Valo ar->num_peers = 0; 4650d8899132SKalle Valo ar->allocated_vdev_map = 0; 4651d8899132SKalle Valo 4652d8899132SKalle Valo /* Configure monitor status ring with default rx_filter to get rx status 4653d8899132SKalle Valo * such as rssi, rx_duration. 4654d8899132SKalle Valo */ 4655d8899132SKalle Valo ret = ath12k_mac_config_mon_status_default(ar, true); 4656d8899132SKalle Valo if (ret && (ret != -ENOTSUPP)) { 4657d8899132SKalle Valo ath12k_err(ab, "failed to configure monitor status ring with default rx_filter: (%d)\n", 4658d8899132SKalle Valo ret); 4659d8899132SKalle Valo goto err; 4660d8899132SKalle Valo } 4661d8899132SKalle Valo 4662d8899132SKalle Valo if (ret == -ENOTSUPP) 4663d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 4664d8899132SKalle Valo "monitor status config is not yet supported"); 4665d8899132SKalle Valo 4666d8899132SKalle Valo /* Configure the hash seed for hash based reo dest ring selection */ 4667d8899132SKalle Valo ath12k_wmi_pdev_lro_cfg(ar, ar->pdev->pdev_id); 4668d8899132SKalle Valo 4669d8899132SKalle Valo /* allow device to enter IMPS */ 4670d8899132SKalle Valo if (ab->hw_params->idle_ps) { 4671d8899132SKalle Valo ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_IDLE_PS_CONFIG, 4672d8899132SKalle Valo 1, pdev->pdev_id); 4673d8899132SKalle Valo if (ret) { 4674d8899132SKalle Valo ath12k_err(ab, "failed to enable idle ps: %d\n", ret); 4675d8899132SKalle Valo goto err; 4676d8899132SKalle Valo } 4677d8899132SKalle Valo } 4678d8899132SKalle Valo 4679d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 4680d8899132SKalle Valo 4681d8899132SKalle Valo rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], 4682d8899132SKalle Valo &ab->pdevs[ar->pdev_idx]); 4683d8899132SKalle Valo 4684d8899132SKalle Valo return 0; 4685d8899132SKalle Valo 4686d8899132SKalle Valo err: 4687d8899132SKalle Valo ar->state = ATH12K_STATE_OFF; 4688d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 4689d8899132SKalle Valo 4690d8899132SKalle Valo return ret; 4691d8899132SKalle Valo } 4692d8899132SKalle Valo 4693d8899132SKalle Valo static void ath12k_mac_op_stop(struct ieee80211_hw *hw) 4694d8899132SKalle Valo { 4695d8899132SKalle Valo struct ath12k *ar = hw->priv; 4696d8899132SKalle Valo struct htt_ppdu_stats_info *ppdu_stats, *tmp; 4697d8899132SKalle Valo int ret; 4698d8899132SKalle Valo 4699d8899132SKalle Valo ath12k_mac_drain_tx(ar); 4700d8899132SKalle Valo 4701d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 4702d8899132SKalle Valo ret = ath12k_mac_config_mon_status_default(ar, false); 4703d8899132SKalle Valo if (ret && (ret != -ENOTSUPP)) 4704d8899132SKalle Valo ath12k_err(ar->ab, "failed to clear rx_filter for monitor status ring: (%d)\n", 4705d8899132SKalle Valo ret); 4706d8899132SKalle Valo 4707d8899132SKalle Valo clear_bit(ATH12K_CAC_RUNNING, &ar->dev_flags); 4708d8899132SKalle Valo ar->state = ATH12K_STATE_OFF; 4709d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 4710d8899132SKalle Valo 4711d8899132SKalle Valo cancel_delayed_work_sync(&ar->scan.timeout); 4712d8899132SKalle Valo cancel_work_sync(&ar->regd_update_work); 4713d8899132SKalle Valo 4714d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 4715d8899132SKalle Valo list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { 4716d8899132SKalle Valo list_del(&ppdu_stats->list); 4717d8899132SKalle Valo kfree(ppdu_stats); 4718d8899132SKalle Valo } 4719d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 4720d8899132SKalle Valo 4721d8899132SKalle Valo rcu_assign_pointer(ar->ab->pdevs_active[ar->pdev_idx], NULL); 4722d8899132SKalle Valo 4723d8899132SKalle Valo synchronize_rcu(); 4724d8899132SKalle Valo 4725d8899132SKalle Valo atomic_set(&ar->num_pending_mgmt_tx, 0); 4726d8899132SKalle Valo } 4727d8899132SKalle Valo 4728d8899132SKalle Valo static u8 4729d8899132SKalle Valo ath12k_mac_get_vdev_stats_id(struct ath12k_vif *arvif) 4730d8899132SKalle Valo { 4731d8899132SKalle Valo struct ath12k_base *ab = arvif->ar->ab; 4732d8899132SKalle Valo u8 vdev_stats_id = 0; 4733d8899132SKalle Valo 4734d8899132SKalle Valo do { 4735d8899132SKalle Valo if (ab->free_vdev_stats_id_map & (1LL << vdev_stats_id)) { 4736d8899132SKalle Valo vdev_stats_id++; 4737d8899132SKalle Valo if (vdev_stats_id <= ATH12K_INVAL_VDEV_STATS_ID) { 4738d8899132SKalle Valo vdev_stats_id = ATH12K_INVAL_VDEV_STATS_ID; 4739d8899132SKalle Valo break; 4740d8899132SKalle Valo } 4741d8899132SKalle Valo } else { 4742d8899132SKalle Valo ab->free_vdev_stats_id_map |= (1LL << vdev_stats_id); 4743d8899132SKalle Valo break; 4744d8899132SKalle Valo } 4745d8899132SKalle Valo } while (vdev_stats_id); 4746d8899132SKalle Valo 4747d8899132SKalle Valo arvif->vdev_stats_id = vdev_stats_id; 4748d8899132SKalle Valo return vdev_stats_id; 4749d8899132SKalle Valo } 4750d8899132SKalle Valo 4751d8899132SKalle Valo static void ath12k_mac_setup_vdev_create_arg(struct ath12k_vif *arvif, 4752d8899132SKalle Valo struct ath12k_wmi_vdev_create_arg *arg) 4753d8899132SKalle Valo { 4754d8899132SKalle Valo struct ath12k *ar = arvif->ar; 4755d8899132SKalle Valo struct ath12k_pdev *pdev = ar->pdev; 4756d8899132SKalle Valo 4757d8899132SKalle Valo arg->if_id = arvif->vdev_id; 4758d8899132SKalle Valo arg->type = arvif->vdev_type; 4759d8899132SKalle Valo arg->subtype = arvif->vdev_subtype; 4760d8899132SKalle Valo arg->pdev_id = pdev->pdev_id; 4761d8899132SKalle Valo 4762d8899132SKalle Valo if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) { 4763d8899132SKalle Valo arg->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains; 4764d8899132SKalle Valo arg->chains[NL80211_BAND_2GHZ].rx = ar->num_rx_chains; 4765d8899132SKalle Valo } 4766d8899132SKalle Valo if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) { 4767d8899132SKalle Valo arg->chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains; 4768d8899132SKalle Valo arg->chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains; 4769d8899132SKalle Valo } 4770d8899132SKalle Valo if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP && 4771d8899132SKalle Valo ar->supports_6ghz) { 4772d8899132SKalle Valo arg->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains; 4773d8899132SKalle Valo arg->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains; 4774d8899132SKalle Valo } 4775d8899132SKalle Valo 4776d8899132SKalle Valo arg->if_stats_id = ath12k_mac_get_vdev_stats_id(arvif); 4777d8899132SKalle Valo } 4778d8899132SKalle Valo 4779d8899132SKalle Valo static u32 4780d8899132SKalle Valo ath12k_mac_prepare_he_mode(struct ath12k_pdev *pdev, u32 viftype) 4781d8899132SKalle Valo { 4782d8899132SKalle Valo struct ath12k_pdev_cap *pdev_cap = &pdev->cap; 4783d8899132SKalle Valo struct ath12k_band_cap *cap_band = NULL; 4784d8899132SKalle Valo u32 *hecap_phy_ptr = NULL; 4785d8899132SKalle Valo u32 hemode; 4786d8899132SKalle Valo 4787d8899132SKalle Valo if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) 4788d8899132SKalle Valo cap_band = &pdev_cap->band[NL80211_BAND_2GHZ]; 4789d8899132SKalle Valo else 4790d8899132SKalle Valo cap_band = &pdev_cap->band[NL80211_BAND_5GHZ]; 4791d8899132SKalle Valo 4792d8899132SKalle Valo hecap_phy_ptr = &cap_band->he_cap_phy_info[0]; 4793d8899132SKalle Valo 4794d8899132SKalle Valo hemode = u32_encode_bits(HE_SU_BFEE_ENABLE, HE_MODE_SU_TX_BFEE) | 4795d8899132SKalle Valo u32_encode_bits(HECAP_PHY_SUBFMR_GET(hecap_phy_ptr), 4796d8899132SKalle Valo HE_MODE_SU_TX_BFER) | 4797d8899132SKalle Valo u32_encode_bits(HECAP_PHY_ULMUMIMO_GET(hecap_phy_ptr), 4798d8899132SKalle Valo HE_MODE_UL_MUMIMO); 4799d8899132SKalle Valo 4800d8899132SKalle Valo /* TODO: WDS and other modes */ 4801d8899132SKalle Valo if (viftype == NL80211_IFTYPE_AP) { 4802d8899132SKalle Valo hemode |= u32_encode_bits(HECAP_PHY_MUBFMR_GET(hecap_phy_ptr), 4803d8899132SKalle Valo HE_MODE_MU_TX_BFER) | 4804d8899132SKalle Valo u32_encode_bits(HE_DL_MUOFDMA_ENABLE, HE_MODE_DL_OFDMA) | 4805d8899132SKalle Valo u32_encode_bits(HE_UL_MUOFDMA_ENABLE, HE_MODE_UL_OFDMA); 4806d8899132SKalle Valo } else { 4807d8899132SKalle Valo hemode |= u32_encode_bits(HE_MU_BFEE_ENABLE, HE_MODE_MU_TX_BFEE); 4808d8899132SKalle Valo } 4809d8899132SKalle Valo 4810d8899132SKalle Valo return hemode; 4811d8899132SKalle Valo } 4812d8899132SKalle Valo 4813d8899132SKalle Valo static int ath12k_set_he_mu_sounding_mode(struct ath12k *ar, 4814d8899132SKalle Valo struct ath12k_vif *arvif) 4815d8899132SKalle Valo { 4816d8899132SKalle Valo u32 param_id, param_value; 4817d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 4818d8899132SKalle Valo int ret; 4819d8899132SKalle Valo 4820d8899132SKalle Valo param_id = WMI_VDEV_PARAM_SET_HEMU_MODE; 4821d8899132SKalle Valo param_value = ath12k_mac_prepare_he_mode(ar->pdev, arvif->vif->type); 4822d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 4823d8899132SKalle Valo param_id, param_value); 4824d8899132SKalle Valo if (ret) { 4825d8899132SKalle Valo ath12k_warn(ab, "failed to set vdev %d HE MU mode: %d param_value %x\n", 4826d8899132SKalle Valo arvif->vdev_id, ret, param_value); 4827d8899132SKalle Valo return ret; 4828d8899132SKalle Valo } 4829d8899132SKalle Valo param_id = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; 4830d8899132SKalle Valo param_value = 4831d8899132SKalle Valo u32_encode_bits(HE_VHT_SOUNDING_MODE_ENABLE, HE_VHT_SOUNDING_MODE) | 4832d8899132SKalle Valo u32_encode_bits(HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE, 4833d8899132SKalle Valo HE_TRIG_NONTRIG_SOUNDING_MODE); 4834d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 4835d8899132SKalle Valo param_id, param_value); 4836d8899132SKalle Valo if (ret) { 4837d8899132SKalle Valo ath12k_warn(ab, "failed to set vdev %d HE MU mode: %d\n", 4838d8899132SKalle Valo arvif->vdev_id, ret); 4839d8899132SKalle Valo return ret; 4840d8899132SKalle Valo } 4841d8899132SKalle Valo return ret; 4842d8899132SKalle Valo } 4843d8899132SKalle Valo 4844d8899132SKalle Valo static void ath12k_mac_op_update_vif_offload(struct ieee80211_hw *hw, 4845d8899132SKalle Valo struct ieee80211_vif *vif) 4846d8899132SKalle Valo { 4847d8899132SKalle Valo struct ath12k *ar = hw->priv; 4848d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 4849d8899132SKalle Valo struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 4850d8899132SKalle Valo u32 param_id, param_value; 4851d8899132SKalle Valo int ret; 4852d8899132SKalle Valo 4853d8899132SKalle Valo param_id = WMI_VDEV_PARAM_TX_ENCAP_TYPE; 4854d8899132SKalle Valo if (vif->type != NL80211_IFTYPE_STATION && 4855d8899132SKalle Valo vif->type != NL80211_IFTYPE_AP) 4856d8899132SKalle Valo vif->offload_flags &= ~(IEEE80211_OFFLOAD_ENCAP_ENABLED | 4857d8899132SKalle Valo IEEE80211_OFFLOAD_DECAP_ENABLED); 4858d8899132SKalle Valo 4859d8899132SKalle Valo if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) 4860d8899132SKalle Valo arvif->tx_encap_type = ATH12K_HW_TXRX_ETHERNET; 4861d8899132SKalle Valo else if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) 4862d8899132SKalle Valo arvif->tx_encap_type = ATH12K_HW_TXRX_RAW; 4863d8899132SKalle Valo else 4864d8899132SKalle Valo arvif->tx_encap_type = ATH12K_HW_TXRX_NATIVE_WIFI; 4865d8899132SKalle Valo 4866d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 4867d8899132SKalle Valo param_id, arvif->tx_encap_type); 4868d8899132SKalle Valo if (ret) { 4869d8899132SKalle Valo ath12k_warn(ab, "failed to set vdev %d tx encap mode: %d\n", 4870d8899132SKalle Valo arvif->vdev_id, ret); 4871d8899132SKalle Valo vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; 4872d8899132SKalle Valo } 4873d8899132SKalle Valo 4874d8899132SKalle Valo param_id = WMI_VDEV_PARAM_RX_DECAP_TYPE; 4875d8899132SKalle Valo if (vif->offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED) 4876d8899132SKalle Valo param_value = ATH12K_HW_TXRX_ETHERNET; 4877d8899132SKalle Valo else if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) 4878d8899132SKalle Valo param_value = ATH12K_HW_TXRX_RAW; 4879d8899132SKalle Valo else 4880d8899132SKalle Valo param_value = ATH12K_HW_TXRX_NATIVE_WIFI; 4881d8899132SKalle Valo 4882d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 4883d8899132SKalle Valo param_id, param_value); 4884d8899132SKalle Valo if (ret) { 4885d8899132SKalle Valo ath12k_warn(ab, "failed to set vdev %d rx decap mode: %d\n", 4886d8899132SKalle Valo arvif->vdev_id, ret); 4887d8899132SKalle Valo vif->offload_flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; 4888d8899132SKalle Valo } 4889d8899132SKalle Valo } 4890d8899132SKalle Valo 4891d8899132SKalle Valo static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, 4892d8899132SKalle Valo struct ieee80211_vif *vif) 4893d8899132SKalle Valo { 4894d8899132SKalle Valo struct ath12k *ar = hw->priv; 4895d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 4896d8899132SKalle Valo struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 4897d8899132SKalle Valo struct ath12k_wmi_vdev_create_arg vdev_arg = {0}; 4898d8899132SKalle Valo struct ath12k_wmi_peer_create_arg peer_param; 4899d8899132SKalle Valo u32 param_id, param_value; 4900d8899132SKalle Valo u16 nss; 4901d8899132SKalle Valo int i; 4902d8899132SKalle Valo int ret; 4903d8899132SKalle Valo int bit; 4904d8899132SKalle Valo 4905d8899132SKalle Valo vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD; 4906d8899132SKalle Valo 4907d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 4908d8899132SKalle Valo 4909d8899132SKalle Valo if (vif->type == NL80211_IFTYPE_AP && 4910d8899132SKalle Valo ar->num_peers > (ar->max_num_peers - 1)) { 4911d8899132SKalle Valo ath12k_warn(ab, "failed to create vdev due to insufficient peer entry resource in firmware\n"); 4912d8899132SKalle Valo ret = -ENOBUFS; 4913d8899132SKalle Valo goto err; 4914d8899132SKalle Valo } 4915d8899132SKalle Valo 4916d8899132SKalle Valo if (ar->num_created_vdevs > (TARGET_NUM_VDEVS - 1)) { 4917d8899132SKalle Valo ath12k_warn(ab, "failed to create vdev, reached max vdev limit %d\n", 4918d8899132SKalle Valo TARGET_NUM_VDEVS); 4919d8899132SKalle Valo ret = -EBUSY; 4920d8899132SKalle Valo goto err; 4921d8899132SKalle Valo } 4922d8899132SKalle Valo 4923d8899132SKalle Valo memset(arvif, 0, sizeof(*arvif)); 4924d8899132SKalle Valo 4925d8899132SKalle Valo arvif->ar = ar; 4926d8899132SKalle Valo arvif->vif = vif; 4927d8899132SKalle Valo 4928d8899132SKalle Valo INIT_LIST_HEAD(&arvif->list); 4929d8899132SKalle Valo 4930d8899132SKalle Valo /* Should we initialize any worker to handle connection loss indication 4931d8899132SKalle Valo * from firmware in sta mode? 4932d8899132SKalle Valo */ 4933d8899132SKalle Valo 4934d8899132SKalle Valo for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) { 4935d8899132SKalle Valo arvif->bitrate_mask.control[i].legacy = 0xffffffff; 4936d8899132SKalle Valo memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff, 4937d8899132SKalle Valo sizeof(arvif->bitrate_mask.control[i].ht_mcs)); 4938d8899132SKalle Valo memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff, 4939d8899132SKalle Valo sizeof(arvif->bitrate_mask.control[i].vht_mcs)); 4940d8899132SKalle Valo } 4941d8899132SKalle Valo 4942d8899132SKalle Valo bit = __ffs64(ab->free_vdev_map); 4943d8899132SKalle Valo 4944d8899132SKalle Valo arvif->vdev_id = bit; 4945d8899132SKalle Valo arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; 4946d8899132SKalle Valo 4947d8899132SKalle Valo switch (vif->type) { 4948d8899132SKalle Valo case NL80211_IFTYPE_UNSPECIFIED: 4949d8899132SKalle Valo case NL80211_IFTYPE_STATION: 4950d8899132SKalle Valo arvif->vdev_type = WMI_VDEV_TYPE_STA; 4951d8899132SKalle Valo break; 4952d8899132SKalle Valo case NL80211_IFTYPE_MESH_POINT: 4953d8899132SKalle Valo arvif->vdev_subtype = WMI_VDEV_SUBTYPE_MESH_11S; 4954d8899132SKalle Valo fallthrough; 4955d8899132SKalle Valo case NL80211_IFTYPE_AP: 4956d8899132SKalle Valo arvif->vdev_type = WMI_VDEV_TYPE_AP; 4957d8899132SKalle Valo break; 4958d8899132SKalle Valo case NL80211_IFTYPE_MONITOR: 4959d8899132SKalle Valo arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; 4960d8899132SKalle Valo ar->monitor_vdev_id = bit; 4961d8899132SKalle Valo break; 4962d8899132SKalle Valo default: 4963d8899132SKalle Valo WARN_ON(1); 4964d8899132SKalle Valo break; 4965d8899132SKalle Valo } 4966d8899132SKalle Valo 4967d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac add interface id %d type %d subtype %d map %llx\n", 4968d8899132SKalle Valo arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype, 4969d8899132SKalle Valo ab->free_vdev_map); 4970d8899132SKalle Valo 4971d8899132SKalle Valo vif->cab_queue = arvif->vdev_id % (ATH12K_HW_MAX_QUEUES - 1); 4972d8899132SKalle Valo for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++) 4973d8899132SKalle Valo vif->hw_queue[i] = i % (ATH12K_HW_MAX_QUEUES - 1); 4974d8899132SKalle Valo 4975d8899132SKalle Valo ath12k_mac_setup_vdev_create_arg(arvif, &vdev_arg); 4976d8899132SKalle Valo 4977d8899132SKalle Valo ret = ath12k_wmi_vdev_create(ar, vif->addr, &vdev_arg); 4978d8899132SKalle Valo if (ret) { 4979d8899132SKalle Valo ath12k_warn(ab, "failed to create WMI vdev %d: %d\n", 4980d8899132SKalle Valo arvif->vdev_id, ret); 4981d8899132SKalle Valo goto err; 4982d8899132SKalle Valo } 4983d8899132SKalle Valo 4984d8899132SKalle Valo ar->num_created_vdevs++; 4985d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, "vdev %pM created, vdev_id %d\n", 4986d8899132SKalle Valo vif->addr, arvif->vdev_id); 4987d8899132SKalle Valo ar->allocated_vdev_map |= 1LL << arvif->vdev_id; 4988d8899132SKalle Valo ab->free_vdev_map &= ~(1LL << arvif->vdev_id); 4989d8899132SKalle Valo 4990d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 4991d8899132SKalle Valo list_add(&arvif->list, &ar->arvifs); 4992d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 4993d8899132SKalle Valo 4994d8899132SKalle Valo ath12k_mac_op_update_vif_offload(hw, vif); 4995d8899132SKalle Valo 4996d8899132SKalle Valo nss = hweight32(ar->cfg_tx_chainmask) ? : 1; 4997d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 4998d8899132SKalle Valo WMI_VDEV_PARAM_NSS, nss); 4999d8899132SKalle Valo if (ret) { 5000d8899132SKalle Valo ath12k_warn(ab, "failed to set vdev %d chainmask 0x%x, nss %d :%d\n", 5001d8899132SKalle Valo arvif->vdev_id, ar->cfg_tx_chainmask, nss, ret); 5002d8899132SKalle Valo goto err_vdev_del; 5003d8899132SKalle Valo } 5004d8899132SKalle Valo 5005d8899132SKalle Valo switch (arvif->vdev_type) { 5006d8899132SKalle Valo case WMI_VDEV_TYPE_AP: 5007d8899132SKalle Valo peer_param.vdev_id = arvif->vdev_id; 5008d8899132SKalle Valo peer_param.peer_addr = vif->addr; 5009d8899132SKalle Valo peer_param.peer_type = WMI_PEER_TYPE_DEFAULT; 5010d8899132SKalle Valo ret = ath12k_peer_create(ar, arvif, NULL, &peer_param); 5011d8899132SKalle Valo if (ret) { 5012d8899132SKalle Valo ath12k_warn(ab, "failed to vdev %d create peer for AP: %d\n", 5013d8899132SKalle Valo arvif->vdev_id, ret); 5014d8899132SKalle Valo goto err_vdev_del; 5015d8899132SKalle Valo } 5016d8899132SKalle Valo 5017d8899132SKalle Valo ret = ath12k_mac_set_kickout(arvif); 5018d8899132SKalle Valo if (ret) { 5019d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set vdev %i kickout parameters: %d\n", 5020d8899132SKalle Valo arvif->vdev_id, ret); 5021d8899132SKalle Valo goto err_peer_del; 5022d8899132SKalle Valo } 5023d8899132SKalle Valo break; 5024d8899132SKalle Valo case WMI_VDEV_TYPE_STA: 5025d8899132SKalle Valo param_id = WMI_STA_PS_PARAM_RX_WAKE_POLICY; 5026d8899132SKalle Valo param_value = WMI_STA_PS_RX_WAKE_POLICY_WAKE; 5027d8899132SKalle Valo ret = ath12k_wmi_set_sta_ps_param(ar, arvif->vdev_id, 5028d8899132SKalle Valo param_id, param_value); 5029d8899132SKalle Valo if (ret) { 5030d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set vdev %d RX wake policy: %d\n", 5031d8899132SKalle Valo arvif->vdev_id, ret); 5032d8899132SKalle Valo goto err_peer_del; 5033d8899132SKalle Valo } 5034d8899132SKalle Valo 5035d8899132SKalle Valo param_id = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD; 5036d8899132SKalle Valo param_value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS; 5037d8899132SKalle Valo ret = ath12k_wmi_set_sta_ps_param(ar, arvif->vdev_id, 5038d8899132SKalle Valo param_id, param_value); 5039d8899132SKalle Valo if (ret) { 5040d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set vdev %d TX wake threshold: %d\n", 5041d8899132SKalle Valo arvif->vdev_id, ret); 5042d8899132SKalle Valo goto err_peer_del; 5043d8899132SKalle Valo } 5044d8899132SKalle Valo 5045d8899132SKalle Valo param_id = WMI_STA_PS_PARAM_PSPOLL_COUNT; 5046d8899132SKalle Valo param_value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX; 5047d8899132SKalle Valo ret = ath12k_wmi_set_sta_ps_param(ar, arvif->vdev_id, 5048d8899132SKalle Valo param_id, param_value); 5049d8899132SKalle Valo if (ret) { 5050d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set vdev %d pspoll count: %d\n", 5051d8899132SKalle Valo arvif->vdev_id, ret); 5052d8899132SKalle Valo goto err_peer_del; 5053d8899132SKalle Valo } 5054d8899132SKalle Valo 5055d8899132SKalle Valo ret = ath12k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id, false); 5056d8899132SKalle Valo if (ret) { 5057d8899132SKalle Valo ath12k_warn(ar->ab, "failed to disable vdev %d ps mode: %d\n", 5058d8899132SKalle Valo arvif->vdev_id, ret); 5059d8899132SKalle Valo goto err_peer_del; 5060d8899132SKalle Valo } 5061d8899132SKalle Valo break; 5062d8899132SKalle Valo default: 5063d8899132SKalle Valo break; 5064d8899132SKalle Valo } 5065d8899132SKalle Valo 5066d8899132SKalle Valo arvif->txpower = vif->bss_conf.txpower; 5067d8899132SKalle Valo ret = ath12k_mac_txpower_recalc(ar); 5068d8899132SKalle Valo if (ret) 5069d8899132SKalle Valo goto err_peer_del; 5070d8899132SKalle Valo 5071d8899132SKalle Valo param_id = WMI_VDEV_PARAM_RTS_THRESHOLD; 5072d8899132SKalle Valo param_value = ar->hw->wiphy->rts_threshold; 5073d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 5074d8899132SKalle Valo param_id, param_value); 5075d8899132SKalle Valo if (ret) { 5076d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set rts threshold for vdev %d: %d\n", 5077d8899132SKalle Valo arvif->vdev_id, ret); 5078d8899132SKalle Valo } 5079d8899132SKalle Valo 5080d8899132SKalle Valo ath12k_dp_vdev_tx_attach(ar, arvif); 5081d8899132SKalle Valo 5082d8899132SKalle Valo if (vif->type != NL80211_IFTYPE_MONITOR && ar->monitor_conf_enabled) 5083d8899132SKalle Valo ath12k_mac_monitor_vdev_create(ar); 5084d8899132SKalle Valo 5085d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5086d8899132SKalle Valo 5087d8899132SKalle Valo return ret; 5088d8899132SKalle Valo 5089d8899132SKalle Valo err_peer_del: 5090d8899132SKalle Valo if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { 5091d8899132SKalle Valo reinit_completion(&ar->peer_delete_done); 5092d8899132SKalle Valo 5093d8899132SKalle Valo ret = ath12k_wmi_send_peer_delete_cmd(ar, vif->addr, 5094d8899132SKalle Valo arvif->vdev_id); 5095d8899132SKalle Valo if (ret) { 5096d8899132SKalle Valo ath12k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n", 5097d8899132SKalle Valo arvif->vdev_id, vif->addr); 5098d8899132SKalle Valo goto err; 5099d8899132SKalle Valo } 5100d8899132SKalle Valo 5101d8899132SKalle Valo ret = ath12k_wait_for_peer_delete_done(ar, arvif->vdev_id, 5102d8899132SKalle Valo vif->addr); 5103d8899132SKalle Valo if (ret) 5104d8899132SKalle Valo goto err; 5105d8899132SKalle Valo 5106d8899132SKalle Valo ar->num_peers--; 5107d8899132SKalle Valo } 5108d8899132SKalle Valo 5109d8899132SKalle Valo err_vdev_del: 5110d8899132SKalle Valo ath12k_wmi_vdev_delete(ar, arvif->vdev_id); 5111d8899132SKalle Valo ar->num_created_vdevs--; 5112d8899132SKalle Valo ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); 5113d8899132SKalle Valo ab->free_vdev_map |= 1LL << arvif->vdev_id; 5114d8899132SKalle Valo ab->free_vdev_stats_id_map &= ~(1LL << arvif->vdev_stats_id); 5115d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 5116d8899132SKalle Valo list_del(&arvif->list); 5117d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 5118d8899132SKalle Valo 5119d8899132SKalle Valo err: 5120d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5121d8899132SKalle Valo 5122d8899132SKalle Valo return ret; 5123d8899132SKalle Valo } 5124d8899132SKalle Valo 5125d8899132SKalle Valo static void ath12k_mac_vif_unref(struct ath12k_dp *dp, struct ieee80211_vif *vif) 5126d8899132SKalle Valo { 5127d8899132SKalle Valo struct ath12k_tx_desc_info *tx_desc_info, *tmp1; 5128d8899132SKalle Valo struct ath12k_skb_cb *skb_cb; 5129d8899132SKalle Valo struct sk_buff *skb; 5130d8899132SKalle Valo int i; 5131d8899132SKalle Valo 5132d8899132SKalle Valo for (i = 0; i < ATH12K_HW_MAX_QUEUES; i++) { 5133d8899132SKalle Valo spin_lock_bh(&dp->tx_desc_lock[i]); 5134d8899132SKalle Valo 5135d8899132SKalle Valo list_for_each_entry_safe(tx_desc_info, tmp1, &dp->tx_desc_used_list[i], 5136d8899132SKalle Valo list) { 5137d8899132SKalle Valo skb = tx_desc_info->skb; 5138d8899132SKalle Valo if (!skb) 5139d8899132SKalle Valo continue; 5140d8899132SKalle Valo 5141d8899132SKalle Valo skb_cb = ATH12K_SKB_CB(skb); 5142d8899132SKalle Valo if (skb_cb->vif == vif) 5143d8899132SKalle Valo skb_cb->vif = NULL; 5144d8899132SKalle Valo } 5145d8899132SKalle Valo 5146d8899132SKalle Valo spin_unlock_bh(&dp->tx_desc_lock[i]); 5147d8899132SKalle Valo } 5148d8899132SKalle Valo } 5149d8899132SKalle Valo 5150d8899132SKalle Valo static void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, 5151d8899132SKalle Valo struct ieee80211_vif *vif) 5152d8899132SKalle Valo { 5153d8899132SKalle Valo struct ath12k *ar = hw->priv; 5154d8899132SKalle Valo struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); 5155d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 5156d8899132SKalle Valo unsigned long time_left; 5157d8899132SKalle Valo int ret; 5158d8899132SKalle Valo 5159d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5160d8899132SKalle Valo 5161d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, "mac remove interface (vdev %d)\n", 5162d8899132SKalle Valo arvif->vdev_id); 5163d8899132SKalle Valo 5164d8899132SKalle Valo if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { 5165d8899132SKalle Valo ret = ath12k_peer_delete(ar, arvif->vdev_id, vif->addr); 5166d8899132SKalle Valo if (ret) 5167d8899132SKalle Valo ath12k_warn(ab, "failed to submit AP self-peer removal on vdev %d: %d\n", 5168d8899132SKalle Valo arvif->vdev_id, ret); 5169d8899132SKalle Valo } 5170d8899132SKalle Valo 5171d8899132SKalle Valo reinit_completion(&ar->vdev_delete_done); 5172d8899132SKalle Valo 5173d8899132SKalle Valo ret = ath12k_wmi_vdev_delete(ar, arvif->vdev_id); 5174d8899132SKalle Valo if (ret) { 5175d8899132SKalle Valo ath12k_warn(ab, "failed to delete WMI vdev %d: %d\n", 5176d8899132SKalle Valo arvif->vdev_id, ret); 5177d8899132SKalle Valo goto err_vdev_del; 5178d8899132SKalle Valo } 5179d8899132SKalle Valo 5180d8899132SKalle Valo time_left = wait_for_completion_timeout(&ar->vdev_delete_done, 5181d8899132SKalle Valo ATH12K_VDEV_DELETE_TIMEOUT_HZ); 5182d8899132SKalle Valo if (time_left == 0) { 5183d8899132SKalle Valo ath12k_warn(ab, "Timeout in receiving vdev delete response\n"); 5184d8899132SKalle Valo goto err_vdev_del; 5185d8899132SKalle Valo } 5186d8899132SKalle Valo 5187d8899132SKalle Valo if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { 5188d8899132SKalle Valo ar->monitor_vdev_id = -1; 5189d8899132SKalle Valo ar->monitor_vdev_created = false; 5190d8899132SKalle Valo } else if (ar->monitor_vdev_created && !ar->monitor_started) { 5191d8899132SKalle Valo ret = ath12k_mac_monitor_vdev_delete(ar); 5192d8899132SKalle Valo } 5193d8899132SKalle Valo 5194d8899132SKalle Valo ab->free_vdev_map |= 1LL << (arvif->vdev_id); 5195d8899132SKalle Valo ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); 5196d8899132SKalle Valo ab->free_vdev_stats_id_map &= ~(1LL << arvif->vdev_stats_id); 5197d8899132SKalle Valo ar->num_created_vdevs--; 5198d8899132SKalle Valo 5199d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, "vdev %pM deleted, vdev_id %d\n", 5200d8899132SKalle Valo vif->addr, arvif->vdev_id); 5201d8899132SKalle Valo 5202d8899132SKalle Valo err_vdev_del: 5203d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 5204d8899132SKalle Valo list_del(&arvif->list); 5205d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 5206d8899132SKalle Valo 5207d8899132SKalle Valo ath12k_peer_cleanup(ar, arvif->vdev_id); 5208d8899132SKalle Valo 5209d8899132SKalle Valo idr_for_each(&ar->txmgmt_idr, 5210d8899132SKalle Valo ath12k_mac_vif_txmgmt_idr_remove, vif); 5211d8899132SKalle Valo 5212d8899132SKalle Valo ath12k_mac_vif_unref(&ab->dp, vif); 5213d8899132SKalle Valo ath12k_dp_tx_put_bank_profile(&ab->dp, arvif->bank_id); 5214d8899132SKalle Valo 5215d8899132SKalle Valo /* Recalc txpower for remaining vdev */ 5216d8899132SKalle Valo ath12k_mac_txpower_recalc(ar); 5217d8899132SKalle Valo clear_bit(ATH12K_FLAG_MONITOR_ENABLED, &ar->monitor_flags); 5218d8899132SKalle Valo 5219d8899132SKalle Valo /* TODO: recal traffic pause state based on the available vdevs */ 5220d8899132SKalle Valo 5221d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5222d8899132SKalle Valo } 5223d8899132SKalle Valo 5224d8899132SKalle Valo /* FIXME: Has to be verified. */ 5225d8899132SKalle Valo #define SUPPORTED_FILTERS \ 5226d8899132SKalle Valo (FIF_ALLMULTI | \ 5227d8899132SKalle Valo FIF_CONTROL | \ 5228d8899132SKalle Valo FIF_PSPOLL | \ 5229d8899132SKalle Valo FIF_OTHER_BSS | \ 5230d8899132SKalle Valo FIF_BCN_PRBRESP_PROMISC | \ 5231d8899132SKalle Valo FIF_PROBE_REQ | \ 5232d8899132SKalle Valo FIF_FCSFAIL) 5233d8899132SKalle Valo 5234d8899132SKalle Valo static void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw, 5235d8899132SKalle Valo unsigned int changed_flags, 5236d8899132SKalle Valo unsigned int *total_flags, 5237d8899132SKalle Valo u64 multicast) 5238d8899132SKalle Valo { 5239d8899132SKalle Valo struct ath12k *ar = hw->priv; 5240d8899132SKalle Valo bool reset_flag; 5241d8899132SKalle Valo int ret; 5242d8899132SKalle Valo 5243d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5244d8899132SKalle Valo 5245d8899132SKalle Valo changed_flags &= SUPPORTED_FILTERS; 5246d8899132SKalle Valo *total_flags &= SUPPORTED_FILTERS; 5247d8899132SKalle Valo ar->filter_flags = *total_flags; 5248d8899132SKalle Valo 5249d8899132SKalle Valo /* For monitor mode */ 5250d8899132SKalle Valo reset_flag = !(ar->filter_flags & FIF_BCN_PRBRESP_PROMISC); 5251d8899132SKalle Valo 5252d8899132SKalle Valo ret = ath12k_dp_tx_htt_monitor_mode_ring_config(ar, reset_flag); 5253d8899132SKalle Valo if (!ret) { 5254d8899132SKalle Valo if (!reset_flag) 5255d8899132SKalle Valo set_bit(ATH12K_FLAG_MONITOR_ENABLED, &ar->monitor_flags); 5256d8899132SKalle Valo else 5257d8899132SKalle Valo clear_bit(ATH12K_FLAG_MONITOR_ENABLED, &ar->monitor_flags); 5258d8899132SKalle Valo } else { 5259d8899132SKalle Valo ath12k_warn(ar->ab, 5260d8899132SKalle Valo "fail to set monitor filter: %d\n", ret); 5261d8899132SKalle Valo } 5262d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 5263d8899132SKalle Valo "changed_flags:0x%x, total_flags:0x%x, reset_flag:%d\n", 5264d8899132SKalle Valo changed_flags, *total_flags, reset_flag); 5265d8899132SKalle Valo 5266d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5267d8899132SKalle Valo } 5268d8899132SKalle Valo 5269d8899132SKalle Valo static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) 5270d8899132SKalle Valo { 5271d8899132SKalle Valo struct ath12k *ar = hw->priv; 5272d8899132SKalle Valo 5273d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5274d8899132SKalle Valo 5275d8899132SKalle Valo *tx_ant = ar->cfg_tx_chainmask; 5276d8899132SKalle Valo *rx_ant = ar->cfg_rx_chainmask; 5277d8899132SKalle Valo 5278d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5279d8899132SKalle Valo 5280d8899132SKalle Valo return 0; 5281d8899132SKalle Valo } 5282d8899132SKalle Valo 5283d8899132SKalle Valo static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 5284d8899132SKalle Valo { 5285d8899132SKalle Valo struct ath12k *ar = hw->priv; 5286d8899132SKalle Valo int ret; 5287d8899132SKalle Valo 5288d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5289d8899132SKalle Valo ret = __ath12k_set_antenna(ar, tx_ant, rx_ant); 5290d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5291d8899132SKalle Valo 5292d8899132SKalle Valo return ret; 5293d8899132SKalle Valo } 5294d8899132SKalle Valo 5295d8899132SKalle Valo static int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw, 5296d8899132SKalle Valo struct ieee80211_vif *vif, 5297d8899132SKalle Valo struct ieee80211_ampdu_params *params) 5298d8899132SKalle Valo { 5299d8899132SKalle Valo struct ath12k *ar = hw->priv; 5300d8899132SKalle Valo int ret = -EINVAL; 5301d8899132SKalle Valo 5302d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5303d8899132SKalle Valo 5304d8899132SKalle Valo switch (params->action) { 5305d8899132SKalle Valo case IEEE80211_AMPDU_RX_START: 5306d8899132SKalle Valo ret = ath12k_dp_rx_ampdu_start(ar, params); 5307d8899132SKalle Valo break; 5308d8899132SKalle Valo case IEEE80211_AMPDU_RX_STOP: 5309d8899132SKalle Valo ret = ath12k_dp_rx_ampdu_stop(ar, params); 5310d8899132SKalle Valo break; 5311d8899132SKalle Valo case IEEE80211_AMPDU_TX_START: 5312d8899132SKalle Valo case IEEE80211_AMPDU_TX_STOP_CONT: 5313d8899132SKalle Valo case IEEE80211_AMPDU_TX_STOP_FLUSH: 5314d8899132SKalle Valo case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 5315d8899132SKalle Valo case IEEE80211_AMPDU_TX_OPERATIONAL: 5316d8899132SKalle Valo /* Tx A-MPDU aggregation offloaded to hw/fw so deny mac80211 5317d8899132SKalle Valo * Tx aggregation requests. 5318d8899132SKalle Valo */ 5319d8899132SKalle Valo ret = -EOPNOTSUPP; 5320d8899132SKalle Valo break; 5321d8899132SKalle Valo } 5322d8899132SKalle Valo 5323d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5324d8899132SKalle Valo 5325d8899132SKalle Valo return ret; 5326d8899132SKalle Valo } 5327d8899132SKalle Valo 5328d8899132SKalle Valo static int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw, 5329d8899132SKalle Valo struct ieee80211_chanctx_conf *ctx) 5330d8899132SKalle Valo { 5331d8899132SKalle Valo struct ath12k *ar = hw->priv; 5332d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 5333d8899132SKalle Valo 5334d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, 5335d8899132SKalle Valo "mac chanctx add freq %u width %d ptr %pK\n", 5336d8899132SKalle Valo ctx->def.chan->center_freq, ctx->def.width, ctx); 5337d8899132SKalle Valo 5338d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5339d8899132SKalle Valo 5340d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 5341d8899132SKalle Valo /* TODO: In case of multiple channel context, populate rx_channel from 5342d8899132SKalle Valo * Rx PPDU desc information. 5343d8899132SKalle Valo */ 5344d8899132SKalle Valo ar->rx_channel = ctx->def.chan; 5345d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 5346d8899132SKalle Valo 5347d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5348d8899132SKalle Valo 5349d8899132SKalle Valo return 0; 5350d8899132SKalle Valo } 5351d8899132SKalle Valo 5352d8899132SKalle Valo static void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw, 5353d8899132SKalle Valo struct ieee80211_chanctx_conf *ctx) 5354d8899132SKalle Valo { 5355d8899132SKalle Valo struct ath12k *ar = hw->priv; 5356d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 5357d8899132SKalle Valo 5358d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, 5359d8899132SKalle Valo "mac chanctx remove freq %u width %d ptr %pK\n", 5360d8899132SKalle Valo ctx->def.chan->center_freq, ctx->def.width, ctx); 5361d8899132SKalle Valo 5362d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5363d8899132SKalle Valo 5364d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 5365d8899132SKalle Valo /* TODO: In case of there is one more channel context left, populate 5366d8899132SKalle Valo * rx_channel with the channel of that remaining channel context. 5367d8899132SKalle Valo */ 5368d8899132SKalle Valo ar->rx_channel = NULL; 5369d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 5370d8899132SKalle Valo 5371d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5372d8899132SKalle Valo } 5373d8899132SKalle Valo 5374d8899132SKalle Valo static int 5375d8899132SKalle Valo ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif, 5376d8899132SKalle Valo const struct cfg80211_chan_def *chandef, 5377d8899132SKalle Valo bool restart) 5378d8899132SKalle Valo { 5379d8899132SKalle Valo struct ath12k *ar = arvif->ar; 5380d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 5381d8899132SKalle Valo struct wmi_vdev_start_req_arg arg = {}; 5382d8899132SKalle Valo int he_support = arvif->vif->bss_conf.he_support; 5383d8899132SKalle Valo int ret; 5384d8899132SKalle Valo 5385d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 5386d8899132SKalle Valo 5387d8899132SKalle Valo reinit_completion(&ar->vdev_setup_done); 5388d8899132SKalle Valo 5389d8899132SKalle Valo arg.vdev_id = arvif->vdev_id; 5390d8899132SKalle Valo arg.dtim_period = arvif->dtim_period; 5391d8899132SKalle Valo arg.bcn_intval = arvif->beacon_interval; 5392d8899132SKalle Valo 5393d8899132SKalle Valo arg.freq = chandef->chan->center_freq; 5394d8899132SKalle Valo arg.band_center_freq1 = chandef->center_freq1; 5395d8899132SKalle Valo arg.band_center_freq2 = chandef->center_freq2; 5396d8899132SKalle Valo arg.mode = ath12k_phymodes[chandef->chan->band][chandef->width]; 5397d8899132SKalle Valo 5398d8899132SKalle Valo arg.min_power = 0; 5399d8899132SKalle Valo arg.max_power = chandef->chan->max_power * 2; 5400d8899132SKalle Valo arg.max_reg_power = chandef->chan->max_reg_power * 2; 5401d8899132SKalle Valo arg.max_antenna_gain = chandef->chan->max_antenna_gain * 2; 5402d8899132SKalle Valo 5403d8899132SKalle Valo arg.pref_tx_streams = ar->num_tx_chains; 5404d8899132SKalle Valo arg.pref_rx_streams = ar->num_rx_chains; 5405d8899132SKalle Valo 5406d8899132SKalle Valo if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { 5407d8899132SKalle Valo arg.ssid = arvif->u.ap.ssid; 5408d8899132SKalle Valo arg.ssid_len = arvif->u.ap.ssid_len; 5409d8899132SKalle Valo arg.hidden_ssid = arvif->u.ap.hidden_ssid; 5410d8899132SKalle Valo 5411d8899132SKalle Valo /* For now allow DFS for AP mode */ 5412d8899132SKalle Valo arg.chan_radar = !!(chandef->chan->flags & IEEE80211_CHAN_RADAR); 5413d8899132SKalle Valo 5414d8899132SKalle Valo arg.passive = arg.chan_radar; 5415d8899132SKalle Valo 5416d8899132SKalle Valo spin_lock_bh(&ab->base_lock); 5417d8899132SKalle Valo arg.regdomain = ar->ab->dfs_region; 5418d8899132SKalle Valo spin_unlock_bh(&ab->base_lock); 5419d8899132SKalle Valo 5420d8899132SKalle Valo /* TODO: Notify if secondary 80Mhz also needs radar detection */ 5421d8899132SKalle Valo if (he_support) { 5422d8899132SKalle Valo ret = ath12k_set_he_mu_sounding_mode(ar, arvif); 5423d8899132SKalle Valo if (ret) { 5424d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set he mode vdev %i\n", 5425d8899132SKalle Valo arg.vdev_id); 5426d8899132SKalle Valo return ret; 5427d8899132SKalle Valo } 5428d8899132SKalle Valo } 5429d8899132SKalle Valo } 5430d8899132SKalle Valo 5431d8899132SKalle Valo arg.passive |= !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR); 5432d8899132SKalle Valo 5433d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, 5434d8899132SKalle Valo "mac vdev %d start center_freq %d phymode %s\n", 5435d8899132SKalle Valo arg.vdev_id, arg.freq, 5436d8899132SKalle Valo ath12k_mac_phymode_str(arg.mode)); 5437d8899132SKalle Valo 5438d8899132SKalle Valo ret = ath12k_wmi_vdev_start(ar, &arg, restart); 5439d8899132SKalle Valo if (ret) { 5440d8899132SKalle Valo ath12k_warn(ar->ab, "failed to %s WMI vdev %i\n", 5441d8899132SKalle Valo restart ? "restart" : "start", arg.vdev_id); 5442d8899132SKalle Valo return ret; 5443d8899132SKalle Valo } 5444d8899132SKalle Valo 5445d8899132SKalle Valo ret = ath12k_mac_vdev_setup_sync(ar); 5446d8899132SKalle Valo if (ret) { 5447d8899132SKalle Valo ath12k_warn(ab, "failed to synchronize setup for vdev %i %s: %d\n", 5448d8899132SKalle Valo arg.vdev_id, restart ? "restart" : "start", ret); 5449d8899132SKalle Valo return ret; 5450d8899132SKalle Valo } 5451d8899132SKalle Valo 5452d8899132SKalle Valo ar->num_started_vdevs++; 5453d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, "vdev %pM started, vdev_id %d\n", 5454d8899132SKalle Valo arvif->vif->addr, arvif->vdev_id); 5455d8899132SKalle Valo 5456d8899132SKalle Valo /* Enable CAC Flag in the driver by checking the channel DFS cac time, 5457d8899132SKalle Valo * i.e dfs_cac_ms value which will be valid only for radar channels 5458d8899132SKalle Valo * and state as NL80211_DFS_USABLE which indicates CAC needs to be 5459d8899132SKalle Valo * done before channel usage. This flags is used to drop rx packets. 5460d8899132SKalle Valo * during CAC. 5461d8899132SKalle Valo */ 5462d8899132SKalle Valo /* TODO: Set the flag for other interface types as required */ 5463d8899132SKalle Valo if (arvif->vdev_type == WMI_VDEV_TYPE_AP && 5464d8899132SKalle Valo chandef->chan->dfs_cac_ms && 5465d8899132SKalle Valo chandef->chan->dfs_state == NL80211_DFS_USABLE) { 5466d8899132SKalle Valo set_bit(ATH12K_CAC_RUNNING, &ar->dev_flags); 5467d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, 5468d8899132SKalle Valo "CAC Started in chan_freq %d for vdev %d\n", 5469d8899132SKalle Valo arg.freq, arg.vdev_id); 5470d8899132SKalle Valo } 5471d8899132SKalle Valo 5472d8899132SKalle Valo ret = ath12k_mac_set_txbf_conf(arvif); 5473d8899132SKalle Valo if (ret) 5474d8899132SKalle Valo ath12k_warn(ab, "failed to set txbf conf for vdev %d: %d\n", 5475d8899132SKalle Valo arvif->vdev_id, ret); 5476d8899132SKalle Valo 5477d8899132SKalle Valo return 0; 5478d8899132SKalle Valo } 5479d8899132SKalle Valo 5480d8899132SKalle Valo static int ath12k_mac_vdev_stop(struct ath12k_vif *arvif) 5481d8899132SKalle Valo { 5482d8899132SKalle Valo struct ath12k *ar = arvif->ar; 5483d8899132SKalle Valo int ret; 5484d8899132SKalle Valo 5485d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 5486d8899132SKalle Valo 5487d8899132SKalle Valo reinit_completion(&ar->vdev_setup_done); 5488d8899132SKalle Valo 5489d8899132SKalle Valo ret = ath12k_wmi_vdev_stop(ar, arvif->vdev_id); 5490d8899132SKalle Valo if (ret) { 5491d8899132SKalle Valo ath12k_warn(ar->ab, "failed to stop WMI vdev %i: %d\n", 5492d8899132SKalle Valo arvif->vdev_id, ret); 5493d8899132SKalle Valo goto err; 5494d8899132SKalle Valo } 5495d8899132SKalle Valo 5496d8899132SKalle Valo ret = ath12k_mac_vdev_setup_sync(ar); 5497d8899132SKalle Valo if (ret) { 5498d8899132SKalle Valo ath12k_warn(ar->ab, "failed to synchronize setup for vdev %i: %d\n", 5499d8899132SKalle Valo arvif->vdev_id, ret); 5500d8899132SKalle Valo goto err; 5501d8899132SKalle Valo } 5502d8899132SKalle Valo 5503d8899132SKalle Valo WARN_ON(ar->num_started_vdevs == 0); 5504d8899132SKalle Valo 5505d8899132SKalle Valo ar->num_started_vdevs--; 5506d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "vdev %pM stopped, vdev_id %d\n", 5507d8899132SKalle Valo arvif->vif->addr, arvif->vdev_id); 5508d8899132SKalle Valo 5509d8899132SKalle Valo if (test_bit(ATH12K_CAC_RUNNING, &ar->dev_flags)) { 5510d8899132SKalle Valo clear_bit(ATH12K_CAC_RUNNING, &ar->dev_flags); 5511d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "CAC Stopped for vdev %d\n", 5512d8899132SKalle Valo arvif->vdev_id); 5513d8899132SKalle Valo } 5514d8899132SKalle Valo 5515d8899132SKalle Valo return 0; 5516d8899132SKalle Valo err: 5517d8899132SKalle Valo return ret; 5518d8899132SKalle Valo } 5519d8899132SKalle Valo 5520d8899132SKalle Valo static int ath12k_mac_vdev_start(struct ath12k_vif *arvif, 5521d8899132SKalle Valo const struct cfg80211_chan_def *chandef) 5522d8899132SKalle Valo { 5523d8899132SKalle Valo return ath12k_mac_vdev_start_restart(arvif, chandef, false); 5524d8899132SKalle Valo } 5525d8899132SKalle Valo 5526d8899132SKalle Valo static int ath12k_mac_vdev_restart(struct ath12k_vif *arvif, 5527d8899132SKalle Valo const struct cfg80211_chan_def *chandef) 5528d8899132SKalle Valo { 5529d8899132SKalle Valo return ath12k_mac_vdev_start_restart(arvif, chandef, true); 5530d8899132SKalle Valo } 5531d8899132SKalle Valo 5532d8899132SKalle Valo struct ath12k_mac_change_chanctx_arg { 5533d8899132SKalle Valo struct ieee80211_chanctx_conf *ctx; 5534d8899132SKalle Valo struct ieee80211_vif_chanctx_switch *vifs; 5535d8899132SKalle Valo int n_vifs; 5536d8899132SKalle Valo int next_vif; 5537d8899132SKalle Valo }; 5538d8899132SKalle Valo 5539d8899132SKalle Valo static void 5540d8899132SKalle Valo ath12k_mac_change_chanctx_cnt_iter(void *data, u8 *mac, 5541d8899132SKalle Valo struct ieee80211_vif *vif) 5542d8899132SKalle Valo { 5543d8899132SKalle Valo struct ath12k_mac_change_chanctx_arg *arg = data; 5544d8899132SKalle Valo 5545d8899132SKalle Valo if (rcu_access_pointer(vif->bss_conf.chanctx_conf) != arg->ctx) 5546d8899132SKalle Valo return; 5547d8899132SKalle Valo 5548d8899132SKalle Valo arg->n_vifs++; 5549d8899132SKalle Valo } 5550d8899132SKalle Valo 5551d8899132SKalle Valo static void 5552d8899132SKalle Valo ath12k_mac_change_chanctx_fill_iter(void *data, u8 *mac, 5553d8899132SKalle Valo struct ieee80211_vif *vif) 5554d8899132SKalle Valo { 5555d8899132SKalle Valo struct ath12k_mac_change_chanctx_arg *arg = data; 5556d8899132SKalle Valo struct ieee80211_chanctx_conf *ctx; 5557d8899132SKalle Valo 5558d8899132SKalle Valo ctx = rcu_access_pointer(vif->bss_conf.chanctx_conf); 5559d8899132SKalle Valo if (ctx != arg->ctx) 5560d8899132SKalle Valo return; 5561d8899132SKalle Valo 5562d8899132SKalle Valo if (WARN_ON(arg->next_vif == arg->n_vifs)) 5563d8899132SKalle Valo return; 5564d8899132SKalle Valo 5565d8899132SKalle Valo arg->vifs[arg->next_vif].vif = vif; 5566d8899132SKalle Valo arg->vifs[arg->next_vif].old_ctx = ctx; 5567d8899132SKalle Valo arg->vifs[arg->next_vif].new_ctx = ctx; 5568d8899132SKalle Valo arg->next_vif++; 5569d8899132SKalle Valo } 5570d8899132SKalle Valo 5571d8899132SKalle Valo static void 5572d8899132SKalle Valo ath12k_mac_update_vif_chan(struct ath12k *ar, 5573d8899132SKalle Valo struct ieee80211_vif_chanctx_switch *vifs, 5574d8899132SKalle Valo int n_vifs) 5575d8899132SKalle Valo { 5576d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 5577d8899132SKalle Valo struct ath12k_vif *arvif; 5578d8899132SKalle Valo int ret; 5579d8899132SKalle Valo int i; 5580d8899132SKalle Valo bool monitor_vif = false; 5581d8899132SKalle Valo 5582d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 5583d8899132SKalle Valo 5584d8899132SKalle Valo for (i = 0; i < n_vifs; i++) { 5585d8899132SKalle Valo arvif = (void *)vifs[i].vif->drv_priv; 5586d8899132SKalle Valo 5587d8899132SKalle Valo if (vifs[i].vif->type == NL80211_IFTYPE_MONITOR) 5588d8899132SKalle Valo monitor_vif = true; 5589d8899132SKalle Valo 5590d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, 5591d8899132SKalle Valo "mac chanctx switch vdev_id %i freq %u->%u width %d->%d\n", 5592d8899132SKalle Valo arvif->vdev_id, 5593d8899132SKalle Valo vifs[i].old_ctx->def.chan->center_freq, 5594d8899132SKalle Valo vifs[i].new_ctx->def.chan->center_freq, 5595d8899132SKalle Valo vifs[i].old_ctx->def.width, 5596d8899132SKalle Valo vifs[i].new_ctx->def.width); 5597d8899132SKalle Valo 5598d8899132SKalle Valo if (WARN_ON(!arvif->is_started)) 5599d8899132SKalle Valo continue; 5600d8899132SKalle Valo 5601d8899132SKalle Valo if (WARN_ON(!arvif->is_up)) 5602d8899132SKalle Valo continue; 5603d8899132SKalle Valo 5604d8899132SKalle Valo ret = ath12k_wmi_vdev_down(ar, arvif->vdev_id); 5605d8899132SKalle Valo if (ret) { 5606d8899132SKalle Valo ath12k_warn(ab, "failed to down vdev %d: %d\n", 5607d8899132SKalle Valo arvif->vdev_id, ret); 5608d8899132SKalle Valo continue; 5609d8899132SKalle Valo } 5610d8899132SKalle Valo } 5611d8899132SKalle Valo 5612d8899132SKalle Valo /* All relevant vdevs are downed and associated channel resources 5613d8899132SKalle Valo * should be available for the channel switch now. 5614d8899132SKalle Valo */ 5615d8899132SKalle Valo 5616d8899132SKalle Valo /* TODO: Update ar->rx_channel */ 5617d8899132SKalle Valo 5618d8899132SKalle Valo for (i = 0; i < n_vifs; i++) { 5619d8899132SKalle Valo arvif = (void *)vifs[i].vif->drv_priv; 5620d8899132SKalle Valo 5621d8899132SKalle Valo if (WARN_ON(!arvif->is_started)) 5622d8899132SKalle Valo continue; 5623d8899132SKalle Valo 5624d8899132SKalle Valo if (WARN_ON(!arvif->is_up)) 5625d8899132SKalle Valo continue; 5626d8899132SKalle Valo 5627d8899132SKalle Valo ret = ath12k_mac_vdev_restart(arvif, &vifs[i].new_ctx->def); 5628d8899132SKalle Valo if (ret) { 5629d8899132SKalle Valo ath12k_warn(ab, "failed to restart vdev %d: %d\n", 5630d8899132SKalle Valo arvif->vdev_id, ret); 5631d8899132SKalle Valo continue; 5632d8899132SKalle Valo } 5633d8899132SKalle Valo 5634d8899132SKalle Valo ret = ath12k_mac_setup_bcn_tmpl(arvif); 5635d8899132SKalle Valo if (ret) 5636d8899132SKalle Valo ath12k_warn(ab, "failed to update bcn tmpl during csa: %d\n", 5637d8899132SKalle Valo ret); 5638d8899132SKalle Valo 5639d8899132SKalle Valo ret = ath12k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, 5640d8899132SKalle Valo arvif->bssid); 5641d8899132SKalle Valo if (ret) { 5642d8899132SKalle Valo ath12k_warn(ab, "failed to bring vdev up %d: %d\n", 5643d8899132SKalle Valo arvif->vdev_id, ret); 5644d8899132SKalle Valo continue; 5645d8899132SKalle Valo } 5646d8899132SKalle Valo } 5647d8899132SKalle Valo 5648d8899132SKalle Valo /* Restart the internal monitor vdev on new channel */ 5649d8899132SKalle Valo if (!monitor_vif && ar->monitor_vdev_created) { 5650d8899132SKalle Valo if (!ath12k_mac_monitor_stop(ar)) 5651d8899132SKalle Valo ath12k_mac_monitor_start(ar); 5652d8899132SKalle Valo } 5653d8899132SKalle Valo } 5654d8899132SKalle Valo 5655d8899132SKalle Valo static void 5656d8899132SKalle Valo ath12k_mac_update_active_vif_chan(struct ath12k *ar, 5657d8899132SKalle Valo struct ieee80211_chanctx_conf *ctx) 5658d8899132SKalle Valo { 5659d8899132SKalle Valo struct ath12k_mac_change_chanctx_arg arg = { .ctx = ctx }; 5660d8899132SKalle Valo 5661d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 5662d8899132SKalle Valo 5663d8899132SKalle Valo ieee80211_iterate_active_interfaces_atomic(ar->hw, 5664d8899132SKalle Valo IEEE80211_IFACE_ITER_NORMAL, 5665d8899132SKalle Valo ath12k_mac_change_chanctx_cnt_iter, 5666d8899132SKalle Valo &arg); 5667d8899132SKalle Valo if (arg.n_vifs == 0) 5668d8899132SKalle Valo return; 5669d8899132SKalle Valo 5670d8899132SKalle Valo arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]), GFP_KERNEL); 5671d8899132SKalle Valo if (!arg.vifs) 5672d8899132SKalle Valo return; 5673d8899132SKalle Valo 5674d8899132SKalle Valo ieee80211_iterate_active_interfaces_atomic(ar->hw, 5675d8899132SKalle Valo IEEE80211_IFACE_ITER_NORMAL, 5676d8899132SKalle Valo ath12k_mac_change_chanctx_fill_iter, 5677d8899132SKalle Valo &arg); 5678d8899132SKalle Valo 5679d8899132SKalle Valo ath12k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs); 5680d8899132SKalle Valo 5681d8899132SKalle Valo kfree(arg.vifs); 5682d8899132SKalle Valo } 5683d8899132SKalle Valo 5684d8899132SKalle Valo static void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw, 5685d8899132SKalle Valo struct ieee80211_chanctx_conf *ctx, 5686d8899132SKalle Valo u32 changed) 5687d8899132SKalle Valo { 5688d8899132SKalle Valo struct ath12k *ar = hw->priv; 5689d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 5690d8899132SKalle Valo 5691d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5692d8899132SKalle Valo 5693d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, 5694d8899132SKalle Valo "mac chanctx change freq %u width %d ptr %pK changed %x\n", 5695d8899132SKalle Valo ctx->def.chan->center_freq, ctx->def.width, ctx, changed); 5696d8899132SKalle Valo 5697d8899132SKalle Valo /* This shouldn't really happen because channel switching should use 5698d8899132SKalle Valo * switch_vif_chanctx(). 5699d8899132SKalle Valo */ 5700d8899132SKalle Valo if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL)) 5701d8899132SKalle Valo goto unlock; 5702d8899132SKalle Valo 5703d8899132SKalle Valo if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) 5704d8899132SKalle Valo ath12k_mac_update_active_vif_chan(ar, ctx); 5705d8899132SKalle Valo 5706d8899132SKalle Valo /* TODO: Recalc radar detection */ 5707d8899132SKalle Valo 5708d8899132SKalle Valo unlock: 5709d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5710d8899132SKalle Valo } 5711d8899132SKalle Valo 5712d8899132SKalle Valo static int ath12k_start_vdev_delay(struct ieee80211_hw *hw, 5713d8899132SKalle Valo struct ieee80211_vif *vif) 5714d8899132SKalle Valo { 5715d8899132SKalle Valo struct ath12k *ar = hw->priv; 5716d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 5717d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 5718d8899132SKalle Valo int ret; 5719d8899132SKalle Valo 5720d8899132SKalle Valo if (WARN_ON(arvif->is_started)) 5721d8899132SKalle Valo return -EBUSY; 5722d8899132SKalle Valo 5723d8899132SKalle Valo ret = ath12k_mac_vdev_start(arvif, &arvif->chanctx.def); 5724d8899132SKalle Valo if (ret) { 5725d8899132SKalle Valo ath12k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n", 5726d8899132SKalle Valo arvif->vdev_id, vif->addr, 5727d8899132SKalle Valo arvif->chanctx.def.chan->center_freq, ret); 5728d8899132SKalle Valo return ret; 5729d8899132SKalle Valo } 5730d8899132SKalle Valo 5731d8899132SKalle Valo if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { 5732d8899132SKalle Valo ret = ath12k_monitor_vdev_up(ar, arvif->vdev_id); 5733d8899132SKalle Valo if (ret) { 5734d8899132SKalle Valo ath12k_warn(ab, "failed put monitor up: %d\n", ret); 5735d8899132SKalle Valo return ret; 5736d8899132SKalle Valo } 5737d8899132SKalle Valo } 5738d8899132SKalle Valo 5739d8899132SKalle Valo arvif->is_started = true; 5740d8899132SKalle Valo 5741d8899132SKalle Valo /* TODO: Setup ps and cts/rts protection */ 5742d8899132SKalle Valo return 0; 5743d8899132SKalle Valo } 5744d8899132SKalle Valo 5745d8899132SKalle Valo static int 5746d8899132SKalle Valo ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, 5747d8899132SKalle Valo struct ieee80211_vif *vif, 5748d8899132SKalle Valo struct ieee80211_bss_conf *link_conf, 5749d8899132SKalle Valo struct ieee80211_chanctx_conf *ctx) 5750d8899132SKalle Valo { 5751d8899132SKalle Valo struct ath12k *ar = hw->priv; 5752d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 5753d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 5754d8899132SKalle Valo int ret; 5755d8899132SKalle Valo struct ath12k_wmi_peer_create_arg param; 5756d8899132SKalle Valo 5757d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5758d8899132SKalle Valo 5759d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, 5760d8899132SKalle Valo "mac chanctx assign ptr %pK vdev_id %i\n", 5761d8899132SKalle Valo ctx, arvif->vdev_id); 5762d8899132SKalle Valo 5763d8899132SKalle Valo /* for some targets bss peer must be created before vdev_start */ 5764d8899132SKalle Valo if (ab->hw_params->vdev_start_delay && 5765d8899132SKalle Valo arvif->vdev_type != WMI_VDEV_TYPE_AP && 5766d8899132SKalle Valo arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && 5767d8899132SKalle Valo !ath12k_peer_exist_by_vdev_id(ab, arvif->vdev_id)) { 5768d8899132SKalle Valo memcpy(&arvif->chanctx, ctx, sizeof(*ctx)); 5769d8899132SKalle Valo ret = 0; 5770d8899132SKalle Valo goto out; 5771d8899132SKalle Valo } 5772d8899132SKalle Valo 5773d8899132SKalle Valo if (WARN_ON(arvif->is_started)) { 5774d8899132SKalle Valo ret = -EBUSY; 5775d8899132SKalle Valo goto out; 5776d8899132SKalle Valo } 5777d8899132SKalle Valo 5778d8899132SKalle Valo if (ab->hw_params->vdev_start_delay && 5779d8899132SKalle Valo (arvif->vdev_type == WMI_VDEV_TYPE_AP || 5780d8899132SKalle Valo arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)) { 5781d8899132SKalle Valo param.vdev_id = arvif->vdev_id; 5782d8899132SKalle Valo param.peer_type = WMI_PEER_TYPE_DEFAULT; 5783d8899132SKalle Valo param.peer_addr = ar->mac_addr; 5784d8899132SKalle Valo 5785d8899132SKalle Valo ret = ath12k_peer_create(ar, arvif, NULL, ¶m); 5786d8899132SKalle Valo if (ret) { 5787d8899132SKalle Valo ath12k_warn(ab, "failed to create peer after vdev start delay: %d", 5788d8899132SKalle Valo ret); 5789d8899132SKalle Valo goto out; 5790d8899132SKalle Valo } 5791d8899132SKalle Valo } 5792d8899132SKalle Valo 5793d8899132SKalle Valo if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { 5794d8899132SKalle Valo ret = ath12k_mac_monitor_start(ar); 5795d8899132SKalle Valo if (ret) 5796d8899132SKalle Valo goto out; 5797d8899132SKalle Valo arvif->is_started = true; 5798d8899132SKalle Valo goto out; 5799d8899132SKalle Valo } 5800d8899132SKalle Valo 5801d8899132SKalle Valo ret = ath12k_mac_vdev_start(arvif, &ctx->def); 5802d8899132SKalle Valo if (ret) { 5803d8899132SKalle Valo ath12k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n", 5804d8899132SKalle Valo arvif->vdev_id, vif->addr, 5805d8899132SKalle Valo ctx->def.chan->center_freq, ret); 5806d8899132SKalle Valo goto out; 5807d8899132SKalle Valo } 5808d8899132SKalle Valo 5809d8899132SKalle Valo if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && ar->monitor_vdev_created) 5810d8899132SKalle Valo ath12k_mac_monitor_start(ar); 5811d8899132SKalle Valo 5812d8899132SKalle Valo arvif->is_started = true; 5813d8899132SKalle Valo 5814d8899132SKalle Valo /* TODO: Setup ps and cts/rts protection */ 5815d8899132SKalle Valo 5816d8899132SKalle Valo out: 5817d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5818d8899132SKalle Valo 5819d8899132SKalle Valo return ret; 5820d8899132SKalle Valo } 5821d8899132SKalle Valo 5822d8899132SKalle Valo static void 5823d8899132SKalle Valo ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, 5824d8899132SKalle Valo struct ieee80211_vif *vif, 5825d8899132SKalle Valo struct ieee80211_bss_conf *link_conf, 5826d8899132SKalle Valo struct ieee80211_chanctx_conf *ctx) 5827d8899132SKalle Valo { 5828d8899132SKalle Valo struct ath12k *ar = hw->priv; 5829d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 5830d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 5831d8899132SKalle Valo int ret; 5832d8899132SKalle Valo 5833d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5834d8899132SKalle Valo 5835d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_MAC, 5836d8899132SKalle Valo "mac chanctx unassign ptr %pK vdev_id %i\n", 5837d8899132SKalle Valo ctx, arvif->vdev_id); 5838d8899132SKalle Valo 5839d8899132SKalle Valo WARN_ON(!arvif->is_started); 5840d8899132SKalle Valo 5841d8899132SKalle Valo if (ab->hw_params->vdev_start_delay && 5842d8899132SKalle Valo arvif->vdev_type == WMI_VDEV_TYPE_MONITOR && 5843d8899132SKalle Valo ath12k_peer_find_by_addr(ab, ar->mac_addr)) 5844d8899132SKalle Valo ath12k_peer_delete(ar, arvif->vdev_id, ar->mac_addr); 5845d8899132SKalle Valo 5846d8899132SKalle Valo if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { 5847d8899132SKalle Valo ret = ath12k_mac_monitor_stop(ar); 5848d8899132SKalle Valo if (ret) { 5849d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5850d8899132SKalle Valo return; 5851d8899132SKalle Valo } 5852d8899132SKalle Valo 5853d8899132SKalle Valo arvif->is_started = false; 5854d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5855d8899132SKalle Valo } 5856d8899132SKalle Valo 5857d8899132SKalle Valo ret = ath12k_mac_vdev_stop(arvif); 5858d8899132SKalle Valo if (ret) 5859d8899132SKalle Valo ath12k_warn(ab, "failed to stop vdev %i: %d\n", 5860d8899132SKalle Valo arvif->vdev_id, ret); 5861d8899132SKalle Valo 5862d8899132SKalle Valo arvif->is_started = false; 5863d8899132SKalle Valo 5864d8899132SKalle Valo if (ab->hw_params->vdev_start_delay && 5865d8899132SKalle Valo arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) 5866d8899132SKalle Valo ath12k_wmi_vdev_down(ar, arvif->vdev_id); 5867d8899132SKalle Valo 5868d8899132SKalle Valo if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && 5869d8899132SKalle Valo ar->num_started_vdevs == 1 && ar->monitor_vdev_created) 5870d8899132SKalle Valo ath12k_mac_monitor_stop(ar); 5871d8899132SKalle Valo 5872d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5873d8899132SKalle Valo } 5874d8899132SKalle Valo 5875d8899132SKalle Valo static int 5876d8899132SKalle Valo ath12k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw, 5877d8899132SKalle Valo struct ieee80211_vif_chanctx_switch *vifs, 5878d8899132SKalle Valo int n_vifs, 5879d8899132SKalle Valo enum ieee80211_chanctx_switch_mode mode) 5880d8899132SKalle Valo { 5881d8899132SKalle Valo struct ath12k *ar = hw->priv; 5882d8899132SKalle Valo 5883d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5884d8899132SKalle Valo 5885d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 5886d8899132SKalle Valo "mac chanctx switch n_vifs %d mode %d\n", 5887d8899132SKalle Valo n_vifs, mode); 5888d8899132SKalle Valo ath12k_mac_update_vif_chan(ar, vifs, n_vifs); 5889d8899132SKalle Valo 5890d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5891d8899132SKalle Valo 5892d8899132SKalle Valo return 0; 5893d8899132SKalle Valo } 5894d8899132SKalle Valo 5895d8899132SKalle Valo static int 5896d8899132SKalle Valo ath12k_set_vdev_param_to_all_vifs(struct ath12k *ar, int param, u32 value) 5897d8899132SKalle Valo { 5898d8899132SKalle Valo struct ath12k_vif *arvif; 5899d8899132SKalle Valo int ret = 0; 5900d8899132SKalle Valo 5901d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 5902d8899132SKalle Valo list_for_each_entry(arvif, &ar->arvifs, list) { 5903d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "setting mac vdev %d param %d value %d\n", 5904d8899132SKalle Valo param, arvif->vdev_id, value); 5905d8899132SKalle Valo 5906d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 5907d8899132SKalle Valo param, value); 5908d8899132SKalle Valo if (ret) { 5909d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set param %d for vdev %d: %d\n", 5910d8899132SKalle Valo param, arvif->vdev_id, ret); 5911d8899132SKalle Valo break; 5912d8899132SKalle Valo } 5913d8899132SKalle Valo } 5914d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 5915d8899132SKalle Valo return ret; 5916d8899132SKalle Valo } 5917d8899132SKalle Valo 5918d8899132SKalle Valo /* mac80211 stores device specific RTS/Fragmentation threshold value, 5919d8899132SKalle Valo * this is set interface specific to firmware from ath12k driver 5920d8899132SKalle Valo */ 5921d8899132SKalle Valo static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 5922d8899132SKalle Valo { 5923d8899132SKalle Valo struct ath12k *ar = hw->priv; 5924d8899132SKalle Valo int param_id = WMI_VDEV_PARAM_RTS_THRESHOLD; 5925d8899132SKalle Valo 5926d8899132SKalle Valo return ath12k_set_vdev_param_to_all_vifs(ar, param_id, value); 5927d8899132SKalle Valo } 5928d8899132SKalle Valo 5929d8899132SKalle Valo static int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) 5930d8899132SKalle Valo { 5931d8899132SKalle Valo /* Even though there's a WMI vdev param for fragmentation threshold no 5932d8899132SKalle Valo * known firmware actually implements it. Moreover it is not possible to 5933d8899132SKalle Valo * rely frame fragmentation to mac80211 because firmware clears the 5934d8899132SKalle Valo * "more fragments" bit in frame control making it impossible for remote 5935d8899132SKalle Valo * devices to reassemble frames. 5936d8899132SKalle Valo * 5937d8899132SKalle Valo * Hence implement a dummy callback just to say fragmentation isn't 5938d8899132SKalle Valo * supported. This effectively prevents mac80211 from doing frame 5939d8899132SKalle Valo * fragmentation in software. 5940d8899132SKalle Valo */ 5941d8899132SKalle Valo return -EOPNOTSUPP; 5942d8899132SKalle Valo } 5943d8899132SKalle Valo 5944d8899132SKalle Valo static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 5945d8899132SKalle Valo u32 queues, bool drop) 5946d8899132SKalle Valo { 5947d8899132SKalle Valo struct ath12k *ar = hw->priv; 5948d8899132SKalle Valo long time_left; 5949d8899132SKalle Valo 5950d8899132SKalle Valo if (drop) 5951d8899132SKalle Valo return; 5952d8899132SKalle Valo 5953d8899132SKalle Valo time_left = wait_event_timeout(ar->dp.tx_empty_waitq, 5954d8899132SKalle Valo (atomic_read(&ar->dp.num_tx_pending) == 0), 5955d8899132SKalle Valo ATH12K_FLUSH_TIMEOUT); 5956d8899132SKalle Valo if (time_left == 0) 5957d8899132SKalle Valo ath12k_warn(ar->ab, "failed to flush transmit queue %ld\n", time_left); 5958d8899132SKalle Valo } 5959d8899132SKalle Valo 5960d8899132SKalle Valo static int 5961d8899132SKalle Valo ath12k_mac_bitrate_mask_num_ht_rates(struct ath12k *ar, 5962d8899132SKalle Valo enum nl80211_band band, 5963d8899132SKalle Valo const struct cfg80211_bitrate_mask *mask) 5964d8899132SKalle Valo { 5965d8899132SKalle Valo int num_rates = 0; 5966d8899132SKalle Valo int i; 5967d8899132SKalle Valo 5968d8899132SKalle Valo for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) 5969d8899132SKalle Valo num_rates += hweight16(mask->control[band].ht_mcs[i]); 5970d8899132SKalle Valo 5971d8899132SKalle Valo return num_rates; 5972d8899132SKalle Valo } 5973d8899132SKalle Valo 5974d8899132SKalle Valo static bool 5975d8899132SKalle Valo ath12k_mac_has_single_legacy_rate(struct ath12k *ar, 5976d8899132SKalle Valo enum nl80211_band band, 5977d8899132SKalle Valo const struct cfg80211_bitrate_mask *mask) 5978d8899132SKalle Valo { 5979d8899132SKalle Valo int num_rates = 0; 5980d8899132SKalle Valo 5981d8899132SKalle Valo num_rates = hweight32(mask->control[band].legacy); 5982d8899132SKalle Valo 5983d8899132SKalle Valo if (ath12k_mac_bitrate_mask_num_ht_rates(ar, band, mask)) 5984d8899132SKalle Valo return false; 5985d8899132SKalle Valo 5986d8899132SKalle Valo if (ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask)) 5987d8899132SKalle Valo return false; 5988d8899132SKalle Valo 5989d8899132SKalle Valo return num_rates == 1; 5990d8899132SKalle Valo } 5991d8899132SKalle Valo 5992d8899132SKalle Valo static bool 5993d8899132SKalle Valo ath12k_mac_bitrate_mask_get_single_nss(struct ath12k *ar, 5994d8899132SKalle Valo enum nl80211_band band, 5995d8899132SKalle Valo const struct cfg80211_bitrate_mask *mask, 5996d8899132SKalle Valo int *nss) 5997d8899132SKalle Valo { 5998d8899132SKalle Valo struct ieee80211_supported_band *sband = &ar->mac.sbands[band]; 5999d8899132SKalle Valo u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map); 6000d8899132SKalle Valo u8 ht_nss_mask = 0; 6001d8899132SKalle Valo u8 vht_nss_mask = 0; 6002d8899132SKalle Valo int i; 6003d8899132SKalle Valo 6004d8899132SKalle Valo /* No need to consider legacy here. Basic rates are always present 6005d8899132SKalle Valo * in bitrate mask 6006d8899132SKalle Valo */ 6007d8899132SKalle Valo 6008d8899132SKalle Valo for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) { 6009d8899132SKalle Valo if (mask->control[band].ht_mcs[i] == 0) 6010d8899132SKalle Valo continue; 6011d8899132SKalle Valo else if (mask->control[band].ht_mcs[i] == 6012d8899132SKalle Valo sband->ht_cap.mcs.rx_mask[i]) 6013d8899132SKalle Valo ht_nss_mask |= BIT(i); 6014d8899132SKalle Valo else 6015d8899132SKalle Valo return false; 6016d8899132SKalle Valo } 6017d8899132SKalle Valo 6018d8899132SKalle Valo for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) { 6019d8899132SKalle Valo if (mask->control[band].vht_mcs[i] == 0) 6020d8899132SKalle Valo continue; 6021d8899132SKalle Valo else if (mask->control[band].vht_mcs[i] == 6022d8899132SKalle Valo ath12k_mac_get_max_vht_mcs_map(vht_mcs_map, i)) 6023d8899132SKalle Valo vht_nss_mask |= BIT(i); 6024d8899132SKalle Valo else 6025d8899132SKalle Valo return false; 6026d8899132SKalle Valo } 6027d8899132SKalle Valo 6028d8899132SKalle Valo if (ht_nss_mask != vht_nss_mask) 6029d8899132SKalle Valo return false; 6030d8899132SKalle Valo 6031d8899132SKalle Valo if (ht_nss_mask == 0) 6032d8899132SKalle Valo return false; 6033d8899132SKalle Valo 6034d8899132SKalle Valo if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask) 6035d8899132SKalle Valo return false; 6036d8899132SKalle Valo 6037d8899132SKalle Valo *nss = fls(ht_nss_mask); 6038d8899132SKalle Valo 6039d8899132SKalle Valo return true; 6040d8899132SKalle Valo } 6041d8899132SKalle Valo 6042d8899132SKalle Valo static int 6043d8899132SKalle Valo ath12k_mac_get_single_legacy_rate(struct ath12k *ar, 6044d8899132SKalle Valo enum nl80211_band band, 6045d8899132SKalle Valo const struct cfg80211_bitrate_mask *mask, 6046d8899132SKalle Valo u32 *rate, u8 *nss) 6047d8899132SKalle Valo { 6048d8899132SKalle Valo int rate_idx; 6049d8899132SKalle Valo u16 bitrate; 6050d8899132SKalle Valo u8 preamble; 6051d8899132SKalle Valo u8 hw_rate; 6052d8899132SKalle Valo 6053d8899132SKalle Valo if (hweight32(mask->control[band].legacy) != 1) 6054d8899132SKalle Valo return -EINVAL; 6055d8899132SKalle Valo 6056d8899132SKalle Valo rate_idx = ffs(mask->control[band].legacy) - 1; 6057d8899132SKalle Valo 6058d8899132SKalle Valo if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) 6059d8899132SKalle Valo rate_idx += ATH12K_MAC_FIRST_OFDM_RATE_IDX; 6060d8899132SKalle Valo 6061d8899132SKalle Valo hw_rate = ath12k_legacy_rates[rate_idx].hw_value; 6062d8899132SKalle Valo bitrate = ath12k_legacy_rates[rate_idx].bitrate; 6063d8899132SKalle Valo 6064d8899132SKalle Valo if (ath12k_mac_bitrate_is_cck(bitrate)) 6065d8899132SKalle Valo preamble = WMI_RATE_PREAMBLE_CCK; 6066d8899132SKalle Valo else 6067d8899132SKalle Valo preamble = WMI_RATE_PREAMBLE_OFDM; 6068d8899132SKalle Valo 6069d8899132SKalle Valo *nss = 1; 6070d8899132SKalle Valo *rate = ATH12K_HW_RATE_CODE(hw_rate, 0, preamble); 6071d8899132SKalle Valo 6072d8899132SKalle Valo return 0; 6073d8899132SKalle Valo } 6074d8899132SKalle Valo 6075d8899132SKalle Valo static int ath12k_mac_set_fixed_rate_params(struct ath12k_vif *arvif, 6076d8899132SKalle Valo u32 rate, u8 nss, u8 sgi, u8 ldpc) 6077d8899132SKalle Valo { 6078d8899132SKalle Valo struct ath12k *ar = arvif->ar; 6079d8899132SKalle Valo u32 vdev_param; 6080d8899132SKalle Valo int ret; 6081d8899132SKalle Valo 6082d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 6083d8899132SKalle Valo 6084d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02x nss %u sgi %u\n", 6085d8899132SKalle Valo arvif->vdev_id, rate, nss, sgi); 6086d8899132SKalle Valo 6087d8899132SKalle Valo vdev_param = WMI_VDEV_PARAM_FIXED_RATE; 6088d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 6089d8899132SKalle Valo vdev_param, rate); 6090d8899132SKalle Valo if (ret) { 6091d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n", 6092d8899132SKalle Valo rate, ret); 6093d8899132SKalle Valo return ret; 6094d8899132SKalle Valo } 6095d8899132SKalle Valo 6096d8899132SKalle Valo vdev_param = WMI_VDEV_PARAM_NSS; 6097d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 6098d8899132SKalle Valo vdev_param, nss); 6099d8899132SKalle Valo if (ret) { 6100d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set nss param %d: %d\n", 6101d8899132SKalle Valo nss, ret); 6102d8899132SKalle Valo return ret; 6103d8899132SKalle Valo } 6104d8899132SKalle Valo 6105d8899132SKalle Valo vdev_param = WMI_VDEV_PARAM_SGI; 6106d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 6107d8899132SKalle Valo vdev_param, sgi); 6108d8899132SKalle Valo if (ret) { 6109d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set sgi param %d: %d\n", 6110d8899132SKalle Valo sgi, ret); 6111d8899132SKalle Valo return ret; 6112d8899132SKalle Valo } 6113d8899132SKalle Valo 6114d8899132SKalle Valo vdev_param = WMI_VDEV_PARAM_LDPC; 6115d8899132SKalle Valo ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, 6116d8899132SKalle Valo vdev_param, ldpc); 6117d8899132SKalle Valo if (ret) { 6118d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set ldpc param %d: %d\n", 6119d8899132SKalle Valo ldpc, ret); 6120d8899132SKalle Valo return ret; 6121d8899132SKalle Valo } 6122d8899132SKalle Valo 6123d8899132SKalle Valo return 0; 6124d8899132SKalle Valo } 6125d8899132SKalle Valo 6126d8899132SKalle Valo static bool 6127d8899132SKalle Valo ath12k_mac_vht_mcs_range_present(struct ath12k *ar, 6128d8899132SKalle Valo enum nl80211_band band, 6129d8899132SKalle Valo const struct cfg80211_bitrate_mask *mask) 6130d8899132SKalle Valo { 6131d8899132SKalle Valo int i; 6132d8899132SKalle Valo u16 vht_mcs; 6133d8899132SKalle Valo 6134d8899132SKalle Valo for (i = 0; i < NL80211_VHT_NSS_MAX; i++) { 6135d8899132SKalle Valo vht_mcs = mask->control[band].vht_mcs[i]; 6136d8899132SKalle Valo 6137d8899132SKalle Valo switch (vht_mcs) { 6138d8899132SKalle Valo case 0: 6139d8899132SKalle Valo case BIT(8) - 1: 6140d8899132SKalle Valo case BIT(9) - 1: 6141d8899132SKalle Valo case BIT(10) - 1: 6142d8899132SKalle Valo break; 6143d8899132SKalle Valo default: 6144d8899132SKalle Valo return false; 6145d8899132SKalle Valo } 6146d8899132SKalle Valo } 6147d8899132SKalle Valo 6148d8899132SKalle Valo return true; 6149d8899132SKalle Valo } 6150d8899132SKalle Valo 6151d8899132SKalle Valo static void ath12k_mac_set_bitrate_mask_iter(void *data, 6152d8899132SKalle Valo struct ieee80211_sta *sta) 6153d8899132SKalle Valo { 6154d8899132SKalle Valo struct ath12k_vif *arvif = data; 6155d8899132SKalle Valo struct ath12k_sta *arsta = (struct ath12k_sta *)sta->drv_priv; 6156d8899132SKalle Valo struct ath12k *ar = arvif->ar; 6157d8899132SKalle Valo 6158d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 6159d8899132SKalle Valo arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED; 6160d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 6161d8899132SKalle Valo 6162d8899132SKalle Valo ieee80211_queue_work(ar->hw, &arsta->update_wk); 6163d8899132SKalle Valo } 6164d8899132SKalle Valo 6165d8899132SKalle Valo static void ath12k_mac_disable_peer_fixed_rate(void *data, 6166d8899132SKalle Valo struct ieee80211_sta *sta) 6167d8899132SKalle Valo { 6168d8899132SKalle Valo struct ath12k_vif *arvif = data; 6169d8899132SKalle Valo struct ath12k *ar = arvif->ar; 6170d8899132SKalle Valo int ret; 6171d8899132SKalle Valo 6172d8899132SKalle Valo ret = ath12k_wmi_set_peer_param(ar, sta->addr, 6173d8899132SKalle Valo arvif->vdev_id, 6174d8899132SKalle Valo WMI_PEER_PARAM_FIXED_RATE, 6175d8899132SKalle Valo WMI_FIXED_RATE_NONE); 6176d8899132SKalle Valo if (ret) 6177d8899132SKalle Valo ath12k_warn(ar->ab, 6178d8899132SKalle Valo "failed to disable peer fixed rate for STA %pM ret %d\n", 6179d8899132SKalle Valo sta->addr, ret); 6180d8899132SKalle Valo } 6181d8899132SKalle Valo 6182d8899132SKalle Valo static int 6183d8899132SKalle Valo ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, 6184d8899132SKalle Valo struct ieee80211_vif *vif, 6185d8899132SKalle Valo const struct cfg80211_bitrate_mask *mask) 6186d8899132SKalle Valo { 6187d8899132SKalle Valo struct ath12k_vif *arvif = (void *)vif->drv_priv; 6188d8899132SKalle Valo struct cfg80211_chan_def def; 6189d8899132SKalle Valo struct ath12k *ar = arvif->ar; 6190d8899132SKalle Valo enum nl80211_band band; 6191d8899132SKalle Valo const u8 *ht_mcs_mask; 6192d8899132SKalle Valo const u16 *vht_mcs_mask; 6193d8899132SKalle Valo u32 rate; 6194d8899132SKalle Valo u8 nss; 6195d8899132SKalle Valo u8 sgi; 6196d8899132SKalle Valo u8 ldpc; 6197d8899132SKalle Valo int single_nss; 6198d8899132SKalle Valo int ret; 6199d8899132SKalle Valo int num_rates; 6200d8899132SKalle Valo 6201d8899132SKalle Valo if (ath12k_mac_vif_chan(vif, &def)) 6202d8899132SKalle Valo return -EPERM; 6203d8899132SKalle Valo 6204d8899132SKalle Valo band = def.chan->band; 6205d8899132SKalle Valo ht_mcs_mask = mask->control[band].ht_mcs; 6206d8899132SKalle Valo vht_mcs_mask = mask->control[band].vht_mcs; 6207d8899132SKalle Valo ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC); 6208d8899132SKalle Valo 6209d8899132SKalle Valo sgi = mask->control[band].gi; 6210d8899132SKalle Valo if (sgi == NL80211_TXRATE_FORCE_LGI) 6211d8899132SKalle Valo return -EINVAL; 6212d8899132SKalle Valo 6213d8899132SKalle Valo /* mac80211 doesn't support sending a fixed HT/VHT MCS alone, rather it 6214d8899132SKalle Valo * requires passing at least one of used basic rates along with them. 6215d8899132SKalle Valo * Fixed rate setting across different preambles(legacy, HT, VHT) is 6216d8899132SKalle Valo * not supported by the FW. Hence use of FIXED_RATE vdev param is not 6217d8899132SKalle Valo * suitable for setting single HT/VHT rates. 6218d8899132SKalle Valo * But, there could be a single basic rate passed from userspace which 6219d8899132SKalle Valo * can be done through the FIXED_RATE param. 6220d8899132SKalle Valo */ 6221d8899132SKalle Valo if (ath12k_mac_has_single_legacy_rate(ar, band, mask)) { 6222d8899132SKalle Valo ret = ath12k_mac_get_single_legacy_rate(ar, band, mask, &rate, 6223d8899132SKalle Valo &nss); 6224d8899132SKalle Valo if (ret) { 6225d8899132SKalle Valo ath12k_warn(ar->ab, "failed to get single legacy rate for vdev %i: %d\n", 6226d8899132SKalle Valo arvif->vdev_id, ret); 6227d8899132SKalle Valo return ret; 6228d8899132SKalle Valo } 6229d8899132SKalle Valo ieee80211_iterate_stations_atomic(ar->hw, 6230d8899132SKalle Valo ath12k_mac_disable_peer_fixed_rate, 6231d8899132SKalle Valo arvif); 6232d8899132SKalle Valo } else if (ath12k_mac_bitrate_mask_get_single_nss(ar, band, mask, 6233d8899132SKalle Valo &single_nss)) { 6234d8899132SKalle Valo rate = WMI_FIXED_RATE_NONE; 6235d8899132SKalle Valo nss = single_nss; 6236d8899132SKalle Valo } else { 6237d8899132SKalle Valo rate = WMI_FIXED_RATE_NONE; 6238d8899132SKalle Valo nss = min_t(u32, ar->num_tx_chains, 6239d8899132SKalle Valo max(ath12k_mac_max_ht_nss(ht_mcs_mask), 6240d8899132SKalle Valo ath12k_mac_max_vht_nss(vht_mcs_mask))); 6241d8899132SKalle Valo 6242d8899132SKalle Valo /* If multiple rates across different preambles are given 6243d8899132SKalle Valo * we can reconfigure this info with all peers using PEER_ASSOC 6244d8899132SKalle Valo * command with the below exception cases. 6245d8899132SKalle Valo * - Single VHT Rate : peer_assoc command accommodates only MCS 6246d8899132SKalle Valo * range values i.e 0-7, 0-8, 0-9 for VHT. Though mac80211 6247d8899132SKalle Valo * mandates passing basic rates along with HT/VHT rates, FW 6248d8899132SKalle Valo * doesn't allow switching from VHT to Legacy. Hence instead of 6249d8899132SKalle Valo * setting legacy and VHT rates using RATEMASK_CMD vdev cmd, 6250d8899132SKalle Valo * we could set this VHT rate as peer fixed rate param, which 6251d8899132SKalle Valo * will override FIXED rate and FW rate control algorithm. 6252d8899132SKalle Valo * If single VHT rate is passed along with HT rates, we select 6253d8899132SKalle Valo * the VHT rate as fixed rate for vht peers. 6254d8899132SKalle Valo * - Multiple VHT Rates : When Multiple VHT rates are given,this 6255d8899132SKalle Valo * can be set using RATEMASK CMD which uses FW rate-ctl alg. 6256d8899132SKalle Valo * TODO: Setting multiple VHT MCS and replacing peer_assoc with 6257d8899132SKalle Valo * RATEMASK_CMDID can cover all use cases of setting rates 6258d8899132SKalle Valo * across multiple preambles and rates within same type. 6259d8899132SKalle Valo * But requires more validation of the command at this point. 6260d8899132SKalle Valo */ 6261d8899132SKalle Valo 6262d8899132SKalle Valo num_rates = ath12k_mac_bitrate_mask_num_vht_rates(ar, band, 6263d8899132SKalle Valo mask); 6264d8899132SKalle Valo 6265d8899132SKalle Valo if (!ath12k_mac_vht_mcs_range_present(ar, band, mask) && 6266d8899132SKalle Valo num_rates > 1) { 6267d8899132SKalle Valo /* TODO: Handle multiple VHT MCS values setting using 6268d8899132SKalle Valo * RATEMASK CMD 6269d8899132SKalle Valo */ 6270d8899132SKalle Valo ath12k_warn(ar->ab, 6271d8899132SKalle Valo "Setting more than one MCS Value in bitrate mask not supported\n"); 6272d8899132SKalle Valo return -EINVAL; 6273d8899132SKalle Valo } 6274d8899132SKalle Valo 6275d8899132SKalle Valo ieee80211_iterate_stations_atomic(ar->hw, 6276d8899132SKalle Valo ath12k_mac_disable_peer_fixed_rate, 6277d8899132SKalle Valo arvif); 6278d8899132SKalle Valo 6279d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 6280d8899132SKalle Valo 6281d8899132SKalle Valo arvif->bitrate_mask = *mask; 6282d8899132SKalle Valo ieee80211_iterate_stations_atomic(ar->hw, 6283d8899132SKalle Valo ath12k_mac_set_bitrate_mask_iter, 6284d8899132SKalle Valo arvif); 6285d8899132SKalle Valo 6286d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 6287d8899132SKalle Valo } 6288d8899132SKalle Valo 6289d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 6290d8899132SKalle Valo 6291d8899132SKalle Valo ret = ath12k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc); 6292d8899132SKalle Valo if (ret) { 6293d8899132SKalle Valo ath12k_warn(ar->ab, "failed to set fixed rate params on vdev %i: %d\n", 6294d8899132SKalle Valo arvif->vdev_id, ret); 6295d8899132SKalle Valo } 6296d8899132SKalle Valo 6297d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 6298d8899132SKalle Valo 6299d8899132SKalle Valo return ret; 6300d8899132SKalle Valo } 6301d8899132SKalle Valo 6302d8899132SKalle Valo static void 6303d8899132SKalle Valo ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, 6304d8899132SKalle Valo enum ieee80211_reconfig_type reconfig_type) 6305d8899132SKalle Valo { 6306d8899132SKalle Valo struct ath12k *ar = hw->priv; 6307d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 6308d8899132SKalle Valo int recovery_count; 6309d8899132SKalle Valo 6310d8899132SKalle Valo if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART) 6311d8899132SKalle Valo return; 6312d8899132SKalle Valo 6313d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 6314d8899132SKalle Valo 6315d8899132SKalle Valo if (ar->state == ATH12K_STATE_RESTARTED) { 6316d8899132SKalle Valo ath12k_warn(ar->ab, "pdev %d successfully recovered\n", 6317d8899132SKalle Valo ar->pdev->pdev_id); 6318d8899132SKalle Valo ar->state = ATH12K_STATE_ON; 6319d8899132SKalle Valo ieee80211_wake_queues(ar->hw); 6320d8899132SKalle Valo 6321d8899132SKalle Valo if (ab->is_reset) { 6322d8899132SKalle Valo recovery_count = atomic_inc_return(&ab->recovery_count); 6323d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_BOOT, "recovery count %d\n", 6324d8899132SKalle Valo recovery_count); 6325d8899132SKalle Valo /* When there are multiple radios in an SOC, 6326d8899132SKalle Valo * the recovery has to be done for each radio 6327d8899132SKalle Valo */ 6328d8899132SKalle Valo if (recovery_count == ab->num_radios) { 6329d8899132SKalle Valo atomic_dec(&ab->reset_count); 6330d8899132SKalle Valo complete(&ab->reset_complete); 6331d8899132SKalle Valo ab->is_reset = false; 6332d8899132SKalle Valo atomic_set(&ab->fail_cont_count, 0); 6333d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_BOOT, "reset success\n"); 6334d8899132SKalle Valo } 6335d8899132SKalle Valo } 6336d8899132SKalle Valo } 6337d8899132SKalle Valo 6338d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 6339d8899132SKalle Valo } 6340d8899132SKalle Valo 6341d8899132SKalle Valo static void 6342d8899132SKalle Valo ath12k_mac_update_bss_chan_survey(struct ath12k *ar, 6343d8899132SKalle Valo struct ieee80211_channel *channel) 6344d8899132SKalle Valo { 6345d8899132SKalle Valo int ret; 6346d8899132SKalle Valo enum wmi_bss_chan_info_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ; 6347d8899132SKalle Valo 6348d8899132SKalle Valo lockdep_assert_held(&ar->conf_mutex); 6349d8899132SKalle Valo 6350d8899132SKalle Valo if (!test_bit(WMI_TLV_SERVICE_BSS_CHANNEL_INFO_64, ar->ab->wmi_ab.svc_map) || 6351d8899132SKalle Valo ar->rx_channel != channel) 6352d8899132SKalle Valo return; 6353d8899132SKalle Valo 6354d8899132SKalle Valo if (ar->scan.state != ATH12K_SCAN_IDLE) { 6355d8899132SKalle Valo ath12k_dbg(ar->ab, ATH12K_DBG_MAC, 6356d8899132SKalle Valo "ignoring bss chan info req while scanning..\n"); 6357d8899132SKalle Valo return; 6358d8899132SKalle Valo } 6359d8899132SKalle Valo 6360d8899132SKalle Valo reinit_completion(&ar->bss_survey_done); 6361d8899132SKalle Valo 6362d8899132SKalle Valo ret = ath12k_wmi_pdev_bss_chan_info_request(ar, type); 6363d8899132SKalle Valo if (ret) { 6364d8899132SKalle Valo ath12k_warn(ar->ab, "failed to send pdev bss chan info request\n"); 6365d8899132SKalle Valo return; 6366d8899132SKalle Valo } 6367d8899132SKalle Valo 6368d8899132SKalle Valo ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ); 6369d8899132SKalle Valo if (ret == 0) 6370d8899132SKalle Valo ath12k_warn(ar->ab, "bss channel survey timed out\n"); 6371d8899132SKalle Valo } 6372d8899132SKalle Valo 6373d8899132SKalle Valo static int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, 6374d8899132SKalle Valo struct survey_info *survey) 6375d8899132SKalle Valo { 6376d8899132SKalle Valo struct ath12k *ar = hw->priv; 6377d8899132SKalle Valo struct ieee80211_supported_band *sband; 6378d8899132SKalle Valo struct survey_info *ar_survey; 6379d8899132SKalle Valo int ret = 0; 6380d8899132SKalle Valo 6381d8899132SKalle Valo if (idx >= ATH12K_NUM_CHANS) 6382d8899132SKalle Valo return -ENOENT; 6383d8899132SKalle Valo 6384d8899132SKalle Valo ar_survey = &ar->survey[idx]; 6385d8899132SKalle Valo 6386d8899132SKalle Valo mutex_lock(&ar->conf_mutex); 6387d8899132SKalle Valo 6388d8899132SKalle Valo sband = hw->wiphy->bands[NL80211_BAND_2GHZ]; 6389d8899132SKalle Valo if (sband && idx >= sband->n_channels) { 6390d8899132SKalle Valo idx -= sband->n_channels; 6391d8899132SKalle Valo sband = NULL; 6392d8899132SKalle Valo } 6393d8899132SKalle Valo 6394d8899132SKalle Valo if (!sband) 6395d8899132SKalle Valo sband = hw->wiphy->bands[NL80211_BAND_5GHZ]; 6396d8899132SKalle Valo 6397d8899132SKalle Valo if (!sband || idx >= sband->n_channels) { 6398d8899132SKalle Valo ret = -ENOENT; 6399d8899132SKalle Valo goto exit; 6400d8899132SKalle Valo } 6401d8899132SKalle Valo 6402d8899132SKalle Valo ath12k_mac_update_bss_chan_survey(ar, &sband->channels[idx]); 6403d8899132SKalle Valo 6404d8899132SKalle Valo spin_lock_bh(&ar->data_lock); 6405d8899132SKalle Valo memcpy(survey, ar_survey, sizeof(*survey)); 6406d8899132SKalle Valo spin_unlock_bh(&ar->data_lock); 6407d8899132SKalle Valo 6408d8899132SKalle Valo survey->channel = &sband->channels[idx]; 6409d8899132SKalle Valo 6410d8899132SKalle Valo if (ar->rx_channel == survey->channel) 6411d8899132SKalle Valo survey->filled |= SURVEY_INFO_IN_USE; 6412d8899132SKalle Valo 6413d8899132SKalle Valo exit: 6414d8899132SKalle Valo mutex_unlock(&ar->conf_mutex); 6415d8899132SKalle Valo return ret; 6416d8899132SKalle Valo } 6417d8899132SKalle Valo 6418d8899132SKalle Valo static void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, 6419d8899132SKalle Valo struct ieee80211_vif *vif, 6420d8899132SKalle Valo struct ieee80211_sta *sta, 6421d8899132SKalle Valo struct station_info *sinfo) 6422d8899132SKalle Valo { 6423d8899132SKalle Valo struct ath12k_sta *arsta = (struct ath12k_sta *)sta->drv_priv; 6424d8899132SKalle Valo 6425d8899132SKalle Valo sinfo->rx_duration = arsta->rx_duration; 6426d8899132SKalle Valo sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); 6427d8899132SKalle Valo 6428d8899132SKalle Valo sinfo->tx_duration = arsta->tx_duration; 6429d8899132SKalle Valo sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); 6430d8899132SKalle Valo 6431d8899132SKalle Valo if (!arsta->txrate.legacy && !arsta->txrate.nss) 6432d8899132SKalle Valo return; 6433d8899132SKalle Valo 6434d8899132SKalle Valo if (arsta->txrate.legacy) { 6435d8899132SKalle Valo sinfo->txrate.legacy = arsta->txrate.legacy; 6436d8899132SKalle Valo } else { 6437d8899132SKalle Valo sinfo->txrate.mcs = arsta->txrate.mcs; 6438d8899132SKalle Valo sinfo->txrate.nss = arsta->txrate.nss; 6439d8899132SKalle Valo sinfo->txrate.bw = arsta->txrate.bw; 6440d8899132SKalle Valo sinfo->txrate.he_gi = arsta->txrate.he_gi; 6441d8899132SKalle Valo sinfo->txrate.he_dcm = arsta->txrate.he_dcm; 6442d8899132SKalle Valo sinfo->txrate.he_ru_alloc = arsta->txrate.he_ru_alloc; 6443d8899132SKalle Valo } 6444d8899132SKalle Valo sinfo->txrate.flags = arsta->txrate.flags; 6445d8899132SKalle Valo sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); 6446d8899132SKalle Valo 6447d8899132SKalle Valo /* TODO: Use real NF instead of default one. */ 6448d8899132SKalle Valo sinfo->signal = arsta->rssi_comb + ATH12K_DEFAULT_NOISE_FLOOR; 6449d8899132SKalle Valo sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); 6450d8899132SKalle Valo } 6451d8899132SKalle Valo 6452d8899132SKalle Valo static const struct ieee80211_ops ath12k_ops = { 6453d8899132SKalle Valo .tx = ath12k_mac_op_tx, 6454d8899132SKalle Valo .wake_tx_queue = ieee80211_handle_wake_tx_queue, 6455d8899132SKalle Valo .start = ath12k_mac_op_start, 6456d8899132SKalle Valo .stop = ath12k_mac_op_stop, 6457d8899132SKalle Valo .reconfig_complete = ath12k_mac_op_reconfig_complete, 6458d8899132SKalle Valo .add_interface = ath12k_mac_op_add_interface, 6459d8899132SKalle Valo .remove_interface = ath12k_mac_op_remove_interface, 6460d8899132SKalle Valo .update_vif_offload = ath12k_mac_op_update_vif_offload, 6461d8899132SKalle Valo .config = ath12k_mac_op_config, 6462d8899132SKalle Valo .bss_info_changed = ath12k_mac_op_bss_info_changed, 6463d8899132SKalle Valo .configure_filter = ath12k_mac_op_configure_filter, 6464d8899132SKalle Valo .hw_scan = ath12k_mac_op_hw_scan, 6465d8899132SKalle Valo .cancel_hw_scan = ath12k_mac_op_cancel_hw_scan, 6466d8899132SKalle Valo .set_key = ath12k_mac_op_set_key, 6467d8899132SKalle Valo .sta_state = ath12k_mac_op_sta_state, 6468d8899132SKalle Valo .sta_set_txpwr = ath12k_mac_op_sta_set_txpwr, 6469d8899132SKalle Valo .sta_rc_update = ath12k_mac_op_sta_rc_update, 6470d8899132SKalle Valo .conf_tx = ath12k_mac_op_conf_tx, 6471d8899132SKalle Valo .set_antenna = ath12k_mac_op_set_antenna, 6472d8899132SKalle Valo .get_antenna = ath12k_mac_op_get_antenna, 6473d8899132SKalle Valo .ampdu_action = ath12k_mac_op_ampdu_action, 6474d8899132SKalle Valo .add_chanctx = ath12k_mac_op_add_chanctx, 6475d8899132SKalle Valo .remove_chanctx = ath12k_mac_op_remove_chanctx, 6476d8899132SKalle Valo .change_chanctx = ath12k_mac_op_change_chanctx, 6477d8899132SKalle Valo .assign_vif_chanctx = ath12k_mac_op_assign_vif_chanctx, 6478d8899132SKalle Valo .unassign_vif_chanctx = ath12k_mac_op_unassign_vif_chanctx, 6479d8899132SKalle Valo .switch_vif_chanctx = ath12k_mac_op_switch_vif_chanctx, 6480d8899132SKalle Valo .set_rts_threshold = ath12k_mac_op_set_rts_threshold, 6481d8899132SKalle Valo .set_frag_threshold = ath12k_mac_op_set_frag_threshold, 6482d8899132SKalle Valo .set_bitrate_mask = ath12k_mac_op_set_bitrate_mask, 6483d8899132SKalle Valo .get_survey = ath12k_mac_op_get_survey, 6484d8899132SKalle Valo .flush = ath12k_mac_op_flush, 6485d8899132SKalle Valo .sta_statistics = ath12k_mac_op_sta_statistics, 6486d8899132SKalle Valo }; 6487d8899132SKalle Valo 6488d8899132SKalle Valo static void ath12k_mac_update_ch_list(struct ath12k *ar, 6489d8899132SKalle Valo struct ieee80211_supported_band *band, 6490d8899132SKalle Valo u32 freq_low, u32 freq_high) 6491d8899132SKalle Valo { 6492d8899132SKalle Valo int i; 6493d8899132SKalle Valo 6494d8899132SKalle Valo if (!(freq_low && freq_high)) 6495d8899132SKalle Valo return; 6496d8899132SKalle Valo 6497d8899132SKalle Valo for (i = 0; i < band->n_channels; i++) { 6498d8899132SKalle Valo if (band->channels[i].center_freq < freq_low || 6499d8899132SKalle Valo band->channels[i].center_freq > freq_high) 6500d8899132SKalle Valo band->channels[i].flags |= IEEE80211_CHAN_DISABLED; 6501d8899132SKalle Valo } 6502d8899132SKalle Valo } 6503d8899132SKalle Valo 6504d8899132SKalle Valo static u32 ath12k_get_phy_id(struct ath12k *ar, u32 band) 6505d8899132SKalle Valo { 6506d8899132SKalle Valo struct ath12k_pdev *pdev = ar->pdev; 6507d8899132SKalle Valo struct ath12k_pdev_cap *pdev_cap = &pdev->cap; 6508d8899132SKalle Valo 6509d8899132SKalle Valo if (band == WMI_HOST_WLAN_2G_CAP) 6510d8899132SKalle Valo return pdev_cap->band[NL80211_BAND_2GHZ].phy_id; 6511d8899132SKalle Valo 6512d8899132SKalle Valo if (band == WMI_HOST_WLAN_5G_CAP) 6513d8899132SKalle Valo return pdev_cap->band[NL80211_BAND_5GHZ].phy_id; 6514d8899132SKalle Valo 6515d8899132SKalle Valo ath12k_warn(ar->ab, "unsupported phy cap:%d\n", band); 6516d8899132SKalle Valo 6517d8899132SKalle Valo return 0; 6518d8899132SKalle Valo } 6519d8899132SKalle Valo 6520d8899132SKalle Valo static int ath12k_mac_setup_channels_rates(struct ath12k *ar, 6521d8899132SKalle Valo u32 supported_bands) 6522d8899132SKalle Valo { 6523d8899132SKalle Valo struct ieee80211_supported_band *band; 6524d8899132SKalle Valo struct ath12k_wmi_hal_reg_capabilities_ext_arg *reg_cap; 6525d8899132SKalle Valo void *channels; 6526d8899132SKalle Valo u32 phy_id; 6527d8899132SKalle Valo 6528d8899132SKalle Valo BUILD_BUG_ON((ARRAY_SIZE(ath12k_2ghz_channels) + 6529d8899132SKalle Valo ARRAY_SIZE(ath12k_5ghz_channels) + 6530d8899132SKalle Valo ARRAY_SIZE(ath12k_6ghz_channels)) != 6531d8899132SKalle Valo ATH12K_NUM_CHANS); 6532d8899132SKalle Valo 6533d8899132SKalle Valo reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx]; 6534d8899132SKalle Valo 6535d8899132SKalle Valo if (supported_bands & WMI_HOST_WLAN_2G_CAP) { 6536d8899132SKalle Valo channels = kmemdup(ath12k_2ghz_channels, 6537d8899132SKalle Valo sizeof(ath12k_2ghz_channels), 6538d8899132SKalle Valo GFP_KERNEL); 6539d8899132SKalle Valo if (!channels) 6540d8899132SKalle Valo return -ENOMEM; 6541d8899132SKalle Valo 6542d8899132SKalle Valo band = &ar->mac.sbands[NL80211_BAND_2GHZ]; 6543d8899132SKalle Valo band->band = NL80211_BAND_2GHZ; 6544d8899132SKalle Valo band->n_channels = ARRAY_SIZE(ath12k_2ghz_channels); 6545d8899132SKalle Valo band->channels = channels; 6546d8899132SKalle Valo band->n_bitrates = ath12k_g_rates_size; 6547d8899132SKalle Valo band->bitrates = ath12k_g_rates; 6548d8899132SKalle Valo ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band; 6549d8899132SKalle Valo 6550d8899132SKalle Valo if (ar->ab->hw_params->single_pdev_only) { 6551d8899132SKalle Valo phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_2G_CAP); 6552d8899132SKalle Valo reg_cap = &ar->ab->hal_reg_cap[phy_id]; 6553d8899132SKalle Valo } 6554d8899132SKalle Valo ath12k_mac_update_ch_list(ar, band, 6555d8899132SKalle Valo reg_cap->low_2ghz_chan, 6556d8899132SKalle Valo reg_cap->high_2ghz_chan); 6557d8899132SKalle Valo } 6558d8899132SKalle Valo 6559d8899132SKalle Valo if (supported_bands & WMI_HOST_WLAN_5G_CAP) { 6560d8899132SKalle Valo if (reg_cap->high_5ghz_chan >= ATH12K_MAX_6G_FREQ) { 6561d8899132SKalle Valo channels = kmemdup(ath12k_6ghz_channels, 6562d8899132SKalle Valo sizeof(ath12k_6ghz_channels), GFP_KERNEL); 6563d8899132SKalle Valo if (!channels) { 6564d8899132SKalle Valo kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels); 6565d8899132SKalle Valo return -ENOMEM; 6566d8899132SKalle Valo } 6567d8899132SKalle Valo 6568d8899132SKalle Valo ar->supports_6ghz = true; 6569d8899132SKalle Valo band = &ar->mac.sbands[NL80211_BAND_6GHZ]; 6570d8899132SKalle Valo band->band = NL80211_BAND_6GHZ; 6571d8899132SKalle Valo band->n_channels = ARRAY_SIZE(ath12k_6ghz_channels); 6572d8899132SKalle Valo band->channels = channels; 6573d8899132SKalle Valo band->n_bitrates = ath12k_a_rates_size; 6574d8899132SKalle Valo band->bitrates = ath12k_a_rates; 6575d8899132SKalle Valo ar->hw->wiphy->bands[NL80211_BAND_6GHZ] = band; 6576d8899132SKalle Valo ath12k_mac_update_ch_list(ar, band, 6577d8899132SKalle Valo reg_cap->low_5ghz_chan, 6578d8899132SKalle Valo reg_cap->high_5ghz_chan); 6579d8899132SKalle Valo } 6580d8899132SKalle Valo 6581d8899132SKalle Valo if (reg_cap->low_5ghz_chan < ATH12K_MIN_6G_FREQ) { 6582d8899132SKalle Valo channels = kmemdup(ath12k_5ghz_channels, 6583d8899132SKalle Valo sizeof(ath12k_5ghz_channels), 6584d8899132SKalle Valo GFP_KERNEL); 6585d8899132SKalle Valo if (!channels) { 6586d8899132SKalle Valo kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels); 6587d8899132SKalle Valo kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels); 6588d8899132SKalle Valo return -ENOMEM; 6589d8899132SKalle Valo } 6590d8899132SKalle Valo 6591d8899132SKalle Valo band = &ar->mac.sbands[NL80211_BAND_5GHZ]; 6592d8899132SKalle Valo band->band = NL80211_BAND_5GHZ; 6593d8899132SKalle Valo band->n_channels = ARRAY_SIZE(ath12k_5ghz_channels); 6594d8899132SKalle Valo band->channels = channels; 6595d8899132SKalle Valo band->n_bitrates = ath12k_a_rates_size; 6596d8899132SKalle Valo band->bitrates = ath12k_a_rates; 6597d8899132SKalle Valo ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band; 6598d8899132SKalle Valo 6599d8899132SKalle Valo if (ar->ab->hw_params->single_pdev_only) { 6600d8899132SKalle Valo phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_5G_CAP); 6601d8899132SKalle Valo reg_cap = &ar->ab->hal_reg_cap[phy_id]; 6602d8899132SKalle Valo } 6603d8899132SKalle Valo 6604d8899132SKalle Valo ath12k_mac_update_ch_list(ar, band, 6605d8899132SKalle Valo reg_cap->low_5ghz_chan, 6606d8899132SKalle Valo reg_cap->high_5ghz_chan); 6607d8899132SKalle Valo } 6608d8899132SKalle Valo } 6609d8899132SKalle Valo 6610d8899132SKalle Valo return 0; 6611d8899132SKalle Valo } 6612d8899132SKalle Valo 6613d8899132SKalle Valo static int ath12k_mac_setup_iface_combinations(struct ath12k *ar) 6614d8899132SKalle Valo { 6615d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 6616d8899132SKalle Valo struct ieee80211_iface_combination *combinations; 6617d8899132SKalle Valo struct ieee80211_iface_limit *limits; 6618d8899132SKalle Valo int n_limits, max_interfaces; 6619d8899132SKalle Valo bool ap, mesh; 6620d8899132SKalle Valo 6621d8899132SKalle Valo ap = ab->hw_params->interface_modes & BIT(NL80211_IFTYPE_AP); 6622d8899132SKalle Valo 6623d8899132SKalle Valo mesh = IS_ENABLED(CONFIG_MAC80211_MESH) && 6624d8899132SKalle Valo ab->hw_params->interface_modes & BIT(NL80211_IFTYPE_MESH_POINT); 6625d8899132SKalle Valo 6626d8899132SKalle Valo combinations = kzalloc(sizeof(*combinations), GFP_KERNEL); 6627d8899132SKalle Valo if (!combinations) 6628d8899132SKalle Valo return -ENOMEM; 6629d8899132SKalle Valo 6630d8899132SKalle Valo if (ap || mesh) { 6631d8899132SKalle Valo n_limits = 2; 6632d8899132SKalle Valo max_interfaces = 16; 6633d8899132SKalle Valo } else { 6634d8899132SKalle Valo n_limits = 1; 6635d8899132SKalle Valo max_interfaces = 1; 6636d8899132SKalle Valo } 6637d8899132SKalle Valo 6638d8899132SKalle Valo limits = kcalloc(n_limits, sizeof(*limits), GFP_KERNEL); 6639d8899132SKalle Valo if (!limits) { 6640d8899132SKalle Valo kfree(combinations); 6641d8899132SKalle Valo return -ENOMEM; 6642d8899132SKalle Valo } 6643d8899132SKalle Valo 6644d8899132SKalle Valo limits[0].max = 1; 6645d8899132SKalle Valo limits[0].types |= BIT(NL80211_IFTYPE_STATION); 6646d8899132SKalle Valo 6647d8899132SKalle Valo if (ap) { 6648d8899132SKalle Valo limits[1].max = max_interfaces; 6649d8899132SKalle Valo limits[1].types |= BIT(NL80211_IFTYPE_AP); 6650d8899132SKalle Valo } 6651d8899132SKalle Valo 6652d8899132SKalle Valo if (mesh) 6653d8899132SKalle Valo limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT); 6654d8899132SKalle Valo 6655d8899132SKalle Valo combinations[0].limits = limits; 6656d8899132SKalle Valo combinations[0].n_limits = n_limits; 6657d8899132SKalle Valo combinations[0].max_interfaces = max_interfaces; 6658d8899132SKalle Valo combinations[0].num_different_channels = 1; 6659d8899132SKalle Valo combinations[0].beacon_int_infra_match = true; 6660d8899132SKalle Valo combinations[0].beacon_int_min_gcd = 100; 6661d8899132SKalle Valo combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | 6662d8899132SKalle Valo BIT(NL80211_CHAN_WIDTH_20) | 6663d8899132SKalle Valo BIT(NL80211_CHAN_WIDTH_40) | 6664d8899132SKalle Valo BIT(NL80211_CHAN_WIDTH_80); 6665d8899132SKalle Valo 6666d8899132SKalle Valo ar->hw->wiphy->iface_combinations = combinations; 6667d8899132SKalle Valo ar->hw->wiphy->n_iface_combinations = 1; 6668d8899132SKalle Valo 6669d8899132SKalle Valo return 0; 6670d8899132SKalle Valo } 6671d8899132SKalle Valo 6672d8899132SKalle Valo static const u8 ath12k_if_types_ext_capa[] = { 6673d8899132SKalle Valo [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, 6674d8899132SKalle Valo [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, 6675d8899132SKalle Valo }; 6676d8899132SKalle Valo 6677d8899132SKalle Valo static const u8 ath12k_if_types_ext_capa_sta[] = { 6678d8899132SKalle Valo [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, 6679d8899132SKalle Valo [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, 6680d8899132SKalle Valo [9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT, 6681d8899132SKalle Valo }; 6682d8899132SKalle Valo 6683d8899132SKalle Valo static const u8 ath12k_if_types_ext_capa_ap[] = { 6684d8899132SKalle Valo [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, 6685d8899132SKalle Valo [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, 6686d8899132SKalle Valo [9] = WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT, 6687d8899132SKalle Valo }; 6688d8899132SKalle Valo 6689d8899132SKalle Valo static const struct wiphy_iftype_ext_capab ath12k_iftypes_ext_capa[] = { 6690d8899132SKalle Valo { 6691d8899132SKalle Valo .extended_capabilities = ath12k_if_types_ext_capa, 6692d8899132SKalle Valo .extended_capabilities_mask = ath12k_if_types_ext_capa, 6693d8899132SKalle Valo .extended_capabilities_len = sizeof(ath12k_if_types_ext_capa), 6694d8899132SKalle Valo }, { 6695d8899132SKalle Valo .iftype = NL80211_IFTYPE_STATION, 6696d8899132SKalle Valo .extended_capabilities = ath12k_if_types_ext_capa_sta, 6697d8899132SKalle Valo .extended_capabilities_mask = ath12k_if_types_ext_capa_sta, 6698d8899132SKalle Valo .extended_capabilities_len = 6699d8899132SKalle Valo sizeof(ath12k_if_types_ext_capa_sta), 6700d8899132SKalle Valo }, { 6701d8899132SKalle Valo .iftype = NL80211_IFTYPE_AP, 6702d8899132SKalle Valo .extended_capabilities = ath12k_if_types_ext_capa_ap, 6703d8899132SKalle Valo .extended_capabilities_mask = ath12k_if_types_ext_capa_ap, 6704d8899132SKalle Valo .extended_capabilities_len = 6705d8899132SKalle Valo sizeof(ath12k_if_types_ext_capa_ap), 6706d8899132SKalle Valo }, 6707d8899132SKalle Valo }; 6708d8899132SKalle Valo 6709d8899132SKalle Valo static void __ath12k_mac_unregister(struct ath12k *ar) 6710d8899132SKalle Valo { 6711d8899132SKalle Valo cancel_work_sync(&ar->regd_update_work); 6712d8899132SKalle Valo 6713d8899132SKalle Valo ieee80211_unregister_hw(ar->hw); 6714d8899132SKalle Valo 6715d8899132SKalle Valo idr_for_each(&ar->txmgmt_idr, ath12k_mac_tx_mgmt_pending_free, ar); 6716d8899132SKalle Valo idr_destroy(&ar->txmgmt_idr); 6717d8899132SKalle Valo 6718d8899132SKalle Valo kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels); 6719d8899132SKalle Valo kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels); 6720d8899132SKalle Valo kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels); 6721d8899132SKalle Valo 6722d8899132SKalle Valo kfree(ar->hw->wiphy->iface_combinations[0].limits); 6723d8899132SKalle Valo kfree(ar->hw->wiphy->iface_combinations); 6724d8899132SKalle Valo 6725d8899132SKalle Valo SET_IEEE80211_DEV(ar->hw, NULL); 6726d8899132SKalle Valo } 6727d8899132SKalle Valo 6728d8899132SKalle Valo void ath12k_mac_unregister(struct ath12k_base *ab) 6729d8899132SKalle Valo { 6730d8899132SKalle Valo struct ath12k *ar; 6731d8899132SKalle Valo struct ath12k_pdev *pdev; 6732d8899132SKalle Valo int i; 6733d8899132SKalle Valo 6734d8899132SKalle Valo for (i = 0; i < ab->num_radios; i++) { 6735d8899132SKalle Valo pdev = &ab->pdevs[i]; 6736d8899132SKalle Valo ar = pdev->ar; 6737d8899132SKalle Valo if (!ar) 6738d8899132SKalle Valo continue; 6739d8899132SKalle Valo 6740d8899132SKalle Valo __ath12k_mac_unregister(ar); 6741d8899132SKalle Valo } 6742d8899132SKalle Valo } 6743d8899132SKalle Valo 6744d8899132SKalle Valo static int __ath12k_mac_register(struct ath12k *ar) 6745d8899132SKalle Valo { 6746d8899132SKalle Valo struct ath12k_base *ab = ar->ab; 6747d8899132SKalle Valo struct ath12k_pdev_cap *cap = &ar->pdev->cap; 6748d8899132SKalle Valo static const u32 cipher_suites[] = { 6749d8899132SKalle Valo WLAN_CIPHER_SUITE_TKIP, 6750d8899132SKalle Valo WLAN_CIPHER_SUITE_CCMP, 6751d8899132SKalle Valo WLAN_CIPHER_SUITE_AES_CMAC, 6752d8899132SKalle Valo WLAN_CIPHER_SUITE_BIP_CMAC_256, 6753d8899132SKalle Valo WLAN_CIPHER_SUITE_BIP_GMAC_128, 6754d8899132SKalle Valo WLAN_CIPHER_SUITE_BIP_GMAC_256, 6755d8899132SKalle Valo WLAN_CIPHER_SUITE_GCMP, 6756d8899132SKalle Valo WLAN_CIPHER_SUITE_GCMP_256, 6757d8899132SKalle Valo WLAN_CIPHER_SUITE_CCMP_256, 6758d8899132SKalle Valo }; 6759d8899132SKalle Valo int ret; 6760d8899132SKalle Valo u32 ht_cap = 0; 6761d8899132SKalle Valo 6762d8899132SKalle Valo ath12k_pdev_caps_update(ar); 6763d8899132SKalle Valo 6764d8899132SKalle Valo SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr); 6765d8899132SKalle Valo 6766d8899132SKalle Valo SET_IEEE80211_DEV(ar->hw, ab->dev); 6767d8899132SKalle Valo 6768d8899132SKalle Valo ret = ath12k_mac_setup_channels_rates(ar, 6769d8899132SKalle Valo cap->supported_bands); 6770d8899132SKalle Valo if (ret) 6771d8899132SKalle Valo goto err; 6772d8899132SKalle Valo 6773d8899132SKalle Valo ath12k_mac_setup_ht_vht_cap(ar, cap, &ht_cap); 6774d8899132SKalle Valo ath12k_mac_setup_he_cap(ar, cap); 6775d8899132SKalle Valo 6776d8899132SKalle Valo ret = ath12k_mac_setup_iface_combinations(ar); 6777d8899132SKalle Valo if (ret) { 6778d8899132SKalle Valo ath12k_err(ar->ab, "failed to setup interface combinations: %d\n", ret); 6779d8899132SKalle Valo goto err_free_channels; 6780d8899132SKalle Valo } 6781d8899132SKalle Valo 6782d8899132SKalle Valo ar->hw->wiphy->available_antennas_rx = cap->rx_chain_mask; 6783d8899132SKalle Valo ar->hw->wiphy->available_antennas_tx = cap->tx_chain_mask; 6784d8899132SKalle Valo 6785d8899132SKalle Valo ar->hw->wiphy->interface_modes = ab->hw_params->interface_modes; 6786d8899132SKalle Valo 6787d8899132SKalle Valo ieee80211_hw_set(ar->hw, SIGNAL_DBM); 6788d8899132SKalle Valo ieee80211_hw_set(ar->hw, SUPPORTS_PS); 6789d8899132SKalle Valo ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS); 6790d8899132SKalle Valo ieee80211_hw_set(ar->hw, MFP_CAPABLE); 6791d8899132SKalle Valo ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS); 6792d8899132SKalle Valo ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL); 6793d8899132SKalle Valo ieee80211_hw_set(ar->hw, AP_LINK_PS); 6794d8899132SKalle Valo ieee80211_hw_set(ar->hw, SPECTRUM_MGMT); 6795d8899132SKalle Valo ieee80211_hw_set(ar->hw, CONNECTION_MONITOR); 6796d8899132SKalle Valo ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK); 6797d8899132SKalle Valo ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA); 6798d8899132SKalle Valo ieee80211_hw_set(ar->hw, QUEUE_CONTROL); 6799d8899132SKalle Valo ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG); 6800d8899132SKalle Valo ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK); 6801d8899132SKalle Valo 6802d8899132SKalle Valo if (ht_cap & WMI_HT_CAP_ENABLED) { 6803d8899132SKalle Valo ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION); 6804d8899132SKalle Valo ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW); 6805d8899132SKalle Valo ieee80211_hw_set(ar->hw, SUPPORTS_REORDERING_BUFFER); 6806d8899132SKalle Valo ieee80211_hw_set(ar->hw, SUPPORTS_AMSDU_IN_AMPDU); 6807d8899132SKalle Valo ieee80211_hw_set(ar->hw, USES_RSS); 6808d8899132SKalle Valo } 6809d8899132SKalle Valo 6810d8899132SKalle Valo ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; 6811d8899132SKalle Valo ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 6812d8899132SKalle Valo 6813d8899132SKalle Valo /* TODO: Check if HT capability advertised from firmware is different 6814d8899132SKalle Valo * for each band for a dual band capable radio. It will be tricky to 6815d8899132SKalle Valo * handle it when the ht capability different for each band. 6816d8899132SKalle Valo */ 6817d8899132SKalle Valo if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS) 6818d8899132SKalle Valo ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS; 6819d8899132SKalle Valo 6820d8899132SKalle Valo ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID; 6821d8899132SKalle Valo ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN; 6822d8899132SKalle Valo 6823d8899132SKalle Valo ar->hw->max_listen_interval = ATH12K_MAX_HW_LISTEN_INTERVAL; 6824d8899132SKalle Valo 6825d8899132SKalle Valo ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 6826d8899132SKalle Valo ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; 6827d8899132SKalle Valo ar->hw->wiphy->max_remain_on_channel_duration = 5000; 6828d8899132SKalle Valo 6829d8899132SKalle Valo ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; 6830d8899132SKalle Valo ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE | 6831d8899132SKalle Valo NL80211_FEATURE_AP_SCAN; 6832d8899132SKalle Valo 6833d8899132SKalle Valo ar->max_num_stations = TARGET_NUM_STATIONS; 6834d8899132SKalle Valo ar->max_num_peers = TARGET_NUM_PEERS_PDEV; 6835d8899132SKalle Valo 6836d8899132SKalle Valo ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations; 6837d8899132SKalle Valo 6838d8899132SKalle Valo ar->hw->queues = ATH12K_HW_MAX_QUEUES; 6839d8899132SKalle Valo ar->hw->wiphy->tx_queue_len = ATH12K_QUEUE_LEN; 6840d8899132SKalle Valo ar->hw->offchannel_tx_hw_queue = ATH12K_HW_MAX_QUEUES - 1; 6841d8899132SKalle Valo ar->hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE; 6842d8899132SKalle Valo 6843d8899132SKalle Valo ar->hw->vif_data_size = sizeof(struct ath12k_vif); 6844d8899132SKalle Valo ar->hw->sta_data_size = sizeof(struct ath12k_sta); 6845d8899132SKalle Valo 6846d8899132SKalle Valo wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); 6847d8899132SKalle Valo wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_STA_TX_PWR); 6848d8899132SKalle Valo 6849d8899132SKalle Valo ar->hw->wiphy->cipher_suites = cipher_suites; 6850d8899132SKalle Valo ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 6851d8899132SKalle Valo 6852d8899132SKalle Valo ar->hw->wiphy->iftype_ext_capab = ath12k_iftypes_ext_capa; 6853d8899132SKalle Valo ar->hw->wiphy->num_iftype_ext_capab = 6854d8899132SKalle Valo ARRAY_SIZE(ath12k_iftypes_ext_capa); 6855d8899132SKalle Valo 6856d8899132SKalle Valo if (ar->supports_6ghz) { 6857d8899132SKalle Valo wiphy_ext_feature_set(ar->hw->wiphy, 6858d8899132SKalle Valo NL80211_EXT_FEATURE_FILS_DISCOVERY); 6859d8899132SKalle Valo wiphy_ext_feature_set(ar->hw->wiphy, 6860d8899132SKalle Valo NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP); 6861d8899132SKalle Valo } 6862d8899132SKalle Valo 6863d8899132SKalle Valo ath12k_reg_init(ar); 6864d8899132SKalle Valo 6865d8899132SKalle Valo if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) { 6866d8899132SKalle Valo ar->hw->netdev_features = NETIF_F_HW_CSUM; 6867d8899132SKalle Valo ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL); 6868d8899132SKalle Valo ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT); 6869d8899132SKalle Valo } 6870d8899132SKalle Valo 6871d8899132SKalle Valo ret = ieee80211_register_hw(ar->hw); 6872d8899132SKalle Valo if (ret) { 6873d8899132SKalle Valo ath12k_err(ar->ab, "ieee80211 registration failed: %d\n", ret); 6874d8899132SKalle Valo goto err_free_if_combs; 6875d8899132SKalle Valo } 6876d8899132SKalle Valo 6877d8899132SKalle Valo if (!ab->hw_params->supports_monitor) 6878d8899132SKalle Valo /* There's a race between calling ieee80211_register_hw() 6879d8899132SKalle Valo * and here where the monitor mode is enabled for a little 6880d8899132SKalle Valo * while. But that time is so short and in practise it make 6881d8899132SKalle Valo * a difference in real life. 6882d8899132SKalle Valo */ 6883d8899132SKalle Valo ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); 6884d8899132SKalle Valo 6885d8899132SKalle Valo /* Apply the regd received during initialization */ 6886d8899132SKalle Valo ret = ath12k_regd_update(ar, true); 6887d8899132SKalle Valo if (ret) { 6888d8899132SKalle Valo ath12k_err(ar->ab, "ath12k regd update failed: %d\n", ret); 6889d8899132SKalle Valo goto err_unregister_hw; 6890d8899132SKalle Valo } 6891d8899132SKalle Valo 6892d8899132SKalle Valo return 0; 6893d8899132SKalle Valo 6894d8899132SKalle Valo err_unregister_hw: 6895d8899132SKalle Valo ieee80211_unregister_hw(ar->hw); 6896d8899132SKalle Valo 6897d8899132SKalle Valo err_free_if_combs: 6898d8899132SKalle Valo kfree(ar->hw->wiphy->iface_combinations[0].limits); 6899d8899132SKalle Valo kfree(ar->hw->wiphy->iface_combinations); 6900d8899132SKalle Valo 6901d8899132SKalle Valo err_free_channels: 6902d8899132SKalle Valo kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels); 6903d8899132SKalle Valo kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels); 6904d8899132SKalle Valo kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels); 6905d8899132SKalle Valo 6906d8899132SKalle Valo err: 6907d8899132SKalle Valo SET_IEEE80211_DEV(ar->hw, NULL); 6908d8899132SKalle Valo return ret; 6909d8899132SKalle Valo } 6910d8899132SKalle Valo 6911d8899132SKalle Valo int ath12k_mac_register(struct ath12k_base *ab) 6912d8899132SKalle Valo { 6913d8899132SKalle Valo struct ath12k *ar; 6914d8899132SKalle Valo struct ath12k_pdev *pdev; 6915d8899132SKalle Valo int i; 6916d8899132SKalle Valo int ret; 6917d8899132SKalle Valo 6918d8899132SKalle Valo if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags)) 6919d8899132SKalle Valo return 0; 6920d8899132SKalle Valo 6921d8899132SKalle Valo for (i = 0; i < ab->num_radios; i++) { 6922d8899132SKalle Valo pdev = &ab->pdevs[i]; 6923d8899132SKalle Valo ar = pdev->ar; 6924d8899132SKalle Valo if (ab->pdevs_macaddr_valid) { 6925d8899132SKalle Valo ether_addr_copy(ar->mac_addr, pdev->mac_addr); 6926d8899132SKalle Valo } else { 6927d8899132SKalle Valo ether_addr_copy(ar->mac_addr, ab->mac_addr); 6928d8899132SKalle Valo ar->mac_addr[4] += i; 6929d8899132SKalle Valo } 6930d8899132SKalle Valo 6931d8899132SKalle Valo ret = __ath12k_mac_register(ar); 6932d8899132SKalle Valo if (ret) 6933d8899132SKalle Valo goto err_cleanup; 6934d8899132SKalle Valo 6935d8899132SKalle Valo idr_init(&ar->txmgmt_idr); 6936d8899132SKalle Valo spin_lock_init(&ar->txmgmt_idr_lock); 6937d8899132SKalle Valo } 6938d8899132SKalle Valo 6939d8899132SKalle Valo /* Initialize channel counters frequency value in hertz */ 6940d8899132SKalle Valo ab->cc_freq_hz = 320000; 6941d8899132SKalle Valo ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS)) - 1; 6942d8899132SKalle Valo 6943d8899132SKalle Valo return 0; 6944d8899132SKalle Valo 6945d8899132SKalle Valo err_cleanup: 6946d8899132SKalle Valo for (i = i - 1; i >= 0; i--) { 6947d8899132SKalle Valo pdev = &ab->pdevs[i]; 6948d8899132SKalle Valo ar = pdev->ar; 6949d8899132SKalle Valo __ath12k_mac_unregister(ar); 6950d8899132SKalle Valo } 6951d8899132SKalle Valo 6952d8899132SKalle Valo return ret; 6953d8899132SKalle Valo } 6954d8899132SKalle Valo 6955d8899132SKalle Valo int ath12k_mac_allocate(struct ath12k_base *ab) 6956d8899132SKalle Valo { 6957d8899132SKalle Valo struct ieee80211_hw *hw; 6958d8899132SKalle Valo struct ath12k *ar; 6959d8899132SKalle Valo struct ath12k_pdev *pdev; 6960d8899132SKalle Valo int ret; 6961d8899132SKalle Valo int i; 6962d8899132SKalle Valo 6963d8899132SKalle Valo if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags)) 6964d8899132SKalle Valo return 0; 6965d8899132SKalle Valo 6966d8899132SKalle Valo for (i = 0; i < ab->num_radios; i++) { 6967d8899132SKalle Valo pdev = &ab->pdevs[i]; 6968d8899132SKalle Valo hw = ieee80211_alloc_hw(sizeof(struct ath12k), &ath12k_ops); 6969d8899132SKalle Valo if (!hw) { 6970d8899132SKalle Valo ath12k_warn(ab, "failed to allocate mac80211 hw device\n"); 6971d8899132SKalle Valo ret = -ENOMEM; 6972d8899132SKalle Valo goto err_free_mac; 6973d8899132SKalle Valo } 6974d8899132SKalle Valo 6975d8899132SKalle Valo ar = hw->priv; 6976d8899132SKalle Valo ar->hw = hw; 6977d8899132SKalle Valo ar->ab = ab; 6978d8899132SKalle Valo ar->pdev = pdev; 6979d8899132SKalle Valo ar->pdev_idx = i; 6980d8899132SKalle Valo ar->lmac_id = ath12k_hw_get_mac_from_pdev_id(ab->hw_params, i); 6981d8899132SKalle Valo 6982d8899132SKalle Valo ar->wmi = &ab->wmi_ab.wmi[i]; 6983d8899132SKalle Valo /* FIXME: wmi[0] is already initialized during attach, 6984d8899132SKalle Valo * Should we do this again? 6985d8899132SKalle Valo */ 6986d8899132SKalle Valo ath12k_wmi_pdev_attach(ab, i); 6987d8899132SKalle Valo 6988d8899132SKalle Valo ar->cfg_tx_chainmask = pdev->cap.tx_chain_mask; 6989d8899132SKalle Valo ar->cfg_rx_chainmask = pdev->cap.rx_chain_mask; 6990d8899132SKalle Valo ar->num_tx_chains = hweight32(pdev->cap.tx_chain_mask); 6991d8899132SKalle Valo ar->num_rx_chains = hweight32(pdev->cap.rx_chain_mask); 6992d8899132SKalle Valo 6993d8899132SKalle Valo pdev->ar = ar; 6994d8899132SKalle Valo spin_lock_init(&ar->data_lock); 6995d8899132SKalle Valo INIT_LIST_HEAD(&ar->arvifs); 6996d8899132SKalle Valo INIT_LIST_HEAD(&ar->ppdu_stats_info); 6997d8899132SKalle Valo mutex_init(&ar->conf_mutex); 6998d8899132SKalle Valo init_completion(&ar->vdev_setup_done); 6999d8899132SKalle Valo init_completion(&ar->vdev_delete_done); 7000d8899132SKalle Valo init_completion(&ar->peer_assoc_done); 7001d8899132SKalle Valo init_completion(&ar->peer_delete_done); 7002d8899132SKalle Valo init_completion(&ar->install_key_done); 7003d8899132SKalle Valo init_completion(&ar->bss_survey_done); 7004d8899132SKalle Valo init_completion(&ar->scan.started); 7005d8899132SKalle Valo init_completion(&ar->scan.completed); 7006d8899132SKalle Valo 7007d8899132SKalle Valo INIT_DELAYED_WORK(&ar->scan.timeout, ath12k_scan_timeout_work); 7008d8899132SKalle Valo INIT_WORK(&ar->regd_update_work, ath12k_regd_update_work); 7009d8899132SKalle Valo 7010d8899132SKalle Valo INIT_WORK(&ar->wmi_mgmt_tx_work, ath12k_mgmt_over_wmi_tx_work); 7011d8899132SKalle Valo skb_queue_head_init(&ar->wmi_mgmt_tx_queue); 7012d8899132SKalle Valo clear_bit(ATH12K_FLAG_MONITOR_ENABLED, &ar->monitor_flags); 7013d8899132SKalle Valo } 7014d8899132SKalle Valo 7015d8899132SKalle Valo return 0; 7016d8899132SKalle Valo 7017d8899132SKalle Valo err_free_mac: 7018d8899132SKalle Valo ath12k_mac_destroy(ab); 7019d8899132SKalle Valo 7020d8899132SKalle Valo return ret; 7021d8899132SKalle Valo } 7022d8899132SKalle Valo 7023d8899132SKalle Valo void ath12k_mac_destroy(struct ath12k_base *ab) 7024d8899132SKalle Valo { 7025d8899132SKalle Valo struct ath12k *ar; 7026d8899132SKalle Valo struct ath12k_pdev *pdev; 7027d8899132SKalle Valo int i; 7028d8899132SKalle Valo 7029d8899132SKalle Valo for (i = 0; i < ab->num_radios; i++) { 7030d8899132SKalle Valo pdev = &ab->pdevs[i]; 7031d8899132SKalle Valo ar = pdev->ar; 7032d8899132SKalle Valo if (!ar) 7033d8899132SKalle Valo continue; 7034d8899132SKalle Valo 7035d8899132SKalle Valo ieee80211_free_hw(ar->hw); 7036d8899132SKalle Valo pdev->ar = NULL; 7037d8899132SKalle Valo } 7038d8899132SKalle Valo } 7039