blob: 83cc8778ca1e31aabf5a5f56c6a0520d10216706 [file] [log] [blame]
Kalle Valof0553ca2019-02-19 19:45:26 +02001// SPDX-License-Identifier: ISC
Kalle Valo5e3dd152013-06-12 20:52:10 +03002/*
3 * Copyright (c) 2005-2011 Atheros Communications Inc.
Kalle Valo8b1083d2017-12-22 18:31:13 +02004 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
Rakesh Pillai6e8a8992019-01-25 09:51:06 +05305 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
Kalle Valo5e3dd152013-06-12 20:52:10 +03006 */
7
8#include "mac.h"
9
Sven Eckelmann34d56292018-08-24 15:04:59 +030010#include <net/cfg80211.h>
Kalle Valo5e3dd152013-06-12 20:52:10 +030011#include <net/mac80211.h>
12#include <linux/etherdevice.h>
Bartosz Markowski209b2a62016-09-28 15:11:58 +030013#include <linux/acpi.h>
Bhagavathi Perumal S84758d42018-12-20 14:26:00 +020014#include <linux/of.h>
Wen Gong13829932019-10-01 15:04:56 +030015#include <linux/bitfield.h>
Kalle Valo5e3dd152013-06-12 20:52:10 +030016
Michal Kazior8cd13ca2013-07-16 09:38:54 +020017#include "hif.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030018#include "core.h"
19#include "debug.h"
20#include "wmi.h"
21#include "htt.h"
22#include "txrx.h"
Kalle Valo43d2a302014-09-10 18:23:30 +030023#include "testmode.h"
Michal Kaziorb4aa5392015-03-31 10:26:24 +000024#include "wmi-tlv.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020025#include "wmi-ops.h"
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +020026#include "wow.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030027
Michal Kaziordcc33092015-03-30 09:51:54 +030028/*********/
29/* Rates */
30/*********/
31
Michal Kaziordcc33092015-03-30 09:51:54 +030032static struct ieee80211_rate ath10k_rates[] = {
Michal Kazior5528e032015-03-30 09:51:56 +030033 { .bitrate = 10,
34 .hw_value = ATH10K_HW_RATE_CCK_LP_1M },
35 { .bitrate = 20,
36 .hw_value = ATH10K_HW_RATE_CCK_LP_2M,
37 .hw_value_short = ATH10K_HW_RATE_CCK_SP_2M,
38 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
39 { .bitrate = 55,
40 .hw_value = ATH10K_HW_RATE_CCK_LP_5_5M,
41 .hw_value_short = ATH10K_HW_RATE_CCK_SP_5_5M,
42 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
43 { .bitrate = 110,
44 .hw_value = ATH10K_HW_RATE_CCK_LP_11M,
45 .hw_value_short = ATH10K_HW_RATE_CCK_SP_11M,
46 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
Michal Kazior5653b392015-03-30 09:51:54 +030047
Michal Kazioraf001482015-03-30 09:51:56 +030048 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
49 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
50 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
51 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
52 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
53 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
54 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
55 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
Michal Kaziordcc33092015-03-30 09:51:54 +030056};
57
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +030058static struct ieee80211_rate ath10k_rates_rev2[] = {
59 { .bitrate = 10,
60 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_1M },
61 { .bitrate = 20,
62 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_2M,
63 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_2M,
64 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
65 { .bitrate = 55,
66 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
67 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
68 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
69 { .bitrate = 110,
70 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_11M,
71 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_11M,
72 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
73
74 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
75 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
76 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
77 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
78 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
79 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
80 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
81 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
82};
83
Michal Kazior8d7aa6b2015-03-30 09:51:57 +030084#define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
85
86#define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
87#define ath10k_a_rates_size (ARRAY_SIZE(ath10k_rates) - \
88 ATH10K_MAC_FIRST_OFDM_RATE_IDX)
Michal Kaziordcc33092015-03-30 09:51:54 +030089#define ath10k_g_rates (ath10k_rates + 0)
90#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
91
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +030092#define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
93#define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
94
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +030095#define ath10k_wmi_legacy_rates ath10k_rates
96
Michal Kazior486017c2015-03-30 09:51:54 +030097static bool ath10k_mac_bitrate_is_cck(int bitrate)
98{
99 switch (bitrate) {
100 case 10:
101 case 20:
102 case 55:
103 case 110:
104 return true;
105 }
106
107 return false;
108}
109
110static u8 ath10k_mac_bitrate_to_rate(int bitrate)
111{
112 return DIV_ROUND_UP(bitrate, 5) |
113 (ath10k_mac_bitrate_is_cck(bitrate) ? BIT(7) : 0);
114}
115
Michal Kazior5528e032015-03-30 09:51:56 +0300116u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
Yanbo Li4b7f3532015-11-12 10:36:10 -0800117 u8 hw_rate, bool cck)
Michal Kazior5528e032015-03-30 09:51:56 +0300118{
119 const struct ieee80211_rate *rate;
120 int i;
121
122 for (i = 0; i < sband->n_bitrates; i++) {
123 rate = &sband->bitrates[i];
124
Yanbo Li4b7f3532015-11-12 10:36:10 -0800125 if (ath10k_mac_bitrate_is_cck(rate->bitrate) != cck)
126 continue;
127
Michal Kazior5528e032015-03-30 09:51:56 +0300128 if (rate->hw_value == hw_rate)
129 return i;
130 else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
131 rate->hw_value_short == hw_rate)
132 return i;
133 }
134
135 return 0;
136}
137
Michal Kazior01cebe12015-03-30 09:51:56 +0300138u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
139 u32 bitrate)
140{
141 int i;
142
143 for (i = 0; i < sband->n_bitrates; i++)
144 if (sband->bitrates[i].bitrate == bitrate)
145 return i;
146
147 return 0;
148}
149
Sriram Rf279294e2018-09-10 11:09:40 +0530150static int ath10k_mac_get_rate_hw_value(int bitrate)
151{
152 int i;
153 u8 hw_value_prefix = 0;
154
155 if (ath10k_mac_bitrate_is_cck(bitrate))
156 hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;
157
Sriram R34e141e2018-10-03 08:43:50 +0530158 for (i = 0; i < ARRAY_SIZE(ath10k_rates); i++) {
Sriram Rf279294e2018-09-10 11:09:40 +0530159 if (ath10k_rates[i].bitrate == bitrate)
160 return hw_value_prefix | ath10k_rates[i].hw_value;
161 }
162
163 return -EINVAL;
164}
165
Michal Kazior3ae54222015-03-31 10:49:20 +0000166static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
167{
168 switch ((mcs_map >> (2 * nss)) & 0x3) {
169 case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;
170 case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;
171 case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;
172 }
173 return 0;
174}
175
Michal Kazior45c9abc2015-04-21 20:42:58 +0300176static u32
177ath10k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
178{
179 int nss;
180
181 for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--)
182 if (ht_mcs_mask[nss])
183 return nss + 1;
184
185 return 1;
186}
187
188static u32
189ath10k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
190{
191 int nss;
192
193 for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--)
194 if (vht_mcs_mask[nss])
195 return nss + 1;
196
197 return 1;
198}
Kalle Valo5e3dd152013-06-12 20:52:10 +0300199
Raja Mani7e247a92016-04-12 20:15:53 +0530200int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val)
201{
202 enum wmi_host_platform_type platform_type;
203 int ret;
204
205 if (test_bit(WMI_SERVICE_TX_MODE_DYNAMIC, ar->wmi.svc_map))
206 platform_type = WMI_HOST_PLATFORM_LOW_PERF;
207 else
208 platform_type = WMI_HOST_PLATFORM_HIGH_PERF;
209
210 ret = ath10k_wmi_ext_resource_config(ar, platform_type, val);
211
212 if (ret && ret != -EOPNOTSUPP) {
213 ath10k_warn(ar, "failed to configure ext resource: %d\n", ret);
214 return ret;
215 }
216
217 return 0;
218}
219
Kalle Valo5e3dd152013-06-12 20:52:10 +0300220/**********/
221/* Crypto */
222/**********/
223
224static int ath10k_send_key(struct ath10k_vif *arvif,
225 struct ieee80211_key_conf *key,
226 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100227 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300228{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200229 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300230 struct wmi_vdev_install_key_arg arg = {
231 .vdev_id = arvif->vdev_id,
232 .key_idx = key->keyidx,
233 .key_len = key->keylen,
234 .key_data = key->key,
Michal Kazior370e5672015-02-18 14:02:26 +0100235 .key_flags = flags,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300236 .macaddr = macaddr,
237 };
238
Michal Kazior548db542013-07-05 16:15:15 +0300239 lockdep_assert_held(&arvif->ar->conf_mutex);
240
Kalle Valo5e3dd152013-06-12 20:52:10 +0300241 switch (key->cipher) {
242 case WLAN_CIPHER_SUITE_CCMP:
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200243 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM];
Marek Kwaczynskie4e82e92015-01-24 12:14:53 +0200244 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300245 break;
246 case WLAN_CIPHER_SUITE_TKIP:
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200247 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_TKIP];
Kalle Valo5e3dd152013-06-12 20:52:10 +0300248 arg.key_txmic_len = 8;
249 arg.key_rxmic_len = 8;
250 break;
251 case WLAN_CIPHER_SUITE_WEP40:
252 case WLAN_CIPHER_SUITE_WEP104:
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200253 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_WEP];
Kalle Valo5e3dd152013-06-12 20:52:10 +0300254 break;
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -0700255 case WLAN_CIPHER_SUITE_CCMP_256:
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200256 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM];
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -0700257 break;
258 case WLAN_CIPHER_SUITE_GCMP:
259 case WLAN_CIPHER_SUITE_GCMP_256:
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200260 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_GCM];
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -0700261 break;
262 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
263 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
264 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
Johannes Berg3cb10942015-01-22 21:38:45 +0100265 case WLAN_CIPHER_SUITE_AES_CMAC:
Bartosz Markowskid7131c02015-03-10 14:32:19 +0100266 WARN_ON(1);
267 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300268 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200269 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300270 return -EOPNOTSUPP;
271 }
272
Kalle Valob9e284e2015-10-05 17:56:35 +0300273 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
David Liuccec9032015-07-24 20:25:32 +0300274 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
David Liuccec9032015-07-24 20:25:32 +0300275
Kalle Valo5e3dd152013-06-12 20:52:10 +0300276 if (cmd == DISABLE_KEY) {
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200277 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_NONE];
Kalle Valo5e3dd152013-06-12 20:52:10 +0300278 arg.key_data = NULL;
279 }
280
281 return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
282}
283
284static int ath10k_install_key(struct ath10k_vif *arvif,
285 struct ieee80211_key_conf *key,
286 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100287 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300288{
289 struct ath10k *ar = arvif->ar;
290 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300291 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300292
Michal Kazior548db542013-07-05 16:15:15 +0300293 lockdep_assert_held(&ar->conf_mutex);
294
Wolfram Sang16735d02013-11-14 14:32:02 -0800295 reinit_completion(&ar->install_key_done);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300296
David Liuccec9032015-07-24 20:25:32 +0300297 if (arvif->nohwcrypt)
298 return 1;
299
Michal Kazior370e5672015-02-18 14:02:26 +0100300 ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300301 if (ret)
302 return ret;
303
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300304 time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);
305 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300306 return -ETIMEDOUT;
307
308 return 0;
309}
310
311static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
312 const u8 *addr)
313{
314 struct ath10k *ar = arvif->ar;
315 struct ath10k_peer *peer;
316 int ret;
317 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100318 u32 flags;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300319
320 lockdep_assert_held(&ar->conf_mutex);
321
Michal Kazior8674d902015-08-13 14:10:46 +0200322 if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP &&
Peter Oh7c97b722015-12-03 09:50:55 -0800323 arvif->vif->type != NL80211_IFTYPE_ADHOC &&
324 arvif->vif->type != NL80211_IFTYPE_MESH_POINT))
Michal Kazior8674d902015-08-13 14:10:46 +0200325 return -EINVAL;
326
Kalle Valo5e3dd152013-06-12 20:52:10 +0300327 spin_lock_bh(&ar->data_lock);
328 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
329 spin_unlock_bh(&ar->data_lock);
330
331 if (!peer)
332 return -ENOENT;
333
334 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
335 if (arvif->wep_keys[i] == NULL)
336 continue;
Michal Kazior370e5672015-02-18 14:02:26 +0100337
Michal Kazior8674d902015-08-13 14:10:46 +0200338 switch (arvif->vif->type) {
339 case NL80211_IFTYPE_AP:
340 flags = WMI_KEY_PAIRWISE;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300341
Michal Kazior8674d902015-08-13 14:10:46 +0200342 if (arvif->def_wep_key_idx == i)
343 flags |= WMI_KEY_TX_USAGE;
Michal Kaziorce90b272015-04-10 13:23:21 +0000344
Michal Kazior8674d902015-08-13 14:10:46 +0200345 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
346 SET_KEY, addr, flags);
347 if (ret < 0)
348 return ret;
349 break;
350 case NL80211_IFTYPE_ADHOC:
351 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
352 SET_KEY, addr,
353 WMI_KEY_PAIRWISE);
354 if (ret < 0)
355 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300356
Michal Kazior8674d902015-08-13 14:10:46 +0200357 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
358 SET_KEY, addr, WMI_KEY_GROUP);
359 if (ret < 0)
360 return ret;
361 break;
362 default:
363 WARN_ON(1);
364 return -EINVAL;
365 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300366
Sujith Manoharanae167132014-11-25 11:46:59 +0530367 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300368 peer->keys[i] = arvif->wep_keys[i];
Sujith Manoharanae167132014-11-25 11:46:59 +0530369 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300370 }
371
Michal Kaziorce90b272015-04-10 13:23:21 +0000372 /* In some cases (notably with static WEP IBSS with multiple keys)
373 * multicast Tx becomes broken. Both pairwise and groupwise keys are
374 * installed already. Using WMI_KEY_TX_USAGE in different combinations
375 * didn't seem help. Using def_keyid vdev parameter seems to be
376 * effective so use that.
377 *
378 * FIXME: Revisit. Perhaps this can be done in a less hacky way.
379 */
Michal Kazior8674d902015-08-13 14:10:46 +0200380 if (arvif->vif->type != NL80211_IFTYPE_ADHOC)
381 return 0;
382
Michal Kaziorce90b272015-04-10 13:23:21 +0000383 if (arvif->def_wep_key_idx == -1)
384 return 0;
385
386 ret = ath10k_wmi_vdev_set_param(arvif->ar,
387 arvif->vdev_id,
388 arvif->ar->wmi.vdev_param->def_keyid,
389 arvif->def_wep_key_idx);
390 if (ret) {
391 ath10k_warn(ar, "failed to re-set def wpa key idxon vdev %i: %d\n",
392 arvif->vdev_id, ret);
393 return ret;
394 }
395
Kalle Valo5e3dd152013-06-12 20:52:10 +0300396 return 0;
397}
398
399static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
400 const u8 *addr)
401{
402 struct ath10k *ar = arvif->ar;
403 struct ath10k_peer *peer;
404 int first_errno = 0;
405 int ret;
406 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100407 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300408
409 lockdep_assert_held(&ar->conf_mutex);
410
411 spin_lock_bh(&ar->data_lock);
412 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
413 spin_unlock_bh(&ar->data_lock);
414
415 if (!peer)
416 return -ENOENT;
417
418 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
419 if (peer->keys[i] == NULL)
420 continue;
421
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200422 /* key flags are not required to delete the key */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300423 ret = ath10k_install_key(arvif, peer->keys[i],
Michal Kazior370e5672015-02-18 14:02:26 +0100424 DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300425 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300426 first_errno = ret;
427
David Liuccec9032015-07-24 20:25:32 +0300428 if (ret < 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200429 ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300430 i, ret);
431
Sujith Manoharanae167132014-11-25 11:46:59 +0530432 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300433 peer->keys[i] = NULL;
Sujith Manoharanae167132014-11-25 11:46:59 +0530434 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300435 }
436
437 return first_errno;
438}
439
Sujith Manoharan504f6cd2014-11-25 11:46:58 +0530440bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
441 u8 keyidx)
442{
443 struct ath10k_peer *peer;
444 int i;
445
446 lockdep_assert_held(&ar->data_lock);
447
448 /* We don't know which vdev this peer belongs to,
449 * since WMI doesn't give us that information.
450 *
451 * FIXME: multi-bss needs to be handled.
452 */
453 peer = ath10k_peer_find(ar, 0, addr);
454 if (!peer)
455 return false;
456
457 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
458 if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)
459 return true;
460 }
461
462 return false;
463}
464
Kalle Valo5e3dd152013-06-12 20:52:10 +0300465static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
466 struct ieee80211_key_conf *key)
467{
468 struct ath10k *ar = arvif->ar;
469 struct ath10k_peer *peer;
470 u8 addr[ETH_ALEN];
471 int first_errno = 0;
472 int ret;
473 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100474 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300475
476 lockdep_assert_held(&ar->conf_mutex);
477
478 for (;;) {
479 /* since ath10k_install_key we can't hold data_lock all the
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +0100480 * time, so we try to remove the keys incrementally
481 */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300482 spin_lock_bh(&ar->data_lock);
483 i = 0;
484 list_for_each_entry(peer, &ar->peers, list) {
485 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
486 if (peer->keys[i] == key) {
Kalle Valob25f32c2014-09-14 12:50:49 +0300487 ether_addr_copy(addr, peer->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300488 peer->keys[i] = NULL;
489 break;
490 }
491 }
492
493 if (i < ARRAY_SIZE(peer->keys))
494 break;
495 }
496 spin_unlock_bh(&ar->data_lock);
497
498 if (i == ARRAY_SIZE(peer->keys))
499 break;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200500 /* key flags are not required to delete the key */
Michal Kazior370e5672015-02-18 14:02:26 +0100501 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300502 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300503 first_errno = ret;
504
505 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200506 ath10k_warn(ar, "failed to remove key for %pM: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +0200507 addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300508 }
509
510 return first_errno;
511}
512
Michal Kaziorad325cb2015-02-18 14:02:27 +0100513static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
514 struct ieee80211_key_conf *key)
515{
516 struct ath10k *ar = arvif->ar;
517 struct ath10k_peer *peer;
518 int ret;
519
520 lockdep_assert_held(&ar->conf_mutex);
521
522 list_for_each_entry(peer, &ar->peers, list) {
Kalle Valoc178da52016-04-13 14:13:49 +0300523 if (ether_addr_equal(peer->addr, arvif->vif->addr))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100524 continue;
525
Kalle Valoc178da52016-04-13 14:13:49 +0300526 if (ether_addr_equal(peer->addr, arvif->bssid))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100527 continue;
528
529 if (peer->keys[key->keyidx] == key)
530 continue;
531
532 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
533 arvif->vdev_id, key->keyidx);
534
535 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
536 if (ret) {
537 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
538 arvif->vdev_id, peer->addr, ret);
539 return ret;
540 }
541 }
542
543 return 0;
544}
545
Kalle Valo5e3dd152013-06-12 20:52:10 +0300546/*********************/
547/* General utilities */
548/*********************/
549
550static inline enum wmi_phy_mode
551chan_to_phymode(const struct cfg80211_chan_def *chandef)
552{
553 enum wmi_phy_mode phymode = MODE_UNKNOWN;
554
555 switch (chandef->chan->band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +0200556 case NL80211_BAND_2GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300557 switch (chandef->width) {
558 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800559 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
560 phymode = MODE_11B;
561 else
562 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300563 break;
564 case NL80211_CHAN_WIDTH_20:
565 phymode = MODE_11NG_HT20;
566 break;
567 case NL80211_CHAN_WIDTH_40:
568 phymode = MODE_11NG_HT40;
569 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400570 case NL80211_CHAN_WIDTH_5:
571 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300572 case NL80211_CHAN_WIDTH_80:
573 case NL80211_CHAN_WIDTH_80P80:
574 case NL80211_CHAN_WIDTH_160:
575 phymode = MODE_UNKNOWN;
576 break;
577 }
578 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +0200579 case NL80211_BAND_5GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300580 switch (chandef->width) {
581 case NL80211_CHAN_WIDTH_20_NOHT:
582 phymode = MODE_11A;
583 break;
584 case NL80211_CHAN_WIDTH_20:
585 phymode = MODE_11NA_HT20;
586 break;
587 case NL80211_CHAN_WIDTH_40:
588 phymode = MODE_11NA_HT40;
589 break;
590 case NL80211_CHAN_WIDTH_80:
591 phymode = MODE_11AC_VHT80;
592 break;
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +0200593 case NL80211_CHAN_WIDTH_160:
594 phymode = MODE_11AC_VHT160;
595 break;
596 case NL80211_CHAN_WIDTH_80P80:
597 phymode = MODE_11AC_VHT80_80;
598 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400599 case NL80211_CHAN_WIDTH_5:
600 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300601 phymode = MODE_UNKNOWN;
602 break;
603 }
604 break;
605 default:
606 break;
607 }
608
609 WARN_ON(phymode == MODE_UNKNOWN);
610 return phymode;
611}
612
613static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
614{
615/*
616 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
617 * 0 for no restriction
618 * 1 for 1/4 us
619 * 2 for 1/2 us
620 * 3 for 1 us
621 * 4 for 2 us
622 * 5 for 4 us
623 * 6 for 8 us
624 * 7 for 16 us
625 */
626 switch (mpdudensity) {
627 case 0:
628 return 0;
629 case 1:
630 case 2:
631 case 3:
632 /* Our lower layer calculations limit our precision to
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +0100633 * 1 microsecond
634 */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300635 return 1;
636 case 4:
637 return 2;
638 case 5:
639 return 4;
640 case 6:
641 return 8;
642 case 7:
643 return 16;
644 default:
645 return 0;
646 }
647}
648
Michal Kazior500ff9f2015-03-31 10:26:21 +0000649int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
650 struct cfg80211_chan_def *def)
651{
652 struct ieee80211_chanctx_conf *conf;
653
654 rcu_read_lock();
655 conf = rcu_dereference(vif->chanctx_conf);
656 if (!conf) {
657 rcu_read_unlock();
658 return -ENOENT;
659 }
660
661 *def = conf->def;
662 rcu_read_unlock();
663
664 return 0;
665}
666
667static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,
668 struct ieee80211_chanctx_conf *conf,
669 void *data)
670{
671 int *num = data;
672
673 (*num)++;
674}
675
676static int ath10k_mac_num_chanctxs(struct ath10k *ar)
677{
678 int num = 0;
679
680 ieee80211_iter_chan_contexts_atomic(ar->hw,
681 ath10k_mac_num_chanctxs_iter,
682 &num);
683
684 return num;
685}
686
687static void
688ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
689 struct ieee80211_chanctx_conf *conf,
690 void *data)
691{
692 struct cfg80211_chan_def **def = data;
693
694 *def = &conf->def;
695}
696
Dundi Ravitejac6f537a2019-06-03 17:41:51 +0300697static void ath10k_wait_for_peer_delete_done(struct ath10k *ar, u32 vdev_id,
698 const u8 *addr)
699{
700 unsigned long time_left;
701 int ret;
702
703 if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) {
704 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
705 if (ret) {
706 ath10k_warn(ar, "failed wait for peer deleted");
707 return;
708 }
709
710 time_left = wait_for_completion_timeout(&ar->peer_delete_done,
711 5 * HZ);
712 if (!time_left)
713 ath10k_warn(ar, "Timeout in receiving peer delete response\n");
714 }
715}
716
Michal Kazior69427262016-03-06 16:14:30 +0200717static int ath10k_peer_create(struct ath10k *ar,
718 struct ieee80211_vif *vif,
719 struct ieee80211_sta *sta,
720 u32 vdev_id,
721 const u8 *addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300722 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300723{
Michal Kaziore04cafb2015-08-05 12:15:24 +0200724 struct ath10k_vif *arvif;
Michal Kazior69427262016-03-06 16:14:30 +0200725 struct ath10k_peer *peer;
Michal Kaziore04cafb2015-08-05 12:15:24 +0200726 int num_peers = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300727 int ret;
728
729 lockdep_assert_held(&ar->conf_mutex);
730
Michal Kaziore04cafb2015-08-05 12:15:24 +0200731 num_peers = ar->num_peers;
732
733 /* Each vdev consumes a peer entry as well */
734 list_for_each_entry(arvif, &ar->arvifs, list)
735 num_peers++;
736
737 if (num_peers >= ar->max_num_peers)
Michal Kaziorcfd10612014-11-25 15:16:05 +0100738 return -ENOBUFS;
739
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300740 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800741 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200742 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200743 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300744 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800745 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300746
747 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800748 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200749 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200750 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300751 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800752 }
Michal Kazior292a7532014-11-25 15:16:04 +0100753
Michal Kazior69427262016-03-06 16:14:30 +0200754 spin_lock_bh(&ar->data_lock);
755
756 peer = ath10k_peer_find(ar, vdev_id, addr);
757 if (!peer) {
Ben Greearfee48cf2016-04-01 14:12:12 -0700758 spin_unlock_bh(&ar->data_lock);
Michal Kazior69427262016-03-06 16:14:30 +0200759 ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n",
760 addr, vdev_id);
Dundi Ravitejac6f537a2019-06-03 17:41:51 +0300761 ath10k_wait_for_peer_delete_done(ar, vdev_id, addr);
Michal Kazior69427262016-03-06 16:14:30 +0200762 return -ENOENT;
763 }
764
765 peer->vif = vif;
766 peer->sta = sta;
767
768 spin_unlock_bh(&ar->data_lock);
769
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100770 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300771
772 return 0;
773}
774
Kalle Valo5a13e762014-01-20 11:01:46 +0200775static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
776{
777 struct ath10k *ar = arvif->ar;
778 u32 param;
779 int ret;
780
781 param = ar->wmi.pdev_param->sta_kickout_th;
782 ret = ath10k_wmi_pdev_set_param(ar, param,
783 ATH10K_KICKOUT_THRESHOLD);
784 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200785 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200786 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200787 return ret;
788 }
789
790 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
791 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
792 ATH10K_KEEPALIVE_MIN_IDLE);
793 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200794 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200795 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200796 return ret;
797 }
798
799 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
800 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
801 ATH10K_KEEPALIVE_MAX_IDLE);
802 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200803 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200804 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200805 return ret;
806 }
807
808 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
809 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
810 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
811 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200812 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200813 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200814 return ret;
815 }
816
817 return 0;
818}
819
Vivek Natarajanacab6402014-11-26 09:06:12 +0200820static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200821{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200822 struct ath10k *ar = arvif->ar;
823 u32 vdev_param;
824
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200825 vdev_param = ar->wmi.vdev_param->rts_threshold;
826 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200827}
828
Kalle Valo5e3dd152013-06-12 20:52:10 +0300829static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
830{
831 int ret;
832
833 lockdep_assert_held(&ar->conf_mutex);
834
835 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
836 if (ret)
837 return ret;
838
839 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
840 if (ret)
841 return ret;
842
Dundi Ravitejac6f537a2019-06-03 17:41:51 +0300843 if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) {
844 unsigned long time_left;
845
846 time_left = wait_for_completion_timeout
847 (&ar->peer_delete_done, 5 * HZ);
848
849 if (!time_left) {
850 ath10k_warn(ar, "Timeout in receiving peer delete response\n");
851 return -ETIMEDOUT;
852 }
853 }
854
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100855 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100856
Kalle Valo5e3dd152013-06-12 20:52:10 +0300857 return 0;
858}
859
860static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
861{
862 struct ath10k_peer *peer, *tmp;
Michal Kazior69427262016-03-06 16:14:30 +0200863 int peer_id;
Ben Greear6d68f792016-06-30 15:23:53 +0300864 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300865
866 lockdep_assert_held(&ar->conf_mutex);
867
868 spin_lock_bh(&ar->data_lock);
869 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
870 if (peer->vdev_id != vdev_id)
871 continue;
872
Michal Kazior7aa7a722014-08-25 12:09:38 +0200873 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300874 peer->addr, vdev_id);
875
Michal Kazior69427262016-03-06 16:14:30 +0200876 for_each_set_bit(peer_id, peer->peer_ids,
877 ATH10K_MAX_NUM_PEER_IDS) {
878 ar->peer_map[peer_id] = NULL;
879 }
880
Ben Greear6d68f792016-06-30 15:23:53 +0300881 /* Double check that peer is properly un-referenced from
882 * the peer_map
883 */
884 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
885 if (ar->peer_map[i] == peer) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +0530886 ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
Ben Greear6d68f792016-06-30 15:23:53 +0300887 peer->addr, peer, i);
888 ar->peer_map[i] = NULL;
889 }
890 }
891
Kalle Valo5e3dd152013-06-12 20:52:10 +0300892 list_del(&peer->list);
893 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100894 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300895 }
896 spin_unlock_bh(&ar->data_lock);
897}
898
Michal Kaziora96d7742013-07-16 09:38:56 +0200899static void ath10k_peer_cleanup_all(struct ath10k *ar)
900{
901 struct ath10k_peer *peer, *tmp;
Ben Greear6d68f792016-06-30 15:23:53 +0300902 int i;
Michal Kaziora96d7742013-07-16 09:38:56 +0200903
904 lockdep_assert_held(&ar->conf_mutex);
905
906 spin_lock_bh(&ar->data_lock);
907 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
908 list_del(&peer->list);
909 kfree(peer);
910 }
Ben Greear6d68f792016-06-30 15:23:53 +0300911
912 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
913 ar->peer_map[i] = NULL;
914
Michal Kaziora96d7742013-07-16 09:38:56 +0200915 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100916
917 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100918 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200919}
920
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300921static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
922 struct ieee80211_sta *sta,
923 enum wmi_tdls_peer_state state)
924{
925 int ret;
926 struct wmi_tdls_peer_update_cmd_arg arg = {};
927 struct wmi_tdls_peer_capab_arg cap = {};
928 struct wmi_channel_arg chan_arg = {};
929
930 lockdep_assert_held(&ar->conf_mutex);
931
932 arg.vdev_id = vdev_id;
933 arg.peer_state = state;
934 ether_addr_copy(arg.addr, sta->addr);
935
936 cap.peer_max_sp = sta->max_sp;
937 cap.peer_uapsd_queues = sta->uapsd_queues;
938
939 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
940 !sta->tdls_initiator)
941 cap.is_peer_responder = 1;
942
943 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
944 if (ret) {
945 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
946 arg.addr, vdev_id, ret);
947 return ret;
948 }
949
950 return 0;
951}
952
Kalle Valo5e3dd152013-06-12 20:52:10 +0300953/************************/
954/* Interface management */
955/************************/
956
Michal Kazior64badcb2014-09-18 11:18:02 +0300957void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
958{
959 struct ath10k *ar = arvif->ar;
960
961 lockdep_assert_held(&ar->data_lock);
962
963 if (!arvif->beacon)
964 return;
965
966 if (!arvif->beacon_buf)
967 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
968 arvif->beacon->len, DMA_TO_DEVICE);
969
Michal Kazioraf213192015-01-29 14:29:52 +0200970 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
971 arvif->beacon_state != ATH10K_BEACON_SENT))
972 return;
973
Michal Kazior64badcb2014-09-18 11:18:02 +0300974 dev_kfree_skb_any(arvif->beacon);
975
976 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200977 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300978}
979
980static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
981{
982 struct ath10k *ar = arvif->ar;
983
984 lockdep_assert_held(&ar->data_lock);
985
986 ath10k_mac_vif_beacon_free(arvif);
987
988 if (arvif->beacon_buf) {
989 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
990 arvif->beacon_buf, arvif->beacon_paddr);
991 arvif->beacon_buf = NULL;
992 }
993}
994
Kalle Valo5e3dd152013-06-12 20:52:10 +0300995static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
996{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300997 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300998
Michal Kazior548db542013-07-05 16:15:15 +0300999 lockdep_assert_held(&ar->conf_mutex);
1000
Michal Kazior7962b0d2014-10-28 10:34:38 +01001001 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
1002 return -ESHUTDOWN;
1003
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03001004 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
1005 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
1006 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001007 return -ETIMEDOUT;
1008
Ben Greear833fd342018-09-06 19:46:20 +03001009 return ar->last_wmi_vdev_start_status;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001010}
1011
Michal Kazior1bbc0972014-04-08 09:45:47 +03001012static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001013{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001014 struct cfg80211_chan_def *chandef = NULL;
Maninder Singh19be9e92015-07-16 09:25:33 +05301015 struct ieee80211_channel *channel = NULL;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001016 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03001017 int ret = 0;
1018
1019 lockdep_assert_held(&ar->conf_mutex);
1020
Michal Kazior500ff9f2015-03-31 10:26:21 +00001021 ieee80211_iter_chan_contexts_atomic(ar->hw,
1022 ath10k_mac_get_any_chandef_iter,
1023 &chandef);
1024 if (WARN_ON_ONCE(!chandef))
1025 return -ENOENT;
1026
1027 channel = chandef->chan;
1028
Kalle Valo5e3dd152013-06-12 20:52:10 +03001029 arg.vdev_id = vdev_id;
1030 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +01001031 arg.channel.band_center_freq1 = chandef->center_freq1;
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02001032 arg.channel.band_center_freq2 = chandef->center_freq2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001033
1034 /* TODO setup this dynamically, what in case we
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01001035 * don't have any vifs?
1036 */
Michal Kaziorc930f742014-01-23 11:38:25 +01001037 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001038 arg.channel.chan_radar =
1039 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001040
Michal Kazior89c5c842013-10-23 04:02:13 -07001041 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07001042 arg.channel.max_power = channel->max_power * 2;
1043 arg.channel.max_reg_power = channel->max_reg_power * 2;
1044 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001045
Michal Kazior7962b0d2014-10-28 10:34:38 +01001046 reinit_completion(&ar->vdev_setup_done);
Rakesh Pillaife36e702019-06-03 17:41:33 +03001047 reinit_completion(&ar->vdev_delete_done);
Michal Kazior7962b0d2014-10-28 10:34:38 +01001048
Kalle Valo5e3dd152013-06-12 20:52:10 +03001049 ret = ath10k_wmi_vdev_start(ar, &arg);
1050 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001051 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001052 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001053 return ret;
1054 }
1055
1056 ret = ath10k_vdev_setup_sync(ar);
1057 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001058 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001059 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001060 return ret;
1061 }
1062
1063 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
1064 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001065 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001066 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001067 goto vdev_stop;
1068 }
1069
1070 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001071
Michal Kazior7aa7a722014-08-25 12:09:38 +02001072 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001073 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001074 return 0;
1075
1076vdev_stop:
1077 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1078 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001079 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001080 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001081
1082 return ret;
1083}
1084
Michal Kazior1bbc0972014-04-08 09:45:47 +03001085static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001086{
1087 int ret = 0;
1088
1089 lockdep_assert_held(&ar->conf_mutex);
1090
Marek Puzyniak52fa0192013-09-24 14:06:24 +02001091 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
1092 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001093 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001094 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001095
Michal Kazior7962b0d2014-10-28 10:34:38 +01001096 reinit_completion(&ar->vdev_setup_done);
Rakesh Pillaife36e702019-06-03 17:41:33 +03001097 reinit_completion(&ar->vdev_delete_done);
Michal Kazior7962b0d2014-10-28 10:34:38 +01001098
Kalle Valo5e3dd152013-06-12 20:52:10 +03001099 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1100 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001101 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001102 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001103
1104 ret = ath10k_vdev_setup_sync(ar);
1105 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +02001106 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001107 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001108
Michal Kazior7aa7a722014-08-25 12:09:38 +02001109 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001110 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001111 return ret;
1112}
1113
Michal Kazior1bbc0972014-04-08 09:45:47 +03001114static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001115{
1116 int bit, ret = 0;
1117
1118 lockdep_assert_held(&ar->conf_mutex);
1119
Ben Greeara9aefb32014-08-12 11:02:19 +03001120 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001121 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03001122 return -ENOMEM;
1123 }
1124
Ben Greear16c11172014-09-23 14:17:16 -07001125 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +03001126
Ben Greear16c11172014-09-23 14:17:16 -07001127 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001128
1129 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
1130 WMI_VDEV_TYPE_MONITOR,
1131 0, ar->mac_addr);
1132 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001133 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001134 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +03001135 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001136 }
1137
Ben Greear16c11172014-09-23 14:17:16 -07001138 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +02001139 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001140 ar->monitor_vdev_id);
1141
Kalle Valo5e3dd152013-06-12 20:52:10 +03001142 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001143}
1144
Michal Kazior1bbc0972014-04-08 09:45:47 +03001145static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001146{
1147 int ret = 0;
1148
1149 lockdep_assert_held(&ar->conf_mutex);
1150
Kalle Valo5e3dd152013-06-12 20:52:10 +03001151 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
1152 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001153 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001154 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001155 return ret;
1156 }
1157
Ben Greear16c11172014-09-23 14:17:16 -07001158 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001159
Michal Kazior7aa7a722014-08-25 12:09:38 +02001160 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001161 ar->monitor_vdev_id);
1162 return ret;
1163}
1164
Michal Kazior1bbc0972014-04-08 09:45:47 +03001165static int ath10k_monitor_start(struct ath10k *ar)
1166{
1167 int ret;
1168
1169 lockdep_assert_held(&ar->conf_mutex);
1170
Michal Kazior1bbc0972014-04-08 09:45:47 +03001171 ret = ath10k_monitor_vdev_create(ar);
1172 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001173 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001174 return ret;
1175 }
1176
1177 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
1178 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001179 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001180 ath10k_monitor_vdev_delete(ar);
1181 return ret;
1182 }
1183
1184 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001185 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +03001186
1187 return 0;
1188}
1189
Michal Kazior19337472014-08-28 12:58:16 +02001190static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +03001191{
1192 int ret;
1193
1194 lockdep_assert_held(&ar->conf_mutex);
1195
Michal Kazior1bbc0972014-04-08 09:45:47 +03001196 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001197 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001198 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001199 return ret;
1200 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001201
1202 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001203 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001204 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001205 return ret;
1206 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001207
1208 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001209 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +02001210
1211 return 0;
1212}
1213
Michal Kazior500ff9f2015-03-31 10:26:21 +00001214static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1215{
1216 int num_ctx;
1217
1218 /* At least one chanctx is required to derive a channel to start
1219 * monitor vdev on.
1220 */
1221 num_ctx = ath10k_mac_num_chanctxs(ar);
1222 if (num_ctx == 0)
1223 return false;
1224
1225 /* If there's already an existing special monitor interface then don't
1226 * bother creating another monitor vdev.
1227 */
1228 if (ar->monitor_arvif)
1229 return false;
1230
1231 return ar->monitor ||
Manoharan, Rajkumar705d7aa2016-11-23 16:58:11 +02001232 (!test_bit(ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST,
1233 ar->running_fw->fw_file.fw_features) &&
1234 (ar->filter_flags & FIF_OTHER_BSS)) ||
Michal Kazior500ff9f2015-03-31 10:26:21 +00001235 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1236}
1237
1238static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1239{
1240 int num_ctx;
1241
1242 num_ctx = ath10k_mac_num_chanctxs(ar);
1243
1244 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1245 * shouldn't allow this but make sure to prevent handling the following
1246 * case anyway since multi-channel DFS hasn't been tested at all.
1247 */
1248 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1249 return false;
1250
1251 return true;
1252}
1253
Michal Kazior19337472014-08-28 12:58:16 +02001254static int ath10k_monitor_recalc(struct ath10k *ar)
1255{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001256 bool needed;
1257 bool allowed;
1258 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001259
1260 lockdep_assert_held(&ar->conf_mutex);
1261
Michal Kazior500ff9f2015-03-31 10:26:21 +00001262 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1263 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001264
1265 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001266 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1267 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001268
Michal Kazior500ff9f2015-03-31 10:26:21 +00001269 if (WARN_ON(needed && !allowed)) {
1270 if (ar->monitor_started) {
1271 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1272
1273 ret = ath10k_monitor_stop(ar);
1274 if (ret)
Kalle Valo2a995082015-10-05 17:56:37 +03001275 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",
1276 ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001277 /* not serious */
1278 }
1279
1280 return -EPERM;
1281 }
1282
1283 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001284 return 0;
1285
Michal Kazior500ff9f2015-03-31 10:26:21 +00001286 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001287 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001288 else
1289 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001290}
1291
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02001292static bool ath10k_mac_can_set_cts_prot(struct ath10k_vif *arvif)
1293{
1294 struct ath10k *ar = arvif->ar;
1295
1296 lockdep_assert_held(&ar->conf_mutex);
1297
1298 if (!arvif->is_started) {
1299 ath10k_dbg(ar, ATH10K_DBG_MAC, "defer cts setup, vdev is not ready yet\n");
1300 return false;
1301 }
1302
1303 return true;
1304}
1305
1306static int ath10k_mac_set_cts_prot(struct ath10k_vif *arvif)
1307{
1308 struct ath10k *ar = arvif->ar;
1309 u32 vdev_param;
1310
1311 lockdep_assert_held(&ar->conf_mutex);
1312
1313 vdev_param = ar->wmi.vdev_param->protection_mode;
1314
1315 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_protection %d\n",
1316 arvif->vdev_id, arvif->use_cts_prot);
1317
1318 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1319 arvif->use_cts_prot ? 1 : 0);
1320}
1321
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001322static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1323{
1324 struct ath10k *ar = arvif->ar;
1325 u32 vdev_param, rts_cts = 0;
1326
1327 lockdep_assert_held(&ar->conf_mutex);
1328
1329 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1330
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001331 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001332
1333 if (arvif->num_legacy_stations > 0)
1334 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1335 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001336 else
1337 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1338 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001339
Bartosz Markowski86176902016-12-15 11:23:24 +02001340 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d recalc rts/cts prot %d\n",
1341 arvif->vdev_id, rts_cts);
1342
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001343 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1344 rts_cts);
1345}
1346
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001347static int ath10k_start_cac(struct ath10k *ar)
1348{
1349 int ret;
1350
1351 lockdep_assert_held(&ar->conf_mutex);
1352
1353 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1354
Michal Kazior19337472014-08-28 12:58:16 +02001355 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001356 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001357 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001358 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1359 return ret;
1360 }
1361
Michal Kazior7aa7a722014-08-25 12:09:38 +02001362 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001363 ar->monitor_vdev_id);
1364
1365 return 0;
1366}
1367
1368static int ath10k_stop_cac(struct ath10k *ar)
1369{
1370 lockdep_assert_held(&ar->conf_mutex);
1371
1372 /* CAC is not running - do nothing */
1373 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1374 return 0;
1375
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001376 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001377 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001378
Michal Kazior7aa7a722014-08-25 12:09:38 +02001379 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001380
1381 return 0;
1382}
1383
Michal Kazior500ff9f2015-03-31 10:26:21 +00001384static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1385 struct ieee80211_chanctx_conf *conf,
1386 void *data)
1387{
1388 bool *ret = data;
1389
1390 if (!*ret && conf->radar_enabled)
1391 *ret = true;
1392}
1393
1394static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1395{
1396 bool has_radar = false;
1397
1398 ieee80211_iter_chan_contexts_atomic(ar->hw,
1399 ath10k_mac_has_radar_iter,
1400 &has_radar);
1401
1402 return has_radar;
1403}
1404
Michal Kaziord6500972014-04-08 09:56:09 +03001405static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001406{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001407 int ret;
1408
1409 lockdep_assert_held(&ar->conf_mutex);
1410
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001411 ath10k_stop_cac(ar);
1412
Michal Kazior500ff9f2015-03-31 10:26:21 +00001413 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001414 return;
1415
Michal Kaziord6500972014-04-08 09:56:09 +03001416 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001417 return;
1418
1419 ret = ath10k_start_cac(ar);
1420 if (ret) {
1421 /*
1422 * Not possible to start CAC on current channel so starting
1423 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1424 * by indicating that radar was detected.
1425 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001426 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001427 ieee80211_radar_detected(ar->hw);
1428 }
1429}
1430
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301431static int ath10k_vdev_stop(struct ath10k_vif *arvif)
Michal Kazior72654fa2014-04-08 09:56:09 +03001432{
1433 struct ath10k *ar = arvif->ar;
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301434 int ret;
1435
1436 lockdep_assert_held(&ar->conf_mutex);
1437
1438 reinit_completion(&ar->vdev_setup_done);
Rakesh Pillaife36e702019-06-03 17:41:33 +03001439 reinit_completion(&ar->vdev_delete_done);
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301440
1441 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1442 if (ret) {
1443 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1444 arvif->vdev_id, ret);
1445 return ret;
1446 }
1447
1448 ret = ath10k_vdev_setup_sync(ar);
1449 if (ret) {
Colin Ian King23de5792017-06-25 22:29:32 +01001450 ath10k_warn(ar, "failed to synchronize setup for vdev %i: %d\n",
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301451 arvif->vdev_id, ret);
1452 return ret;
1453 }
1454
1455 WARN_ON(ar->num_started_vdevs == 0);
1456
1457 if (ar->num_started_vdevs != 0) {
1458 ar->num_started_vdevs--;
1459 ath10k_recalc_radar_detection(ar);
1460 }
1461
1462 return ret;
1463}
1464
Michal Kazior500ff9f2015-03-31 10:26:21 +00001465static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1466 const struct cfg80211_chan_def *chandef,
1467 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001468{
1469 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001470 struct wmi_vdev_start_request_arg arg = {};
1471 int ret = 0;
1472
1473 lockdep_assert_held(&ar->conf_mutex);
1474
1475 reinit_completion(&ar->vdev_setup_done);
Rakesh Pillaife36e702019-06-03 17:41:33 +03001476 reinit_completion(&ar->vdev_delete_done);
Michal Kazior72654fa2014-04-08 09:56:09 +03001477
1478 arg.vdev_id = arvif->vdev_id;
1479 arg.dtim_period = arvif->dtim_period;
1480 arg.bcn_intval = arvif->beacon_interval;
1481
1482 arg.channel.freq = chandef->chan->center_freq;
1483 arg.channel.band_center_freq1 = chandef->center_freq1;
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02001484 arg.channel.band_center_freq2 = chandef->center_freq2;
Michal Kazior72654fa2014-04-08 09:56:09 +03001485 arg.channel.mode = chan_to_phymode(chandef);
1486
1487 arg.channel.min_power = 0;
1488 arg.channel.max_power = chandef->chan->max_power * 2;
1489 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1490 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1491
1492 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1493 arg.ssid = arvif->u.ap.ssid;
1494 arg.ssid_len = arvif->u.ap.ssid_len;
1495 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1496
1497 /* For now allow DFS for AP mode */
1498 arg.channel.chan_radar =
1499 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1500 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1501 arg.ssid = arvif->vif->bss_conf.ssid;
1502 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1503 }
1504
Michal Kazior7aa7a722014-08-25 12:09:38 +02001505 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001506 "mac vdev %d start center_freq %d phymode %s\n",
1507 arg.vdev_id, arg.channel.freq,
1508 ath10k_wmi_phymode_str(arg.channel.mode));
1509
Michal Kaziordc55e302014-07-29 12:53:36 +03001510 if (restart)
1511 ret = ath10k_wmi_vdev_restart(ar, &arg);
1512 else
1513 ret = ath10k_wmi_vdev_start(ar, &arg);
1514
Michal Kazior72654fa2014-04-08 09:56:09 +03001515 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001516 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001517 arg.vdev_id, ret);
1518 return ret;
1519 }
1520
1521 ret = ath10k_vdev_setup_sync(ar);
1522 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001523 ath10k_warn(ar,
1524 "failed to synchronize setup for vdev %i restart %d: %d\n",
1525 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001526 return ret;
1527 }
1528
Michal Kaziord6500972014-04-08 09:56:09 +03001529 ar->num_started_vdevs++;
1530 ath10k_recalc_radar_detection(ar);
1531
Michal Kazior72654fa2014-04-08 09:56:09 +03001532 return ret;
1533}
1534
Michal Kazior500ff9f2015-03-31 10:26:21 +00001535static int ath10k_vdev_start(struct ath10k_vif *arvif,
1536 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001537{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001538 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001539}
1540
Michal Kazior500ff9f2015-03-31 10:26:21 +00001541static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1542 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001543{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001544 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kazior72654fa2014-04-08 09:56:09 +03001545}
1546
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001547static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1548 struct sk_buff *bcn)
1549{
1550 struct ath10k *ar = arvif->ar;
1551 struct ieee80211_mgmt *mgmt;
1552 const u8 *p2p_ie;
1553 int ret;
1554
Peter Oh08c27be2016-01-28 13:54:09 -08001555 if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001556 return 0;
1557
1558 mgmt = (void *)bcn->data;
1559 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1560 mgmt->u.beacon.variable,
1561 bcn->len - (mgmt->u.beacon.variable -
1562 bcn->data));
1563 if (!p2p_ie)
1564 return -ENOENT;
1565
1566 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1567 if (ret) {
1568 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1569 arvif->vdev_id, ret);
1570 return ret;
1571 }
1572
1573 return 0;
1574}
1575
1576static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1577 u8 oui_type, size_t ie_offset)
1578{
1579 size_t len;
1580 const u8 *next;
1581 const u8 *end;
1582 u8 *ie;
1583
1584 if (WARN_ON(skb->len < ie_offset))
1585 return -EINVAL;
1586
1587 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1588 skb->data + ie_offset,
1589 skb->len - ie_offset);
1590 if (!ie)
1591 return -ENOENT;
1592
1593 len = ie[1] + 2;
1594 end = skb->data + skb->len;
1595 next = ie + len;
1596
1597 if (WARN_ON(next > end))
1598 return -EINVAL;
1599
1600 memmove(ie, next, end - next);
1601 skb_trim(skb, skb->len - len);
1602
1603 return 0;
1604}
1605
1606static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1607{
1608 struct ath10k *ar = arvif->ar;
1609 struct ieee80211_hw *hw = ar->hw;
1610 struct ieee80211_vif *vif = arvif->vif;
1611 struct ieee80211_mutable_offsets offs = {};
1612 struct sk_buff *bcn;
1613 int ret;
1614
1615 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1616 return 0;
1617
Michal Kazior81a9a172015-03-05 16:02:17 +02001618 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1619 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1620 return 0;
1621
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001622 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1623 if (!bcn) {
1624 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1625 return -EPERM;
1626 }
1627
1628 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1629 if (ret) {
1630 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1631 kfree_skb(bcn);
1632 return ret;
1633 }
1634
1635 /* P2P IE is inserted by firmware automatically (as configured above)
1636 * so remove it from the base beacon template to avoid duplicate P2P
1637 * IEs in beacon frames.
1638 */
1639 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1640 offsetof(struct ieee80211_mgmt,
1641 u.beacon.variable));
1642
1643 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1644 0, NULL, 0);
1645 kfree_skb(bcn);
1646
1647 if (ret) {
1648 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1649 ret);
1650 return ret;
1651 }
1652
1653 return 0;
1654}
1655
1656static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1657{
1658 struct ath10k *ar = arvif->ar;
1659 struct ieee80211_hw *hw = ar->hw;
1660 struct ieee80211_vif *vif = arvif->vif;
1661 struct sk_buff *prb;
1662 int ret;
1663
1664 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1665 return 0;
1666
Michal Kazior81a9a172015-03-05 16:02:17 +02001667 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1668 return 0;
1669
Surabhi Vishnoi97354f2c2019-04-17 14:01:46 +05301670 /* For mesh, probe response and beacon share the same template */
1671 if (ieee80211_vif_is_mesh(vif))
1672 return 0;
1673
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001674 prb = ieee80211_proberesp_get(hw, vif);
1675 if (!prb) {
1676 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1677 return -EPERM;
1678 }
1679
1680 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1681 kfree_skb(prb);
1682
1683 if (ret) {
1684 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1685 ret);
1686 return ret;
1687 }
1688
1689 return 0;
1690}
1691
Michal Kazior500ff9f2015-03-31 10:26:21 +00001692static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1693{
1694 struct ath10k *ar = arvif->ar;
1695 struct cfg80211_chan_def def;
1696 int ret;
1697
1698 /* When originally vdev is started during assign_vif_chanctx() some
1699 * information is missing, notably SSID. Firmware revisions with beacon
1700 * offloading require the SSID to be provided during vdev (re)start to
1701 * handle hidden SSID properly.
1702 *
1703 * Vdev restart must be done after vdev has been both started and
1704 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1705 * deliver vdev restart response event causing timeouts during vdev
1706 * syncing in ath10k.
1707 *
1708 * Note: The vdev down/up and template reinstallation could be skipped
1709 * since only wmi-tlv firmware are known to have beacon offload and
1710 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1711 * response delivery. It's probably more robust to keep it as is.
1712 */
1713 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1714 return 0;
1715
1716 if (WARN_ON(!arvif->is_started))
1717 return -EINVAL;
1718
1719 if (WARN_ON(!arvif->is_up))
1720 return -EINVAL;
1721
1722 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1723 return -EINVAL;
1724
1725 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1726 if (ret) {
1727 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1728 arvif->vdev_id, ret);
1729 return ret;
1730 }
1731
1732 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1733 * firmware will crash upon vdev up.
1734 */
1735
1736 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1737 if (ret) {
1738 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1739 return ret;
1740 }
1741
1742 ret = ath10k_mac_setup_prb_tmpl(arvif);
1743 if (ret) {
1744 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1745 return ret;
1746 }
1747
1748 ret = ath10k_vdev_restart(arvif, &def);
1749 if (ret) {
1750 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1751 arvif->vdev_id, ret);
1752 return ret;
1753 }
1754
1755 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1756 arvif->bssid);
1757 if (ret) {
1758 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1759 arvif->vdev_id, ret);
1760 return ret;
1761 }
1762
1763 return 0;
1764}
1765
Kalle Valo5e3dd152013-06-12 20:52:10 +03001766static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001767 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001768{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001769 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001770 int ret = 0;
1771
Michal Kazior548db542013-07-05 16:15:15 +03001772 lockdep_assert_held(&arvif->ar->conf_mutex);
1773
Kalle Valo5e3dd152013-06-12 20:52:10 +03001774 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001775 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1776 if (ret)
1777 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1778 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001779
Michal Kaziorc930f742014-01-23 11:38:25 +01001780 arvif->is_up = false;
1781
Michal Kazior748afc42014-01-23 12:48:21 +01001782 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001783 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001784 spin_unlock_bh(&arvif->ar->data_lock);
1785
Kalle Valo5e3dd152013-06-12 20:52:10 +03001786 return;
1787 }
1788
1789 arvif->tx_seq_no = 0x1000;
1790
Michal Kaziorc930f742014-01-23 11:38:25 +01001791 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001792 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001793
1794 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1795 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001796 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001797 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001798 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001799 return;
1800 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001801
Michal Kaziorc930f742014-01-23 11:38:25 +01001802 arvif->is_up = true;
1803
Michal Kazior500ff9f2015-03-31 10:26:21 +00001804 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1805 if (ret) {
1806 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1807 arvif->vdev_id, ret);
1808 return;
1809 }
1810
Michal Kazior7aa7a722014-08-25 12:09:38 +02001811 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001812}
1813
1814static void ath10k_control_ibss(struct ath10k_vif *arvif,
1815 struct ieee80211_bss_conf *info,
1816 const u8 self_peer[ETH_ALEN])
1817{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001818 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001819 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001820 int ret = 0;
1821
Michal Kazior548db542013-07-05 16:15:15 +03001822 lockdep_assert_held(&arvif->ar->conf_mutex);
1823
Kalle Valo5e3dd152013-06-12 20:52:10 +03001824 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001825 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001826 return;
1827
Joe Perches93803b32015-03-02 19:54:49 -08001828 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001829
1830 return;
1831 }
1832
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001833 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1834 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001835 ATH10K_DEFAULT_ATIM);
1836 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001837 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001838 arvif->vdev_id, ret);
1839}
1840
Michal Kazior9f9b5742014-12-12 12:41:36 +01001841static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1842{
1843 struct ath10k *ar = arvif->ar;
1844 u32 param;
1845 u32 value;
1846 int ret;
1847
1848 lockdep_assert_held(&arvif->ar->conf_mutex);
1849
1850 if (arvif->u.sta.uapsd)
1851 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1852 else
1853 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1854
1855 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1856 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1857 if (ret) {
1858 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1859 value, arvif->vdev_id, ret);
1860 return ret;
1861 }
1862
1863 return 0;
1864}
1865
1866static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1867{
1868 struct ath10k *ar = arvif->ar;
1869 u32 param;
1870 u32 value;
1871 int ret;
1872
1873 lockdep_assert_held(&arvif->ar->conf_mutex);
1874
1875 if (arvif->u.sta.uapsd)
1876 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1877 else
1878 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1879
1880 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1881 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1882 param, value);
1883 if (ret) {
1884 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1885 value, arvif->vdev_id, ret);
1886 return ret;
1887 }
1888
1889 return 0;
1890}
1891
Michal Kazior424f2632015-07-09 13:08:35 +02001892static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001893{
1894 struct ath10k_vif *arvif;
1895 int num = 0;
1896
1897 lockdep_assert_held(&ar->conf_mutex);
1898
1899 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001900 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001901 num++;
1902
1903 return num;
1904}
1905
Michal Kaziorad088bf2013-10-16 15:44:46 +03001906static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001907{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001908 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001909 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001910 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001911 enum wmi_sta_powersave_param param;
1912 enum wmi_sta_ps_mode psmode;
1913 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001914 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001915 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001916
Michal Kazior548db542013-07-05 16:15:15 +03001917 lockdep_assert_held(&arvif->ar->conf_mutex);
1918
Michal Kaziorad088bf2013-10-16 15:44:46 +03001919 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1920 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001921
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001922 enable_ps = arvif->ps;
1923
Michal Kazior424f2632015-07-09 13:08:35 +02001924 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001925 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
Kalle Valoc4cdf752016-04-20 19:45:18 +03001926 ar->running_fw->fw_file.fw_features)) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001927 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1928 arvif->vdev_id);
1929 enable_ps = false;
1930 }
1931
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001932 if (!arvif->is_started) {
1933 /* mac80211 can update vif powersave state while disconnected.
1934 * Firmware doesn't behave nicely and consumes more power than
1935 * necessary if PS is disabled on a non-started vdev. Hence
1936 * force-enable PS for non-running vdevs.
1937 */
1938 psmode = WMI_STA_PS_MODE_ENABLED;
1939 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001940 psmode = WMI_STA_PS_MODE_ENABLED;
1941 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1942
Michal Kazior526549a2014-12-12 12:41:37 +01001943 ps_timeout = conf->dynamic_ps_timeout;
1944 if (ps_timeout == 0) {
1945 /* Firmware doesn't like 0 */
1946 ps_timeout = ieee80211_tu_to_usec(
1947 vif->bss_conf.beacon_int) / 1000;
1948 }
1949
Michal Kaziorad088bf2013-10-16 15:44:46 +03001950 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001951 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001952 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001953 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001954 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001955 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001956 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001957 } else {
1958 psmode = WMI_STA_PS_MODE_DISABLED;
1959 }
1960
Michal Kazior7aa7a722014-08-25 12:09:38 +02001961 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001962 arvif->vdev_id, psmode ? "enable" : "disable");
1963
Michal Kaziorad088bf2013-10-16 15:44:46 +03001964 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1965 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001966 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001967 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001968 return ret;
1969 }
1970
1971 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001972}
1973
Michal Kazior46725b152015-01-28 09:57:49 +02001974static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1975{
1976 struct ath10k *ar = arvif->ar;
1977 struct wmi_sta_keepalive_arg arg = {};
1978 int ret;
1979
1980 lockdep_assert_held(&arvif->ar->conf_mutex);
1981
1982 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1983 return 0;
1984
1985 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1986 return 0;
1987
1988 /* Some firmware revisions have a bug and ignore the `enabled` field.
1989 * Instead use the interval to disable the keepalive.
1990 */
1991 arg.vdev_id = arvif->vdev_id;
1992 arg.enabled = 1;
1993 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1994 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1995
1996 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1997 if (ret) {
1998 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1999 arvif->vdev_id, ret);
2000 return ret;
2001 }
2002
2003 return 0;
2004}
2005
Michal Kazior81a9a172015-03-05 16:02:17 +02002006static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
2007{
2008 struct ath10k *ar = arvif->ar;
2009 struct ieee80211_vif *vif = arvif->vif;
2010 int ret;
2011
Michal Kazior8513d952015-03-09 14:19:24 +01002012 lockdep_assert_held(&arvif->ar->conf_mutex);
2013
2014 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
2015 return;
2016
Michal Kazior81a9a172015-03-05 16:02:17 +02002017 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
2018 return;
2019
2020 if (!vif->csa_active)
2021 return;
2022
2023 if (!arvif->is_up)
2024 return;
2025
2026 if (!ieee80211_csa_is_complete(vif)) {
2027 ieee80211_csa_update_counter(vif);
2028
2029 ret = ath10k_mac_setup_bcn_tmpl(arvif);
2030 if (ret)
2031 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
2032 ret);
2033
2034 ret = ath10k_mac_setup_prb_tmpl(arvif);
2035 if (ret)
2036 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
2037 ret);
2038 } else {
2039 ieee80211_csa_finish(vif);
2040 }
2041}
2042
2043static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
2044{
2045 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
2046 ap_csa_work);
2047 struct ath10k *ar = arvif->ar;
2048
2049 mutex_lock(&ar->conf_mutex);
2050 ath10k_mac_vif_ap_csa_count_down(arvif);
2051 mutex_unlock(&ar->conf_mutex);
2052}
2053
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002054static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
2055 struct ieee80211_vif *vif)
2056{
2057 struct sk_buff *skb = data;
2058 struct ieee80211_mgmt *mgmt = (void *)skb->data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002059 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002060
2061 if (vif->type != NL80211_IFTYPE_STATION)
2062 return;
2063
2064 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
2065 return;
2066
2067 cancel_delayed_work(&arvif->connection_loss_work);
2068}
2069
2070void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
2071{
2072 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2073 IEEE80211_IFACE_ITER_NORMAL,
2074 ath10k_mac_handle_beacon_iter,
2075 skb);
2076}
2077
2078static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
2079 struct ieee80211_vif *vif)
2080{
2081 u32 *vdev_id = data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002082 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002083 struct ath10k *ar = arvif->ar;
2084 struct ieee80211_hw *hw = ar->hw;
2085
2086 if (arvif->vdev_id != *vdev_id)
2087 return;
2088
2089 if (!arvif->is_up)
2090 return;
2091
2092 ieee80211_beacon_loss(vif);
2093
2094 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
2095 * (done by mac80211) succeeds but beacons do not resume then it
2096 * doesn't make sense to continue operation. Queue connection loss work
2097 * which can be cancelled when beacon is received.
2098 */
2099 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
2100 ATH10K_CONNECTION_LOSS_HZ);
2101}
2102
2103void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
2104{
2105 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2106 IEEE80211_IFACE_ITER_NORMAL,
2107 ath10k_mac_handle_beacon_miss_iter,
2108 &vdev_id);
2109}
2110
2111static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
2112{
2113 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
2114 connection_loss_work.work);
2115 struct ieee80211_vif *vif = arvif->vif;
2116
2117 if (!arvif->is_up)
2118 return;
2119
2120 ieee80211_connection_loss(vif);
2121}
2122
Kalle Valo5e3dd152013-06-12 20:52:10 +03002123/**********************/
2124/* Station management */
2125/**********************/
2126
Michal Kazior590922a2014-10-21 10:10:29 +03002127static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
2128 struct ieee80211_vif *vif)
2129{
2130 /* Some firmware revisions have unstable STA powersave when listen
2131 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
2132 * generate NullFunc frames properly even if buffered frames have been
2133 * indicated in Beacon TIM. Firmware would seldom wake up to pull
2134 * buffered frames. Often pinging the device from AP would simply fail.
2135 *
2136 * As a workaround set it to 1.
2137 */
2138 if (vif->type == NL80211_IFTYPE_STATION)
2139 return 1;
2140
2141 return ar->hw->conf.listen_interval;
2142}
2143
Kalle Valo5e3dd152013-06-12 20:52:10 +03002144static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002145 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002146 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002147 struct wmi_peer_assoc_complete_arg *arg)
2148{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002149 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002150 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03002151
Michal Kazior548db542013-07-05 16:15:15 +03002152 lockdep_assert_held(&ar->conf_mutex);
2153
Michal Kaziorc51880e2015-03-30 09:51:57 +03002154 if (vif->type == NL80211_IFTYPE_STATION)
2155 aid = vif->bss_conf.aid;
2156 else
2157 aid = sta->aid;
2158
Kalle Valob25f32c2014-09-14 12:50:49 +03002159 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002160 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002161 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002162 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03002163 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002164 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03002165 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002166}
2167
2168static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002169 struct ieee80211_vif *vif,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002170 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002171 struct wmi_peer_assoc_complete_arg *arg)
2172{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002173 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002174 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002175 struct cfg80211_bss *bss;
2176 const u8 *rsnie = NULL;
2177 const u8 *wpaie = NULL;
2178
Michal Kazior548db542013-07-05 16:15:15 +03002179 lockdep_assert_held(&ar->conf_mutex);
2180
Michal Kazior500ff9f2015-03-31 10:26:21 +00002181 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2182 return;
2183
2184 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
2185 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002186 if (bss) {
2187 const struct cfg80211_bss_ies *ies;
2188
2189 rcu_read_lock();
2190 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
2191
2192 ies = rcu_dereference(bss->ies);
2193
2194 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03002195 WLAN_OUI_TYPE_MICROSOFT_WPA,
2196 ies->data,
2197 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002198 rcu_read_unlock();
2199 cfg80211_put_bss(ar->hw->wiphy, bss);
2200 }
2201
2202 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2203 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002204 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002205 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002206 }
2207
2208 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002209 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002210 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002211 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002212
2213 if (sta->mfp &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03002214 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT,
2215 ar->running_fw->fw_file.fw_features)) {
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002216 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002217 }
2218}
2219
2220static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002221 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002222 struct ieee80211_sta *sta,
2223 struct wmi_peer_assoc_complete_arg *arg)
2224{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002225 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002226 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002227 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002228 const struct ieee80211_supported_band *sband;
2229 const struct ieee80211_rate *rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002230 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002231 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002232 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002233 int i;
2234
Michal Kazior548db542013-07-05 16:15:15 +03002235 lockdep_assert_held(&ar->conf_mutex);
2236
Michal Kazior500ff9f2015-03-31 10:26:21 +00002237 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2238 return;
2239
Michal Kazior45c9abc2015-04-21 20:42:58 +03002240 band = def.chan->band;
2241 sband = ar->hw->wiphy->bands[band];
2242 ratemask = sta->supp_rates[band];
2243 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002244 rates = sband->bitrates;
2245
2246 rateset->num_rates = 0;
2247
2248 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2249 if (!(ratemask & 1))
2250 continue;
2251
Michal Kazior486017c2015-03-30 09:51:54 +03002252 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2253 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002254 rateset->num_rates++;
2255 }
2256}
2257
Michal Kazior45c9abc2015-04-21 20:42:58 +03002258static bool
2259ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2260{
2261 int nss;
2262
2263 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2264 if (ht_mcs_mask[nss])
2265 return false;
2266
2267 return true;
2268}
2269
2270static bool
2271ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2272{
2273 int nss;
2274
2275 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2276 if (vht_mcs_mask[nss])
2277 return false;
2278
2279 return true;
2280}
2281
Kalle Valo5e3dd152013-06-12 20:52:10 +03002282static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002283 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002284 struct ieee80211_sta *sta,
2285 struct wmi_peer_assoc_complete_arg *arg)
2286{
2287 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002288 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002289 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002290 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002291 const u8 *ht_mcs_mask;
2292 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002293 int i, n;
2294 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002295 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002296
Michal Kazior548db542013-07-05 16:15:15 +03002297 lockdep_assert_held(&ar->conf_mutex);
2298
Michal Kazior45c9abc2015-04-21 20:42:58 +03002299 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2300 return;
2301
Kalle Valo5e3dd152013-06-12 20:52:10 +03002302 if (!ht_cap->ht_supported)
2303 return;
2304
Michal Kazior45c9abc2015-04-21 20:42:58 +03002305 band = def.chan->band;
2306 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2307 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2308
2309 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2310 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2311 return;
2312
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002313 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002314 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2315 ht_cap->ampdu_factor)) - 1;
2316
2317 arg->peer_mpdu_density =
2318 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2319
2320 arg->peer_ht_caps = ht_cap->cap;
2321 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2322
2323 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002324 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002325
2326 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002327 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002328 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2329 }
2330
Michal Kazior45c9abc2015-04-21 20:42:58 +03002331 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2332 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2333 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002334
Michal Kazior45c9abc2015-04-21 20:42:58 +03002335 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2336 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2337 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002338
2339 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2340 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002341 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002342 }
2343
2344 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002345 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2346 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2347 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2348 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002349 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002350 }
2351
Kalle Valo5e3dd152013-06-12 20:52:10 +03002352 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2353 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2354 else if (ht_cap->mcs.rx_mask[1])
2355 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2356
Michal Kazior45c9abc2015-04-21 20:42:58 +03002357 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2358 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2359 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2360 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002361 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002362 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002363
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002364 /*
2365 * This is a workaround for HT-enabled STAs which break the spec
2366 * and have no HT capabilities RX mask (no HT RX MCS map).
2367 *
2368 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2369 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2370 *
2371 * Firmware asserts if such situation occurs.
2372 */
2373 if (n == 0) {
2374 arg->peer_ht_rates.num_rates = 8;
2375 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2376 arg->peer_ht_rates.rates[i] = i;
2377 } else {
2378 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002379 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002380 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002381
Michal Kazior7aa7a722014-08-25 12:09:38 +02002382 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002383 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002384 arg->peer_ht_rates.num_rates,
2385 arg->peer_num_spatial_streams);
2386}
2387
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002388static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2389 struct ath10k_vif *arvif,
2390 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002391{
2392 u32 uapsd = 0;
2393 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002394 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002395
Michal Kazior548db542013-07-05 16:15:15 +03002396 lockdep_assert_held(&ar->conf_mutex);
2397
Kalle Valo5e3dd152013-06-12 20:52:10 +03002398 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002399 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002400 sta->uapsd_queues, sta->max_sp);
2401
Kalle Valo5e3dd152013-06-12 20:52:10 +03002402 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2403 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2404 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2405 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2406 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2407 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2408 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2409 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2410 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2411 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2412 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2413 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2414
Kalle Valo5e3dd152013-06-12 20:52:10 +03002415 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2416 max_sp = sta->max_sp;
2417
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002418 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2419 sta->addr,
2420 WMI_AP_PS_PEER_PARAM_UAPSD,
2421 uapsd);
2422 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002423 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002424 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002425 return ret;
2426 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002427
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002428 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2429 sta->addr,
2430 WMI_AP_PS_PEER_PARAM_MAX_SP,
2431 max_sp);
2432 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002433 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002434 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002435 return ret;
2436 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002437
2438 /* TODO setup this based on STA listen interval and
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01002439 * beacon interval. Currently we don't know
2440 * sta->listen_interval - mac80211 patch required.
2441 * Currently use 10 seconds
2442 */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002443 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002444 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2445 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002446 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002447 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002448 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002449 return ret;
2450 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002451 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002452
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002453 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002454}
2455
Michal Kazior45c9abc2015-04-21 20:42:58 +03002456static u16
2457ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2458 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2459{
2460 int idx_limit;
2461 int nss;
2462 u16 mcs_map;
2463 u16 mcs;
2464
2465 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2466 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2467 vht_mcs_limit[nss];
2468
2469 if (mcs_map)
2470 idx_limit = fls(mcs_map) - 1;
2471 else
2472 idx_limit = -1;
2473
2474 switch (idx_limit) {
2475 case 0: /* fall through */
2476 case 1: /* fall through */
2477 case 2: /* fall through */
2478 case 3: /* fall through */
2479 case 4: /* fall through */
2480 case 5: /* fall through */
2481 case 6: /* fall through */
2482 default:
2483 /* see ath10k_mac_can_set_bitrate_mask() */
2484 WARN_ON(1);
2485 /* fall through */
2486 case -1:
2487 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2488 break;
2489 case 7:
2490 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2491 break;
2492 case 8:
2493 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2494 break;
2495 case 9:
2496 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2497 break;
2498 }
2499
2500 tx_mcs_set &= ~(0x3 << (nss * 2));
2501 tx_mcs_set |= mcs << (nss * 2);
2502 }
2503
2504 return tx_mcs_set;
2505}
2506
Kalle Valo5e3dd152013-06-12 20:52:10 +03002507static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002508 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002509 struct ieee80211_sta *sta,
2510 struct wmi_peer_assoc_complete_arg *arg)
2511{
2512 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002513 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002514 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002515 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002516 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002517 u8 ampdu_factor;
Venkateswara Rao Naralasettyfefcd112017-03-24 13:27:28 +05302518 u8 max_nss, vht_mcs;
2519 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002520
Michal Kazior500ff9f2015-03-31 10:26:21 +00002521 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2522 return;
2523
Kalle Valo5e3dd152013-06-12 20:52:10 +03002524 if (!vht_cap->vht_supported)
2525 return;
2526
Michal Kazior45c9abc2015-04-21 20:42:58 +03002527 band = def.chan->band;
2528 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2529
2530 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2531 return;
2532
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002533 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002534
Johannes Berg57fbcce2016-04-12 15:56:15 +02002535 if (def.chan->band == NL80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002536 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002537
Kalle Valo5e3dd152013-06-12 20:52:10 +03002538 arg->peer_vht_caps = vht_cap->cap;
2539
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002540 ampdu_factor = (vht_cap->cap &
2541 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2542 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2543
2544 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2545 * zero in VHT IE. Using it would result in degraded throughput.
2546 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01002547 * it if VHT max_mpdu is smaller.
2548 */
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002549 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2550 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2551 ampdu_factor)) - 1);
2552
Kalle Valo5e3dd152013-06-12 20:52:10 +03002553 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002554 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002555
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02002556 if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
2557 arg->peer_flags |= ar->wmi.peer_flags->bw160;
2558
Venkateswara Rao Naralasettyfefcd112017-03-24 13:27:28 +05302559 /* Calculate peer NSS capability from VHT capabilities if STA
2560 * supports VHT.
2561 */
2562 for (i = 0, max_nss = 0, vht_mcs = 0; i < NL80211_VHT_NSS_MAX; i++) {
2563 vht_mcs = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) >>
2564 (2 * i) & 3;
2565
2566 if ((vht_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED) &&
2567 vht_mcs_mask[i])
2568 max_nss = i + 1;
2569 }
2570 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002571 arg->peer_vht_rates.rx_max_rate =
2572 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2573 arg->peer_vht_rates.rx_mcs_set =
2574 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2575 arg->peer_vht_rates.tx_max_rate =
2576 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002577 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2578 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002579
Michal Kazior7aa7a722014-08-25 12:09:38 +02002580 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002581 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Ben Greearcc914a52017-06-16 10:37:45 +03002582
2583 if (arg->peer_vht_rates.rx_max_rate &&
2584 (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) {
2585 switch (arg->peer_vht_rates.rx_max_rate) {
2586 case 1560:
2587 /* Must be 2x2 at 160Mhz is all it can do. */
2588 arg->peer_bw_rxnss_override = 2;
2589 break;
2590 case 780:
2591 /* Can only do 1x1 at 160Mhz (Long Guard Interval) */
2592 arg->peer_bw_rxnss_override = 1;
2593 break;
2594 }
2595 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002596}
2597
2598static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002599 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002600 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002601 struct wmi_peer_assoc_complete_arg *arg)
2602{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002603 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior590922a2014-10-21 10:10:29 +03002604
Kalle Valo5e3dd152013-06-12 20:52:10 +03002605 switch (arvif->vdev_type) {
2606 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002607 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002608 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002609
2610 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002611 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002612 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2613 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002614 break;
2615 case WMI_VDEV_TYPE_STA:
Balaji Pothunoori07ffb442017-12-07 16:58:04 +02002616 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002617 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002618 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002619 case WMI_VDEV_TYPE_IBSS:
2620 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002621 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002622 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002623 default:
2624 break;
2625 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002626
2627 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002628 sta->addr, !!(arg->peer_flags &
2629 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002630}
2631
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002632static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002633{
Johannes Berg57fbcce2016-04-12 15:56:15 +02002634 return sta->supp_rates[NL80211_BAND_2GHZ] >>
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002635 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002636}
2637
Kalle Valo06efdbe2017-01-12 13:02:11 +02002638static enum wmi_phy_mode ath10k_mac_get_phymode_vht(struct ath10k *ar,
2639 struct ieee80211_sta *sta)
2640{
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02002641 if (sta->bandwidth == IEEE80211_STA_RX_BW_160) {
2642 switch (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
2643 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
2644 return MODE_11AC_VHT160;
2645 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
2646 return MODE_11AC_VHT80_80;
2647 default:
2648 /* not sure if this is a valid case? */
2649 return MODE_11AC_VHT160;
2650 }
2651 }
2652
Kalle Valo06efdbe2017-01-12 13:02:11 +02002653 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2654 return MODE_11AC_VHT80;
2655
2656 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2657 return MODE_11AC_VHT40;
2658
2659 if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2660 return MODE_11AC_VHT20;
2661
2662 return MODE_UNKNOWN;
2663}
2664
Kalle Valo5e3dd152013-06-12 20:52:10 +03002665static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002666 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002667 struct ieee80211_sta *sta,
2668 struct wmi_peer_assoc_complete_arg *arg)
2669{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002670 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002671 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002672 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002673 const u8 *ht_mcs_mask;
2674 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002675 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2676
Michal Kazior500ff9f2015-03-31 10:26:21 +00002677 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2678 return;
2679
Michal Kazior45c9abc2015-04-21 20:42:58 +03002680 band = def.chan->band;
2681 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2682 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2683
2684 switch (band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02002685 case NL80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002686 if (sta->vht_cap.vht_supported &&
2687 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002688 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2689 phymode = MODE_11AC_VHT40;
2690 else
2691 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002692 } else if (sta->ht_cap.ht_supported &&
2693 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002694 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2695 phymode = MODE_11NG_HT40;
2696 else
2697 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002698 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002699 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002700 } else {
2701 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002702 }
2703
2704 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002705 case NL80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002706 /*
2707 * Check VHT first.
2708 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002709 if (sta->vht_cap.vht_supported &&
2710 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Kalle Valo06efdbe2017-01-12 13:02:11 +02002711 phymode = ath10k_mac_get_phymode_vht(ar, sta);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002712 } else if (sta->ht_cap.ht_supported &&
2713 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2714 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002715 phymode = MODE_11NA_HT40;
2716 else
2717 phymode = MODE_11NA_HT20;
2718 } else {
2719 phymode = MODE_11A;
2720 }
2721
2722 break;
2723 default:
2724 break;
2725 }
2726
Michal Kazior7aa7a722014-08-25 12:09:38 +02002727 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002728 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002729
Kalle Valo5e3dd152013-06-12 20:52:10 +03002730 arg->peer_phymode = phymode;
2731 WARN_ON(phymode == MODE_UNKNOWN);
2732}
2733
Kalle Valob9ada652013-10-16 15:44:46 +03002734static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002735 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002736 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002737 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002738{
Michal Kazior548db542013-07-05 16:15:15 +03002739 lockdep_assert_held(&ar->conf_mutex);
2740
Kalle Valob9ada652013-10-16 15:44:46 +03002741 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002742
Michal Kazior590922a2014-10-21 10:10:29 +03002743 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002744 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002745 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002746 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002747 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002748 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2749 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002750
Kalle Valob9ada652013-10-16 15:44:46 +03002751 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002752}
2753
Michal Kazior90046f52014-02-14 14:45:51 +01002754static const u32 ath10k_smps_map[] = {
2755 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2756 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2757 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2758 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2759};
2760
2761static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2762 const u8 *addr,
2763 const struct ieee80211_sta_ht_cap *ht_cap)
2764{
2765 int smps;
2766
2767 if (!ht_cap->ht_supported)
2768 return 0;
2769
2770 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2771 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2772
2773 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2774 return -EINVAL;
2775
2776 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
Rakesh Pillaic0e33fe2019-02-19 11:39:36 +05302777 ar->wmi.peer_param->smps_state,
Michal Kazior90046f52014-02-14 14:45:51 +01002778 ath10k_smps_map[smps]);
2779}
2780
Michal Kazior139e1702015-02-15 16:50:42 +02002781static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2782 struct ieee80211_vif *vif,
2783 struct ieee80211_sta_vht_cap vht_cap)
2784{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002785 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior139e1702015-02-15 16:50:42 +02002786 int ret;
2787 u32 param;
2788 u32 value;
2789
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302790 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2791 return 0;
2792
Michal Kazior139e1702015-02-15 16:50:42 +02002793 if (!(ar->vht_cap_info &
2794 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2795 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2796 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2797 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2798 return 0;
2799
2800 param = ar->wmi.vdev_param->txbf;
2801 value = 0;
2802
2803 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2804 return 0;
2805
2806 /* The following logic is correct. If a remote STA advertises support
2807 * for being a beamformer then we should enable us being a beamformee.
2808 */
2809
2810 if (ar->vht_cap_info &
2811 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2812 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2813 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2814 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2815
2816 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2817 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2818 }
2819
2820 if (ar->vht_cap_info &
2821 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2822 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2823 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2824 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2825
2826 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2827 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2828 }
2829
2830 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2831 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2832
2833 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2834 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2835
2836 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2837 if (ret) {
2838 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2839 value, ret);
2840 return ret;
2841 }
2842
2843 return 0;
2844}
2845
Kalle Valo5e3dd152013-06-12 20:52:10 +03002846/* can be called only in mac80211 callbacks due to `key_count` usage */
2847static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2848 struct ieee80211_vif *vif,
2849 struct ieee80211_bss_conf *bss_conf)
2850{
2851 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002852 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior90046f52014-02-14 14:45:51 +01002853 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002854 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002855 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002856 struct ieee80211_sta *ap_sta;
2857 int ret;
2858
Michal Kazior548db542013-07-05 16:15:15 +03002859 lockdep_assert_held(&ar->conf_mutex);
2860
Michal Kazior077efc82014-10-21 10:10:29 +03002861 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2862 arvif->vdev_id, arvif->bssid, arvif->aid);
2863
Kalle Valo5e3dd152013-06-12 20:52:10 +03002864 rcu_read_lock();
2865
2866 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2867 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002868 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002869 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002870 rcu_read_unlock();
2871 return;
2872 }
2873
Michal Kazior90046f52014-02-14 14:45:51 +01002874 /* ap_sta must be accessed only within rcu section which must be left
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01002875 * before calling ath10k_setup_peer_smps() which might sleep.
2876 */
Michal Kazior90046f52014-02-14 14:45:51 +01002877 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002878 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002879
Michal Kazior590922a2014-10-21 10:10:29 +03002880 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002881 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002882 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002883 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002884 rcu_read_unlock();
2885 return;
2886 }
2887
2888 rcu_read_unlock();
2889
Kalle Valob9ada652013-10-16 15:44:46 +03002890 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2891 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002892 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002893 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002894 return;
2895 }
2896
Michal Kazior90046f52014-02-14 14:45:51 +01002897 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2898 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002899 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002900 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002901 return;
2902 }
2903
Michal Kazior139e1702015-02-15 16:50:42 +02002904 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2905 if (ret) {
2906 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2907 arvif->vdev_id, bss_conf->bssid, ret);
2908 return;
2909 }
2910
Michal Kazior7aa7a722014-08-25 12:09:38 +02002911 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002912 "mac vdev %d up (associated) bssid %pM aid %d\n",
2913 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2914
Michal Kazior077efc82014-10-21 10:10:29 +03002915 WARN_ON(arvif->is_up);
2916
Michal Kaziorc930f742014-01-23 11:38:25 +01002917 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002918 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002919
2920 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2921 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002922 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002923 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002924 return;
2925 }
2926
2927 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002928
2929 /* Workaround: Some firmware revisions (tested with qca6174
2930 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2931 * poked with peer param command.
2932 */
2933 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
Rakesh Pillaic0e33fe2019-02-19 11:39:36 +05302934 ar->wmi.peer_param->dummy_var, 1);
Michal Kazior0a987fb2015-02-13 13:30:15 +01002935 if (ret) {
2936 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2937 arvif->bssid, arvif->vdev_id, ret);
2938 return;
2939 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002940}
2941
Kalle Valo5e3dd152013-06-12 20:52:10 +03002942static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2943 struct ieee80211_vif *vif)
2944{
2945 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002946 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior139e1702015-02-15 16:50:42 +02002947 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002948 int ret;
2949
Michal Kazior548db542013-07-05 16:15:15 +03002950 lockdep_assert_held(&ar->conf_mutex);
2951
Michal Kazior077efc82014-10-21 10:10:29 +03002952 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2953 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002954
Kalle Valo5e3dd152013-06-12 20:52:10 +03002955 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002956 if (ret)
Ben Greearaa66ba02016-09-26 21:56:25 +03002957 ath10k_warn(ar, "failed to down vdev %i: %d\n",
Michal Kazior077efc82014-10-21 10:10:29 +03002958 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002959
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002960 arvif->def_wep_key_idx = -1;
2961
Michal Kazior139e1702015-02-15 16:50:42 +02002962 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2963 if (ret) {
2964 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2965 arvif->vdev_id, ret);
2966 return;
2967 }
2968
Michal Kaziorc930f742014-01-23 11:38:25 +01002969 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002970
2971 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002972}
2973
Michal Kazior590922a2014-10-21 10:10:29 +03002974static int ath10k_station_assoc(struct ath10k *ar,
2975 struct ieee80211_vif *vif,
2976 struct ieee80211_sta *sta,
2977 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002978{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002979 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valob9ada652013-10-16 15:44:46 +03002980 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002981 int ret = 0;
2982
Michal Kazior548db542013-07-05 16:15:15 +03002983 lockdep_assert_held(&ar->conf_mutex);
2984
Michal Kazior590922a2014-10-21 10:10:29 +03002985 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002986 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002987 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002988 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002989 return ret;
2990 }
2991
2992 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2993 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002994 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002995 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002996 return ret;
2997 }
2998
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002999 /* Re-assoc is run only to update supported rates for given station. It
3000 * doesn't make much sense to reconfigure the peer completely.
3001 */
3002 if (!reassoc) {
3003 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
3004 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02003005 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03003006 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02003007 arvif->vdev_id, ret);
3008 return ret;
3009 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02003010
Michal Kaziorb1ecde32014-10-21 10:10:29 +03003011 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
3012 if (ret) {
3013 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
3014 sta->addr, arvif->vdev_id, ret);
3015 return ret;
3016 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003017
Michal Kaziorb1ecde32014-10-21 10:10:29 +03003018 if (!sta->wme) {
3019 arvif->num_legacy_stations++;
3020 ret = ath10k_recalc_rtscts_prot(arvif);
3021 if (ret) {
3022 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
3023 arvif->vdev_id, ret);
3024 return ret;
3025 }
3026 }
3027
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02003028 /* Plumb cached keys only for static WEP */
Yingying Tangc3816c92018-03-28 12:15:23 +03003029 if ((arvif->def_wep_key_idx != -1) && (!sta->tdls)) {
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02003030 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
3031 if (ret) {
3032 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
3033 arvif->vdev_id, ret);
3034 return ret;
3035 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003036 }
3037 }
3038
Kalle Valo5e3dd152013-06-12 20:52:10 +03003039 return ret;
3040}
3041
Michal Kazior590922a2014-10-21 10:10:29 +03003042static int ath10k_station_disassoc(struct ath10k *ar,
3043 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003044 struct ieee80211_sta *sta)
3045{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003046 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003047 int ret = 0;
3048
3049 lockdep_assert_held(&ar->conf_mutex);
3050
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02003051 if (!sta->wme) {
3052 arvif->num_legacy_stations--;
3053 ret = ath10k_recalc_rtscts_prot(arvif);
3054 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003055 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02003056 arvif->vdev_id, ret);
3057 return ret;
3058 }
3059 }
3060
Kalle Valo5e3dd152013-06-12 20:52:10 +03003061 ret = ath10k_clear_peer_keys(arvif, sta->addr);
3062 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003063 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003064 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003065 return ret;
3066 }
3067
3068 return ret;
3069}
3070
3071/**************/
3072/* Regulatory */
3073/**************/
3074
3075static int ath10k_update_channel_list(struct ath10k *ar)
3076{
3077 struct ieee80211_hw *hw = ar->hw;
3078 struct ieee80211_supported_band **bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02003079 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003080 struct ieee80211_channel *channel;
3081 struct wmi_scan_chan_list_arg arg = {0};
3082 struct wmi_channel_arg *ch;
3083 bool passive;
3084 int len;
3085 int ret;
3086 int i;
3087
Michal Kazior548db542013-07-05 16:15:15 +03003088 lockdep_assert_held(&ar->conf_mutex);
3089
Kalle Valo5e3dd152013-06-12 20:52:10 +03003090 bands = hw->wiphy->bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02003091 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003092 if (!bands[band])
3093 continue;
3094
3095 for (i = 0; i < bands[band]->n_channels; i++) {
3096 if (bands[band]->channels[i].flags &
3097 IEEE80211_CHAN_DISABLED)
3098 continue;
3099
3100 arg.n_channels++;
3101 }
3102 }
3103
3104 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
3105 arg.channels = kzalloc(len, GFP_KERNEL);
3106 if (!arg.channels)
3107 return -ENOMEM;
3108
3109 ch = arg.channels;
Johannes Berg57fbcce2016-04-12 15:56:15 +02003110 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003111 if (!bands[band])
3112 continue;
3113
3114 for (i = 0; i < bands[band]->n_channels; i++) {
3115 channel = &bands[band]->channels[i];
3116
3117 if (channel->flags & IEEE80211_CHAN_DISABLED)
3118 continue;
3119
Eduardo Abinader98029772016-06-30 15:23:55 +03003120 ch->allow_ht = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003121
3122 /* FIXME: when should we really allow VHT? */
3123 ch->allow_vht = true;
3124
3125 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02003126 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003127
3128 ch->ht40plus =
3129 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
3130
Marek Puzyniake8a50f82013-11-20 09:59:47 +02003131 ch->chan_radar =
3132 !!(channel->flags & IEEE80211_CHAN_RADAR);
3133
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02003134 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003135 ch->passive = passive;
3136
Sven Eckelmann3f259112018-07-26 15:59:48 +02003137 /* the firmware is ignoring the "radar" flag of the
3138 * channel and is scanning actively using Probe Requests
3139 * on "Radar detection"/DFS channels which are not
3140 * marked as "available"
3141 */
3142 ch->passive |= ch->chan_radar;
3143
Kalle Valo5e3dd152013-06-12 20:52:10 +03003144 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02003145 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07003146 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07003147 ch->max_power = channel->max_power * 2;
3148 ch->max_reg_power = channel->max_reg_power * 2;
3149 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003150 ch->reg_class_id = 0; /* FIXME */
3151
3152 /* FIXME: why use only legacy modes, why not any
3153 * HT/VHT modes? Would that even make any
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01003154 * difference?
3155 */
Johannes Berg57fbcce2016-04-12 15:56:15 +02003156 if (channel->band == NL80211_BAND_2GHZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003157 ch->mode = MODE_11G;
3158 else
3159 ch->mode = MODE_11A;
3160
3161 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
3162 continue;
3163
Michal Kazior7aa7a722014-08-25 12:09:38 +02003164 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03003165 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
3166 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003167 ch->freq, ch->max_power, ch->max_reg_power,
3168 ch->max_antenna_gain, ch->mode);
3169
3170 ch++;
3171 }
3172 }
3173
3174 ret = ath10k_wmi_scan_chan_list(ar, &arg);
3175 kfree(arg.channels);
3176
3177 return ret;
3178}
3179
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003180static enum wmi_dfs_region
3181ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
3182{
3183 switch (dfs_region) {
3184 case NL80211_DFS_UNSET:
3185 return WMI_UNINIT_DFS_DOMAIN;
3186 case NL80211_DFS_FCC:
3187 return WMI_FCC_DFS_DOMAIN;
3188 case NL80211_DFS_ETSI:
3189 return WMI_ETSI_DFS_DOMAIN;
3190 case NL80211_DFS_JP:
3191 return WMI_MKK4_DFS_DOMAIN;
3192 }
3193 return WMI_UNINIT_DFS_DOMAIN;
3194}
3195
Michal Kaziorf7843d72013-07-16 09:38:52 +02003196static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003197{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003198 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003199 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003200 enum wmi_dfs_region wmi_dfs_reg;
3201 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003202
Michal Kaziorf7843d72013-07-16 09:38:52 +02003203 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003204
3205 ret = ath10k_update_channel_list(ar);
3206 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003207 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003208
3209 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003210
Masahiro Yamada97f26452016-08-03 13:45:50 -07003211 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003212 nl_dfs_reg = ar->dfs_detector->region;
3213 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
3214 } else {
3215 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
3216 }
3217
Kalle Valo5e3dd152013-06-12 20:52:10 +03003218 /* Target allows setting up per-band regdomain but ath_common provides
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01003219 * a combined one only
3220 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003221 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02003222 regpair->reg_domain,
3223 regpair->reg_domain, /* 2ghz */
3224 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003225 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003226 regpair->reg_5ghz_ctl,
3227 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003228 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003229 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02003230}
Michal Kazior548db542013-07-05 16:15:15 +03003231
Kalle Valo46bc92b2017-03-16 11:11:02 +02003232static void ath10k_mac_update_channel_list(struct ath10k *ar,
3233 struct ieee80211_supported_band *band)
Tamizh chelvam523f6702017-02-23 18:48:22 +05303234{
3235 int i;
3236
3237 if (ar->low_5ghz_chan && ar->high_5ghz_chan) {
3238 for (i = 0; i < band->n_channels; i++) {
3239 if (band->channels[i].center_freq < ar->low_5ghz_chan ||
3240 band->channels[i].center_freq > ar->high_5ghz_chan)
3241 band->channels[i].flags |=
3242 IEEE80211_CHAN_DISABLED;
3243 }
3244 }
3245}
3246
Michal Kaziorf7843d72013-07-16 09:38:52 +02003247static void ath10k_reg_notifier(struct wiphy *wiphy,
3248 struct regulatory_request *request)
3249{
3250 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
3251 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003252 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003253
3254 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3255
Masahiro Yamada97f26452016-08-03 13:45:50 -07003256 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003257 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003258 request->dfs_region);
3259 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3260 request->dfs_region);
3261 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003262 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003263 request->dfs_region);
3264 }
3265
Michal Kaziorf7843d72013-07-16 09:38:52 +02003266 mutex_lock(&ar->conf_mutex);
3267 if (ar->state == ATH10K_STATE_ON)
3268 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003269 mutex_unlock(&ar->conf_mutex);
Tamizh chelvam523f6702017-02-23 18:48:22 +05303270
3271 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
3272 ath10k_mac_update_channel_list(ar,
Kalle Valo46bc92b2017-03-16 11:11:02 +02003273 ar->hw->wiphy->bands[NL80211_BAND_5GHZ]);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003274}
3275
Sriram R6f6eb1b2018-05-15 14:39:49 +05303276static void ath10k_stop_radar_confirmation(struct ath10k *ar)
3277{
3278 spin_lock_bh(&ar->data_lock);
3279 ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_STOPPED;
3280 spin_unlock_bh(&ar->data_lock);
3281
3282 cancel_work_sync(&ar->radar_confirmation_work);
3283}
3284
Kalle Valo5e3dd152013-06-12 20:52:10 +03003285/***************/
3286/* TX handlers */
3287/***************/
3288
Michal Kaziora30c7d02016-03-06 16:14:23 +02003289enum ath10k_mac_tx_path {
3290 ATH10K_MAC_TX_HTT,
3291 ATH10K_MAC_TX_HTT_MGMT,
3292 ATH10K_MAC_TX_WMI_MGMT,
3293 ATH10K_MAC_TX_UNKNOWN,
3294};
3295
Michal Kazior96d828d2015-03-31 10:26:23 +00003296void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3297{
3298 lockdep_assert_held(&ar->htt.tx_lock);
3299
3300 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3301 ar->tx_paused |= BIT(reason);
3302 ieee80211_stop_queues(ar->hw);
3303}
3304
3305static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3306 struct ieee80211_vif *vif)
3307{
3308 struct ath10k *ar = data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003309 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior96d828d2015-03-31 10:26:23 +00003310
3311 if (arvif->tx_paused)
3312 return;
3313
3314 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3315}
3316
3317void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3318{
3319 lockdep_assert_held(&ar->htt.tx_lock);
3320
3321 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3322 ar->tx_paused &= ~BIT(reason);
3323
3324 if (ar->tx_paused)
3325 return;
3326
3327 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3328 IEEE80211_IFACE_ITER_RESUME_ALL,
3329 ath10k_mac_tx_unlock_iter,
3330 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003331
3332 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003333}
3334
3335void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3336{
3337 struct ath10k *ar = arvif->ar;
3338
3339 lockdep_assert_held(&ar->htt.tx_lock);
3340
3341 WARN_ON(reason >= BITS_PER_LONG);
3342 arvif->tx_paused |= BIT(reason);
3343 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3344}
3345
3346void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3347{
3348 struct ath10k *ar = arvif->ar;
3349
3350 lockdep_assert_held(&ar->htt.tx_lock);
3351
3352 WARN_ON(reason >= BITS_PER_LONG);
3353 arvif->tx_paused &= ~BIT(reason);
3354
3355 if (ar->tx_paused)
3356 return;
3357
3358 if (arvif->tx_paused)
3359 return;
3360
3361 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3362}
3363
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003364static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3365 enum wmi_tlv_tx_pause_id pause_id,
3366 enum wmi_tlv_tx_pause_action action)
3367{
3368 struct ath10k *ar = arvif->ar;
3369
3370 lockdep_assert_held(&ar->htt.tx_lock);
3371
Michal Kazioracd0b272015-07-09 13:08:38 +02003372 switch (action) {
3373 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3374 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003375 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003376 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3377 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3378 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003379 default:
Bartosz Markowski209b2a62016-09-28 15:11:58 +03003380 ath10k_dbg(ar, ATH10K_DBG_BOOT,
3381 "received unknown tx pause action %d on vdev %i, ignoring\n",
Michal Kazioracd0b272015-07-09 13:08:38 +02003382 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003383 break;
3384 }
3385}
3386
3387struct ath10k_mac_tx_pause {
3388 u32 vdev_id;
3389 enum wmi_tlv_tx_pause_id pause_id;
3390 enum wmi_tlv_tx_pause_action action;
3391};
3392
3393static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3394 struct ieee80211_vif *vif)
3395{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003396 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003397 struct ath10k_mac_tx_pause *arg = data;
3398
Michal Kazioracd0b272015-07-09 13:08:38 +02003399 if (arvif->vdev_id != arg->vdev_id)
3400 return;
3401
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003402 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3403}
3404
Michal Kazioracd0b272015-07-09 13:08:38 +02003405void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3406 enum wmi_tlv_tx_pause_id pause_id,
3407 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003408{
3409 struct ath10k_mac_tx_pause arg = {
3410 .vdev_id = vdev_id,
3411 .pause_id = pause_id,
3412 .action = action,
3413 };
3414
3415 spin_lock_bh(&ar->htt.tx_lock);
3416 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3417 IEEE80211_IFACE_ITER_RESUME_ALL,
3418 ath10k_mac_handle_tx_pause_iter,
3419 &arg);
3420 spin_unlock_bh(&ar->htt.tx_lock);
3421}
3422
Michal Kaziord740d8f2015-03-30 09:51:51 +03003423static enum ath10k_hw_txrx_mode
Michal Kazior6a2636d2015-11-18 06:59:16 +01003424ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3425 struct ieee80211_vif *vif,
3426 struct ieee80211_sta *sta,
3427 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003428{
3429 const struct ieee80211_hdr *hdr = (void *)skb->data;
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003430 const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003431 __le16 fc = hdr->frame_control;
3432
3433 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3434 return ATH10K_HW_TXRX_RAW;
3435
3436 if (ieee80211_is_mgmt(fc))
3437 return ATH10K_HW_TXRX_MGMT;
3438
3439 /* Workaround:
3440 *
3441 * NullFunc frames are mostly used to ping if a client or AP are still
3442 * reachable and responsive. This implies tx status reports must be
3443 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3444 * come to a conclusion that the other end disappeared and tear down
3445 * BSS connection or it can never disconnect from BSS/client (which is
3446 * the case).
3447 *
3448 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3449 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3450 * which seems to deliver correct tx reports for NullFunc frames. The
3451 * downside of using it is it ignores client powersave state so it can
3452 * end up disconnecting sleeping clients in AP mode. It should fix STA
3453 * mode though because AP don't sleep.
3454 */
3455 if (ar->htt.target_version_major < 3 &&
3456 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03003457 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3458 ar->running_fw->fw_file.fw_features))
Michal Kaziord740d8f2015-03-30 09:51:51 +03003459 return ATH10K_HW_TXRX_MGMT;
3460
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003461 /* Workaround:
3462 *
3463 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3464 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3465 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003466 *
3467 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003468 */
3469 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3470 return ATH10K_HW_TXRX_ETHERNET;
3471
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003472 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) ||
3473 skb_cb->flags & ATH10K_SKB_F_RAW_TX)
David Liuccec9032015-07-24 20:25:32 +03003474 return ATH10K_HW_TXRX_RAW;
3475
Michal Kaziord740d8f2015-03-30 09:51:51 +03003476 return ATH10K_HW_TXRX_NATIVE_WIFI;
3477}
3478
David Liuccec9032015-07-24 20:25:32 +03003479static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003480 struct sk_buff *skb)
3481{
3482 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3483 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003484 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3485 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003486
3487 if (!ieee80211_has_protected(hdr->frame_control))
3488 return false;
3489
David Liuccec9032015-07-24 20:25:32 +03003490 if ((info->flags & mask) == mask)
3491 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003492
David Liuccec9032015-07-24 20:25:32 +03003493 if (vif)
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003494 return !((struct ath10k_vif *)vif->drv_priv)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003495
David Liuccec9032015-07-24 20:25:32 +03003496 return true;
3497}
3498
Michal Kazior4b604552014-07-21 21:03:09 +03003499/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3500 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003501 */
Michal Kazior4b604552014-07-21 21:03:09 +03003502static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003503{
3504 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003505 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003506 u8 *qos_ctl;
3507
3508 if (!ieee80211_is_data_qos(hdr->frame_control))
3509 return;
3510
3511 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003512 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3513 skb->data, (void *)qos_ctl - (void *)skb->data);
3514 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003515
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003516 /* Some firmware revisions don't handle sending QoS NullFunc well.
3517 * These frames are mainly used for CQM purposes so it doesn't really
3518 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003519 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003520 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003521 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003522 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003523
3524 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003525}
3526
Michal Kaziord740d8f2015-03-30 09:51:51 +03003527static void ath10k_tx_h_8023(struct sk_buff *skb)
3528{
3529 struct ieee80211_hdr *hdr;
3530 struct rfc1042_hdr *rfc1042;
3531 struct ethhdr *eth;
3532 size_t hdrlen;
3533 u8 da[ETH_ALEN];
3534 u8 sa[ETH_ALEN];
3535 __be16 type;
3536
3537 hdr = (void *)skb->data;
3538 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3539 rfc1042 = (void *)skb->data + hdrlen;
3540
3541 ether_addr_copy(da, ieee80211_get_DA(hdr));
3542 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3543 type = rfc1042->snap_type;
3544
3545 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3546 skb_push(skb, sizeof(*eth));
3547
3548 eth = (void *)skb->data;
3549 ether_addr_copy(eth->h_dest, da);
3550 ether_addr_copy(eth->h_source, sa);
3551 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003552}
3553
Michal Kazior4b604552014-07-21 21:03:09 +03003554static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3555 struct ieee80211_vif *vif,
3556 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003557{
3558 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003559 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003560
3561 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003562 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003563 return;
3564
3565 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3566 spin_lock_bh(&ar->data_lock);
3567 if (arvif->u.ap.noa_data)
3568 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3569 GFP_ATOMIC))
Johannes Berg59ae1d12017-06-16 14:29:20 +02003570 skb_put_data(skb, arvif->u.ap.noa_data,
3571 arvif->u.ap.noa_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003572 spin_unlock_bh(&ar->data_lock);
3573 }
3574}
3575
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003576static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3577 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003578 struct ieee80211_txq *txq,
Kan Yand1ce37b2019-02-11 18:47:52 +02003579 struct sk_buff *skb, u16 airtime)
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003580{
3581 struct ieee80211_hdr *hdr = (void *)skb->data;
3582 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003583 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3584 bool is_data = ieee80211_is_data(hdr->frame_control) ||
3585 ieee80211_is_data_qos(hdr->frame_control);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003586
3587 cb->flags = 0;
3588 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3589 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3590
3591 if (ieee80211_is_mgmt(hdr->frame_control))
3592 cb->flags |= ATH10K_SKB_F_MGMT;
3593
3594 if (ieee80211_is_data_qos(hdr->frame_control))
3595 cb->flags |= ATH10K_SKB_F_QOS;
3596
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003597 /* Data frames encrypted in software will be posted to firmware
3598 * with tx encap mode set to RAW. Ex: Multicast traffic generated
3599 * for a specific VLAN group will always be encrypted in software.
3600 */
3601 if (is_data && ieee80211_has_protected(hdr->frame_control) &&
3602 !info->control.hw_key) {
3603 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3604 cb->flags |= ATH10K_SKB_F_RAW_TX;
3605 }
3606
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003607 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003608 cb->txq = txq;
Kan Yand1ce37b2019-02-11 18:47:52 +02003609 cb->airtime_est = airtime;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003610}
3611
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303612bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003613{
3614 /* FIXME: Not really sure since when the behaviour changed. At some
3615 * point new firmware stopped requiring creation of peer entries for
3616 * offchannel tx (and actually creating them causes issues with wmi-htc
3617 * tx credit replenishment and reliability). Assuming it's at least 3.4
3618 * because that's when the `freq` was introduced to TX_FRM HTT command.
3619 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303620 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303621 ar->htt.target_version_minor >= 4 &&
Kalle Valo77561f92016-04-20 19:45:47 +03003622 ar->running_fw->fw_file.htt_op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003623}
3624
Michal Kaziord740d8f2015-03-30 09:51:51 +03003625static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003626{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003627 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003628 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003629
Michal Kaziord740d8f2015-03-30 09:51:51 +03003630 spin_lock_bh(&ar->data_lock);
3631
3632 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3633 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3634 ret = -ENOSPC;
3635 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003636 }
3637
Michal Kaziord740d8f2015-03-30 09:51:51 +03003638 __skb_queue_tail(q, skb);
3639 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3640
3641unlock:
3642 spin_unlock_bh(&ar->data_lock);
3643
3644 return ret;
3645}
3646
Michal Kaziora30c7d02016-03-06 16:14:23 +02003647static enum ath10k_mac_tx_path
3648ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3649 struct sk_buff *skb,
3650 enum ath10k_hw_txrx_mode txmode)
3651{
3652 switch (txmode) {
3653 case ATH10K_HW_TXRX_RAW:
3654 case ATH10K_HW_TXRX_NATIVE_WIFI:
3655 case ATH10K_HW_TXRX_ETHERNET:
3656 return ATH10K_MAC_TX_HTT;
3657 case ATH10K_HW_TXRX_MGMT:
3658 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Rakesh Pillai229329f2017-12-11 19:52:52 +05303659 ar->running_fw->fw_file.fw_features) ||
3660 test_bit(WMI_SERVICE_MGMT_TX_WMI,
3661 ar->wmi.svc_map))
Michal Kaziora30c7d02016-03-06 16:14:23 +02003662 return ATH10K_MAC_TX_WMI_MGMT;
3663 else if (ar->htt.target_version_major >= 3)
3664 return ATH10K_MAC_TX_HTT;
3665 else
3666 return ATH10K_MAC_TX_HTT_MGMT;
3667 }
3668
3669 return ATH10K_MAC_TX_UNKNOWN;
3670}
3671
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003672static int ath10k_mac_tx_submit(struct ath10k *ar,
3673 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003674 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003675 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003676{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003677 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003678 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003679
3680 switch (txpath) {
3681 case ATH10K_MAC_TX_HTT:
Erik Stromdahl5df6e132018-04-15 14:22:27 +02003682 ret = ath10k_htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003683 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003684 case ATH10K_MAC_TX_HTT_MGMT:
3685 ret = ath10k_htt_mgmt_tx(htt, skb);
3686 break;
3687 case ATH10K_MAC_TX_WMI_MGMT:
3688 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3689 break;
3690 case ATH10K_MAC_TX_UNKNOWN:
3691 WARN_ON_ONCE(1);
3692 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003693 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003694 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003695
3696 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003697 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3698 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003699 ieee80211_free_txskb(ar->hw, skb);
3700 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003701
3702 return ret;
3703}
3704
3705/* This function consumes the sk_buff regardless of return value as far as
3706 * caller is concerned so no freeing is necessary afterwards.
3707 */
3708static int ath10k_mac_tx(struct ath10k *ar,
3709 struct ieee80211_vif *vif,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003710 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003711 enum ath10k_mac_tx_path txpath,
Ben Greearcc6df012017-10-17 17:03:12 -07003712 struct sk_buff *skb, bool noque_offchan)
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003713{
3714 struct ieee80211_hw *hw = ar->hw;
3715 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003716 const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003717 int ret;
3718
3719 /* We should disable CCK RATE due to P2P */
3720 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3721 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3722
3723 switch (txmode) {
3724 case ATH10K_HW_TXRX_MGMT:
3725 case ATH10K_HW_TXRX_NATIVE_WIFI:
3726 ath10k_tx_h_nwifi(hw, skb);
3727 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3728 ath10k_tx_h_seq_no(vif, skb);
3729 break;
3730 case ATH10K_HW_TXRX_ETHERNET:
3731 ath10k_tx_h_8023(skb);
3732 break;
3733 case ATH10K_HW_TXRX_RAW:
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003734 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) &&
3735 !(skb_cb->flags & ATH10K_SKB_F_RAW_TX)) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003736 WARN_ON_ONCE(1);
3737 ieee80211_free_txskb(hw, skb);
3738 return -ENOTSUPP;
3739 }
3740 }
3741
Ben Greearcc6df012017-10-17 17:03:12 -07003742 if (!noque_offchan && info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003743 if (!ath10k_mac_tx_frm_has_freq(ar)) {
Ben Greearcc6df012017-10-17 17:03:12 -07003744 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac queued offchannel skb %pK len %d\n",
3745 skb, skb->len);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003746
3747 skb_queue_tail(&ar->offchan_tx_queue, skb);
3748 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3749 return 0;
3750 }
3751 }
3752
Michal Kazior6421969f2016-03-06 16:14:25 +02003753 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003754 if (ret) {
3755 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3756 return ret;
3757 }
3758
3759 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003760}
3761
3762void ath10k_offchan_tx_purge(struct ath10k *ar)
3763{
3764 struct sk_buff *skb;
3765
3766 for (;;) {
3767 skb = skb_dequeue(&ar->offchan_tx_queue);
3768 if (!skb)
3769 break;
3770
3771 ieee80211_free_txskb(ar->hw, skb);
3772 }
3773}
3774
3775void ath10k_offchan_tx_work(struct work_struct *work)
3776{
3777 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3778 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003779 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003780 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003781 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003782 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003783 struct ieee80211_vif *vif;
3784 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003785 struct sk_buff *skb;
3786 const u8 *peer_addr;
3787 int vdev_id;
3788 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003789 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003790 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003791
3792 /* FW requirement: We must create a peer before FW will send out
3793 * an offchannel frame. Otherwise the frame will be stuck and
3794 * never transmitted. We delete the peer upon tx completion.
3795 * It is unlikely that a peer for offchannel tx will already be
3796 * present. However it may be in some rare cases so account for that.
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01003797 * Otherwise we might remove a legitimate peer and break stuff.
3798 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003799
3800 for (;;) {
3801 skb = skb_dequeue(&ar->offchan_tx_queue);
3802 if (!skb)
3803 break;
3804
3805 mutex_lock(&ar->conf_mutex);
3806
Ben Greearcc6df012017-10-17 17:03:12 -07003807 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK len %d\n",
3808 skb, skb->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003809
3810 hdr = (struct ieee80211_hdr *)skb->data;
3811 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003812
3813 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003814 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003815 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3816 spin_unlock_bh(&ar->data_lock);
3817
3818 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003819 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003820 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003821 peer_addr, vdev_id);
3822
3823 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003824 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3825 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003826 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003827 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003828 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003829 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003830 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003831 }
3832
3833 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003834 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003835 ar->offchan_tx_skb = skb;
3836 spin_unlock_bh(&ar->data_lock);
3837
Michal Kazior8a933962015-11-18 06:59:17 +01003838 /* It's safe to access vif and sta - conf_mutex guarantees that
3839 * sta_state() and remove_interface() are locked exclusively
3840 * out wrt to this offchannel worker.
3841 */
3842 arvif = ath10k_get_arvif(ar, vdev_id);
3843 if (arvif) {
3844 vif = arvif->vif;
3845 sta = ieee80211_find_sta(vif, peer_addr);
3846 } else {
3847 vif = NULL;
3848 sta = NULL;
3849 }
3850
3851 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003852 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003853
Ben Greearcc6df012017-10-17 17:03:12 -07003854 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, true);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003855 if (ret) {
3856 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3857 ret);
3858 /* not serious */
3859 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003860
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003861 time_left =
3862 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3863 if (time_left == 0)
Ben Greearcc6df012017-10-17 17:03:12 -07003864 ath10k_warn(ar, "timed out waiting for offchannel skb %pK, len: %d\n",
3865 skb, skb->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003866
Michal Kazioradaeed72015-08-05 12:15:23 +02003867 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003868 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3869 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003870 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003871 peer_addr, vdev_id, ret);
3872 }
3873
3874 mutex_unlock(&ar->conf_mutex);
3875 }
3876}
3877
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003878void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3879{
3880 struct sk_buff *skb;
3881
3882 for (;;) {
3883 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3884 if (!skb)
3885 break;
3886
3887 ieee80211_free_txskb(ar->hw, skb);
3888 }
3889}
3890
3891void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3892{
3893 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3894 struct sk_buff *skb;
Rakesh Pillai38a13902018-02-27 19:09:07 +02003895 dma_addr_t paddr;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003896 int ret;
3897
3898 for (;;) {
3899 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3900 if (!skb)
3901 break;
3902
Rakesh Pillai38a13902018-02-27 19:09:07 +02003903 if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF,
3904 ar->running_fw->fw_file.fw_features)) {
3905 paddr = dma_map_single(ar->dev, skb->data,
3906 skb->len, DMA_TO_DEVICE);
Bjorn Anderssond43810b2019-10-11 11:28:17 -07003907 if (dma_mapping_error(ar->dev, paddr)) {
3908 ieee80211_free_txskb(ar->hw, skb);
Rakesh Pillai38a13902018-02-27 19:09:07 +02003909 continue;
Bjorn Anderssond43810b2019-10-11 11:28:17 -07003910 }
Rakesh Pillai38a13902018-02-27 19:09:07 +02003911 ret = ath10k_wmi_mgmt_tx_send(ar, skb, paddr);
3912 if (ret) {
3913 ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n",
3914 ret);
3915 dma_unmap_single(ar->dev, paddr, skb->len,
Rakesh Pillai6e8a8992019-01-25 09:51:06 +05303916 DMA_TO_DEVICE);
Rakesh Pillai38a13902018-02-27 19:09:07 +02003917 ieee80211_free_txskb(ar->hw, skb);
3918 }
3919 } else {
3920 ret = ath10k_wmi_mgmt_tx(ar, skb);
3921 if (ret) {
3922 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
3923 ret);
3924 ieee80211_free_txskb(ar->hw, skb);
3925 }
Michal Kazior5fb5e412013-10-28 07:18:13 +01003926 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003927 }
3928}
3929
Michal Kazior29946872016-03-06 16:14:34 +02003930static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3931{
Bob Copelanda66cd732016-06-29 19:29:25 +03003932 struct ath10k_txq *artxq;
Michal Kazior29946872016-03-06 16:14:34 +02003933
3934 if (!txq)
3935 return;
3936
Bob Copelanda66cd732016-06-29 19:29:25 +03003937 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003938 INIT_LIST_HEAD(&artxq->list);
3939}
3940
3941static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3942{
Michal Kaziordd4717b2016-03-06 16:14:39 +02003943 struct ath10k_skb_cb *cb;
3944 struct sk_buff *msdu;
3945 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003946
3947 if (!txq)
3948 return;
3949
Michal Kaziordd4717b2016-03-06 16:14:39 +02003950 spin_lock_bh(&ar->htt.tx_lock);
3951 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3952 cb = ATH10K_SKB_CB(msdu);
3953 if (cb->txq == txq)
3954 cb->txq = NULL;
3955 }
3956 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003957}
3958
Michal Kazior426e10e2016-03-06 16:14:43 +02003959struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
3960 u16 peer_id,
3961 u8 tid)
3962{
3963 struct ath10k_peer *peer;
3964
3965 lockdep_assert_held(&ar->data_lock);
3966
3967 peer = ar->peer_map[peer_id];
3968 if (!peer)
3969 return NULL;
3970
Michal Kazior0a744d92017-01-12 16:14:30 +01003971 if (peer->removed)
3972 return NULL;
3973
Michal Kazior426e10e2016-03-06 16:14:43 +02003974 if (peer->sta)
3975 return peer->sta->txq[tid];
3976 else if (peer->vif)
3977 return peer->vif->txq;
3978 else
3979 return NULL;
3980}
3981
Michal Kazior29946872016-03-06 16:14:34 +02003982static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3983 struct ieee80211_txq *txq)
3984{
Michal Kazior426e10e2016-03-06 16:14:43 +02003985 struct ath10k *ar = hw->priv;
3986 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3987
3988 /* No need to get locks */
Michal Kazior426e10e2016-03-06 16:14:43 +02003989 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3990 return true;
3991
3992 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3993 return true;
3994
3995 if (artxq->num_fw_queued < artxq->num_push_allowed)
3996 return true;
3997
3998 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003999}
4000
Kan Yand1ce37b2019-02-11 18:47:52 +02004001/* Return estimated airtime in microsecond, which is calculated using last
4002 * reported TX rate. This is just a rough estimation because host driver has no
4003 * knowledge of the actual transmit rate, retries or aggregation. If actual
4004 * airtime can be reported by firmware, then delta between estimated and actual
4005 * airtime can be adjusted from deficit.
4006 */
4007#define IEEE80211_ATF_OVERHEAD 100 /* IFS + some slot time */
4008#define IEEE80211_ATF_OVERHEAD_IFS 16 /* IFS only */
4009static u16 ath10k_mac_update_airtime(struct ath10k *ar,
4010 struct ieee80211_txq *txq,
4011 struct sk_buff *skb)
4012{
4013 struct ath10k_sta *arsta;
4014 u32 pktlen;
4015 u16 airtime = 0;
4016
4017 if (!txq || !txq->sta)
4018 return airtime;
4019
Manikanta Pubbisettybb31b7c2019-02-11 18:47:59 +02004020 if (test_bit(WMI_SERVICE_REPORT_AIRTIME, ar->wmi.svc_map))
4021 return airtime;
4022
Kan Yand1ce37b2019-02-11 18:47:52 +02004023 spin_lock_bh(&ar->data_lock);
4024 arsta = (struct ath10k_sta *)txq->sta->drv_priv;
4025
4026 pktlen = skb->len + 38; /* Assume MAC header 30, SNAP 8 for most case */
4027 if (arsta->last_tx_bitrate) {
4028 /* airtime in us, last_tx_bitrate in 100kbps */
4029 airtime = (pktlen * 8 * (1000 / 100))
4030 / arsta->last_tx_bitrate;
4031 /* overhead for media access time and IFS */
4032 airtime += IEEE80211_ATF_OVERHEAD_IFS;
4033 } else {
4034 /* This is mostly for throttle excessive BC/MC frames, and the
4035 * airtime/rate doesn't need be exact. Airtime of BC/MC frames
4036 * in 2G get some discount, which helps prevent very low rate
4037 * frames from being blocked for too long.
4038 */
4039 airtime = (pktlen * 8 * (1000 / 100)) / 60; /* 6M */
4040 airtime += IEEE80211_ATF_OVERHEAD;
4041 }
4042 spin_unlock_bh(&ar->data_lock);
4043
4044 return airtime;
4045}
4046
Michal Kazior426e10e2016-03-06 16:14:43 +02004047int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
4048 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02004049{
Michal Kazior29946872016-03-06 16:14:34 +02004050 struct ath10k *ar = hw->priv;
4051 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02004052 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02004053 struct ieee80211_vif *vif = txq->vif;
4054 struct ieee80211_sta *sta = txq->sta;
4055 enum ath10k_hw_txrx_mode txmode;
4056 enum ath10k_mac_tx_path txpath;
4057 struct sk_buff *skb;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304058 struct ieee80211_hdr *hdr;
Michal Kazior426e10e2016-03-06 16:14:43 +02004059 size_t skb_len;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304060 bool is_mgmt, is_presp;
Michal Kazior29946872016-03-06 16:14:34 +02004061 int ret;
Kan Yand1ce37b2019-02-11 18:47:52 +02004062 u16 airtime;
Michal Kazior29946872016-03-06 16:14:34 +02004063
4064 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304065 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02004066 spin_unlock_bh(&ar->htt.tx_lock);
4067
4068 if (ret)
4069 return ret;
4070
Erik Stromdahl30654762019-06-17 22:01:40 +02004071 skb = ieee80211_tx_dequeue_ni(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02004072 if (!skb) {
4073 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304074 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02004075 spin_unlock_bh(&ar->htt.tx_lock);
4076
4077 return -ENOENT;
4078 }
4079
Kan Yand1ce37b2019-02-11 18:47:52 +02004080 airtime = ath10k_mac_update_airtime(ar, txq, skb);
4081 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
Michal Kazior29946872016-03-06 16:14:34 +02004082
Michal Kazior426e10e2016-03-06 16:14:43 +02004083 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02004084 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
4085 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304086 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
4087
4088 if (is_mgmt) {
4089 hdr = (struct ieee80211_hdr *)skb->data;
4090 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4091
4092 spin_lock_bh(&ar->htt.tx_lock);
4093 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4094
4095 if (ret) {
4096 ath10k_htt_tx_dec_pending(htt);
4097 spin_unlock_bh(&ar->htt.tx_lock);
4098 return ret;
4099 }
4100 spin_unlock_bh(&ar->htt.tx_lock);
4101 }
Michal Kazior29946872016-03-06 16:14:34 +02004102
Ben Greearcc6df012017-10-17 17:03:12 -07004103 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, false);
Michal Kazior29946872016-03-06 16:14:34 +02004104 if (unlikely(ret)) {
4105 ath10k_warn(ar, "failed to push frame: %d\n", ret);
4106
4107 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304108 ath10k_htt_tx_dec_pending(htt);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304109 if (is_mgmt)
4110 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02004111 spin_unlock_bh(&ar->htt.tx_lock);
4112
4113 return ret;
4114 }
4115
Michal Kazior3cc0fef2016-03-06 16:14:41 +02004116 spin_lock_bh(&ar->htt.tx_lock);
4117 artxq->num_fw_queued++;
4118 spin_unlock_bh(&ar->htt.tx_lock);
4119
Michal Kazior426e10e2016-03-06 16:14:43 +02004120 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02004121}
4122
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004123static int ath10k_mac_schedule_txq(struct ieee80211_hw *hw, u32 ac)
Michal Kazior29946872016-03-06 16:14:34 +02004124{
Michal Kazior29946872016-03-06 16:14:34 +02004125 struct ieee80211_txq *txq;
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004126 int ret = 0;
Michal Kazior29946872016-03-06 16:14:34 +02004127
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004128 ieee80211_txq_schedule_start(hw, ac);
4129 while ((txq = ieee80211_next_txq(hw, ac))) {
4130 while (ath10k_mac_tx_can_push(hw, txq)) {
Michal Kazior29946872016-03-06 16:14:34 +02004131 ret = ath10k_mac_tx_push_txq(hw, txq);
4132 if (ret < 0)
4133 break;
4134 }
Felix Fietkau2b4a6692019-03-18 12:00:58 +01004135 ieee80211_return_txq(hw, txq, false);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004136 ath10k_htt_tx_txq_update(hw, txq);
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004137 if (ret == -EBUSY)
Michal Kazior29946872016-03-06 16:14:34 +02004138 break;
Michal Kazior29946872016-03-06 16:14:34 +02004139 }
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004140 ieee80211_txq_schedule_end(hw, ac);
Michal Kazior29946872016-03-06 16:14:34 +02004141
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004142 return ret;
4143}
4144
4145void ath10k_mac_tx_push_pending(struct ath10k *ar)
4146{
4147 struct ieee80211_hw *hw = ar->hw;
4148 u32 ac;
4149
4150 if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)
4151 return;
4152
4153 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
4154 return;
4155
4156 rcu_read_lock();
4157 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
4158 if (ath10k_mac_schedule_txq(hw, ac) == -EBUSY)
4159 break;
4160 }
Michal Kazior29946872016-03-06 16:14:34 +02004161 rcu_read_unlock();
Michal Kazior29946872016-03-06 16:14:34 +02004162}
Niklas Cassel3f049502018-06-18 17:00:49 +03004163EXPORT_SYMBOL(ath10k_mac_tx_push_pending);
Michal Kazior29946872016-03-06 16:14:34 +02004164
Kalle Valo5e3dd152013-06-12 20:52:10 +03004165/************/
4166/* Scanning */
4167/************/
4168
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004169void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004170{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004171 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004172
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004173 switch (ar->scan.state) {
4174 case ATH10K_SCAN_IDLE:
4175 break;
4176 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01004177 case ATH10K_SCAN_ABORTING:
Avraham Stern7947d3e2016-07-05 15:23:12 +03004178 if (!ar->scan.is_roc) {
4179 struct cfg80211_scan_info info = {
4180 .aborted = (ar->scan.state ==
4181 ATH10K_SCAN_ABORTING),
4182 };
4183
4184 ieee80211_scan_completed(ar->hw, &info);
4185 } else if (ar->scan.roc_notify) {
Michal Kaziord710e752015-07-09 13:08:36 +02004186 ieee80211_remain_on_channel_expired(ar->hw);
Avraham Stern7947d3e2016-07-05 15:23:12 +03004187 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004188 /* fall through */
4189 case ATH10K_SCAN_STARTING:
4190 ar->scan.state = ATH10K_SCAN_IDLE;
4191 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01004192 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004193 ath10k_offchan_tx_purge(ar);
4194 cancel_delayed_work(&ar->scan.timeout);
Daniel Wagner881ed542016-08-18 15:12:06 +02004195 complete(&ar->scan.completed);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004196 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004197 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004198}
Kalle Valo5e3dd152013-06-12 20:52:10 +03004199
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004200void ath10k_scan_finish(struct ath10k *ar)
4201{
4202 spin_lock_bh(&ar->data_lock);
4203 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004204 spin_unlock_bh(&ar->data_lock);
4205}
4206
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004207static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004208{
4209 struct wmi_stop_scan_arg arg = {
4210 .req_id = 1, /* FIXME */
4211 .req_type = WMI_SCAN_STOP_ONE,
4212 .u.scan_id = ATH10K_SCAN_ID,
4213 };
4214 int ret;
4215
4216 lockdep_assert_held(&ar->conf_mutex);
4217
Kalle Valo5e3dd152013-06-12 20:52:10 +03004218 ret = ath10k_wmi_stop_scan(ar, &arg);
4219 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004220 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004221 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004222 }
4223
Kalle Valo14e105c2016-04-13 14:13:21 +03004224 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004225 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004226 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004227 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004228 } else if (ret > 0) {
4229 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004230 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004231
4232out:
4233 /* Scan state should be updated upon scan completion but in case
4234 * firmware fails to deliver the event (for whatever reason) it is
4235 * desired to clean up scan state anyway. Firmware may have just
4236 * dropped the scan completion event delivery due to transport pipe
4237 * being overflown with data and/or it can recover on its own before
4238 * next scan request is submitted.
4239 */
4240 spin_lock_bh(&ar->data_lock);
4241 if (ar->scan.state != ATH10K_SCAN_IDLE)
4242 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004243 spin_unlock_bh(&ar->data_lock);
4244
4245 return ret;
4246}
4247
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004248static void ath10k_scan_abort(struct ath10k *ar)
4249{
4250 int ret;
4251
4252 lockdep_assert_held(&ar->conf_mutex);
4253
4254 spin_lock_bh(&ar->data_lock);
4255
4256 switch (ar->scan.state) {
4257 case ATH10K_SCAN_IDLE:
4258 /* This can happen if timeout worker kicked in and called
4259 * abortion while scan completion was being processed.
4260 */
4261 break;
4262 case ATH10K_SCAN_STARTING:
4263 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02004264 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004265 ath10k_scan_state_str(ar->scan.state),
4266 ar->scan.state);
4267 break;
4268 case ATH10K_SCAN_RUNNING:
4269 ar->scan.state = ATH10K_SCAN_ABORTING;
4270 spin_unlock_bh(&ar->data_lock);
4271
4272 ret = ath10k_scan_stop(ar);
4273 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004274 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004275
4276 spin_lock_bh(&ar->data_lock);
4277 break;
4278 }
4279
4280 spin_unlock_bh(&ar->data_lock);
4281}
4282
4283void ath10k_scan_timeout_work(struct work_struct *work)
4284{
4285 struct ath10k *ar = container_of(work, struct ath10k,
4286 scan.timeout.work);
4287
4288 mutex_lock(&ar->conf_mutex);
4289 ath10k_scan_abort(ar);
4290 mutex_unlock(&ar->conf_mutex);
4291}
4292
Kalle Valo5e3dd152013-06-12 20:52:10 +03004293static int ath10k_start_scan(struct ath10k *ar,
4294 const struct wmi_start_scan_arg *arg)
4295{
4296 int ret;
4297
4298 lockdep_assert_held(&ar->conf_mutex);
4299
4300 ret = ath10k_wmi_start_scan(ar, arg);
4301 if (ret)
4302 return ret;
4303
Kalle Valo14e105c2016-04-13 14:13:21 +03004304 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004305 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004306 ret = ath10k_scan_stop(ar);
4307 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004308 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004309
4310 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004311 }
4312
Ben Greear2f9eec02015-02-15 16:50:38 +02004313 /* If we failed to start the scan, return error code at
4314 * this point. This is probably due to some issue in the
4315 * firmware, but no need to wedge the driver due to that...
4316 */
4317 spin_lock_bh(&ar->data_lock);
4318 if (ar->scan.state == ATH10K_SCAN_IDLE) {
4319 spin_unlock_bh(&ar->data_lock);
4320 return -EINVAL;
4321 }
4322 spin_unlock_bh(&ar->data_lock);
4323
Kalle Valo5e3dd152013-06-12 20:52:10 +03004324 return 0;
4325}
4326
4327/**********************/
4328/* mac80211 callbacks */
4329/**********************/
4330
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004331static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4332 struct ieee80211_tx_control *control,
4333 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004334{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004335 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02004336 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03004337 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4338 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004339 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02004340 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02004341 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01004342 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02004343 enum ath10k_mac_tx_path txpath;
4344 bool is_htt;
4345 bool is_mgmt;
4346 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004347 int ret;
Kan Yand1ce37b2019-02-11 18:47:52 +02004348 u16 airtime;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004349
Kan Yand1ce37b2019-02-11 18:47:52 +02004350 airtime = ath10k_mac_update_airtime(ar, txq, skb);
4351 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004352
Michal Kazior8a933962015-11-18 06:59:17 +01004353 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004354 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
4355 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
4356 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304357 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004358
Michal Kazior6421969f2016-03-06 16:14:25 +02004359 if (is_htt) {
4360 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004361 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4362
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304363 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004364 if (ret) {
4365 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4366 ret);
4367 spin_unlock_bh(&ar->htt.tx_lock);
4368 ieee80211_free_txskb(ar->hw, skb);
4369 return;
4370 }
4371
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304372 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4373 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304374 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4375 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304376 ath10k_htt_tx_dec_pending(htt);
4377 spin_unlock_bh(&ar->htt.tx_lock);
4378 ieee80211_free_txskb(ar->hw, skb);
4379 return;
4380 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004381 spin_unlock_bh(&ar->htt.tx_lock);
4382 }
4383
Ben Greearcc6df012017-10-17 17:03:12 -07004384 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, false);
Michal Kazior6421969f2016-03-06 16:14:25 +02004385 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004386 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004387 if (is_htt) {
4388 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304389 ath10k_htt_tx_dec_pending(htt);
4390 if (is_mgmt)
4391 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004392 spin_unlock_bh(&ar->htt.tx_lock);
4393 }
4394 return;
4395 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004396}
4397
Michal Kazior29946872016-03-06 16:14:34 +02004398static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4399 struct ieee80211_txq *txq)
4400{
4401 struct ath10k *ar = hw->priv;
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004402 int ret;
4403 u8 ac;
Michal Kazior29946872016-03-06 16:14:34 +02004404
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004405 ath10k_htt_tx_txq_update(hw, txq);
4406 if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)
4407 return;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304408
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004409 ac = txq->ac;
4410 ieee80211_txq_schedule_start(hw, ac);
4411 txq = ieee80211_next_txq(hw, ac);
4412 if (!txq)
4413 goto out;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304414
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004415 while (ath10k_mac_tx_can_push(hw, txq)) {
4416 ret = ath10k_mac_tx_push_txq(hw, txq);
Erik Stromdahle3148cc2018-05-06 15:25:00 +02004417 if (ret < 0)
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304418 break;
4419 }
Felix Fietkau2b4a6692019-03-18 12:00:58 +01004420 ieee80211_return_txq(hw, txq, false);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004421 ath10k_htt_tx_txq_update(hw, txq);
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004422out:
4423 ieee80211_txq_schedule_end(hw, ac);
Michal Kazior29946872016-03-06 16:14:34 +02004424}
4425
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004426/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004427void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004428{
4429 /* make sure rcu-protected mac80211 tx path itself is drained */
4430 synchronize_net();
4431
4432 ath10k_offchan_tx_purge(ar);
4433 ath10k_mgmt_over_wmi_tx_purge(ar);
4434
4435 cancel_work_sync(&ar->offchan_tx_work);
4436 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4437}
4438
Michal Kazioraffd3212013-07-16 09:54:35 +02004439void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004440{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004441 struct ath10k_vif *arvif;
4442
Michal Kazior818bdd12013-07-16 09:38:57 +02004443 lockdep_assert_held(&ar->conf_mutex);
4444
Michal Kazior19337472014-08-28 12:58:16 +02004445 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4446 ar->filter_flags = 0;
4447 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004448 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004449
4450 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004451 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004452
4453 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004454 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004455
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004456 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004457 ath10k_peer_cleanup_all(ar);
Sriram R6f6eb1b2018-05-15 14:39:49 +05304458 ath10k_stop_radar_confirmation(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004459 ath10k_core_stop(ar);
4460 ath10k_hif_power_down(ar);
4461
4462 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004463 list_for_each_entry(arvif, &ar->arvifs, list)
4464 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004465 spin_unlock_bh(&ar->data_lock);
4466}
4467
Ben Greear46acf7bb2014-05-16 17:15:38 +03004468static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4469{
4470 struct ath10k *ar = hw->priv;
4471
4472 mutex_lock(&ar->conf_mutex);
4473
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304474 *tx_ant = ar->cfg_tx_chainmask;
4475 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03004476
4477 mutex_unlock(&ar->conf_mutex);
4478
4479 return 0;
4480}
4481
Ben Greear5572a952014-11-24 16:22:10 +02004482static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4483{
4484 /* It is not clear that allowing gaps in chainmask
4485 * is helpful. Probably it will not do what user
4486 * is hoping for, so warn in that case.
4487 */
4488 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4489 return;
4490
4491 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4492 dbg, cm);
4493}
4494
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304495static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4496{
4497 int nsts = ar->vht_cap_info;
4498
4499 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4500 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4501
4502 /* If firmware does not deliver to host number of space-time
4503 * streams supported, assume it support up to 4 BF STS and return
4504 * the value for VHT CAP: nsts-1)
4505 */
4506 if (nsts == 0)
4507 return 3;
4508
4509 return nsts;
4510}
4511
4512static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4513{
4514 int sound_dim = ar->vht_cap_info;
4515
4516 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4517 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4518
4519 /* If the sounding dimension is not advertised by the firmware,
4520 * let's use a default value of 1
4521 */
4522 if (sound_dim == 0)
4523 return 1;
4524
4525 return sound_dim;
4526}
4527
4528static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4529{
4530 struct ieee80211_sta_vht_cap vht_cap = {0};
Ben Greearcc914a52017-06-16 10:37:45 +03004531 struct ath10k_hw_params *hw = &ar->hw_params;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304532 u16 mcs_map;
4533 u32 val;
4534 int i;
4535
4536 vht_cap.vht_supported = 1;
4537 vht_cap.cap = ar->vht_cap_info;
4538
4539 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4540 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4541 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4542 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4543 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4544
4545 vht_cap.cap |= val;
4546 }
4547
4548 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4549 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4550 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4551 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4552 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4553
4554 vht_cap.cap |= val;
4555 }
4556
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02004557 /* Currently the firmware seems to be buggy, don't enable 80+80
4558 * mode until that's resolved.
4559 */
4560 if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) &&
Ben Greeare509e592017-06-16 10:37:44 +03004561 (ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == 0)
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02004562 vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
4563
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304564 mcs_map = 0;
4565 for (i = 0; i < 8; i++) {
4566 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4567 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4568 else
4569 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4570 }
4571
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004572 if (ar->cfg_tx_chainmask <= 1)
4573 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4574
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304575 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4576 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4577
Ben Greearcc914a52017-06-16 10:37:45 +03004578 /* If we are supporting 160Mhz or 80+80, then the NIC may be able to do
4579 * a restricted NSS for 160 or 80+80 vs what it can do for 80Mhz. Give
4580 * user-space a clue if that is the case.
4581 */
4582 if ((vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) &&
4583 (hw->vht160_mcs_rx_highest != 0 ||
4584 hw->vht160_mcs_tx_highest != 0)) {
4585 vht_cap.vht_mcs.rx_highest = cpu_to_le16(hw->vht160_mcs_rx_highest);
4586 vht_cap.vht_mcs.tx_highest = cpu_to_le16(hw->vht160_mcs_tx_highest);
4587 }
4588
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304589 return vht_cap;
4590}
4591
4592static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4593{
4594 int i;
4595 struct ieee80211_sta_ht_cap ht_cap = {0};
4596
4597 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4598 return ht_cap;
4599
4600 ht_cap.ht_supported = 1;
4601 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4602 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4603 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4604 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004605 ht_cap.cap |=
4606 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304607
4608 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4609 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4610
4611 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4612 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4613
4614 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4615 u32 smps;
4616
4617 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4618 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4619
4620 ht_cap.cap |= smps;
4621 }
4622
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004623 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304624 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4625
4626 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4627 u32 stbc;
4628
4629 stbc = ar->ht_cap_info;
4630 stbc &= WMI_HT_CAP_RX_STBC;
4631 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4632 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4633 stbc &= IEEE80211_HT_CAP_RX_STBC;
4634
4635 ht_cap.cap |= stbc;
4636 }
4637
Surabhi Vishnoiff488d02019-02-01 11:04:22 +05304638 if (ar->ht_cap_info & WMI_HT_CAP_LDPC || (ar->ht_cap_info &
4639 WMI_HT_CAP_RX_LDPC && (ar->ht_cap_info & WMI_HT_CAP_TX_LDPC)))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304640 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4641
4642 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4643 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4644
4645 /* max AMSDU is implicitly taken from vht_cap_info */
4646 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4647 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4648
4649 for (i = 0; i < ar->num_rf_chains; i++) {
4650 if (ar->cfg_rx_chainmask & BIT(i))
4651 ht_cap.mcs.rx_mask[i] = 0xFF;
4652 }
4653
4654 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4655
4656 return ht_cap;
4657}
4658
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304659static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4660{
4661 struct ieee80211_supported_band *band;
4662 struct ieee80211_sta_vht_cap vht_cap;
4663 struct ieee80211_sta_ht_cap ht_cap;
4664
4665 ht_cap = ath10k_get_ht_cap(ar);
4666 vht_cap = ath10k_create_vht_cap(ar);
4667
4668 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004669 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304670 band->ht_cap = ht_cap;
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304671 }
4672 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004673 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304674 band->ht_cap = ht_cap;
4675 band->vht_cap = vht_cap;
4676 }
4677}
4678
Ben Greear46acf7bb2014-05-16 17:15:38 +03004679static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4680{
4681 int ret;
4682
4683 lockdep_assert_held(&ar->conf_mutex);
4684
Ben Greear5572a952014-11-24 16:22:10 +02004685 ath10k_check_chain_mask(ar, tx_ant, "tx");
4686 ath10k_check_chain_mask(ar, rx_ant, "rx");
4687
Ben Greear46acf7bb2014-05-16 17:15:38 +03004688 ar->cfg_tx_chainmask = tx_ant;
4689 ar->cfg_rx_chainmask = rx_ant;
4690
4691 if ((ar->state != ATH10K_STATE_ON) &&
4692 (ar->state != ATH10K_STATE_RESTARTED))
4693 return 0;
4694
4695 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4696 tx_ant);
4697 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004698 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03004699 ret, tx_ant);
4700 return ret;
4701 }
4702
4703 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4704 rx_ant);
4705 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004706 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03004707 ret, rx_ant);
4708 return ret;
4709 }
4710
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304711 /* Reload HT/VHT capability */
4712 ath10k_mac_setup_ht_vht_cap(ar);
4713
Ben Greear46acf7bb2014-05-16 17:15:38 +03004714 return 0;
4715}
4716
4717static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4718{
4719 struct ath10k *ar = hw->priv;
4720 int ret;
4721
4722 mutex_lock(&ar->conf_mutex);
4723 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4724 mutex_unlock(&ar->conf_mutex);
4725 return ret;
4726}
4727
Bhagavathi Perumal S84758d42018-12-20 14:26:00 +02004728static int __ath10k_fetch_bb_timing_dt(struct ath10k *ar,
4729 struct wmi_bb_timing_cfg_arg *bb_timing)
4730{
4731 struct device_node *node;
4732 const char *fem_name;
4733 int ret;
4734
4735 node = ar->dev->of_node;
4736 if (!node)
4737 return -ENOENT;
4738
4739 ret = of_property_read_string_index(node, "ext-fem-name", 0, &fem_name);
4740 if (ret)
4741 return -ENOENT;
4742
4743 /*
4744 * If external Front End module used in hardware, then default base band timing
4745 * parameter cannot be used since they were fine tuned for reference hardware,
4746 * so choosing different value suitable for that external FEM.
4747 */
4748 if (!strcmp("microsemi-lx5586", fem_name)) {
4749 bb_timing->bb_tx_timing = 0x00;
4750 bb_timing->bb_xpa_timing = 0x0101;
4751 } else {
4752 return -ENOENT;
4753 }
4754
4755 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot bb_tx_timing 0x%x bb_xpa_timing 0x%x\n",
4756 bb_timing->bb_tx_timing, bb_timing->bb_xpa_timing);
4757 return 0;
4758}
4759
Wen Gong13829932019-10-01 15:04:56 +03004760static int ath10k_mac_rfkill_config(struct ath10k *ar)
4761{
4762 u32 param;
4763 int ret;
4764
4765 if (ar->hw_values->rfkill_pin == 0) {
4766 ath10k_warn(ar, "ath10k does not support hardware rfkill with this device\n");
4767 return -EOPNOTSUPP;
4768 }
4769
4770 ath10k_dbg(ar, ATH10K_DBG_MAC,
4771 "mac rfkill_pin %d rfkill_cfg %d rfkill_on_level %d",
4772 ar->hw_values->rfkill_pin, ar->hw_values->rfkill_cfg,
4773 ar->hw_values->rfkill_on_level);
4774
4775 param = FIELD_PREP(WMI_TLV_RFKILL_CFG_RADIO_LEVEL,
4776 ar->hw_values->rfkill_on_level) |
4777 FIELD_PREP(WMI_TLV_RFKILL_CFG_GPIO_PIN_NUM,
4778 ar->hw_values->rfkill_pin) |
4779 FIELD_PREP(WMI_TLV_RFKILL_CFG_PIN_AS_GPIO,
4780 ar->hw_values->rfkill_cfg);
4781
4782 ret = ath10k_wmi_pdev_set_param(ar,
4783 ar->wmi.pdev_param->rfkill_config,
4784 param);
4785 if (ret) {
4786 ath10k_warn(ar,
4787 "failed to set rfkill config 0x%x: %d\n",
4788 param, ret);
4789 return ret;
4790 }
4791 return 0;
4792}
4793
4794int ath10k_mac_rfkill_enable_radio(struct ath10k *ar, bool enable)
4795{
4796 enum wmi_tlv_rfkill_enable_radio param;
4797 int ret;
4798
4799 if (enable)
4800 param = WMI_TLV_RFKILL_ENABLE_RADIO_ON;
4801 else
4802 param = WMI_TLV_RFKILL_ENABLE_RADIO_OFF;
4803
4804 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac rfkill enable %d", param);
4805
4806 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rfkill_enable,
4807 param);
4808 if (ret) {
4809 ath10k_warn(ar, "failed to set rfkill enable param %d: %d\n",
4810 param, ret);
4811 return ret;
4812 }
4813
4814 return 0;
4815}
4816
Kalle Valo5e3dd152013-06-12 20:52:10 +03004817static int ath10k_start(struct ieee80211_hw *hw)
4818{
4819 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304820 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004821 int ret = 0;
Bhagavathi Perumal S84758d42018-12-20 14:26:00 +02004822 struct wmi_bb_timing_cfg_arg bb_timing = {0};
Kalle Valo5e3dd152013-06-12 20:52:10 +03004823
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004824 /*
4825 * This makes sense only when restarting hw. It is harmless to call
Mohammed Shafi Shajakhan6dfdbfc2016-04-26 14:41:36 +03004826 * unconditionally. This is necessary to make sure no HTT/WMI tx
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004827 * commands will be submitted while restarting.
4828 */
4829 ath10k_drain_tx(ar);
4830
Michal Kazior548db542013-07-05 16:15:15 +03004831 mutex_lock(&ar->conf_mutex);
4832
Michal Kaziorc5058f52014-05-26 12:46:03 +03004833 switch (ar->state) {
4834 case ATH10K_STATE_OFF:
4835 ar->state = ATH10K_STATE_ON;
4836 break;
4837 case ATH10K_STATE_RESTARTING:
Michal Kaziorc5058f52014-05-26 12:46:03 +03004838 ar->state = ATH10K_STATE_RESTARTED;
4839 break;
4840 case ATH10K_STATE_ON:
4841 case ATH10K_STATE_RESTARTED:
4842 case ATH10K_STATE_WEDGED:
4843 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004844 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004845 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004846 case ATH10K_STATE_UTF:
4847 ret = -EBUSY;
4848 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004849 }
4850
Wen Gong13829932019-10-01 15:04:56 +03004851 spin_lock_bh(&ar->data_lock);
4852
4853 if (ar->hw_rfkill_on) {
4854 ar->hw_rfkill_on = false;
4855 spin_unlock_bh(&ar->data_lock);
4856 goto err;
4857 }
4858
4859 spin_unlock_bh(&ar->data_lock);
4860
Rakesh Pillai3c545a22019-02-08 15:50:10 +02004861 ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02004862 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004863 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004864 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004865 }
4866
Kalle Valo7ebf7212016-04-20 19:44:51 +03004867 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
4868 &ar->normal_mode_fw);
Michal Kazior818bdd12013-07-16 09:38:57 +02004869 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004870 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004871 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004872 }
4873
Wen Gong13829932019-10-01 15:04:56 +03004874 if (ar->sys_cap_info & WMI_TLV_SYS_CAP_INFO_RFKILL) {
4875 ret = ath10k_mac_rfkill_config(ar);
4876 if (ret && ret != -EOPNOTSUPP) {
4877 ath10k_warn(ar, "failed to configure rfkill: %d", ret);
4878 goto err_core_stop;
4879 }
4880 }
4881
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304882 param = ar->wmi.pdev_param->pmf_qos;
4883 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004884 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004885 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004886 goto err_core_stop;
4887 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004888
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304889 param = ar->wmi.pdev_param->dynamic_bw;
4890 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004891 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004892 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004893 goto err_core_stop;
4894 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004895
Rakesh Pillaif1157692018-10-02 23:33:13 +05304896 if (test_bit(WMI_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi.svc_map)) {
4897 ret = ath10k_wmi_scan_prob_req_oui(ar, ar->mac_addr);
4898 if (ret) {
4899 ath10k_err(ar, "failed to set prob req oui: %i\n", ret);
4900 goto err_core_stop;
4901 }
4902 }
4903
Michal Kaziorcf327842015-03-31 10:26:25 +00004904 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4905 ret = ath10k_wmi_adaptive_qcs(ar, true);
4906 if (ret) {
4907 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4908 ret);
4909 goto err_core_stop;
4910 }
4911 }
4912
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004913 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304914 param = ar->wmi.pdev_param->burst_enable;
4915 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004916 if (ret) {
4917 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4918 goto err_core_stop;
4919 }
4920 }
4921
Govind Singhd5cded12018-04-17 17:37:01 +05304922 param = ar->wmi.pdev_param->idle_ps_config;
4923 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
4924 if (ret && ret != -EOPNOTSUPP) {
4925 ath10k_warn(ar, "failed to enable idle_ps_config: %d\n", ret);
4926 goto err_core_stop;
4927 }
4928
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304929 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7bb2014-05-16 17:15:38 +03004930
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004931 /*
4932 * By default FW set ARP frames ac to voice (6). In that case ARP
4933 * exchange is not working properly for UAPSD enabled AP. ARP requests
4934 * which arrives with access category 0 are processed by network stack
4935 * and send back with access category 0, but FW changes access category
4936 * to 6. Set ARP frames access category to best effort (0) solves
4937 * this problem.
4938 */
4939
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304940 param = ar->wmi.pdev_param->arp_ac_override;
4941 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004942 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004943 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004944 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004945 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004946 }
4947
Maharaja62f77f02015-10-21 11:49:18 +03004948 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
Kalle Valoc4cdf752016-04-20 19:45:18 +03004949 ar->running_fw->fw_file.fw_features)) {
Maharaja62f77f02015-10-21 11:49:18 +03004950 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4951 WMI_CCA_DETECT_LEVEL_AUTO,
4952 WMI_CCA_DETECT_MARGIN_AUTO);
4953 if (ret) {
4954 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4955 ret);
4956 goto err_core_stop;
4957 }
4958 }
4959
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304960 param = ar->wmi.pdev_param->ani_enable;
4961 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304962 if (ret) {
4963 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4964 ret);
4965 goto err_core_stop;
4966 }
4967
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304968 ar->ani_enabled = true;
4969
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304970 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304971 param = ar->wmi.pdev_param->peer_stats_update_period;
4972 ret = ath10k_wmi_pdev_set_param(ar, param,
4973 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4974 if (ret) {
4975 ath10k_warn(ar,
4976 "failed to set peer stats period : %d\n",
4977 ret);
4978 goto err_core_stop;
4979 }
4980 }
4981
Rajkumar Manoharan39136242016-05-27 20:15:59 +05304982 param = ar->wmi.pdev_param->enable_btcoex;
4983 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
4984 test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
4985 ar->running_fw->fw_file.fw_features)) {
4986 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4987 if (ret) {
4988 ath10k_warn(ar,
4989 "failed to set btcoex param: %d\n", ret);
4990 goto err_core_stop;
4991 }
4992 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
4993 }
4994
Bhagavathi Perumal S84758d42018-12-20 14:26:00 +02004995 if (test_bit(WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT, ar->wmi.svc_map)) {
4996 ret = __ath10k_fetch_bb_timing_dt(ar, &bb_timing);
4997 if (!ret) {
4998 ret = ath10k_wmi_pdev_bb_timing(ar, &bb_timing);
4999 if (ret) {
5000 ath10k_warn(ar,
5001 "failed to set bb timings: %d\n",
5002 ret);
5003 goto err_core_stop;
5004 }
5005 }
5006 }
5007
Michal Kaziord6500972014-04-08 09:56:09 +03005008 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02005009 ath10k_regd_update(ar);
5010
Simon Wunderlich855aed12014-08-02 09:12:54 +03005011 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05305012 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03005013
Sriram R6f6eb1b2018-05-15 14:39:49 +05305014 ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_IDLE;
5015
Michal Kaziorae254432014-05-26 12:46:02 +03005016 mutex_unlock(&ar->conf_mutex);
5017 return 0;
5018
5019err_core_stop:
5020 ath10k_core_stop(ar);
5021
5022err_power_down:
5023 ath10k_hif_power_down(ar);
5024
5025err_off:
5026 ar->state = ATH10K_STATE_OFF;
5027
5028err:
Michal Kazior548db542013-07-05 16:15:15 +03005029 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01005030 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005031}
5032
5033static void ath10k_stop(struct ieee80211_hw *hw)
5034{
5035 struct ath10k *ar = hw->priv;
5036
Michal Kaziorbca7baf2014-05-26 12:46:03 +03005037 ath10k_drain_tx(ar);
5038
Michal Kazior548db542013-07-05 16:15:15 +03005039 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03005040 if (ar->state != ATH10K_STATE_OFF) {
Wen Gong13829932019-10-01 15:04:56 +03005041 if (!ar->hw_rfkill_on)
5042 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03005043 ar->state = ATH10K_STATE_OFF;
5044 }
Michal Kazior548db542013-07-05 16:15:15 +03005045 mutex_unlock(&ar->conf_mutex);
5046
Mohammed Shafi Shajakhand94475c2017-03-31 17:28:41 +05305047 cancel_work_sync(&ar->set_coverage_class_work);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005048 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02005049 cancel_work_sync(&ar->restart_work);
5050}
5051
Michal Kaziorad088bf2013-10-16 15:44:46 +03005052static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02005053{
Michal Kaziorad088bf2013-10-16 15:44:46 +03005054 struct ath10k_vif *arvif;
5055 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02005056
5057 lockdep_assert_held(&ar->conf_mutex);
5058
Michal Kaziorad088bf2013-10-16 15:44:46 +03005059 list_for_each_entry(arvif, &ar->arvifs, list) {
5060 ret = ath10k_mac_vif_setup_ps(arvif);
5061 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005062 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03005063 break;
5064 }
5065 }
Michal Kazioraffd3212013-07-16 09:54:35 +02005066
Michal Kaziorad088bf2013-10-16 15:44:46 +03005067 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005068}
5069
Michal Kazior7d9d5582014-10-21 10:40:15 +03005070static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
5071{
5072 int ret;
5073 u32 param;
5074
5075 lockdep_assert_held(&ar->conf_mutex);
5076
5077 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
5078
5079 param = ar->wmi.pdev_param->txpower_limit2g;
5080 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
5081 if (ret) {
5082 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
5083 txpower, ret);
5084 return ret;
5085 }
5086
5087 param = ar->wmi.pdev_param->txpower_limit5g;
5088 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
5089 if (ret) {
5090 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
5091 txpower, ret);
5092 return ret;
5093 }
5094
5095 return 0;
5096}
5097
5098static int ath10k_mac_txpower_recalc(struct ath10k *ar)
5099{
5100 struct ath10k_vif *arvif;
5101 int ret, txpower = -1;
5102
5103 lockdep_assert_held(&ar->conf_mutex);
5104
5105 list_for_each_entry(arvif, &ar->arvifs, list) {
Ryan Hsu88407be2016-12-13 14:55:19 -08005106 if (arvif->txpower <= 0)
5107 continue;
Michal Kazior7d9d5582014-10-21 10:40:15 +03005108
5109 if (txpower == -1)
5110 txpower = arvif->txpower;
5111 else
5112 txpower = min(txpower, arvif->txpower);
5113 }
5114
Ryan Hsu88407be2016-12-13 14:55:19 -08005115 if (txpower == -1)
5116 return 0;
Michal Kazior7d9d5582014-10-21 10:40:15 +03005117
5118 ret = ath10k_mac_txpower_setup(ar, txpower);
5119 if (ret) {
5120 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
5121 txpower, ret);
5122 return ret;
5123 }
5124
5125 return 0;
5126}
5127
Kalle Valo5e3dd152013-06-12 20:52:10 +03005128static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
5129{
Kalle Valo5e3dd152013-06-12 20:52:10 +03005130 struct ath10k *ar = hw->priv;
5131 struct ieee80211_conf *conf = &hw->conf;
5132 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005133
5134 mutex_lock(&ar->conf_mutex);
5135
Michal Kazioraffd3212013-07-16 09:54:35 +02005136 if (changed & IEEE80211_CONF_CHANGE_PS)
5137 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005138
5139 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02005140 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
5141 ret = ath10k_monitor_recalc(ar);
5142 if (ret)
5143 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005144 }
5145
5146 mutex_unlock(&ar->conf_mutex);
5147 return ret;
5148}
5149
Ben Greear5572a952014-11-24 16:22:10 +02005150static u32 get_nss_from_chainmask(u16 chain_mask)
5151{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05305152 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02005153 return 4;
5154 else if ((chain_mask & 0x7) == 0x7)
5155 return 3;
5156 else if ((chain_mask & 0x3) == 0x3)
5157 return 2;
5158 return 1;
5159}
5160
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305161static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
5162{
5163 u32 value = 0;
5164 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02005165 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02005166 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305167
5168 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
5169 return 0;
5170
Bartosz Markowski707a0c82015-09-02 13:20:19 +02005171 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305172 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
5173 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02005174 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305175
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02005176 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305177 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
5178 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02005179 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305180
5181 if (!value)
5182 return 0;
5183
5184 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
5185 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
5186
5187 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
5188 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
5189 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
5190
5191 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
5192 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
5193
5194 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
5195 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
5196 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
5197
5198 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
5199 ar->wmi.vdev_param->txbf, value);
5200}
5201
Kalle Valo5e3dd152013-06-12 20:52:10 +03005202/*
5203 * TODO:
5204 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
5205 * because we will send mgmt frames without CCK. This requirement
5206 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
5207 * in the TX packet.
5208 */
5209static int ath10k_add_interface(struct ieee80211_hw *hw,
5210 struct ieee80211_vif *vif)
5211{
5212 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005213 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005214 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005215 enum wmi_sta_powersave_param param;
5216 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02005217 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005218 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00005219 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005220 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005221
Johannes Berg848955c2014-11-11 12:48:42 +01005222 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
5223
Kalle Valo5e3dd152013-06-12 20:52:10 +03005224 mutex_lock(&ar->conf_mutex);
5225
Michal Kazior0dbd09e2013-07-31 10:55:14 +02005226 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02005227 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02005228
Kalle Valo5e3dd152013-06-12 20:52:10 +03005229 arvif->ar = ar;
5230 arvif->vif = vif;
5231
Ben Greeare63b33f2013-10-22 14:54:14 -07005232 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02005233 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005234 INIT_DELAYED_WORK(&arvif->connection_loss_work,
5235 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03005236
Michal Kazior45c9abc2015-04-21 20:42:58 +03005237 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
5238 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
5239 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
5240 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
5241 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
5242 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
5243 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005244
Michal Kaziore04cafb2015-08-05 12:15:24 +02005245 if (ar->num_peers >= ar->max_num_peers) {
5246 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02005247 ret = -ENOBUFS;
5248 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02005249 }
5250
Ben Greeara9aefb32014-08-12 11:02:19 +03005251 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005252 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03005253 ret = -EBUSY;
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005254 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005255 }
Ben Greear16c11172014-09-23 14:17:16 -07005256 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005257
Ben Greear16c11172014-09-23 14:17:16 -07005258 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
5259 bit, ar->free_vdev_map);
5260
5261 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08005262 arvif->vdev_subtype =
5263 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005264
Kalle Valo5e3dd152013-06-12 20:52:10 +03005265 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01005266 case NL80211_IFTYPE_P2P_DEVICE:
5267 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08005268 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5269 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01005270 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005271 case NL80211_IFTYPE_UNSPECIFIED:
5272 case NL80211_IFTYPE_STATION:
5273 arvif->vdev_type = WMI_VDEV_TYPE_STA;
5274 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08005275 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5276 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005277 break;
5278 case NL80211_IFTYPE_ADHOC:
5279 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
5280 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005281 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08005282 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08005283 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5284 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08005285 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005286 ret = -EINVAL;
5287 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
5288 goto err;
5289 }
5290 arvif->vdev_type = WMI_VDEV_TYPE_AP;
5291 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005292 case NL80211_IFTYPE_AP:
5293 arvif->vdev_type = WMI_VDEV_TYPE_AP;
5294
5295 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08005296 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5297 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005298 break;
5299 case NL80211_IFTYPE_MONITOR:
5300 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
5301 break;
5302 default:
5303 WARN_ON(1);
5304 break;
5305 }
5306
Michal Kazior96d828d2015-03-31 10:26:23 +00005307 /* Using vdev_id as queue number will make it very easy to do per-vif
5308 * tx queue locking. This shouldn't wrap due to interface combinations
5309 * but do a modulo for correctness sake and prevent using offchannel tx
5310 * queues for regular vif tx.
5311 */
5312 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
5313 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
5314 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
5315
Michal Kazior64badcb2014-09-18 11:18:02 +03005316 /* Some firmware revisions don't wait for beacon tx completion before
5317 * sending another SWBA event. This could lead to hardware using old
5318 * (freed) beacon data in some cases, e.g. tx credit starvation
5319 * combined with missed TBTT. This is very very rare.
5320 *
5321 * On non-IOMMU-enabled hosts this could be a possible security issue
5322 * because hw could beacon some random data on the air. On
5323 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
5324 * device would crash.
5325 *
5326 * Since there are no beacon tx completions (implicit nor explicit)
5327 * propagated to host the only workaround for this is to allocate a
5328 * DMA-coherent buffer for a lifetime of a vif and use it for all
5329 * beacon tx commands. Worst case for this approach is some beacons may
5330 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
5331 */
5332 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005333 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03005334 vif->type == NL80211_IFTYPE_AP) {
Luis Chamberlain750afb02019-01-04 09:23:09 +01005335 arvif->beacon_buf = dma_alloc_coherent(ar->dev,
5336 IEEE80211_MAX_FRAME_LEN,
5337 &arvif->beacon_paddr,
5338 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03005339 if (!arvif->beacon_buf) {
5340 ret = -ENOMEM;
5341 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
5342 ret);
5343 goto err;
5344 }
5345 }
David Liuccec9032015-07-24 20:25:32 +03005346 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
5347 arvif->nohwcrypt = true;
5348
5349 if (arvif->nohwcrypt &&
5350 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
5351 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
5352 goto err;
5353 }
Michal Kazior64badcb2014-09-18 11:18:02 +03005354
5355 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
5356 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
5357 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03005358
5359 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
5360 arvif->vdev_subtype, vif->addr);
5361 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005362 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005363 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005364 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005365 }
5366
Sathishkumar Muruganandam68c295f2018-12-20 09:53:30 +02005367 if (test_bit(WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,
5368 ar->wmi.svc_map)) {
5369 vdev_param = ar->wmi.vdev_param->disable_4addr_src_lrn;
5370 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5371 WMI_VDEV_DISABLE_4_ADDR_SRC_LRN);
5372 if (ret && ret != -EOPNOTSUPP) {
5373 ath10k_warn(ar, "failed to disable 4addr src lrn vdev %i: %d\n",
5374 arvif->vdev_id, ret);
5375 }
5376 }
5377
Ben Greear16c11172014-09-23 14:17:16 -07005378 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305379 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005380 list_add(&arvif->list, &ar->arvifs);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305381 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005382
Michal Kazior46725b152015-01-28 09:57:49 +02005383 /* It makes no sense to have firmware do keepalives. mac80211 already
5384 * takes care of this with idle connection polling.
5385 */
5386 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005387 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02005388 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005389 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005390 goto err_vdev_delete;
5391 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005392
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005393 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005394
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005395 vdev_param = ar->wmi.vdev_param->tx_encap_type;
5396 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005397 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02005398 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005399 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005400 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005401 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005402 goto err_vdev_delete;
5403 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005404
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05305405 /* Configuring number of spatial stream for monitor interface is causing
5406 * target assert in qca9888 and qca6174.
5407 */
5408 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02005409 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
5410
5411 vdev_param = ar->wmi.vdev_param->nss;
5412 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5413 nss);
5414 if (ret) {
5415 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
5416 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
5417 ret);
5418 goto err_vdev_delete;
5419 }
5420 }
5421
Michal Kaziore57e0572015-03-24 13:14:03 +00005422 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5423 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02005424 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
5425 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005426 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00005427 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005428 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005429 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005430 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005431
5432 spin_lock_bh(&ar->data_lock);
5433
5434 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
5435 if (!peer) {
5436 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5437 vif->addr, arvif->vdev_id);
5438 spin_unlock_bh(&ar->data_lock);
5439 ret = -ENOENT;
5440 goto err_peer_delete;
5441 }
5442
5443 arvif->peer_id = find_first_bit(peer->peer_ids,
5444 ATH10K_MAX_NUM_PEER_IDS);
5445
5446 spin_unlock_bh(&ar->data_lock);
5447 } else {
5448 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00005449 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01005450
Michal Kaziore57e0572015-03-24 13:14:03 +00005451 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02005452 ret = ath10k_mac_set_kickout(arvif);
5453 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005454 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005455 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02005456 goto err_peer_delete;
5457 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005458 }
5459
5460 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
5461 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
5462 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5463 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5464 param, value);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005465 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005466 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005467 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005468 goto err_peer_delete;
5469 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005470
Michal Kazior9f9b5742014-12-12 12:41:36 +01005471 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005472 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005473 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005474 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005475 goto err_peer_delete;
5476 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005477
Michal Kazior9f9b5742014-12-12 12:41:36 +01005478 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005479 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005480 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005481 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005482 goto err_peer_delete;
5483 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005484 }
5485
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305486 ret = ath10k_mac_set_txbf_conf(arvif);
5487 if (ret) {
5488 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
5489 arvif->vdev_id, ret);
5490 goto err_peer_delete;
5491 }
5492
Michal Kazior424121c2013-07-22 14:13:31 +02005493 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005494 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005495 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03005496 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005497 goto err_peer_delete;
5498 }
Michal Kazior679c54a2013-07-05 16:15:04 +03005499
Michal Kazior7d9d5582014-10-21 10:40:15 +03005500 arvif->txpower = vif->bss_conf.txpower;
5501 ret = ath10k_mac_txpower_recalc(ar);
5502 if (ret) {
5503 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5504 goto err_peer_delete;
5505 }
5506
Pradeep Kumar Chitrapu059104b2019-02-11 18:47:54 +02005507 if (test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map)) {
5508 vdev_param = ar->wmi.vdev_param->rtt_responder_role;
5509 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5510 arvif->ftm_responder);
5511
5512 /* It is harmless to not set FTM role. Do not warn */
5513 if (ret && ret != -EOPNOTSUPP)
5514 ath10k_warn(ar, "failed to set vdev %i FTM Responder: %d\n",
5515 arvif->vdev_id, ret);
5516 }
5517
Michal Kazior500ff9f2015-03-31 10:26:21 +00005518 if (vif->type == NL80211_IFTYPE_MONITOR) {
5519 ar->monitor_arvif = arvif;
5520 ret = ath10k_monitor_recalc(ar);
5521 if (ret) {
5522 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5523 goto err_peer_delete;
5524 }
5525 }
5526
Michal Kazior6d2d51e2015-08-07 09:08:21 +02005527 spin_lock_bh(&ar->htt.tx_lock);
5528 if (!ar->tx_paused)
5529 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
5530 spin_unlock_bh(&ar->htt.tx_lock);
5531
Kalle Valo5e3dd152013-06-12 20:52:10 +03005532 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005533 return 0;
5534
5535err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00005536 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
Dundi Ravitejac6f537a2019-06-03 17:41:51 +03005537 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005538 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
Dundi Ravitejac6f537a2019-06-03 17:41:51 +03005539 ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id,
5540 vif->addr);
5541 }
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005542
5543err_vdev_delete:
5544 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07005545 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305546 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005547 list_del(&arvif->list);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305548 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005549
5550err:
Michal Kazior64badcb2014-09-18 11:18:02 +03005551 if (arvif->beacon_buf) {
5552 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
5553 arvif->beacon_buf, arvif->beacon_paddr);
5554 arvif->beacon_buf = NULL;
5555 }
5556
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005557 mutex_unlock(&ar->conf_mutex);
5558
Kalle Valo5e3dd152013-06-12 20:52:10 +03005559 return ret;
5560}
5561
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005562static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
5563{
5564 int i;
5565
5566 for (i = 0; i < BITS_PER_LONG; i++)
5567 ath10k_mac_vif_tx_unlock(arvif, i);
5568}
5569
Kalle Valo5e3dd152013-06-12 20:52:10 +03005570static void ath10k_remove_interface(struct ieee80211_hw *hw,
5571 struct ieee80211_vif *vif)
5572{
5573 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005574 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior69427262016-03-06 16:14:30 +02005575 struct ath10k_peer *peer;
Rakesh Pillaife36e702019-06-03 17:41:33 +03005576 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005577 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005578 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005579
Michal Kazior81a9a172015-03-05 16:02:17 +02005580 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005581 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005582
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305583 mutex_lock(&ar->conf_mutex);
5584
Simon Wunderlich855aed12014-08-02 09:12:54 +03005585 ret = ath10k_spectral_vif_stop(arvif);
5586 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005587 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005588 arvif->vdev_id, ret);
5589
Ben Greear16c11172014-09-23 14:17:16 -07005590 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305591 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005592 list_del(&arvif->list);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305593 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005594
Michal Kaziore57e0572015-03-24 13:14:03 +00005595 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5596 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005597 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5598 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005599 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005600 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005601 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005602
Dundi Ravitejac6f537a2019-06-03 17:41:51 +03005603 ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id,
5604 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005605 kfree(arvif->u.ap.noa_data);
5606 }
5607
Michal Kazior7aa7a722014-08-25 12:09:38 +02005608 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005609 arvif->vdev_id);
5610
Kalle Valo5e3dd152013-06-12 20:52:10 +03005611 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5612 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005613 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005614 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005615
Rakesh Pillaife36e702019-06-03 17:41:33 +03005616 if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) {
5617 time_left = wait_for_completion_timeout(&ar->vdev_delete_done,
5618 ATH10K_VDEV_DELETE_TIMEOUT_HZ);
5619 if (time_left == 0) {
5620 ath10k_warn(ar, "Timeout in receiving vdev delete response\n");
5621 goto out;
5622 }
5623 }
5624
Michal Kazior2c512052015-02-15 16:50:40 +02005625 /* Some firmware revisions don't notify host about self-peer removal
5626 * until after associated vdev is deleted.
5627 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005628 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5629 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005630 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5631 vif->addr);
5632 if (ret)
5633 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5634 arvif->vdev_id, ret);
5635
5636 spin_lock_bh(&ar->data_lock);
5637 ar->num_peers--;
5638 spin_unlock_bh(&ar->data_lock);
5639 }
5640
Michal Kazior69427262016-03-06 16:14:30 +02005641 spin_lock_bh(&ar->data_lock);
5642 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5643 peer = ar->peer_map[i];
5644 if (!peer)
5645 continue;
5646
5647 if (peer->vif == vif) {
5648 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5649 vif->addr, arvif->vdev_id);
5650 peer->vif = NULL;
5651 }
5652 }
Ben Greearb3281c62019-09-10 16:46:15 +03005653
5654 /* Clean this up late, less opportunity for firmware to access
5655 * DMA memory we have deleted.
5656 */
5657 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior69427262016-03-06 16:14:30 +02005658 spin_unlock_bh(&ar->data_lock);
5659
Kalle Valo5e3dd152013-06-12 20:52:10 +03005660 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005661 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005662
Michal Kazior500ff9f2015-03-31 10:26:21 +00005663 if (vif->type == NL80211_IFTYPE_MONITOR) {
5664 ar->monitor_arvif = NULL;
5665 ret = ath10k_monitor_recalc(ar);
5666 if (ret)
5667 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5668 }
5669
Ryan Hsud679fa12016-12-22 14:31:46 -08005670 ret = ath10k_mac_txpower_recalc(ar);
5671 if (ret)
5672 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5673
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005674 spin_lock_bh(&ar->htt.tx_lock);
5675 ath10k_mac_vif_tx_unlock_all(arvif);
5676 spin_unlock_bh(&ar->htt.tx_lock);
5677
Michal Kazior29946872016-03-06 16:14:34 +02005678 ath10k_mac_txq_unref(ar, vif->txq);
5679
Rakesh Pillaife36e702019-06-03 17:41:33 +03005680out:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005681 mutex_unlock(&ar->conf_mutex);
5682}
5683
5684/*
5685 * FIXME: Has to be verified.
5686 */
5687#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005688 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005689 FIF_CONTROL | \
5690 FIF_PSPOLL | \
5691 FIF_OTHER_BSS | \
5692 FIF_BCN_PRBRESP_PROMISC | \
5693 FIF_PROBE_REQ | \
5694 FIF_FCSFAIL)
5695
5696static void ath10k_configure_filter(struct ieee80211_hw *hw,
5697 unsigned int changed_flags,
5698 unsigned int *total_flags,
5699 u64 multicast)
5700{
5701 struct ath10k *ar = hw->priv;
5702 int ret;
5703
5704 mutex_lock(&ar->conf_mutex);
5705
5706 changed_flags &= SUPPORTED_FILTERS;
5707 *total_flags &= SUPPORTED_FILTERS;
5708 ar->filter_flags = *total_flags;
5709
Michal Kazior19337472014-08-28 12:58:16 +02005710 ret = ath10k_monitor_recalc(ar);
5711 if (ret)
Colin Ian King7f03d302016-08-26 19:08:52 +01005712 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005713
5714 mutex_unlock(&ar->conf_mutex);
5715}
5716
Sven Eckelmann0227ff362019-07-03 16:19:49 +02005717static void ath10k_recalculate_mgmt_rate(struct ath10k *ar,
5718 struct ieee80211_vif *vif,
5719 struct cfg80211_chan_def *def)
5720{
5721 struct ath10k_vif *arvif = (void *)vif->drv_priv;
5722 const struct ieee80211_supported_band *sband;
5723 u8 basic_rate_idx;
5724 int hw_rate_code;
5725 u32 vdev_param;
5726 u16 bitrate;
5727 int ret;
5728
5729 lockdep_assert_held(&ar->conf_mutex);
5730
5731 sband = ar->hw->wiphy->bands[def->chan->band];
5732 basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
5733 bitrate = sband->bitrates[basic_rate_idx].bitrate;
5734
5735 hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
5736 if (hw_rate_code < 0) {
5737 ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
5738 return;
5739 }
5740
5741 vdev_param = ar->wmi.vdev_param->mgmt_rate;
5742 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5743 hw_rate_code);
5744 if (ret)
5745 ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
5746}
5747
Kalle Valo5e3dd152013-06-12 20:52:10 +03005748static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5749 struct ieee80211_vif *vif,
5750 struct ieee80211_bss_conf *info,
5751 u32 changed)
5752{
5753 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005754 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005755 struct cfg80211_chan_def def;
Kalle Valoaf762c02014-09-14 12:50:17 +03005756 u32 vdev_param, pdev_param, slottime, preamble;
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005757 u16 bitrate, hw_value;
Sven Eckelmann0227ff362019-07-03 16:19:49 +02005758 u8 rate, rateidx;
5759 int ret = 0, mcast_rate;
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005760 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005761
5762 mutex_lock(&ar->conf_mutex);
5763
5764 if (changed & BSS_CHANGED_IBSS)
5765 ath10k_control_ibss(arvif, info, vif->addr);
5766
5767 if (changed & BSS_CHANGED_BEACON_INT) {
5768 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005769 vdev_param = ar->wmi.vdev_param->beacon_interval;
5770 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005771 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005772 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005773 "mac vdev %d beacon_interval %d\n",
5774 arvif->vdev_id, arvif->beacon_interval);
5775
Kalle Valo5e3dd152013-06-12 20:52:10 +03005776 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005777 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005778 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005779 }
5780
5781 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005782 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005783 "vdev %d set beacon tx mode to staggered\n",
5784 arvif->vdev_id);
5785
Bartosz Markowski226a3392013-09-26 17:47:16 +02005786 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5787 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005788 WMI_BEACON_STAGGERED_MODE);
5789 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005790 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005791 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005792
5793 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5794 if (ret)
5795 ath10k_warn(ar, "failed to update beacon template: %d\n",
5796 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005797
5798 if (ieee80211_vif_is_mesh(vif)) {
5799 /* mesh doesn't use SSID but firmware needs it */
5800 strncpy(arvif->u.ap.ssid, "mesh",
5801 sizeof(arvif->u.ap.ssid));
5802 arvif->u.ap.ssid_len = 4;
5803 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005804 }
5805
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005806 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5807 ret = ath10k_mac_setup_prb_tmpl(arvif);
5808 if (ret)
5809 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5810 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005811 }
5812
Michal Kaziorba2479f2015-01-24 12:14:51 +02005813 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005814 arvif->dtim_period = info->dtim_period;
5815
Michal Kazior7aa7a722014-08-25 12:09:38 +02005816 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005817 "mac vdev %d dtim_period %d\n",
5818 arvif->vdev_id, arvif->dtim_period);
5819
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005820 vdev_param = ar->wmi.vdev_param->dtim_period;
5821 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005822 arvif->dtim_period);
5823 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005824 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005825 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005826 }
5827
5828 if (changed & BSS_CHANGED_SSID &&
5829 vif->type == NL80211_IFTYPE_AP) {
5830 arvif->u.ap.ssid_len = info->ssid_len;
5831 if (info->ssid_len)
5832 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5833 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5834 }
5835
Michal Kazior077efc82014-10-21 10:10:29 +03005836 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5837 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005838
Pradeep Kumar Chitrapu059104b2019-02-11 18:47:54 +02005839 if (changed & BSS_CHANGED_FTM_RESPONDER &&
5840 arvif->ftm_responder != info->ftm_responder &&
5841 test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map)) {
5842 arvif->ftm_responder = info->ftm_responder;
5843
5844 vdev_param = ar->wmi.vdev_param->rtt_responder_role;
5845 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5846 arvif->ftm_responder);
5847
5848 ath10k_dbg(ar, ATH10K_DBG_MAC,
5849 "mac vdev %d ftm_responder %d:ret %d\n",
5850 arvif->vdev_id, arvif->ftm_responder, ret);
5851 }
5852
Kalle Valo5e3dd152013-06-12 20:52:10 +03005853 if (changed & BSS_CHANGED_BEACON_ENABLED)
5854 ath10k_control_beaconing(arvif, info);
5855
5856 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005857 arvif->use_cts_prot = info->use_cts_prot;
Kalle Valo60c3daa2013-09-08 17:56:07 +03005858
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005859 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005860 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005861 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005862 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005863
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02005864 if (ath10k_mac_can_set_cts_prot(arvif)) {
5865 ret = ath10k_mac_set_cts_prot(arvif);
5866 if (ret)
5867 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
5868 arvif->vdev_id, ret);
5869 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005870 }
5871
5872 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005873 if (info->use_short_slot)
5874 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5875
5876 else
5877 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5878
Michal Kazior7aa7a722014-08-25 12:09:38 +02005879 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005880 arvif->vdev_id, slottime);
5881
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005882 vdev_param = ar->wmi.vdev_param->slot_time;
5883 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005884 slottime);
5885 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005886 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005887 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005888 }
5889
5890 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005891 if (info->use_short_preamble)
5892 preamble = WMI_VDEV_PREAMBLE_SHORT;
5893 else
5894 preamble = WMI_VDEV_PREAMBLE_LONG;
5895
Michal Kazior7aa7a722014-08-25 12:09:38 +02005896 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005897 "mac vdev %d preamble %dn",
5898 arvif->vdev_id, preamble);
5899
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005900 vdev_param = ar->wmi.vdev_param->preamble;
5901 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005902 preamble);
5903 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005904 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005905 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005906 }
5907
5908 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005909 if (info->assoc) {
5910 /* Workaround: Make sure monitor vdev is not running
5911 * when associating to prevent some firmware revisions
5912 * (e.g. 10.1 and 10.2) from crashing.
5913 */
5914 if (ar->monitor_started)
5915 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005916 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005917 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005918 } else {
5919 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005920 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005921 }
5922
Michal Kazior7d9d5582014-10-21 10:40:15 +03005923 if (changed & BSS_CHANGED_TXPOWER) {
5924 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5925 arvif->vdev_id, info->txpower);
5926
5927 arvif->txpower = info->txpower;
5928 ret = ath10k_mac_txpower_recalc(ar);
5929 if (ret)
5930 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5931 }
5932
Michal Kaziorbf14e652014-12-12 12:41:38 +01005933 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005934 arvif->ps = vif->bss_conf.ps;
5935
5936 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005937 if (ret)
5938 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5939 arvif->vdev_id, ret);
5940 }
5941
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005942 if (changed & BSS_CHANGED_MCAST_RATE &&
Rafael J. Wysocki9e80ad32019-03-03 18:24:33 +01005943 !ath10k_mac_vif_chan(arvif->vif, &def)) {
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005944 band = def.chan->band;
Pradeep kumar Chitrapu93ee3d12019-04-23 16:43:28 +03005945 mcast_rate = vif->bss_conf.mcast_rate[band];
5946 if (mcast_rate > 0)
5947 rateidx = mcast_rate - 1;
5948 else
5949 rateidx = ffs(vif->bss_conf.basic_rates) - 1;
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005950
5951 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
5952 rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
5953
5954 bitrate = ath10k_wmi_legacy_rates[rateidx].bitrate;
5955 hw_value = ath10k_wmi_legacy_rates[rateidx].hw_value;
5956 if (ath10k_mac_bitrate_is_cck(bitrate))
5957 preamble = WMI_RATE_PREAMBLE_CCK;
5958 else
5959 preamble = WMI_RATE_PREAMBLE_OFDM;
5960
5961 rate = ATH10K_HW_RATECODE(hw_value, 0, preamble);
5962
5963 ath10k_dbg(ar, ATH10K_DBG_MAC,
5964 "mac vdev %d mcast_rate %x\n",
5965 arvif->vdev_id, rate);
5966
5967 vdev_param = ar->wmi.vdev_param->mcast_data_rate;
5968 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
5969 vdev_param, rate);
5970 if (ret)
5971 ath10k_warn(ar,
5972 "failed to set mcast rate on vdev %i: %d\n",
5973 arvif->vdev_id, ret);
5974
5975 vdev_param = ar->wmi.vdev_param->bcast_data_rate;
5976 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
5977 vdev_param, rate);
5978 if (ret)
5979 ath10k_warn(ar,
5980 "failed to set bcast rate on vdev %i: %d\n",
5981 arvif->vdev_id, ret);
5982 }
5983
Sven Eckelmann0227ff362019-07-03 16:19:49 +02005984 if (changed & BSS_CHANGED_BASIC_RATES &&
5985 !ath10k_mac_vif_chan(arvif->vif, &def))
5986 ath10k_recalculate_mgmt_rate(ar, vif, &def);
Sriram Rf279294e2018-09-10 11:09:40 +05305987
Kalle Valo5e3dd152013-06-12 20:52:10 +03005988 mutex_unlock(&ar->conf_mutex);
5989}
5990
Benjamin Bergebee76f2016-09-28 15:11:58 +03005991static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, s16 value)
5992{
5993 struct ath10k *ar = hw->priv;
5994
5995 /* This function should never be called if setting the coverage class
5996 * is not supported on this hardware.
5997 */
5998 if (!ar->hw_params.hw_ops->set_coverage_class) {
5999 WARN_ON_ONCE(1);
6000 return;
6001 }
6002 ar->hw_params.hw_ops->set_coverage_class(ar, value);
6003}
6004
Anilkumar Kollidd0f9cd2017-10-27 11:12:27 +03006005struct ath10k_mac_tdls_iter_data {
6006 u32 num_tdls_stations;
6007 struct ieee80211_vif *curr_vif;
6008};
6009
6010static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
6011 struct ieee80211_sta *sta)
6012{
6013 struct ath10k_mac_tdls_iter_data *iter_data = data;
6014 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6015 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
6016
6017 if (sta->tdls && sta_vif == iter_data->curr_vif)
6018 iter_data->num_tdls_stations++;
6019}
6020
6021static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
6022 struct ieee80211_vif *vif)
6023{
6024 struct ath10k_mac_tdls_iter_data data = {};
6025
6026 data.curr_vif = vif;
6027
6028 ieee80211_iterate_stations_atomic(hw,
6029 ath10k_mac_tdls_vif_stations_count_iter,
6030 &data);
6031 return data.num_tdls_stations;
6032}
6033
Kalle Valo5e3dd152013-06-12 20:52:10 +03006034static int ath10k_hw_scan(struct ieee80211_hw *hw,
6035 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02006036 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006037{
6038 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006039 struct ath10k_vif *arvif = (void *)vif->drv_priv;
David Spinadelc56ef672014-02-05 15:21:13 +02006040 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006041 struct wmi_start_scan_arg arg;
6042 int ret = 0;
6043 int i;
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03006044 u32 scan_timeout;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006045
6046 mutex_lock(&ar->conf_mutex);
6047
Anilkumar Kollia6080932017-10-27 11:12:28 +03006048 if (ath10k_mac_tdls_vif_stations_count(hw, vif) > 0) {
6049 ret = -EBUSY;
6050 goto exit;
6051 }
6052
Kalle Valo5e3dd152013-06-12 20:52:10 +03006053 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006054 switch (ar->scan.state) {
6055 case ATH10K_SCAN_IDLE:
6056 reinit_completion(&ar->scan.started);
6057 reinit_completion(&ar->scan.completed);
6058 ar->scan.state = ATH10K_SCAN_STARTING;
6059 ar->scan.is_roc = false;
6060 ar->scan.vdev_id = arvif->vdev_id;
6061 ret = 0;
6062 break;
6063 case ATH10K_SCAN_STARTING:
6064 case ATH10K_SCAN_RUNNING:
6065 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006066 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006067 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006068 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006069 spin_unlock_bh(&ar->data_lock);
6070
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006071 if (ret)
6072 goto exit;
6073
Kalle Valo5e3dd152013-06-12 20:52:10 +03006074 memset(&arg, 0, sizeof(arg));
6075 ath10k_wmi_start_scan_init(ar, &arg);
6076 arg.vdev_id = arvif->vdev_id;
6077 arg.scan_id = ATH10K_SCAN_ID;
6078
Kalle Valo5e3dd152013-06-12 20:52:10 +03006079 if (req->ie_len) {
6080 arg.ie_len = req->ie_len;
6081 memcpy(arg.ie, req->ie, arg.ie_len);
6082 }
6083
6084 if (req->n_ssids) {
6085 arg.n_ssids = req->n_ssids;
6086 for (i = 0; i < arg.n_ssids; i++) {
6087 arg.ssids[i].len = req->ssids[i].ssid_len;
6088 arg.ssids[i].ssid = req->ssids[i].ssid;
6089 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02006090 } else {
6091 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006092 }
6093
Carl Huang60e1d0f2018-04-19 19:39:40 +03006094 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
6095 arg.scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ;
6096 ether_addr_copy(arg.mac_addr.addr, req->mac_addr);
6097 ether_addr_copy(arg.mac_mask.addr, req->mac_addr_mask);
6098 }
6099
Kalle Valo5e3dd152013-06-12 20:52:10 +03006100 if (req->n_channels) {
6101 arg.n_channels = req->n_channels;
6102 for (i = 0; i < arg.n_channels; i++)
6103 arg.channels[i] = req->channels[i]->center_freq;
6104 }
6105
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03006106 /* if duration is set, default dwell times will be overwritten */
6107 if (req->duration) {
6108 arg.dwell_time_active = req->duration;
6109 arg.dwell_time_passive = req->duration;
6110 arg.burst_duration_ms = req->duration;
6111
6112 scan_timeout = min_t(u32, arg.max_rest_time *
6113 (arg.n_channels - 1) + (req->duration +
6114 ATH10K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) *
6115 arg.n_channels, arg.max_scan_time + 200);
6116
6117 } else {
6118 /* Add a 200ms margin to account for event/command processing */
6119 scan_timeout = arg.max_scan_time + 200;
6120 }
6121
Kalle Valo5e3dd152013-06-12 20:52:10 +03006122 ret = ath10k_start_scan(ar, &arg);
6123 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006124 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006125 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006126 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006127 spin_unlock_bh(&ar->data_lock);
6128 }
6129
Michal Kazior634349b2015-09-03 10:43:45 +02006130 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03006131 msecs_to_jiffies(scan_timeout));
Michal Kazior634349b2015-09-03 10:43:45 +02006132
Kalle Valo5e3dd152013-06-12 20:52:10 +03006133exit:
6134 mutex_unlock(&ar->conf_mutex);
6135 return ret;
6136}
6137
6138static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
6139 struct ieee80211_vif *vif)
6140{
6141 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006142
6143 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006144 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006145 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01006146
6147 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006148}
6149
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006150static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
6151 struct ath10k_vif *arvif,
6152 enum set_key_cmd cmd,
6153 struct ieee80211_key_conf *key)
6154{
6155 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
6156 int ret;
6157
6158 /* 10.1 firmware branch requires default key index to be set to group
6159 * key index after installing it. Otherwise FW/HW Txes corrupted
6160 * frames with multi-vif APs. This is not required for main firmware
6161 * branch (e.g. 636).
6162 *
Michal Kazior8461baf2015-04-10 13:23:22 +00006163 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
6164 *
6165 * FIXME: It remains unknown if this is required for multi-vif STA
6166 * interfaces on 10.1.
6167 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006168
Michal Kazior8461baf2015-04-10 13:23:22 +00006169 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
6170 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006171 return;
6172
6173 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
6174 return;
6175
6176 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
6177 return;
6178
6179 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
6180 return;
6181
6182 if (cmd != SET_KEY)
6183 return;
6184
6185 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
6186 key->keyidx);
6187 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006188 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02006189 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006190}
6191
Kalle Valo5e3dd152013-06-12 20:52:10 +03006192static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
6193 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
6194 struct ieee80211_key_conf *key)
6195{
6196 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006197 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006198 struct ath10k_peer *peer;
6199 const u8 *peer_addr;
6200 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
6201 key->cipher == WLAN_CIPHER_SUITE_WEP104;
6202 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00006203 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01006204 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00006205 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006206
Bartosz Markowskid7131c02015-03-10 14:32:19 +01006207 /* this one needs to be done in software */
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07006208 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
6209 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
6210 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 ||
6211 key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)
Bartosz Markowskid7131c02015-03-10 14:32:19 +01006212 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006213
David Liuccec9032015-07-24 20:25:32 +03006214 if (arvif->nohwcrypt)
6215 return 1;
6216
Kalle Valo5e3dd152013-06-12 20:52:10 +03006217 if (key->keyidx > WMI_MAX_KEY_INDEX)
6218 return -ENOSPC;
6219
6220 mutex_lock(&ar->conf_mutex);
6221
6222 if (sta)
6223 peer_addr = sta->addr;
6224 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
6225 peer_addr = vif->bss_conf.bssid;
6226 else
6227 peer_addr = vif->addr;
6228
6229 key->hw_key_idx = key->keyidx;
6230
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03006231 if (is_wep) {
6232 if (cmd == SET_KEY)
6233 arvif->wep_keys[key->keyidx] = key;
6234 else
6235 arvif->wep_keys[key->keyidx] = NULL;
6236 }
6237
Kalle Valo5e3dd152013-06-12 20:52:10 +03006238 /* the peer should not disappear in mid-way (unless FW goes awry) since
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01006239 * we already hold conf_mutex. we just make sure its there now.
6240 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006241 spin_lock_bh(&ar->data_lock);
6242 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
6243 spin_unlock_bh(&ar->data_lock);
6244
6245 if (!peer) {
6246 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006247 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03006248 peer_addr);
6249 ret = -EOPNOTSUPP;
6250 goto exit;
6251 } else {
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01006252 /* if the peer doesn't exist there is no key to disable anymore */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006253 goto exit;
6254 }
6255 }
6256
Michal Kazior7cc45732015-03-09 14:24:17 +01006257 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
6258 flags |= WMI_KEY_PAIRWISE;
6259 else
6260 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006261
Kalle Valo5e3dd152013-06-12 20:52:10 +03006262 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006263 if (cmd == DISABLE_KEY)
6264 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01006265
Michal Kaziorad325cb2015-02-18 14:02:27 +01006266 /* When WEP keys are uploaded it's possible that there are
6267 * stations associated already (e.g. when merging) without any
6268 * keys. Static WEP needs an explicit per-peer key upload.
6269 */
6270 if (vif->type == NL80211_IFTYPE_ADHOC &&
6271 cmd == SET_KEY)
6272 ath10k_mac_vif_update_wep_key(arvif, key);
6273
Michal Kazior370e5672015-02-18 14:02:26 +01006274 /* 802.1x never sets the def_wep_key_idx so each set_key()
6275 * call changes default tx key.
6276 *
6277 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
6278 * after first set_key().
6279 */
6280 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
6281 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006282 }
6283
Michal Kazior370e5672015-02-18 14:02:26 +01006284 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006285 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03006286 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02006287 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02006288 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006289 goto exit;
6290 }
6291
Michal Kazior29a10002015-04-10 13:05:58 +00006292 /* mac80211 sets static WEP keys as groupwise while firmware requires
6293 * them to be installed twice as both pairwise and groupwise.
6294 */
6295 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
6296 flags2 = flags;
6297 flags2 &= ~WMI_KEY_GROUP;
6298 flags2 |= WMI_KEY_PAIRWISE;
6299
6300 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
6301 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03006302 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00006303 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
6304 arvif->vdev_id, peer_addr, ret);
6305 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
6306 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03006307 if (ret2) {
6308 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00006309 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
6310 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03006311 }
Michal Kazior29a10002015-04-10 13:05:58 +00006312 goto exit;
6313 }
6314 }
6315
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006316 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
6317
Kalle Valo5e3dd152013-06-12 20:52:10 +03006318 spin_lock_bh(&ar->data_lock);
6319 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
6320 if (peer && cmd == SET_KEY)
6321 peer->keys[key->keyidx] = key;
6322 else if (peer && cmd == DISABLE_KEY)
6323 peer->keys[key->keyidx] = NULL;
6324 else if (peer == NULL)
6325 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006326 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006327 spin_unlock_bh(&ar->data_lock);
6328
Yingying Tang9cdd0052018-03-28 12:15:35 +03006329 if (sta && sta->tdls)
6330 ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
Rakesh Pillaic0e33fe2019-02-19 11:39:36 +05306331 ar->wmi.peer_param->authorize, 1);
Yingying Tang9cdd0052018-03-28 12:15:35 +03006332
Kalle Valo5e3dd152013-06-12 20:52:10 +03006333exit:
6334 mutex_unlock(&ar->conf_mutex);
6335 return ret;
6336}
6337
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006338static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
6339 struct ieee80211_vif *vif,
6340 int keyidx)
6341{
6342 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006343 struct ath10k_vif *arvif = (void *)vif->drv_priv;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006344 int ret;
6345
6346 mutex_lock(&arvif->ar->conf_mutex);
6347
6348 if (arvif->ar->state != ATH10K_STATE_ON)
6349 goto unlock;
6350
6351 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
6352 arvif->vdev_id, keyidx);
6353
6354 ret = ath10k_wmi_vdev_set_param(arvif->ar,
6355 arvif->vdev_id,
6356 arvif->ar->wmi.vdev_param->def_keyid,
6357 keyidx);
6358
6359 if (ret) {
6360 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
6361 arvif->vdev_id,
6362 ret);
6363 goto unlock;
6364 }
6365
6366 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01006367
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006368unlock:
6369 mutex_unlock(&arvif->ar->conf_mutex);
6370}
6371
Michal Kazior9797feb2014-02-14 14:49:48 +01006372static void ath10k_sta_rc_update_wk(struct work_struct *wk)
6373{
6374 struct ath10k *ar;
6375 struct ath10k_vif *arvif;
6376 struct ath10k_sta *arsta;
6377 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006378 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02006379 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006380 const u8 *ht_mcs_mask;
6381 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01006382 u32 changed, bw, nss, smps;
6383 int err;
6384
6385 arsta = container_of(wk, struct ath10k_sta, update_wk);
6386 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
6387 arvif = arsta->arvif;
6388 ar = arvif->ar;
6389
Michal Kazior45c9abc2015-04-21 20:42:58 +03006390 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
6391 return;
6392
6393 band = def.chan->band;
6394 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
6395 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
6396
Michal Kazior9797feb2014-02-14 14:49:48 +01006397 spin_lock_bh(&ar->data_lock);
6398
6399 changed = arsta->changed;
6400 arsta->changed = 0;
6401
6402 bw = arsta->bw;
6403 nss = arsta->nss;
6404 smps = arsta->smps;
6405
6406 spin_unlock_bh(&ar->data_lock);
6407
6408 mutex_lock(&ar->conf_mutex);
6409
Michal Kazior45c9abc2015-04-21 20:42:58 +03006410 nss = max_t(u32, 1, nss);
6411 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6412 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6413
Michal Kazior9797feb2014-02-14 14:49:48 +01006414 if (changed & IEEE80211_RC_BW_CHANGED) {
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006415 enum wmi_phy_mode mode;
6416
6417 mode = chan_to_phymode(&def);
6418 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d phymode %d\n",
Kalle Valoebfac1d2018-07-30 21:56:43 +03006419 sta->addr, bw, mode);
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006420
6421 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
Rakesh Pillaic0e33fe2019-02-19 11:39:36 +05306422 ar->wmi.peer_param->phymode, mode);
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006423 if (err) {
6424 ath10k_warn(ar, "failed to update STA %pM peer phymode %d: %d\n",
Kalle Valoebfac1d2018-07-30 21:56:43 +03006425 sta->addr, mode, err);
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006426 goto exit;
6427 }
Michal Kazior9797feb2014-02-14 14:49:48 +01006428
6429 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
Rakesh Pillaic0e33fe2019-02-19 11:39:36 +05306430 ar->wmi.peer_param->chan_width, bw);
Michal Kazior9797feb2014-02-14 14:49:48 +01006431 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006432 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006433 sta->addr, bw, err);
6434 }
6435
6436 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006437 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006438 sta->addr, nss);
6439
6440 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
Rakesh Pillaic0e33fe2019-02-19 11:39:36 +05306441 ar->wmi.peer_param->nss, nss);
Michal Kazior9797feb2014-02-14 14:49:48 +01006442 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006443 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006444 sta->addr, nss, err);
6445 }
6446
6447 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006448 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006449 sta->addr, smps);
6450
6451 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
Rakesh Pillaic0e33fe2019-02-19 11:39:36 +05306452 ar->wmi.peer_param->smps_state, smps);
Michal Kazior9797feb2014-02-14 14:49:48 +01006453 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006454 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006455 sta->addr, smps, err);
6456 }
6457
Karthikeyan Periyasamy55cc11d2018-03-27 11:25:29 +03006458 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
6459 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006460 sta->addr);
6461
Michal Kazior590922a2014-10-21 10:10:29 +03006462 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006463 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006464 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006465 sta->addr);
6466 }
6467
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006468exit:
Michal Kazior9797feb2014-02-14 14:49:48 +01006469 mutex_unlock(&ar->conf_mutex);
6470}
6471
Marek Puzyniak7c354242015-03-30 09:51:52 +03006472static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
6473 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006474{
6475 struct ath10k *ar = arvif->ar;
6476
6477 lockdep_assert_held(&ar->conf_mutex);
6478
Marek Puzyniak7c354242015-03-30 09:51:52 +03006479 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006480 return 0;
6481
6482 if (ar->num_stations >= ar->max_num_stations)
6483 return -ENOBUFS;
6484
6485 ar->num_stations++;
6486
6487 return 0;
6488}
6489
Marek Puzyniak7c354242015-03-30 09:51:52 +03006490static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
6491 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006492{
6493 struct ath10k *ar = arvif->ar;
6494
6495 lockdep_assert_held(&ar->conf_mutex);
6496
Marek Puzyniak7c354242015-03-30 09:51:52 +03006497 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006498 return;
6499
6500 ar->num_stations--;
6501}
6502
Ashok Raj Nagarajan33410a52019-06-03 18:09:02 +03006503static int ath10k_sta_set_txpwr(struct ieee80211_hw *hw,
6504 struct ieee80211_vif *vif,
6505 struct ieee80211_sta *sta)
6506{
6507 struct ath10k *ar = hw->priv;
6508 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6509 int ret = 0;
6510 s16 txpwr;
6511
6512 if (sta->txpwr.type == NL80211_TX_POWER_AUTOMATIC) {
6513 txpwr = 0;
6514 } else {
6515 txpwr = sta->txpwr.power;
6516 if (!txpwr)
6517 return -EINVAL;
6518 }
6519
6520 if (txpwr > ATH10K_TX_POWER_MAX_VAL || txpwr < ATH10K_TX_POWER_MIN_VAL)
6521 return -EINVAL;
6522
6523 mutex_lock(&ar->conf_mutex);
6524
6525 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
Rakesh Pillaic0e33fe2019-02-19 11:39:36 +05306526 ar->wmi.peer_param->use_fixed_power, txpwr);
Ashok Raj Nagarajan33410a52019-06-03 18:09:02 +03006527 if (ret) {
6528 ath10k_warn(ar, "failed to set tx power for station ret: %d\n",
6529 ret);
6530 goto out;
6531 }
6532
6533out:
6534 mutex_unlock(&ar->conf_mutex);
6535 return ret;
6536}
6537
Kalle Valo5e3dd152013-06-12 20:52:10 +03006538static int ath10k_sta_state(struct ieee80211_hw *hw,
6539 struct ieee80211_vif *vif,
6540 struct ieee80211_sta *sta,
6541 enum ieee80211_sta_state old_state,
6542 enum ieee80211_sta_state new_state)
6543{
6544 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006545 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior9797feb2014-02-14 14:49:48 +01006546 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006547 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006548 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02006549 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006550
Michal Kazior76f90022014-02-25 09:29:57 +02006551 if (old_state == IEEE80211_STA_NOTEXIST &&
6552 new_state == IEEE80211_STA_NONE) {
6553 memset(arsta, 0, sizeof(*arsta));
6554 arsta->arvif = arvif;
Maharaja Kennadyrajand70c0d42018-09-18 12:04:27 +05306555 arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
Michal Kazior76f90022014-02-25 09:29:57 +02006556 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02006557
6558 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6559 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02006560 }
6561
Michal Kazior9797feb2014-02-14 14:49:48 +01006562 /* cancel must be done outside the mutex to avoid deadlock */
6563 if ((old_state == IEEE80211_STA_NONE &&
6564 new_state == IEEE80211_STA_NOTEXIST))
6565 cancel_work_sync(&arsta->update_wk);
6566
Kalle Valo5e3dd152013-06-12 20:52:10 +03006567 mutex_lock(&ar->conf_mutex);
6568
6569 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03006570 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006571 /*
6572 * New station addition.
6573 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006574 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
6575 u32 num_tdls_stations;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006576
Michal Kaziorcfd10612014-11-25 15:16:05 +01006577 ath10k_dbg(ar, ATH10K_DBG_MAC,
6578 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
6579 arvif->vdev_id, sta->addr,
6580 ar->num_stations + 1, ar->max_num_stations,
6581 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006582
Ryan Hsu9a993cc2017-05-31 14:21:28 +03006583 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
Ryan Hsu9a993cc2017-05-31 14:21:28 +03006584
6585 if (sta->tdls) {
6586 if (num_tdls_stations >= ar->max_num_tdls_vdevs) {
6587 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
6588 arvif->vdev_id,
6589 ar->max_num_tdls_vdevs);
6590 ret = -ELNRNG;
6591 goto exit;
6592 }
6593 peer_type = WMI_PEER_TYPE_TDLS;
6594 }
6595
Marek Puzyniak7c354242015-03-30 09:51:52 +03006596 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01006597 if (ret) {
6598 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
6599 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006600 goto exit;
6601 }
6602
Zhi Chen386f97e2018-12-20 14:25:18 +02006603 if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {
6604 arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats),
6605 GFP_KERNEL);
6606 if (!arsta->tx_stats) {
Zhi Chen402838a2019-11-06 20:04:42 +02006607 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006608 ret = -ENOMEM;
6609 goto exit;
6610 }
6611 }
6612
Michal Kazior69427262016-03-06 16:14:30 +02006613 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
6614 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01006615 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006616 ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n",
Ben Greear479398b2013-11-04 09:19:34 -08006617 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03006618 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006619 kfree(arsta->tx_stats);
Michal Kaziora52c0282014-11-25 15:16:03 +01006620 goto exit;
6621 }
Michal Kazior077efc82014-10-21 10:10:29 +03006622
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006623 spin_lock_bh(&ar->data_lock);
6624
6625 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
6626 if (!peer) {
6627 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
6628 vif->addr, arvif->vdev_id);
6629 spin_unlock_bh(&ar->data_lock);
6630 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6631 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006632 kfree(arsta->tx_stats);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006633 ret = -ENOENT;
6634 goto exit;
6635 }
6636
6637 arsta->peer_id = find_first_bit(peer->peer_ids,
6638 ATH10K_MAX_NUM_PEER_IDS);
6639
6640 spin_unlock_bh(&ar->data_lock);
6641
Bjorn Anderssonf4fe2e52019-11-13 12:26:44 -08006642 if (!sta->tdls)
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006643 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03006644
Ryan Hsu9a993cc2017-05-31 14:21:28 +03006645 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6646 WMI_TDLS_ENABLE_ACTIVE);
6647 if (ret) {
6648 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6649 arvif->vdev_id, ret);
6650 ath10k_peer_delete(ar, arvif->vdev_id,
6651 sta->addr);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006652 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006653 kfree(arsta->tx_stats);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006654 goto exit;
6655 }
6656
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006657 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6658 WMI_TDLS_PEER_STATE_PEERING);
6659 if (ret) {
6660 ath10k_warn(ar,
6661 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
6662 sta->addr, arvif->vdev_id, ret);
6663 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6664 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006665 kfree(arsta->tx_stats);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006666
6667 if (num_tdls_stations != 0)
6668 goto exit;
6669 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6670 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03006671 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006672 } else if ((old_state == IEEE80211_STA_NONE &&
6673 new_state == IEEE80211_STA_NOTEXIST)) {
6674 /*
6675 * Existing station deletion.
6676 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006677 ath10k_dbg(ar, ATH10K_DBG_MAC,
Ben Greear30404202016-08-18 18:26:35 -07006678 "mac vdev %d peer delete %pM sta %pK (sta gone)\n",
6679 arvif->vdev_id, sta->addr, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006680
Manikanta Pubbisetty424ea0d2017-11-06 13:39:31 +05306681 if (sta->tdls) {
6682 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id,
6683 sta,
6684 WMI_TDLS_PEER_STATE_TEARDOWN);
6685 if (ret)
6686 ath10k_warn(ar, "failed to update tdls peer state for %pM state %d: %i\n",
6687 sta->addr,
6688 WMI_TDLS_PEER_STATE_TEARDOWN, ret);
6689 }
6690
Kalle Valo5e3dd152013-06-12 20:52:10 +03006691 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6692 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006693 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006694 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006695
Marek Puzyniak7c354242015-03-30 09:51:52 +03006696 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006697
Michal Kazior69427262016-03-06 16:14:30 +02006698 spin_lock_bh(&ar->data_lock);
6699 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
6700 peer = ar->peer_map[i];
6701 if (!peer)
6702 continue;
6703
6704 if (peer->sta == sta) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05306705 ath10k_warn(ar, "found sta peer %pM (ptr %pK id %d) entry on vdev %i after it was supposedly removed\n",
Ben Greeard0eeafa2016-06-30 15:23:59 +03006706 sta->addr, peer, i, arvif->vdev_id);
Michal Kazior69427262016-03-06 16:14:30 +02006707 peer->sta = NULL;
Ben Greeard0eeafa2016-06-30 15:23:59 +03006708
6709 /* Clean up the peer object as well since we
6710 * must have failed to do this above.
6711 */
6712 list_del(&peer->list);
6713 ar->peer_map[i] = NULL;
6714 kfree(peer);
6715 ar->num_peers--;
Michal Kazior69427262016-03-06 16:14:30 +02006716 }
6717 }
6718 spin_unlock_bh(&ar->data_lock);
6719
Karthikeyan Periyasamy553a7cc2018-12-20 09:53:17 +02006720 if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {
6721 kfree(arsta->tx_stats);
6722 arsta->tx_stats = NULL;
6723 }
6724
Michal Kazior29946872016-03-06 16:14:34 +02006725 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6726 ath10k_mac_txq_unref(ar, sta->txq[i]);
6727
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006728 if (!sta->tdls)
6729 goto exit;
6730
6731 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
6732 goto exit;
6733
6734 /* This was the last tdls peer in current vif */
6735 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6736 WMI_TDLS_DISABLE);
6737 if (ret) {
6738 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6739 arvif->vdev_id, ret);
6740 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006741 } else if (old_state == IEEE80211_STA_AUTH &&
6742 new_state == IEEE80211_STA_ASSOC &&
6743 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006744 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03006745 vif->type == NL80211_IFTYPE_ADHOC)) {
6746 /*
6747 * New association.
6748 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006749 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006750 sta->addr);
6751
Michal Kazior590922a2014-10-21 10:10:29 +03006752 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006753 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006754 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006755 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006756 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006757 new_state == IEEE80211_STA_AUTHORIZED &&
6758 sta->tdls) {
6759 /*
6760 * Tdls station authorized.
6761 */
6762 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
6763 sta->addr);
6764
6765 ret = ath10k_station_assoc(ar, vif, sta, false);
6766 if (ret) {
6767 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
6768 sta->addr, arvif->vdev_id, ret);
6769 goto exit;
6770 }
6771
6772 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6773 WMI_TDLS_PEER_STATE_CONNECTED);
6774 if (ret)
6775 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
6776 sta->addr, arvif->vdev_id, ret);
6777 } else if (old_state == IEEE80211_STA_ASSOC &&
6778 new_state == IEEE80211_STA_AUTH &&
6779 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006780 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006781 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006782 /*
6783 * Disassociation.
6784 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006785 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006786 sta->addr);
6787
Michal Kazior590922a2014-10-21 10:10:29 +03006788 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006789 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006790 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006791 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006792 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006793exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006794 mutex_unlock(&ar->conf_mutex);
6795 return ret;
6796}
6797
6798static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006799 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006800{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006801 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006802 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6803 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006804 u32 value = 0;
6805 int ret = 0;
6806
Michal Kazior548db542013-07-05 16:15:15 +03006807 lockdep_assert_held(&ar->conf_mutex);
6808
Kalle Valo5e3dd152013-06-12 20:52:10 +03006809 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6810 return 0;
6811
6812 switch (ac) {
6813 case IEEE80211_AC_VO:
6814 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6815 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006816 prio = 7;
6817 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006818 break;
6819 case IEEE80211_AC_VI:
6820 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6821 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006822 prio = 5;
6823 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006824 break;
6825 case IEEE80211_AC_BE:
6826 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6827 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006828 prio = 2;
6829 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006830 break;
6831 case IEEE80211_AC_BK:
6832 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6833 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006834 prio = 0;
6835 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006836 break;
6837 }
6838
6839 if (enable)
6840 arvif->u.sta.uapsd |= value;
6841 else
6842 arvif->u.sta.uapsd &= ~value;
6843
6844 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6845 WMI_STA_PS_PARAM_UAPSD,
6846 arvif->u.sta.uapsd);
6847 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006848 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006849 goto exit;
6850 }
6851
6852 if (arvif->u.sta.uapsd)
6853 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6854 else
6855 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6856
6857 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6858 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6859 value);
6860 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006861 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006862
Michal Kazior9f9b5742014-12-12 12:41:36 +01006863 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6864 if (ret) {
6865 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6866 arvif->vdev_id, ret);
6867 return ret;
6868 }
6869
6870 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6871 if (ret) {
6872 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6873 arvif->vdev_id, ret);
6874 return ret;
6875 }
6876
Michal Kaziorb0e56152015-01-24 12:14:52 +02006877 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6878 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6879 /* Only userspace can make an educated decision when to send
6880 * trigger frame. The following effectively disables u-UAPSD
6881 * autotrigger in firmware (which is enabled by default
6882 * provided the autotrigger service is available).
6883 */
6884
6885 arg.wmm_ac = acc;
6886 arg.user_priority = prio;
6887 arg.service_interval = 0;
6888 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6889 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6890
6891 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6892 arvif->bssid, &arg, 1);
6893 if (ret) {
6894 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6895 ret);
6896 return ret;
6897 }
6898 }
6899
Kalle Valo5e3dd152013-06-12 20:52:10 +03006900exit:
6901 return ret;
6902}
6903
6904static int ath10k_conf_tx(struct ieee80211_hw *hw,
6905 struct ieee80211_vif *vif, u16 ac,
6906 const struct ieee80211_tx_queue_params *params)
6907{
6908 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006909 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006910 struct wmi_wmm_params_arg *p = NULL;
6911 int ret;
6912
6913 mutex_lock(&ar->conf_mutex);
6914
6915 switch (ac) {
6916 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006917 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006918 break;
6919 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006920 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006921 break;
6922 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006923 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006924 break;
6925 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006926 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006927 break;
6928 }
6929
6930 if (WARN_ON(!p)) {
6931 ret = -EINVAL;
6932 goto exit;
6933 }
6934
6935 p->cwmin = params->cw_min;
6936 p->cwmax = params->cw_max;
6937 p->aifs = params->aifs;
6938
6939 /*
6940 * The channel time duration programmed in the HW is in absolute
6941 * microseconds, while mac80211 gives the txop in units of
6942 * 32 microseconds.
6943 */
6944 p->txop = params->txop * 32;
6945
Michal Kazior7fc979a2015-01-28 09:57:28 +02006946 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6947 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6948 &arvif->wmm_params);
6949 if (ret) {
6950 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6951 arvif->vdev_id, ret);
6952 goto exit;
6953 }
6954 } else {
6955 /* This won't work well with multi-interface cases but it's
6956 * better than nothing.
6957 */
6958 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6959 if (ret) {
6960 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6961 goto exit;
6962 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006963 }
6964
6965 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6966 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006967 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006968
6969exit:
6970 mutex_unlock(&ar->conf_mutex);
6971 return ret;
6972}
6973
Kalle Valo14e105c2016-04-13 14:13:21 +03006974#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006975
6976static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6977 struct ieee80211_vif *vif,
6978 struct ieee80211_channel *chan,
6979 int duration,
6980 enum ieee80211_roc_type type)
6981{
6982 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006983 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006984 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006985 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006986 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006987
6988 mutex_lock(&ar->conf_mutex);
6989
Anilkumar Kollia6080932017-10-27 11:12:28 +03006990 if (ath10k_mac_tdls_vif_stations_count(hw, vif) > 0) {
6991 ret = -EBUSY;
6992 goto exit;
6993 }
6994
Kalle Valo5e3dd152013-06-12 20:52:10 +03006995 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006996 switch (ar->scan.state) {
6997 case ATH10K_SCAN_IDLE:
6998 reinit_completion(&ar->scan.started);
6999 reinit_completion(&ar->scan.completed);
7000 reinit_completion(&ar->scan.on_channel);
7001 ar->scan.state = ATH10K_SCAN_STARTING;
7002 ar->scan.is_roc = true;
7003 ar->scan.vdev_id = arvif->vdev_id;
7004 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02007005 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02007006 ret = 0;
7007 break;
7008 case ATH10K_SCAN_STARTING:
7009 case ATH10K_SCAN_RUNNING:
7010 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03007011 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02007012 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007013 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007014 spin_unlock_bh(&ar->data_lock);
7015
Michal Kazior5c81c7f2014-08-05 14:54:44 +02007016 if (ret)
7017 goto exit;
7018
Michal Kaziorfcf98442015-03-31 11:03:47 +00007019 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01007020
Kalle Valo5e3dd152013-06-12 20:52:10 +03007021 memset(&arg, 0, sizeof(arg));
7022 ath10k_wmi_start_scan_init(ar, &arg);
7023 arg.vdev_id = arvif->vdev_id;
7024 arg.scan_id = ATH10K_SCAN_ID;
7025 arg.n_channels = 1;
7026 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00007027 arg.dwell_time_active = scan_time_msec;
7028 arg.dwell_time_passive = scan_time_msec;
7029 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007030 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
7031 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00007032 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007033
7034 ret = ath10k_start_scan(ar, &arg);
7035 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007036 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007037 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02007038 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007039 spin_unlock_bh(&ar->data_lock);
7040 goto exit;
7041 }
7042
Kalle Valo14e105c2016-04-13 14:13:21 +03007043 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007044 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007045 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02007046
7047 ret = ath10k_scan_stop(ar);
7048 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02007049 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02007050
Kalle Valo5e3dd152013-06-12 20:52:10 +03007051 ret = -ETIMEDOUT;
7052 goto exit;
7053 }
7054
Michal Kaziorfcf98442015-03-31 11:03:47 +00007055 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
7056 msecs_to_jiffies(duration));
7057
Kalle Valo5e3dd152013-06-12 20:52:10 +03007058 ret = 0;
7059exit:
7060 mutex_unlock(&ar->conf_mutex);
7061 return ret;
7062}
7063
Emmanuel Grumbach5db4c4b2019-07-23 21:00:01 +03007064static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw,
7065 struct ieee80211_vif *vif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007066{
7067 struct ath10k *ar = hw->priv;
7068
7069 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02007070
7071 spin_lock_bh(&ar->data_lock);
7072 ar->scan.roc_notify = false;
7073 spin_unlock_bh(&ar->data_lock);
7074
Michal Kazior5c81c7f2014-08-05 14:54:44 +02007075 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02007076
Kalle Valo5e3dd152013-06-12 20:52:10 +03007077 mutex_unlock(&ar->conf_mutex);
7078
Michal Kazior4eb2e162014-10-28 10:23:09 +01007079 cancel_delayed_work_sync(&ar->scan.timeout);
7080
Kalle Valo5e3dd152013-06-12 20:52:10 +03007081 return 0;
7082}
7083
7084/*
7085 * Both RTS and Fragmentation threshold are interface-specific
7086 * in ath10k, but device-specific in mac80211.
7087 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03007088
7089static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
7090{
Kalle Valo5e3dd152013-06-12 20:52:10 +03007091 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03007092 struct ath10k_vif *arvif;
7093 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03007094
Michal Kaziorad088bf2013-10-16 15:44:46 +03007095 mutex_lock(&ar->conf_mutex);
7096 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007097 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03007098 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03007099
Michal Kaziorad088bf2013-10-16 15:44:46 +03007100 ret = ath10k_mac_set_rts(arvif, value);
7101 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007102 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03007103 arvif->vdev_id, ret);
7104 break;
7105 }
7106 }
7107 mutex_unlock(&ar->conf_mutex);
7108
7109 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007110}
7111
Michal Kazior92092fe2015-08-03 11:16:43 +02007112static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
7113{
7114 /* Even though there's a WMI enum for fragmentation threshold no known
7115 * firmware actually implements it. Moreover it is not possible to rely
7116 * frame fragmentation to mac80211 because firmware clears the "more
7117 * fragments" bit in frame control making it impossible for remote
7118 * devices to reassemble frames.
7119 *
7120 * Hence implement a dummy callback just to say fragmentation isn't
7121 * supported. This effectively prevents mac80211 from doing frame
7122 * fragmentation in software.
7123 */
7124 return -EOPNOTSUPP;
7125}
7126
Wen Gong828853a2018-08-28 19:48:42 +03007127void ath10k_mac_wait_tx_complete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007128{
Michal Kazioraffd3212013-07-16 09:54:35 +02007129 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03007130 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007131
7132 /* mac80211 doesn't care if we really xmit queued frames or not
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01007133 * we'll collect those frames either way if we stop/delete vdevs
7134 */
Michal Kazior548db542013-07-05 16:15:15 +03007135
Michal Kazioraffd3212013-07-16 09:54:35 +02007136 if (ar->state == ATH10K_STATE_WEDGED)
Wen Gong828853a2018-08-28 19:48:42 +03007137 return;
Michal Kazioraffd3212013-07-16 09:54:35 +02007138
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03007139 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03007140 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02007141
Michal Kazioredb82362013-07-05 16:15:14 +03007142 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02007143 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03007144 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02007145
Michal Kazior7962b0d2014-10-28 10:34:38 +01007146 skip = (ar->state == ATH10K_STATE_WEDGED) ||
7147 test_bit(ATH10K_FLAG_CRASH_FLUSH,
7148 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02007149
7150 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007151 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02007152
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03007153 if (time_left == 0 || skip)
7154 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
7155 skip, ar->state, time_left);
Wen Gong828853a2018-08-28 19:48:42 +03007156}
Michal Kazior548db542013-07-05 16:15:15 +03007157
Wen Gong828853a2018-08-28 19:48:42 +03007158static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
7159 u32 queues, bool drop)
7160{
7161 struct ath10k *ar = hw->priv;
Wen Gong9de41622018-10-08 17:02:43 +08007162 struct ath10k_vif *arvif;
7163 u32 bitmap;
Wen Gong828853a2018-08-28 19:48:42 +03007164
Wen Gong9de41622018-10-08 17:02:43 +08007165 if (drop) {
Brian Norrisd987f782018-11-07 16:40:35 -08007166 if (vif && vif->type == NL80211_IFTYPE_STATION) {
Wen Gong9de41622018-10-08 17:02:43 +08007167 bitmap = ~(1 << WMI_MGMT_TID);
7168 list_for_each_entry(arvif, &ar->arvifs, list) {
7169 if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
7170 ath10k_wmi_peer_flush(ar, arvif->vdev_id,
7171 arvif->bssid, bitmap);
7172 }
7173 }
Wen Gong828853a2018-08-28 19:48:42 +03007174 return;
Wen Gong9de41622018-10-08 17:02:43 +08007175 }
Wen Gong828853a2018-08-28 19:48:42 +03007176
7177 mutex_lock(&ar->conf_mutex);
7178 ath10k_mac_wait_tx_complete(ar);
Michal Kazior548db542013-07-05 16:15:15 +03007179 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007180}
7181
7182/* TODO: Implement this function properly
7183 * For now it is needed to reply to Probe Requests in IBSS mode.
7184 * Propably we need this information from FW.
7185 */
7186static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
7187{
7188 return 1;
7189}
7190
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007191static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
7192 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02007193{
7194 struct ath10k *ar = hw->priv;
7195
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007196 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
7197 return;
7198
Michal Kazioraffd3212013-07-16 09:54:35 +02007199 mutex_lock(&ar->conf_mutex);
7200
7201 /* If device failed to restart it will be in a different state, e.g.
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01007202 * ATH10K_STATE_WEDGED
7203 */
Michal Kazioraffd3212013-07-16 09:54:35 +02007204 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007205 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02007206 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01007207 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02007208 }
7209
7210 mutex_unlock(&ar->conf_mutex);
7211}
7212
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05307213static void
7214ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
7215 struct ieee80211_channel *channel)
7216{
7217 int ret;
7218 enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
7219
7220 lockdep_assert_held(&ar->conf_mutex);
7221
7222 if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
7223 (ar->rx_channel != channel))
7224 return;
7225
7226 if (ar->scan.state != ATH10K_SCAN_IDLE) {
7227 ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
7228 return;
7229 }
7230
7231 reinit_completion(&ar->bss_survey_done);
7232
7233 ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
7234 if (ret) {
7235 ath10k_warn(ar, "failed to send pdev bss chan info request\n");
7236 return;
7237 }
7238
7239 ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
7240 if (!ret) {
7241 ath10k_warn(ar, "bss channel survey timed out\n");
7242 return;
7243 }
7244}
7245
Michal Kazior2e1dea42013-07-31 10:32:40 +02007246static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
7247 struct survey_info *survey)
7248{
7249 struct ath10k *ar = hw->priv;
7250 struct ieee80211_supported_band *sband;
7251 struct survey_info *ar_survey = &ar->survey[idx];
7252 int ret = 0;
7253
7254 mutex_lock(&ar->conf_mutex);
7255
Johannes Berg57fbcce2016-04-12 15:56:15 +02007256 sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02007257 if (sband && idx >= sband->n_channels) {
7258 idx -= sband->n_channels;
7259 sband = NULL;
7260 }
7261
7262 if (!sband)
Johannes Berg57fbcce2016-04-12 15:56:15 +02007263 sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02007264
7265 if (!sband || idx >= sband->n_channels) {
7266 ret = -ENOENT;
7267 goto exit;
7268 }
7269
Ashok Raj Nagarajan77eb3d62016-09-02 10:59:53 +05307270 ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05307271
Michal Kazior2e1dea42013-07-31 10:32:40 +02007272 spin_lock_bh(&ar->data_lock);
7273 memcpy(survey, ar_survey, sizeof(*survey));
7274 spin_unlock_bh(&ar->data_lock);
7275
7276 survey->channel = &sband->channels[idx];
7277
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03007278 if (ar->rx_channel == survey->channel)
7279 survey->filled |= SURVEY_INFO_IN_USE;
7280
Michal Kazior2e1dea42013-07-31 10:32:40 +02007281exit:
7282 mutex_unlock(&ar->conf_mutex);
7283 return ret;
7284}
7285
Michal Kazior3ae54222015-03-31 10:49:20 +00007286static bool
7287ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007288 enum nl80211_band band,
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007289 const struct cfg80211_bitrate_mask *mask,
7290 int *vht_num_rates)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007291{
Michal Kazior3ae54222015-03-31 10:49:20 +00007292 int num_rates = 0;
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007293 int i, tmp;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007294
Michal Kazior3ae54222015-03-31 10:49:20 +00007295 num_rates += hweight32(mask->control[band].legacy);
7296
7297 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
7298 num_rates += hweight8(mask->control[band].ht_mcs[i]);
7299
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007300 *vht_num_rates = 0;
7301 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
7302 tmp = hweight16(mask->control[band].vht_mcs[i]);
7303 num_rates += tmp;
7304 *vht_num_rates += tmp;
7305 }
Michal Kazior3ae54222015-03-31 10:49:20 +00007306
7307 return num_rates == 1;
7308}
7309
7310static bool
7311ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007312 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00007313 const struct cfg80211_bitrate_mask *mask,
7314 int *nss)
7315{
7316 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
7317 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
7318 u8 ht_nss_mask = 0;
7319 u8 vht_nss_mask = 0;
7320 int i;
7321
7322 if (mask->control[band].legacy)
7323 return false;
7324
7325 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
7326 if (mask->control[band].ht_mcs[i] == 0)
7327 continue;
7328 else if (mask->control[band].ht_mcs[i] ==
7329 sband->ht_cap.mcs.rx_mask[i])
7330 ht_nss_mask |= BIT(i);
7331 else
7332 return false;
7333 }
7334
7335 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
7336 if (mask->control[band].vht_mcs[i] == 0)
7337 continue;
7338 else if (mask->control[band].vht_mcs[i] ==
7339 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
7340 vht_nss_mask |= BIT(i);
7341 else
7342 return false;
7343 }
7344
7345 if (ht_nss_mask != vht_nss_mask)
7346 return false;
7347
7348 if (ht_nss_mask == 0)
7349 return false;
7350
7351 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
7352 return false;
7353
7354 *nss = fls(ht_nss_mask);
7355
7356 return true;
7357}
7358
7359static int
7360ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007361 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00007362 const struct cfg80211_bitrate_mask *mask,
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007363 u8 *rate, u8 *nss, bool vht_only)
Michal Kazior3ae54222015-03-31 10:49:20 +00007364{
Michal Kazior3ae54222015-03-31 10:49:20 +00007365 int rate_idx;
7366 int i;
7367 u16 bitrate;
7368 u8 preamble;
7369 u8 hw_rate;
7370
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007371 if (vht_only)
7372 goto next;
7373
Michal Kazior3ae54222015-03-31 10:49:20 +00007374 if (hweight32(mask->control[band].legacy) == 1) {
7375 rate_idx = ffs(mask->control[band].legacy) - 1;
7376
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03007377 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
7378 rate_idx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
7379
7380 hw_rate = ath10k_wmi_legacy_rates[rate_idx].hw_value;
7381 bitrate = ath10k_wmi_legacy_rates[rate_idx].bitrate;
Michal Kazior3ae54222015-03-31 10:49:20 +00007382
7383 if (ath10k_mac_bitrate_is_cck(bitrate))
7384 preamble = WMI_RATE_PREAMBLE_CCK;
7385 else
7386 preamble = WMI_RATE_PREAMBLE_OFDM;
7387
7388 *nss = 1;
7389 *rate = preamble << 6 |
7390 (*nss - 1) << 4 |
7391 hw_rate << 0;
7392
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007393 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007394 }
7395
Michal Kazior3ae54222015-03-31 10:49:20 +00007396 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
7397 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
7398 *nss = i + 1;
7399 *rate = WMI_RATE_PREAMBLE_HT << 6 |
7400 (*nss - 1) << 4 |
7401 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007402
Michal Kazior3ae54222015-03-31 10:49:20 +00007403 return 0;
7404 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007405 }
7406
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007407next:
Michal Kazior3ae54222015-03-31 10:49:20 +00007408 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
7409 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
7410 *nss = i + 1;
7411 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
7412 (*nss - 1) << 4 |
7413 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007414
Michal Kazior3ae54222015-03-31 10:49:20 +00007415 return 0;
7416 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007417 }
7418
Michal Kazior3ae54222015-03-31 10:49:20 +00007419 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007420}
7421
Michal Kazior3ae54222015-03-31 10:49:20 +00007422static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307423 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007424{
7425 struct ath10k *ar = arvif->ar;
7426 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00007427 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007428
Michal Kazior3ae54222015-03-31 10:49:20 +00007429 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007430
Michal Kazior3ae54222015-03-31 10:49:20 +00007431 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
7432 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007433
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007434 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00007435 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007436 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007437 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00007438 rate, ret);
7439 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007440 }
7441
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007442 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00007443 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007444 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00007445 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
7446 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007447 }
7448
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007449 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00007450 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007451 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00007452 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
7453 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007454 }
7455
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307456 vdev_param = ar->wmi.vdev_param->ldpc;
7457 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
7458 if (ret) {
7459 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
7460 return ret;
7461 }
7462
Michal Kazior3ae54222015-03-31 10:49:20 +00007463 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007464}
7465
Michal Kazior45c9abc2015-04-21 20:42:58 +03007466static bool
7467ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007468 enum nl80211_band band,
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007469 const struct cfg80211_bitrate_mask *mask,
7470 bool allow_pfr)
Michal Kazior45c9abc2015-04-21 20:42:58 +03007471{
7472 int i;
7473 u16 vht_mcs;
7474
7475 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
7476 * to express all VHT MCS rate masks. Effectively only the following
7477 * ranges can be used: none, 0-7, 0-8 and 0-9.
7478 */
7479 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
7480 vht_mcs = mask->control[band].vht_mcs[i];
7481
7482 switch (vht_mcs) {
7483 case 0:
7484 case BIT(8) - 1:
7485 case BIT(9) - 1:
7486 case BIT(10) - 1:
7487 break;
7488 default:
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007489 if (!allow_pfr)
7490 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
Michal Kazior45c9abc2015-04-21 20:42:58 +03007491 return false;
7492 }
7493 }
7494
7495 return true;
7496}
7497
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007498static bool ath10k_mac_set_vht_bitrate_mask_fixup(struct ath10k *ar,
7499 struct ath10k_vif *arvif,
7500 struct ieee80211_sta *sta)
7501{
7502 int err;
7503 u8 rate = arvif->vht_pfr;
7504
7505 /* skip non vht and multiple rate peers */
7506 if (!sta->vht_cap.vht_supported || arvif->vht_num_rates != 1)
7507 return false;
7508
7509 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
7510 WMI_PEER_PARAM_FIXED_RATE, rate);
7511 if (err)
Colin Ian King09764652019-09-13 08:43:39 +01007512 ath10k_warn(ar, "failed to enable STA %pM peer fixed rate: %d\n",
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007513 sta->addr, err);
7514
7515 return true;
7516}
7517
Michal Kazior45c9abc2015-04-21 20:42:58 +03007518static void ath10k_mac_set_bitrate_mask_iter(void *data,
7519 struct ieee80211_sta *sta)
7520{
7521 struct ath10k_vif *arvif = data;
7522 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
7523 struct ath10k *ar = arvif->ar;
7524
7525 if (arsta->arvif != arvif)
7526 return;
7527
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007528 if (ath10k_mac_set_vht_bitrate_mask_fixup(ar, arvif, sta))
7529 return;
7530
Michal Kazior45c9abc2015-04-21 20:42:58 +03007531 spin_lock_bh(&ar->data_lock);
7532 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
7533 spin_unlock_bh(&ar->data_lock);
7534
7535 ieee80211_queue_work(ar->hw, &arsta->update_wk);
7536}
7537
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007538static void ath10k_mac_clr_bitrate_mask_iter(void *data,
7539 struct ieee80211_sta *sta)
7540{
7541 struct ath10k_vif *arvif = data;
7542 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
7543 struct ath10k *ar = arvif->ar;
7544 int err;
7545
7546 /* clear vht peers only */
7547 if (arsta->arvif != arvif || !sta->vht_cap.vht_supported)
7548 return;
7549
7550 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
7551 WMI_PEER_PARAM_FIXED_RATE,
7552 WMI_FIXED_RATE_NONE);
7553 if (err)
7554 ath10k_warn(ar, "failed to clear STA %pM peer fixed rate: %d\n",
7555 sta->addr, err);
7556}
7557
Michal Kazior3ae54222015-03-31 10:49:20 +00007558static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
7559 struct ieee80211_vif *vif,
7560 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007561{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007562 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007563 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007564 struct ath10k *ar = arvif->ar;
Johannes Berg57fbcce2016-04-12 15:56:15 +02007565 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007566 const u8 *ht_mcs_mask;
7567 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00007568 u8 rate;
7569 u8 nss;
7570 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307571 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00007572 int single_nss;
7573 int ret;
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007574 int vht_num_rates, allow_pfr;
7575 u8 vht_pfr;
7576 bool update_bitrate_mask = true;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007577
Michal Kazior500ff9f2015-03-31 10:26:21 +00007578 if (ath10k_mac_vif_chan(vif, &def))
7579 return -EPERM;
7580
Michal Kazior500ff9f2015-03-31 10:26:21 +00007581 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007582 ht_mcs_mask = mask->control[band].ht_mcs;
7583 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307584 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007585
Michal Kazior3ae54222015-03-31 10:49:20 +00007586 sgi = mask->control[band].gi;
7587 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007588 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007589
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007590 allow_pfr = test_bit(ATH10K_FW_FEATURE_PEER_FIXED_RATE,
7591 ar->normal_mode_fw.fw_file.fw_features);
7592 if (allow_pfr) {
7593 mutex_lock(&ar->conf_mutex);
7594 ieee80211_iterate_stations_atomic(ar->hw,
7595 ath10k_mac_clr_bitrate_mask_iter,
7596 arvif);
7597 mutex_unlock(&ar->conf_mutex);
7598 }
7599
7600 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask,
7601 &vht_num_rates)) {
Michal Kazior3ae54222015-03-31 10:49:20 +00007602 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007603 &rate, &nss,
7604 false);
Michal Kazior3ae54222015-03-31 10:49:20 +00007605 if (ret) {
7606 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
7607 arvif->vdev_id, ret);
7608 return ret;
7609 }
7610 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
7611 &single_nss)) {
7612 rate = WMI_FIXED_RATE_NONE;
7613 nss = single_nss;
7614 } else {
7615 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007616 nss = min(ar->num_rf_chains,
7617 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
7618 ath10k_mac_max_vht_nss(vht_mcs_mask)));
7619
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007620 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask,
7621 allow_pfr)) {
7622 u8 vht_nss;
7623
7624 if (!allow_pfr || vht_num_rates != 1)
7625 return -EINVAL;
7626
7627 /* Reach here, firmware supports peer fixed rate and has
7628 * single vht rate, and don't update vif birate_mask, as
7629 * the rate only for specific peer.
7630 */
7631 ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
7632 &vht_pfr,
7633 &vht_nss,
7634 true);
7635 update_bitrate_mask = false;
Arnd Bergmannff414f32019-07-08 14:50:06 +02007636 } else {
7637 vht_pfr = 0;
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007638 }
Michal Kazior45c9abc2015-04-21 20:42:58 +03007639
7640 mutex_lock(&ar->conf_mutex);
7641
Miaoqing Pan8b97b052019-05-29 16:13:28 +08007642 if (update_bitrate_mask)
7643 arvif->bitrate_mask = *mask;
7644 arvif->vht_num_rates = vht_num_rates;
7645 arvif->vht_pfr = vht_pfr;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007646 ieee80211_iterate_stations_atomic(ar->hw,
7647 ath10k_mac_set_bitrate_mask_iter,
7648 arvif);
7649
7650 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007651 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007652
7653 mutex_lock(&ar->conf_mutex);
7654
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307655 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007656 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00007657 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
7658 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007659 goto exit;
7660 }
7661
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007662exit:
7663 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00007664
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007665 return ret;
7666}
7667
Michal Kazior9797feb2014-02-14 14:49:48 +01007668static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
7669 struct ieee80211_vif *vif,
7670 struct ieee80211_sta *sta,
7671 u32 changed)
7672{
7673 struct ath10k *ar = hw->priv;
7674 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Karthikeyan Periyasamy8b2d93d2018-03-12 17:09:40 +05307675 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7676 struct ath10k_peer *peer;
Michal Kazior9797feb2014-02-14 14:49:48 +01007677 u32 bw, smps;
7678
7679 spin_lock_bh(&ar->data_lock);
7680
Karthikeyan Periyasamy8b2d93d2018-03-12 17:09:40 +05307681 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
7682 if (!peer) {
7683 spin_unlock_bh(&ar->data_lock);
7684 ath10k_warn(ar, "mac sta rc update failed to find peer %pM on vdev %i\n",
7685 sta->addr, arvif->vdev_id);
7686 return;
7687 }
7688
Michal Kazior7aa7a722014-08-25 12:09:38 +02007689 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01007690 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
7691 sta->addr, changed, sta->bandwidth, sta->rx_nss,
7692 sta->smps_mode);
7693
7694 if (changed & IEEE80211_RC_BW_CHANGED) {
7695 bw = WMI_PEER_CHWIDTH_20MHZ;
7696
7697 switch (sta->bandwidth) {
7698 case IEEE80211_STA_RX_BW_20:
7699 bw = WMI_PEER_CHWIDTH_20MHZ;
7700 break;
7701 case IEEE80211_STA_RX_BW_40:
7702 bw = WMI_PEER_CHWIDTH_40MHZ;
7703 break;
7704 case IEEE80211_STA_RX_BW_80:
7705 bw = WMI_PEER_CHWIDTH_80MHZ;
7706 break;
7707 case IEEE80211_STA_RX_BW_160:
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02007708 bw = WMI_PEER_CHWIDTH_160MHZ;
7709 break;
7710 default:
Masanari Iidad939be32015-02-27 23:52:31 +09007711 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02007712 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01007713 bw = WMI_PEER_CHWIDTH_20MHZ;
7714 break;
7715 }
7716
7717 arsta->bw = bw;
7718 }
7719
7720 if (changed & IEEE80211_RC_NSS_CHANGED)
7721 arsta->nss = sta->rx_nss;
7722
7723 if (changed & IEEE80211_RC_SMPS_CHANGED) {
7724 smps = WMI_PEER_SMPS_PS_NONE;
7725
7726 switch (sta->smps_mode) {
7727 case IEEE80211_SMPS_AUTOMATIC:
7728 case IEEE80211_SMPS_OFF:
7729 smps = WMI_PEER_SMPS_PS_NONE;
7730 break;
7731 case IEEE80211_SMPS_STATIC:
7732 smps = WMI_PEER_SMPS_STATIC;
7733 break;
7734 case IEEE80211_SMPS_DYNAMIC:
7735 smps = WMI_PEER_SMPS_DYNAMIC;
7736 break;
7737 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02007738 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02007739 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01007740 smps = WMI_PEER_SMPS_PS_NONE;
7741 break;
7742 }
7743
7744 arsta->smps = smps;
7745 }
7746
Michal Kazior9797feb2014-02-14 14:49:48 +01007747 arsta->changed |= changed;
7748
7749 spin_unlock_bh(&ar->data_lock);
7750
7751 ieee80211_queue_work(hw, &arsta->update_wk);
7752}
7753
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007754static void ath10k_offset_tsf(struct ieee80211_hw *hw,
7755 struct ieee80211_vif *vif, s64 tsf_offset)
Peter Oh9f0b7e72016-04-04 16:19:14 -07007756{
7757 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007758 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007759 u32 offset, vdev_param;
Peter Oh9f0b7e72016-04-04 16:19:14 -07007760 int ret;
7761
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007762 if (tsf_offset < 0) {
7763 vdev_param = ar->wmi.vdev_param->dec_tsf;
7764 offset = -tsf_offset;
7765 } else {
7766 vdev_param = ar->wmi.vdev_param->inc_tsf;
7767 offset = tsf_offset;
7768 }
7769
Peter Oh9f0b7e72016-04-04 16:19:14 -07007770 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007771 vdev_param, offset);
7772
Peter Oh9f0b7e72016-04-04 16:19:14 -07007773 if (ret && ret != -EOPNOTSUPP)
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007774 ath10k_warn(ar, "failed to set tsf offset %d cmd %d: %d\n",
7775 offset, vdev_param, ret);
Peter Oh9f0b7e72016-04-04 16:19:14 -07007776}
7777
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007778static int ath10k_ampdu_action(struct ieee80211_hw *hw,
7779 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02007780 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007781{
Michal Kazior7aa7a722014-08-25 12:09:38 +02007782 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007783 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Sara Sharon50ea05e2015-12-30 16:06:04 +02007784 struct ieee80211_sta *sta = params->sta;
7785 enum ieee80211_ampdu_mlme_action action = params->action;
7786 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007787
Michal Kazior7aa7a722014-08-25 12:09:38 +02007788 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ampdu vdev_id %i sta %pM tid %hu action %d\n",
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007789 arvif->vdev_id, sta->addr, tid, action);
7790
7791 switch (action) {
7792 case IEEE80211_AMPDU_RX_START:
7793 case IEEE80211_AMPDU_RX_STOP:
7794 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
7795 * creation/removal. Do we need to verify this?
7796 */
7797 return 0;
7798 case IEEE80211_AMPDU_TX_START:
7799 case IEEE80211_AMPDU_TX_STOP_CONT:
7800 case IEEE80211_AMPDU_TX_STOP_FLUSH:
7801 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
7802 case IEEE80211_AMPDU_TX_OPERATIONAL:
7803 /* Firmware offloads Tx aggregation entirely so deny mac80211
7804 * Tx aggregation requests.
7805 */
7806 return -EOPNOTSUPP;
7807 }
7808
7809 return -EINVAL;
7810}
7811
Michal Kazior500ff9f2015-03-31 10:26:21 +00007812static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007813ath10k_mac_update_rx_channel(struct ath10k *ar,
7814 struct ieee80211_chanctx_conf *ctx,
7815 struct ieee80211_vif_chanctx_switch *vifs,
7816 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00007817{
7818 struct cfg80211_chan_def *def = NULL;
7819
7820 /* Both locks are required because ar->rx_channel is modified. This
7821 * allows readers to hold either lock.
7822 */
7823 lockdep_assert_held(&ar->conf_mutex);
7824 lockdep_assert_held(&ar->data_lock);
7825
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007826 WARN_ON(ctx && vifs);
Mohammed Shafi Shajakhanc73f8c02017-03-08 13:52:06 +02007827 WARN_ON(vifs && !n_vifs);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007828
Michal Kazior500ff9f2015-03-31 10:26:21 +00007829 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
7830 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
7831 * ppdu on Rx may reduce performance on low-end systems. It should be
7832 * possible to make tables/hashmaps to speed the lookup up (be vary of
7833 * cpu data cache lines though regarding sizes) but to keep the initial
7834 * implementation simple and less intrusive fallback to the slow lookup
7835 * only for multi-channel cases. Single-channel cases will remain to
7836 * use the old channel derival and thus performance should not be
7837 * affected much.
7838 */
7839 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007840 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00007841 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03007842 ath10k_mac_get_any_chandef_iter,
7843 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007844
7845 if (vifs)
7846 def = &vifs[0].new_ctx->def;
7847
Michal Kazior500ff9f2015-03-31 10:26:21 +00007848 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05307849 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
7850 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
7851 /* During driver restart due to firmware assert, since mac80211
7852 * already has valid channel context for given radio, channel
7853 * context iteration return num_chanctx > 0. So fix rx_channel
7854 * when restart is in progress.
7855 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007856 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007857 } else {
7858 ar->rx_channel = NULL;
7859 }
7860 rcu_read_unlock();
7861}
7862
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007863static void
7864ath10k_mac_update_vif_chan(struct ath10k *ar,
7865 struct ieee80211_vif_chanctx_switch *vifs,
7866 int n_vifs)
7867{
7868 struct ath10k_vif *arvif;
7869 int ret;
7870 int i;
7871
7872 lockdep_assert_held(&ar->conf_mutex);
7873
7874 /* First stop monitor interface. Some FW versions crash if there's a
7875 * lone monitor interface.
7876 */
7877 if (ar->monitor_started)
7878 ath10k_monitor_stop(ar);
7879
7880 for (i = 0; i < n_vifs; i++) {
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007881 arvif = (void *)vifs[i].vif->drv_priv;
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007882
7883 ath10k_dbg(ar, ATH10K_DBG_MAC,
7884 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
7885 arvif->vdev_id,
7886 vifs[i].old_ctx->def.chan->center_freq,
7887 vifs[i].new_ctx->def.chan->center_freq,
7888 vifs[i].old_ctx->def.width,
7889 vifs[i].new_ctx->def.width);
7890
7891 if (WARN_ON(!arvif->is_started))
7892 continue;
7893
7894 if (WARN_ON(!arvif->is_up))
7895 continue;
7896
7897 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7898 if (ret) {
7899 ath10k_warn(ar, "failed to down vdev %d: %d\n",
7900 arvif->vdev_id, ret);
7901 continue;
7902 }
7903 }
7904
7905 /* All relevant vdevs are downed and associated channel resources
7906 * should be available for the channel switch now.
7907 */
7908
7909 spin_lock_bh(&ar->data_lock);
7910 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
7911 spin_unlock_bh(&ar->data_lock);
7912
7913 for (i = 0; i < n_vifs; i++) {
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007914 arvif = (void *)vifs[i].vif->drv_priv;
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007915
7916 if (WARN_ON(!arvif->is_started))
7917 continue;
7918
7919 if (WARN_ON(!arvif->is_up))
7920 continue;
7921
7922 ret = ath10k_mac_setup_bcn_tmpl(arvif);
7923 if (ret)
7924 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
7925 ret);
7926
7927 ret = ath10k_mac_setup_prb_tmpl(arvif);
7928 if (ret)
7929 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
7930 ret);
7931
7932 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7933 if (ret) {
7934 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7935 arvif->vdev_id, ret);
7936 continue;
7937 }
7938
7939 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7940 arvif->bssid);
7941 if (ret) {
7942 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7943 arvif->vdev_id, ret);
7944 continue;
7945 }
7946 }
7947
7948 ath10k_monitor_recalc(ar);
7949}
7950
Michal Kazior500ff9f2015-03-31 10:26:21 +00007951static int
7952ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7953 struct ieee80211_chanctx_conf *ctx)
7954{
7955 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007956
7957 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307958 "mac chanctx add freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007959 ctx->def.chan->center_freq, ctx->def.width, ctx);
7960
7961 mutex_lock(&ar->conf_mutex);
7962
7963 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007964 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007965 spin_unlock_bh(&ar->data_lock);
7966
7967 ath10k_recalc_radar_detection(ar);
7968 ath10k_monitor_recalc(ar);
7969
7970 mutex_unlock(&ar->conf_mutex);
7971
7972 return 0;
7973}
7974
7975static void
7976ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7977 struct ieee80211_chanctx_conf *ctx)
7978{
7979 struct ath10k *ar = hw->priv;
7980
7981 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307982 "mac chanctx remove freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007983 ctx->def.chan->center_freq, ctx->def.width, ctx);
7984
7985 mutex_lock(&ar->conf_mutex);
7986
7987 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007988 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007989 spin_unlock_bh(&ar->data_lock);
7990
7991 ath10k_recalc_radar_detection(ar);
7992 ath10k_monitor_recalc(ar);
7993
7994 mutex_unlock(&ar->conf_mutex);
7995}
7996
Michal Kazior9713e3d2015-09-03 10:44:52 +02007997struct ath10k_mac_change_chanctx_arg {
7998 struct ieee80211_chanctx_conf *ctx;
7999 struct ieee80211_vif_chanctx_switch *vifs;
8000 int n_vifs;
8001 int next_vif;
8002};
8003
8004static void
8005ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
8006 struct ieee80211_vif *vif)
8007{
8008 struct ath10k_mac_change_chanctx_arg *arg = data;
8009
8010 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
8011 return;
8012
8013 arg->n_vifs++;
8014}
8015
8016static void
8017ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
8018 struct ieee80211_vif *vif)
8019{
8020 struct ath10k_mac_change_chanctx_arg *arg = data;
8021 struct ieee80211_chanctx_conf *ctx;
8022
8023 ctx = rcu_access_pointer(vif->chanctx_conf);
8024 if (ctx != arg->ctx)
8025 return;
8026
8027 if (WARN_ON(arg->next_vif == arg->n_vifs))
8028 return;
8029
8030 arg->vifs[arg->next_vif].vif = vif;
8031 arg->vifs[arg->next_vif].old_ctx = ctx;
8032 arg->vifs[arg->next_vif].new_ctx = ctx;
8033 arg->next_vif++;
8034}
8035
Michal Kazior500ff9f2015-03-31 10:26:21 +00008036static void
8037ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
8038 struct ieee80211_chanctx_conf *ctx,
8039 u32 changed)
8040{
8041 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02008042 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00008043
8044 mutex_lock(&ar->conf_mutex);
8045
8046 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05308047 "mac chanctx change freq %hu width %d ptr %pK changed %x\n",
Michal Kazior089ab7a2015-06-03 12:16:55 +02008048 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00008049
8050 /* This shouldn't really happen because channel switching should use
8051 * switch_vif_chanctx().
8052 */
8053 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
8054 goto unlock;
8055
Michal Kazior9713e3d2015-09-03 10:44:52 +02008056 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
8057 ieee80211_iterate_active_interfaces_atomic(
8058 hw,
8059 IEEE80211_IFACE_ITER_NORMAL,
8060 ath10k_mac_change_chanctx_cnt_iter,
8061 &arg);
8062 if (arg.n_vifs == 0)
8063 goto radar;
8064
8065 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
8066 GFP_KERNEL);
8067 if (!arg.vifs)
8068 goto radar;
8069
8070 ieee80211_iterate_active_interfaces_atomic(
8071 hw,
8072 IEEE80211_IFACE_ITER_NORMAL,
8073 ath10k_mac_change_chanctx_fill_iter,
8074 &arg);
8075 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
8076 kfree(arg.vifs);
8077 }
8078
8079radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00008080 ath10k_recalc_radar_detection(ar);
8081
8082 /* FIXME: How to configure Rx chains properly? */
8083
8084 /* No other actions are actually necessary. Firmware maintains channel
8085 * definitions per vdev internally and there's no host-side channel
8086 * context abstraction to configure, e.g. channel width.
8087 */
8088
8089unlock:
8090 mutex_unlock(&ar->conf_mutex);
8091}
8092
8093static int
8094ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
8095 struct ieee80211_vif *vif,
8096 struct ieee80211_chanctx_conf *ctx)
8097{
8098 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00008099 struct ath10k_vif *arvif = (void *)vif->drv_priv;
8100 int ret;
8101
8102 mutex_lock(&ar->conf_mutex);
8103
8104 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05308105 "mac chanctx assign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00008106 ctx, arvif->vdev_id);
8107
8108 if (WARN_ON(arvif->is_started)) {
8109 mutex_unlock(&ar->conf_mutex);
8110 return -EBUSY;
8111 }
8112
Michal Kazior089ab7a2015-06-03 12:16:55 +02008113 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00008114 if (ret) {
8115 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
8116 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02008117 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00008118 goto err;
8119 }
8120
8121 arvif->is_started = true;
8122
Michal Kaziorf23e587e2015-07-09 13:08:37 +02008123 ret = ath10k_mac_vif_setup_ps(arvif);
8124 if (ret) {
8125 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
8126 arvif->vdev_id, ret);
8127 goto err_stop;
8128 }
8129
Michal Kazior500ff9f2015-03-31 10:26:21 +00008130 if (vif->type == NL80211_IFTYPE_MONITOR) {
8131 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
8132 if (ret) {
8133 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
8134 arvif->vdev_id, ret);
8135 goto err_stop;
8136 }
8137
8138 arvif->is_up = true;
8139 }
8140
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02008141 if (ath10k_mac_can_set_cts_prot(arvif)) {
8142 ret = ath10k_mac_set_cts_prot(arvif);
8143 if (ret)
8144 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
8145 arvif->vdev_id, ret);
8146 }
8147
Balaji Pothunoori4fa42ad2019-05-13 20:23:07 +05308148 if (ath10k_peer_stats_enabled(ar) &&
8149 ar->hw_params.tx_stats_over_pktlog) {
Anilkumar Kollie8123bb2017-12-05 19:01:25 +05308150 ar->pktlog_filter |= ATH10K_PKTLOG_PEER_STATS;
8151 ret = ath10k_wmi_pdev_pktlog_enable(ar,
8152 ar->pktlog_filter);
8153 if (ret) {
8154 ath10k_warn(ar, "failed to enable pktlog %d\n", ret);
8155 goto err_stop;
8156 }
8157 }
8158
Michal Kazior500ff9f2015-03-31 10:26:21 +00008159 mutex_unlock(&ar->conf_mutex);
8160 return 0;
8161
8162err_stop:
8163 ath10k_vdev_stop(arvif);
8164 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02008165 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00008166
8167err:
8168 mutex_unlock(&ar->conf_mutex);
8169 return ret;
8170}
8171
8172static void
8173ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
8174 struct ieee80211_vif *vif,
8175 struct ieee80211_chanctx_conf *ctx)
8176{
8177 struct ath10k *ar = hw->priv;
8178 struct ath10k_vif *arvif = (void *)vif->drv_priv;
8179 int ret;
8180
8181 mutex_lock(&ar->conf_mutex);
8182
8183 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05308184 "mac chanctx unassign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00008185 ctx, arvif->vdev_id);
8186
8187 WARN_ON(!arvif->is_started);
8188
8189 if (vif->type == NL80211_IFTYPE_MONITOR) {
8190 WARN_ON(!arvif->is_up);
8191
8192 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
8193 if (ret)
8194 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
8195 arvif->vdev_id, ret);
8196
8197 arvif->is_up = false;
8198 }
8199
8200 ret = ath10k_vdev_stop(arvif);
8201 if (ret)
8202 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
8203 arvif->vdev_id, ret);
8204
8205 arvif->is_started = false;
8206
8207 mutex_unlock(&ar->conf_mutex);
8208}
8209
8210static int
8211ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
8212 struct ieee80211_vif_chanctx_switch *vifs,
8213 int n_vifs,
8214 enum ieee80211_chanctx_switch_mode mode)
8215{
8216 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00008217
8218 mutex_lock(&ar->conf_mutex);
8219
8220 ath10k_dbg(ar, ATH10K_DBG_MAC,
8221 "mac chanctx switch n_vifs %d mode %d\n",
8222 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02008223 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00008224
8225 mutex_unlock(&ar->conf_mutex);
8226 return 0;
8227}
8228
Michal Kazior0a744d92017-01-12 16:14:30 +01008229static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,
8230 struct ieee80211_vif *vif,
8231 struct ieee80211_sta *sta)
8232{
8233 struct ath10k *ar;
8234 struct ath10k_peer *peer;
8235
8236 ar = hw->priv;
8237
8238 list_for_each_entry(peer, &ar->peers, list)
8239 if (peer->sta == sta)
8240 peer->removed = true;
8241}
8242
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05308243static void ath10k_sta_statistics(struct ieee80211_hw *hw,
8244 struct ieee80211_vif *vif,
8245 struct ieee80211_sta *sta,
8246 struct station_info *sinfo)
8247{
8248 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
8249 struct ath10k *ar = arsta->arvif->ar;
8250
8251 if (!ath10k_peer_stats_enabled(ar))
8252 return;
8253
8254 sinfo->rx_duration = arsta->rx_duration;
Omer Efrat22d0d2f2018-06-17 13:07:13 +03008255 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05308256
8257 if (!arsta->txrate.legacy && !arsta->txrate.nss)
8258 return;
8259
8260 if (arsta->txrate.legacy) {
8261 sinfo->txrate.legacy = arsta->txrate.legacy;
8262 } else {
8263 sinfo->txrate.mcs = arsta->txrate.mcs;
8264 sinfo->txrate.nss = arsta->txrate.nss;
8265 sinfo->txrate.bw = arsta->txrate.bw;
8266 }
8267 sinfo->txrate.flags = arsta->txrate.flags;
Omer Efrat22d0d2f2018-06-17 13:07:13 +03008268 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05308269}
8270
Kalle Valo5e3dd152013-06-12 20:52:10 +03008271static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01008272 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02008273 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03008274 .start = ath10k_start,
8275 .stop = ath10k_stop,
8276 .config = ath10k_config,
8277 .add_interface = ath10k_add_interface,
8278 .remove_interface = ath10k_remove_interface,
8279 .configure_filter = ath10k_configure_filter,
8280 .bss_info_changed = ath10k_bss_info_changed,
Benjamin Bergebee76f2016-09-28 15:11:58 +03008281 .set_coverage_class = ath10k_mac_op_set_coverage_class,
Kalle Valo5e3dd152013-06-12 20:52:10 +03008282 .hw_scan = ath10k_hw_scan,
8283 .cancel_hw_scan = ath10k_cancel_hw_scan,
8284 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02008285 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03008286 .sta_state = ath10k_sta_state,
Ashok Raj Nagarajan33410a52019-06-03 18:09:02 +03008287 .sta_set_txpwr = ath10k_sta_set_txpwr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03008288 .conf_tx = ath10k_conf_tx,
8289 .remain_on_channel = ath10k_remain_on_channel,
8290 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
8291 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02008292 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03008293 .flush = ath10k_flush,
8294 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7bb2014-05-16 17:15:38 +03008295 .set_antenna = ath10k_set_antenna,
8296 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02008297 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02008298 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00008299 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01008300 .sta_rc_update = ath10k_sta_rc_update,
Pedersen, Thomas973324f2016-09-28 16:56:29 -07008301 .offset_tsf = ath10k_offset_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02008302 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03008303 .get_et_sset_count = ath10k_debug_get_et_sset_count,
8304 .get_et_stats = ath10k_debug_get_et_stats,
8305 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00008306 .add_chanctx = ath10k_mac_op_add_chanctx,
8307 .remove_chanctx = ath10k_mac_op_remove_chanctx,
8308 .change_chanctx = ath10k_mac_op_change_chanctx,
8309 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
8310 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
8311 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Michal Kazior0a744d92017-01-12 16:14:30 +01008312 .sta_pre_rcu_remove = ath10k_mac_op_sta_pre_rcu_remove,
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05308313 .sta_statistics = ath10k_sta_statistics,
Kalle Valo43d2a302014-09-10 18:23:30 +03008314
8315 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
8316
Michal Kazior8cd13ca2013-07-16 09:38:54 +02008317#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02008318 .suspend = ath10k_wow_op_suspend,
8319 .resume = ath10k_wow_op_resume,
Ryan Hsu393b7062017-08-31 15:36:16 +03008320 .set_wakeup = ath10k_wow_op_set_wakeup,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02008321#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02008322#ifdef CONFIG_MAC80211_DEBUGFS
8323 .sta_add_debugfs = ath10k_sta_add_debugfs,
8324#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03008325};
8326
Kalle Valo5e3dd152013-06-12 20:52:10 +03008327#define CHAN2G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02008328 .band = NL80211_BAND_2GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03008329 .hw_value = (_channel), \
8330 .center_freq = (_freq), \
8331 .flags = (_flags), \
8332 .max_antenna_gain = 0, \
8333 .max_power = 30, \
8334}
8335
8336#define CHAN5G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02008337 .band = NL80211_BAND_5GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03008338 .hw_value = (_channel), \
8339 .center_freq = (_freq), \
8340 .flags = (_flags), \
8341 .max_antenna_gain = 0, \
8342 .max_power = 30, \
8343}
8344
8345static const struct ieee80211_channel ath10k_2ghz_channels[] = {
8346 CHAN2G(1, 2412, 0),
8347 CHAN2G(2, 2417, 0),
8348 CHAN2G(3, 2422, 0),
8349 CHAN2G(4, 2427, 0),
8350 CHAN2G(5, 2432, 0),
8351 CHAN2G(6, 2437, 0),
8352 CHAN2G(7, 2442, 0),
8353 CHAN2G(8, 2447, 0),
8354 CHAN2G(9, 2452, 0),
8355 CHAN2G(10, 2457, 0),
8356 CHAN2G(11, 2462, 0),
8357 CHAN2G(12, 2467, 0),
8358 CHAN2G(13, 2472, 0),
8359 CHAN2G(14, 2484, 0),
8360};
8361
8362static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02008363 CHAN5G(36, 5180, 0),
8364 CHAN5G(40, 5200, 0),
8365 CHAN5G(44, 5220, 0),
8366 CHAN5G(48, 5240, 0),
8367 CHAN5G(52, 5260, 0),
8368 CHAN5G(56, 5280, 0),
8369 CHAN5G(60, 5300, 0),
8370 CHAN5G(64, 5320, 0),
8371 CHAN5G(100, 5500, 0),
8372 CHAN5G(104, 5520, 0),
8373 CHAN5G(108, 5540, 0),
8374 CHAN5G(112, 5560, 0),
8375 CHAN5G(116, 5580, 0),
8376 CHAN5G(120, 5600, 0),
8377 CHAN5G(124, 5620, 0),
8378 CHAN5G(128, 5640, 0),
8379 CHAN5G(132, 5660, 0),
8380 CHAN5G(136, 5680, 0),
8381 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07008382 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02008383 CHAN5G(149, 5745, 0),
8384 CHAN5G(153, 5765, 0),
8385 CHAN5G(157, 5785, 0),
8386 CHAN5G(161, 5805, 0),
8387 CHAN5G(165, 5825, 0),
Mohammed Shafi Shajakhan34c30b02016-12-27 20:53:35 +05308388 CHAN5G(169, 5845, 0),
Ben Greear38441fb2018-01-02 16:51:01 -08008389 CHAN5G(173, 5865, 0),
8390 /* If you add more, you may need to change ATH10K_MAX_5G_CHAN */
8391 /* And you will definitely need to change ATH10K_NUM_CHANS in core.h */
Kalle Valo5e3dd152013-06-12 20:52:10 +03008392};
8393
Michal Kaziore7b54192014-08-07 11:03:27 +02008394struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03008395{
8396 struct ieee80211_hw *hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03008397 struct ieee80211_ops *ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008398 struct ath10k *ar;
8399
Michal Kazior4ca18072016-07-18 23:22:18 +03008400 ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);
8401 if (!ops)
Kalle Valo5e3dd152013-06-12 20:52:10 +03008402 return NULL;
8403
Michal Kazior4ca18072016-07-18 23:22:18 +03008404 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);
8405 if (!hw) {
8406 kfree(ops);
8407 return NULL;
8408 }
8409
Kalle Valo5e3dd152013-06-12 20:52:10 +03008410 ar = hw->priv;
8411 ar->hw = hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03008412 ar->ops = ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008413
8414 return ar;
8415}
8416
8417void ath10k_mac_destroy(struct ath10k *ar)
8418{
Michal Kazior4ca18072016-07-18 23:22:18 +03008419 struct ieee80211_ops *ops = ar->ops;
8420
Kalle Valo5e3dd152013-06-12 20:52:10 +03008421 ieee80211_free_hw(ar->hw);
Michal Kazior4ca18072016-07-18 23:22:18 +03008422 kfree(ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008423}
8424
8425static const struct ieee80211_iface_limit ath10k_if_limits[] = {
8426 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308427 .max = 8,
8428 .types = BIT(NL80211_IFTYPE_STATION)
8429 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02008430 },
8431 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308432 .max = 3,
8433 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02008434 },
8435 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308436 .max = 1,
8437 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01008438 },
8439 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308440 .max = 7,
8441 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008442#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308443 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008444#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02008445 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03008446};
8447
Bartosz Markowskif2595092013-12-10 16:20:39 +01008448static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008449 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308450 .max = 8,
8451 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008452#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308453 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008454#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008455 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308456 {
8457 .max = 1,
8458 .types = BIT(NL80211_IFTYPE_STATION)
8459 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008460};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008461
8462static const struct ieee80211_iface_combination ath10k_if_comb[] = {
8463 {
8464 .limits = ath10k_if_limits,
8465 .n_limits = ARRAY_SIZE(ath10k_if_limits),
8466 .max_interfaces = 8,
8467 .num_different_channels = 1,
8468 .beacon_int_infra_match = true,
8469 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01008470};
8471
8472static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008473 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01008474 .limits = ath10k_10x_if_limits,
8475 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008476 .max_interfaces = 8,
8477 .num_different_channels = 1,
8478 .beacon_int_infra_match = true,
Anilkumar Kolli8ebee732018-03-28 12:19:40 +03008479 .beacon_int_min_gcd = 1,
Bartosz Markowskif2595092013-12-10 16:20:39 +01008480#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008481 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
8482 BIT(NL80211_CHAN_WIDTH_20) |
8483 BIT(NL80211_CHAN_WIDTH_40) |
8484 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008485#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01008486 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03008487};
8488
Michal Kaziorcf327842015-03-31 10:26:25 +00008489static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
8490 {
8491 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02008492 .types = BIT(NL80211_IFTYPE_STATION),
8493 },
8494 {
8495 .max = 2,
8496 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008497#ifdef CONFIG_MAC80211_MESH
8498 BIT(NL80211_IFTYPE_MESH_POINT) |
8499#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00008500 BIT(NL80211_IFTYPE_P2P_CLIENT) |
8501 BIT(NL80211_IFTYPE_P2P_GO),
8502 },
8503 {
8504 .max = 1,
8505 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
8506 },
8507};
8508
Michal Kaziored25b112015-07-09 13:08:39 +02008509static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
8510 {
8511 .max = 2,
8512 .types = BIT(NL80211_IFTYPE_STATION),
8513 },
8514 {
8515 .max = 2,
8516 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
8517 },
8518 {
8519 .max = 1,
8520 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008521#ifdef CONFIG_MAC80211_MESH
8522 BIT(NL80211_IFTYPE_MESH_POINT) |
8523#endif
Michal Kaziored25b112015-07-09 13:08:39 +02008524 BIT(NL80211_IFTYPE_P2P_GO),
8525 },
8526 {
8527 .max = 1,
8528 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
8529 },
8530};
8531
Michal Kaziorcf327842015-03-31 10:26:25 +00008532static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
8533 {
8534 .max = 1,
8535 .types = BIT(NL80211_IFTYPE_STATION),
8536 },
8537 {
8538 .max = 1,
8539 .types = BIT(NL80211_IFTYPE_ADHOC),
8540 },
8541};
8542
8543/* FIXME: This is not thouroughly tested. These combinations may over- or
8544 * underestimate hw/fw capabilities.
8545 */
8546static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
8547 {
8548 .limits = ath10k_tlv_if_limit,
8549 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02008550 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00008551 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
8552 },
8553 {
8554 .limits = ath10k_tlv_if_limit_ibss,
8555 .num_different_channels = 1,
8556 .max_interfaces = 2,
8557 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
8558 },
8559};
8560
8561static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
8562 {
8563 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02008564 .num_different_channels = 1,
8565 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00008566 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
8567 },
8568 {
Michal Kaziored25b112015-07-09 13:08:39 +02008569 .limits = ath10k_tlv_qcs_if_limit,
8570 .num_different_channels = 2,
8571 .max_interfaces = 4,
8572 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
8573 },
8574 {
Michal Kaziorcf327842015-03-31 10:26:25 +00008575 .limits = ath10k_tlv_if_limit_ibss,
8576 .num_different_channels = 1,
8577 .max_interfaces = 2,
8578 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
8579 },
8580};
8581
Raja Manicf36fef2015-06-22 20:22:25 +05308582static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
8583 {
8584 .max = 1,
8585 .types = BIT(NL80211_IFTYPE_STATION),
8586 },
8587 {
8588 .max = 16,
8589 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008590#ifdef CONFIG_MAC80211_MESH
8591 | BIT(NL80211_IFTYPE_MESH_POINT)
8592#endif
Raja Manicf36fef2015-06-22 20:22:25 +05308593 },
8594};
8595
8596static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
8597 {
8598 .limits = ath10k_10_4_if_limits,
8599 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
8600 .max_interfaces = 16,
8601 .num_different_channels = 1,
8602 .beacon_int_infra_match = true,
Anilkumar Kolli8ebee732018-03-28 12:19:40 +03008603 .beacon_int_min_gcd = 1,
Raja Manicf36fef2015-06-22 20:22:25 +05308604#ifdef CONFIG_ATH10K_DFS_CERTIFIED
8605 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
8606 BIT(NL80211_CHAN_WIDTH_20) |
8607 BIT(NL80211_CHAN_WIDTH_40) |
8608 BIT(NL80211_CHAN_WIDTH_80),
8609#endif
8610 },
8611};
8612
Maharaja Kennadyrajan46005632018-09-18 17:37:26 +05308613static const struct
8614ieee80211_iface_combination ath10k_10_4_bcn_int_if_comb[] = {
8615 {
8616 .limits = ath10k_10_4_if_limits,
8617 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
8618 .max_interfaces = 16,
8619 .num_different_channels = 1,
8620 .beacon_int_infra_match = true,
8621 .beacon_int_min_gcd = 100,
8622#ifdef CONFIG_ATH10K_DFS_CERTIFIED
8623 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
8624 BIT(NL80211_CHAN_WIDTH_20) |
8625 BIT(NL80211_CHAN_WIDTH_40) |
8626 BIT(NL80211_CHAN_WIDTH_80),
8627#endif
8628 },
8629};
8630
Kalle Valo5e3dd152013-06-12 20:52:10 +03008631static void ath10k_get_arvif_iter(void *data, u8 *mac,
8632 struct ieee80211_vif *vif)
8633{
8634 struct ath10k_vif_iter *arvif_iter = data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02008635 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008636
8637 if (arvif->vdev_id == arvif_iter->vdev_id)
8638 arvif_iter->arvif = arvif;
8639}
8640
8641struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
8642{
8643 struct ath10k_vif_iter arvif_iter;
8644 u32 flags;
8645
8646 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
8647 arvif_iter.vdev_id = vdev_id;
8648
8649 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
8650 ieee80211_iterate_active_interfaces_atomic(ar->hw,
8651 flags,
8652 ath10k_get_arvif_iter,
8653 &arvif_iter);
8654 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008655 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008656 return NULL;
8657 }
8658
8659 return arvif_iter.arvif;
8660}
8661
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008662#define WRD_METHOD "WRDD"
8663#define WRDD_WIFI (0x07)
8664
8665static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_object *wrdd)
8666{
8667 union acpi_object *mcc_pkg;
8668 union acpi_object *domain_type;
8669 union acpi_object *mcc_value;
8670 u32 i;
8671
8672 if (wrdd->type != ACPI_TYPE_PACKAGE ||
8673 wrdd->package.count < 2 ||
8674 wrdd->package.elements[0].type != ACPI_TYPE_INTEGER ||
8675 wrdd->package.elements[0].integer.value != 0) {
8676 ath10k_warn(ar, "ignoring malformed/unsupported wrdd structure\n");
8677 return 0;
8678 }
8679
8680 for (i = 1; i < wrdd->package.count; ++i) {
8681 mcc_pkg = &wrdd->package.elements[i];
8682
8683 if (mcc_pkg->type != ACPI_TYPE_PACKAGE)
8684 continue;
8685 if (mcc_pkg->package.count < 2)
8686 continue;
8687 if (mcc_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
8688 mcc_pkg->package.elements[1].type != ACPI_TYPE_INTEGER)
8689 continue;
8690
8691 domain_type = &mcc_pkg->package.elements[0];
8692 if (domain_type->integer.value != WRDD_WIFI)
8693 continue;
8694
8695 mcc_value = &mcc_pkg->package.elements[1];
8696 return mcc_value->integer.value;
8697 }
8698 return 0;
8699}
8700
8701static int ath10k_mac_get_wrdd_regulatory(struct ath10k *ar, u16 *rd)
8702{
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008703 acpi_handle root_handle;
8704 acpi_handle handle;
8705 struct acpi_buffer wrdd = {ACPI_ALLOCATE_BUFFER, NULL};
8706 acpi_status status;
8707 u32 alpha2_code;
8708 char alpha2[3];
8709
Brian Norris79169f12018-11-02 10:17:48 -07008710 root_handle = ACPI_HANDLE(ar->dev);
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008711 if (!root_handle)
8712 return -EOPNOTSUPP;
8713
8714 status = acpi_get_handle(root_handle, (acpi_string)WRD_METHOD, &handle);
8715 if (ACPI_FAILURE(status)) {
8716 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8717 "failed to get wrd method %d\n", status);
8718 return -EIO;
8719 }
8720
8721 status = acpi_evaluate_object(handle, NULL, NULL, &wrdd);
8722 if (ACPI_FAILURE(status)) {
8723 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8724 "failed to call wrdc %d\n", status);
8725 return -EIO;
8726 }
8727
8728 alpha2_code = ath10k_mac_wrdd_get_mcc(ar, wrdd.pointer);
8729 kfree(wrdd.pointer);
8730 if (!alpha2_code)
8731 return -EIO;
8732
8733 alpha2[0] = (alpha2_code >> 8) & 0xff;
8734 alpha2[1] = (alpha2_code >> 0) & 0xff;
8735 alpha2[2] = '\0';
8736
8737 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8738 "regulatory hint from WRDD (alpha2-code): %s\n", alpha2);
8739
8740 *rd = ath_regd_find_country_by_name(alpha2);
8741 if (*rd == 0xffff)
8742 return -EIO;
8743
8744 *rd |= COUNTRY_ERD_FLAG;
8745 return 0;
8746}
8747
8748static int ath10k_mac_init_rd(struct ath10k *ar)
8749{
8750 int ret;
8751 u16 rd;
8752
8753 ret = ath10k_mac_get_wrdd_regulatory(ar, &rd);
8754 if (ret) {
8755 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8756 "fallback to eeprom programmed regulatory settings\n");
8757 rd = ar->hw_eeprom_rd;
8758 }
8759
8760 ar->ath_common.regulatory.current_rd = rd;
8761 return 0;
8762}
8763
Kalle Valo5e3dd152013-06-12 20:52:10 +03008764int ath10k_mac_register(struct ath10k *ar)
8765{
Johannes Berg3cb10942015-01-22 21:38:45 +01008766 static const u32 cipher_suites[] = {
8767 WLAN_CIPHER_SUITE_WEP40,
8768 WLAN_CIPHER_SUITE_WEP104,
8769 WLAN_CIPHER_SUITE_TKIP,
8770 WLAN_CIPHER_SUITE_CCMP,
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07008771
8772 /* Do not add hardware supported ciphers before this line.
8773 * Allow software encryption for all chips. Don't forget to
8774 * update n_cipher_suites below.
8775 */
Johannes Berg3cb10942015-01-22 21:38:45 +01008776 WLAN_CIPHER_SUITE_AES_CMAC,
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07008777 WLAN_CIPHER_SUITE_BIP_CMAC_256,
8778 WLAN_CIPHER_SUITE_BIP_GMAC_128,
8779 WLAN_CIPHER_SUITE_BIP_GMAC_256,
8780
8781 /* Only QCA99x0 and QCA4019 varients support GCMP-128, GCMP-256
8782 * and CCMP-256 in hardware.
8783 */
8784 WLAN_CIPHER_SUITE_GCMP,
8785 WLAN_CIPHER_SUITE_GCMP_256,
8786 WLAN_CIPHER_SUITE_CCMP_256,
Johannes Berg3cb10942015-01-22 21:38:45 +01008787 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03008788 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008789 void *channels;
8790 int ret;
8791
Brian Norris234e4302018-09-07 10:21:57 -07008792 if (!is_valid_ether_addr(ar->mac_addr)) {
8793 ath10k_warn(ar, "invalid MAC address; choosing random\n");
8794 eth_random_addr(ar->mac_addr);
8795 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008796 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
8797
8798 SET_IEEE80211_DEV(ar->hw, ar->dev);
8799
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00008800 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
8801 ARRAY_SIZE(ath10k_5ghz_channels)) !=
8802 ATH10K_NUM_CHANS);
8803
Kalle Valo5e3dd152013-06-12 20:52:10 +03008804 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
8805 channels = kmemdup(ath10k_2ghz_channels,
8806 sizeof(ath10k_2ghz_channels),
8807 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02008808 if (!channels) {
8809 ret = -ENOMEM;
8810 goto err_free;
8811 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008812
Johannes Berg57fbcce2016-04-12 15:56:15 +02008813 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03008814 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
8815 band->channels = channels;
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +03008816
8817 if (ar->hw_params.cck_rate_map_rev2) {
8818 band->n_bitrates = ath10k_g_rates_rev2_size;
8819 band->bitrates = ath10k_g_rates_rev2;
8820 } else {
8821 band->n_bitrates = ath10k_g_rates_size;
8822 band->bitrates = ath10k_g_rates;
8823 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008824
Johannes Berg57fbcce2016-04-12 15:56:15 +02008825 ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008826 }
8827
8828 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
8829 channels = kmemdup(ath10k_5ghz_channels,
8830 sizeof(ath10k_5ghz_channels),
8831 GFP_KERNEL);
8832 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02008833 ret = -ENOMEM;
8834 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008835 }
8836
Johannes Berg57fbcce2016-04-12 15:56:15 +02008837 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03008838 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
8839 band->channels = channels;
8840 band->n_bitrates = ath10k_a_rates_size;
8841 band->bitrates = ath10k_a_rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02008842 ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008843 }
8844
Sven Eckelmann34d56292018-08-24 15:04:59 +03008845 wiphy_read_of_freq_limits(ar->hw->wiphy);
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05308846 ath10k_mac_setup_ht_vht_cap(ar);
8847
Kalle Valo5e3dd152013-06-12 20:52:10 +03008848 ar->hw->wiphy->interface_modes =
8849 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008850 BIT(NL80211_IFTYPE_AP) |
8851 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01008852
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05308853 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
8854 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03008855
Kalle Valoc4cdf752016-04-20 19:45:18 +03008856 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))
Bartosz Markowskid3541812013-12-10 16:20:40 +01008857 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01008858 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01008859 BIT(NL80211_IFTYPE_P2P_CLIENT) |
8860 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008861
Johannes Berg30686bf2015-06-02 21:39:54 +02008862 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
Venkateswara Naralasetty36d9cdb2017-10-04 12:22:57 +03008863
8864 if (!test_bit(ATH10K_FW_FEATURE_NO_PS,
8865 ar->running_fw->fw_file.fw_features)) {
8866 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
8867 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
8868 }
8869
Johannes Berg30686bf2015-06-02 21:39:54 +02008870 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
8871 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
8872 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
8873 ieee80211_hw_set(ar->hw, AP_LINK_PS);
8874 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02008875 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
8876 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
8877 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
8878 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
8879 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
8880 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Sara Sharonf3fe4e92016-10-18 23:12:11 +03008881 ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
Rajkumar Manoharanff32eeb2016-09-06 12:38:41 +05308882 ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008883
David Liuccec9032015-07-24 20:25:32 +03008884 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8885 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
8886
Eliad Peller0d8614b2014-09-10 14:07:36 +03008887 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00008888 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03008889
Kalle Valo5e3dd152013-06-12 20:52:10 +03008890 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03008891 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008892
8893 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02008894 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
8895 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008896 }
8897
8898 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
8899 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
8900
Wen Gongce834e22018-10-04 08:45:31 +03008901 if (test_bit(WMI_SERVICE_NLO, ar->wmi.svc_map)) {
8902 ar->hw->wiphy->max_sched_scan_reqs = 1;
8903 ar->hw->wiphy->max_sched_scan_ssids = WMI_PNO_MAX_SUPP_NETWORKS;
8904 ar->hw->wiphy->max_match_sets = WMI_PNO_MAX_SUPP_NETWORKS;
8905 ar->hw->wiphy->max_sched_scan_ie_len = WMI_PNO_MAX_IE_LENGTH;
8906 ar->hw->wiphy->max_sched_scan_plans = WMI_PNO_MAX_SCHED_SCAN_PLANS;
8907 ar->hw->wiphy->max_sched_scan_plan_interval =
8908 WMI_PNO_MAX_SCHED_SCAN_PLAN_INT;
8909 ar->hw->wiphy->max_sched_scan_plan_iterations =
8910 WMI_PNO_MAX_SCHED_SCAN_PLAN_ITRNS;
8911 }
8912
Kalle Valo5e3dd152013-06-12 20:52:10 +03008913 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01008914 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02008915 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008916
Kalle Valo5e3dd152013-06-12 20:52:10 +03008917 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
8918
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02008919 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
8920 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
8921
8922 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
8923 * that userspace (e.g. wpa_supplicant/hostapd) can generate
8924 * correct Probe Responses. This is more of a hack advert..
8925 */
8926 ar->hw->wiphy->probe_resp_offload |=
8927 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
8928 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
8929 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
8930 }
8931
Manikanta Pubbisettyadd6cd82017-07-28 15:15:42 +03008932 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map) ||
8933 test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, ar->wmi.svc_map)) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03008934 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
Balaji Pothunoori14d65772017-12-21 20:00:42 +05308935 if (test_bit(WMI_SERVICE_TDLS_WIDER_BANDWIDTH, ar->wmi.svc_map))
8936 ieee80211_hw_set(ar->hw, TDLS_WIDER_BW);
Manikanta Pubbisettyadd6cd82017-07-28 15:15:42 +03008937 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03008938
Yingying Tang802ca332018-03-28 12:12:52 +03008939 if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
8940 ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA);
8941
Kalle Valo5e3dd152013-06-12 20:52:10 +03008942 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01008943 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008944 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
8945
8946 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05308947 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
8948 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02008949
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01008950 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
8951
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02008952 ret = ath10k_wow_init(ar);
8953 if (ret) {
8954 ath10k_warn(ar, "failed to init wow: %d\n", ret);
8955 goto err_free;
8956 }
8957
Janusz Dziedzicc7025342015-06-15 14:46:41 +03008958 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03008959 wiphy_ext_feature_set(ar->hw->wiphy,
8960 NL80211_EXT_FEATURE_SET_SCAN_DWELL);
Janusz Dziedzicc7025342015-06-15 14:46:41 +03008961
Balaji Pothunoori6bc17952018-09-10 11:54:30 +05308962 if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map) ||
8963 test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, ar->wmi.svc_map))
Balaji Pothunooric7fd8d22018-09-04 12:52:18 +03008964 wiphy_ext_feature_set(ar->hw->wiphy,
Balaji Pothunoori6bc17952018-09-10 11:54:30 +05308965 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
Balaji Pothunooric7fd8d22018-09-04 12:52:18 +03008966
Manikanta Pubbisettybb31b7c2019-02-11 18:47:59 +02008967 if (ath10k_peer_stats_enabled(ar) ||
8968 test_bit(WMI_SERVICE_REPORT_AIRTIME, ar->wmi.svc_map))
Kan Yand1ce37b2019-02-11 18:47:52 +02008969 wiphy_ext_feature_set(ar->hw->wiphy,
8970 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
Pradeep Kumar Chitrapu059104b2019-02-11 18:47:54 +02008971
8972 if (test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map))
8973 wiphy_ext_feature_set(ar->hw->wiphy,
8974 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
8975
Ashok Raj Nagarajan33410a52019-06-03 18:09:02 +03008976 if (test_bit(WMI_SERVICE_TX_PWR_PER_PEER, ar->wmi.svc_map))
8977 wiphy_ext_feature_set(ar->hw->wiphy,
8978 NL80211_EXT_FEATURE_STA_TX_PWR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008979 /*
8980 * on LL hardware queues are managed entirely by the FW
8981 * so we only advertise to mac we can do the queues thing
8982 */
Michal Kazior96d828d2015-03-31 10:26:23 +00008983 ar->hw->queues = IEEE80211_MAX_QUEUES;
8984
8985 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
8986 * something that vdev_ids can't reach so that we don't stop the queue
8987 * accidentally.
8988 */
8989 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008990
Kalle Valobf3c13a2016-04-20 19:45:33 +03008991 switch (ar->running_fw->fw_file.wmi_op_version) {
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008992 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01008993 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
8994 ar->hw->wiphy->n_iface_combinations =
8995 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03008996 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008997 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00008998 case ATH10K_FW_WMI_OP_VERSION_TLV:
8999 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
9000 ar->hw->wiphy->iface_combinations =
9001 ath10k_tlv_qcs_if_comb;
9002 ar->hw->wiphy->n_iface_combinations =
9003 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
9004 } else {
9005 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
9006 ar->hw->wiphy->n_iface_combinations =
9007 ARRAY_SIZE(ath10k_tlv_if_comb);
9008 }
9009 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
9010 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02009011 case ATH10K_FW_WMI_OP_VERSION_10_1:
9012 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02009013 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02009014 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
9015 ar->hw->wiphy->n_iface_combinations =
9016 ARRAY_SIZE(ath10k_10x_if_comb);
9017 break;
Raja Mani9bd21322015-06-22 20:10:09 +05309018 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05309019 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
9020 ar->hw->wiphy->n_iface_combinations =
9021 ARRAY_SIZE(ath10k_10_4_if_comb);
Maharaja Kennadyrajan46005632018-09-18 17:37:26 +05309022 if (test_bit(WMI_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT,
9023 ar->wmi.svc_map)) {
9024 ar->hw->wiphy->iface_combinations =
9025 ath10k_10_4_bcn_int_if_comb;
9026 ar->hw->wiphy->n_iface_combinations =
9027 ARRAY_SIZE(ath10k_10_4_bcn_int_if_comb);
9028 }
Raja Mani9bd21322015-06-22 20:10:09 +05309029 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02009030 case ATH10K_FW_WMI_OP_VERSION_UNSET:
9031 case ATH10K_FW_WMI_OP_VERSION_MAX:
9032 WARN_ON(1);
9033 ret = -EINVAL;
9034 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01009035 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03009036
David Liuccec9032015-07-24 20:25:32 +03009037 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
9038 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02009039
Masahiro Yamada97f26452016-08-03 13:45:50 -07009040 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
Janusz Dziedzic9702c682013-11-20 09:59:41 +02009041 /* Init ath dfs pattern detector */
9042 ar->ath_common.debug_mask = ATH_DBG_DFS;
9043 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
9044 NL80211_DFS_UNSET);
9045
9046 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02009047 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02009048 }
9049
Bartosz Markowski209b2a62016-09-28 15:11:58 +03009050 ret = ath10k_mac_init_rd(ar);
9051 if (ret) {
9052 ath10k_err(ar, "failed to derive regdom: %d\n", ret);
9053 goto err_dfs_detector_exit;
9054 }
9055
Benjamin Bergebee76f2016-09-28 15:11:58 +03009056 /* Disable set_coverage_class for chipsets that do not support it. */
9057 if (!ar->hw_params.hw_ops->set_coverage_class)
9058 ar->ops->set_coverage_class = NULL;
9059
Kalle Valo5e3dd152013-06-12 20:52:10 +03009060 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
9061 ath10k_reg_notifier);
9062 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02009063 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07009064 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03009065 }
9066
Carl Huang60e1d0f2018-04-19 19:39:40 +03009067 if (test_bit(WMI_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi.svc_map)) {
Carl Huang60e1d0f2018-04-19 19:39:40 +03009068 ar->hw->wiphy->features |=
9069 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
9070 }
9071
Johannes Berg3cb10942015-01-22 21:38:45 +01009072 ar->hw->wiphy->cipher_suites = cipher_suites;
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07009073
9074 /* QCA988x and QCA6174 family chips do not support CCMP-256, GCMP-128
9075 * and GCMP-256 ciphers in hardware. Fetch number of ciphers supported
9076 * from chip specific hw_param table.
9077 */
9078 if (!ar->hw_params.n_cipher_suites ||
9079 ar->hw_params.n_cipher_suites > ARRAY_SIZE(cipher_suites)) {
9080 ath10k_err(ar, "invalid hw_params.n_cipher_suites %d\n",
9081 ar->hw_params.n_cipher_suites);
9082 ar->hw_params.n_cipher_suites = 8;
9083 }
9084 ar->hw->wiphy->n_cipher_suites = ar->hw_params.n_cipher_suites;
Johannes Berg3cb10942015-01-22 21:38:45 +01009085
Andrew Zaborowskiae44b502017-02-10 04:50:23 +01009086 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
9087
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02009088 ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
9089
Kalle Valo5e3dd152013-06-12 20:52:10 +03009090 ret = ieee80211_register_hw(ar->hw);
9091 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02009092 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07009093 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03009094 }
9095
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02009096 if (test_bit(WMI_SERVICE_PER_PACKET_SW_ENCRYPT, ar->wmi.svc_map)) {
9097 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
9098 ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN);
9099 }
9100
Kalle Valo5e3dd152013-06-12 20:52:10 +03009101 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
9102 ret = regulatory_hint(ar->hw->wiphy,
9103 ar->ath_common.regulatory.alpha2);
9104 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02009105 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03009106 }
9107
9108 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02009109
9110err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03009111 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07009112
9113err_dfs_detector_exit:
Masahiro Yamada97f26452016-08-03 13:45:50 -07009114 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Jeff Johnson0e339442015-10-08 09:15:53 -07009115 ar->dfs_detector->exit(ar->dfs_detector);
9116
Michal Kaziord6015b22013-07-22 14:13:30 +02009117err_free:
Johannes Berg57fbcce2016-04-12 15:56:15 +02009118 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
9119 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Michal Kaziord6015b22013-07-22 14:13:30 +02009120
Jeff Johnson0e339442015-10-08 09:15:53 -07009121 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03009122 return ret;
9123}
9124
9125void ath10k_mac_unregister(struct ath10k *ar)
9126{
9127 ieee80211_unregister_hw(ar->hw);
9128
Masahiro Yamada97f26452016-08-03 13:45:50 -07009129 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Janusz Dziedzic9702c682013-11-20 09:59:41 +02009130 ar->dfs_detector->exit(ar->dfs_detector);
9131
Johannes Berg57fbcce2016-04-12 15:56:15 +02009132 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
9133 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Kalle Valo5e3dd152013-06-12 20:52:10 +03009134
9135 SET_IEEE80211_DEV(ar->hw, NULL);
9136}