blob: bf094f44e9ad6a97395f4332ed555684029b353d [file] [log] [blame]
Kalle Valo5e3dd152013-06-12 20:52:10 +03001/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc.
Kalle Valo8b1083d2017-12-22 18:31:13 +02003 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
Rakesh Pillai6e8a8992019-01-25 09:51:06 +05304 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
Kalle Valo5e3dd152013-06-12 20:52:10 +03005 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include "mac.h"
20
Sven Eckelmann34d56292018-08-24 15:04:59 +030021#include <net/cfg80211.h>
Kalle Valo5e3dd152013-06-12 20:52:10 +030022#include <net/mac80211.h>
23#include <linux/etherdevice.h>
Bartosz Markowski209b2a62016-09-28 15:11:58 +030024#include <linux/acpi.h>
Bhagavathi Perumal S84758d42018-12-20 14:26:00 +020025#include <linux/of.h>
Kalle Valo5e3dd152013-06-12 20:52:10 +030026
Michal Kazior8cd13ca2013-07-16 09:38:54 +020027#include "hif.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030028#include "core.h"
29#include "debug.h"
30#include "wmi.h"
31#include "htt.h"
32#include "txrx.h"
Kalle Valo43d2a302014-09-10 18:23:30 +030033#include "testmode.h"
Michal Kaziorb4aa5392015-03-31 10:26:24 +000034#include "wmi-tlv.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020035#include "wmi-ops.h"
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +020036#include "wow.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030037
Michal Kaziordcc33092015-03-30 09:51:54 +030038/*********/
39/* Rates */
40/*********/
41
Michal Kaziordcc33092015-03-30 09:51:54 +030042static struct ieee80211_rate ath10k_rates[] = {
Michal Kazior5528e032015-03-30 09:51:56 +030043 { .bitrate = 10,
44 .hw_value = ATH10K_HW_RATE_CCK_LP_1M },
45 { .bitrate = 20,
46 .hw_value = ATH10K_HW_RATE_CCK_LP_2M,
47 .hw_value_short = ATH10K_HW_RATE_CCK_SP_2M,
48 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
49 { .bitrate = 55,
50 .hw_value = ATH10K_HW_RATE_CCK_LP_5_5M,
51 .hw_value_short = ATH10K_HW_RATE_CCK_SP_5_5M,
52 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
53 { .bitrate = 110,
54 .hw_value = ATH10K_HW_RATE_CCK_LP_11M,
55 .hw_value_short = ATH10K_HW_RATE_CCK_SP_11M,
56 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
Michal Kazior5653b392015-03-30 09:51:54 +030057
Michal Kazioraf001482015-03-30 09:51:56 +030058 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
59 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
60 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
61 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
62 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
63 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
64 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
65 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
Michal Kaziordcc33092015-03-30 09:51:54 +030066};
67
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +030068static struct ieee80211_rate ath10k_rates_rev2[] = {
69 { .bitrate = 10,
70 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_1M },
71 { .bitrate = 20,
72 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_2M,
73 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_2M,
74 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
75 { .bitrate = 55,
76 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
77 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
78 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
79 { .bitrate = 110,
80 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_11M,
81 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_11M,
82 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
83
84 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
85 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
86 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
87 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
88 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
89 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
90 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
91 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
92};
93
Michal Kazior8d7aa6b2015-03-30 09:51:57 +030094#define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
95
96#define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
97#define ath10k_a_rates_size (ARRAY_SIZE(ath10k_rates) - \
98 ATH10K_MAC_FIRST_OFDM_RATE_IDX)
Michal Kaziordcc33092015-03-30 09:51:54 +030099#define ath10k_g_rates (ath10k_rates + 0)
100#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
101
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +0300102#define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
103#define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
104
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +0300105#define ath10k_wmi_legacy_rates ath10k_rates
106
Michal Kazior486017c2015-03-30 09:51:54 +0300107static bool ath10k_mac_bitrate_is_cck(int bitrate)
108{
109 switch (bitrate) {
110 case 10:
111 case 20:
112 case 55:
113 case 110:
114 return true;
115 }
116
117 return false;
118}
119
120static u8 ath10k_mac_bitrate_to_rate(int bitrate)
121{
122 return DIV_ROUND_UP(bitrate, 5) |
123 (ath10k_mac_bitrate_is_cck(bitrate) ? BIT(7) : 0);
124}
125
Michal Kazior5528e032015-03-30 09:51:56 +0300126u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
Yanbo Li4b7f3532015-11-12 10:36:10 -0800127 u8 hw_rate, bool cck)
Michal Kazior5528e032015-03-30 09:51:56 +0300128{
129 const struct ieee80211_rate *rate;
130 int i;
131
132 for (i = 0; i < sband->n_bitrates; i++) {
133 rate = &sband->bitrates[i];
134
Yanbo Li4b7f3532015-11-12 10:36:10 -0800135 if (ath10k_mac_bitrate_is_cck(rate->bitrate) != cck)
136 continue;
137
Michal Kazior5528e032015-03-30 09:51:56 +0300138 if (rate->hw_value == hw_rate)
139 return i;
140 else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
141 rate->hw_value_short == hw_rate)
142 return i;
143 }
144
145 return 0;
146}
147
Michal Kazior01cebe12015-03-30 09:51:56 +0300148u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
149 u32 bitrate)
150{
151 int i;
152
153 for (i = 0; i < sband->n_bitrates; i++)
154 if (sband->bitrates[i].bitrate == bitrate)
155 return i;
156
157 return 0;
158}
159
Sriram Rf279294e2018-09-10 11:09:40 +0530160static int ath10k_mac_get_rate_hw_value(int bitrate)
161{
162 int i;
163 u8 hw_value_prefix = 0;
164
165 if (ath10k_mac_bitrate_is_cck(bitrate))
166 hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;
167
Sriram R34e141e2018-10-03 08:43:50 +0530168 for (i = 0; i < ARRAY_SIZE(ath10k_rates); i++) {
Sriram Rf279294e2018-09-10 11:09:40 +0530169 if (ath10k_rates[i].bitrate == bitrate)
170 return hw_value_prefix | ath10k_rates[i].hw_value;
171 }
172
173 return -EINVAL;
174}
175
Michal Kazior3ae54222015-03-31 10:49:20 +0000176static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
177{
178 switch ((mcs_map >> (2 * nss)) & 0x3) {
179 case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;
180 case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;
181 case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;
182 }
183 return 0;
184}
185
Michal Kazior45c9abc2015-04-21 20:42:58 +0300186static u32
187ath10k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
188{
189 int nss;
190
191 for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--)
192 if (ht_mcs_mask[nss])
193 return nss + 1;
194
195 return 1;
196}
197
198static u32
199ath10k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
200{
201 int nss;
202
203 for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--)
204 if (vht_mcs_mask[nss])
205 return nss + 1;
206
207 return 1;
208}
Kalle Valo5e3dd152013-06-12 20:52:10 +0300209
Raja Mani7e247a92016-04-12 20:15:53 +0530210int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val)
211{
212 enum wmi_host_platform_type platform_type;
213 int ret;
214
215 if (test_bit(WMI_SERVICE_TX_MODE_DYNAMIC, ar->wmi.svc_map))
216 platform_type = WMI_HOST_PLATFORM_LOW_PERF;
217 else
218 platform_type = WMI_HOST_PLATFORM_HIGH_PERF;
219
220 ret = ath10k_wmi_ext_resource_config(ar, platform_type, val);
221
222 if (ret && ret != -EOPNOTSUPP) {
223 ath10k_warn(ar, "failed to configure ext resource: %d\n", ret);
224 return ret;
225 }
226
227 return 0;
228}
229
Kalle Valo5e3dd152013-06-12 20:52:10 +0300230/**********/
231/* Crypto */
232/**********/
233
234static int ath10k_send_key(struct ath10k_vif *arvif,
235 struct ieee80211_key_conf *key,
236 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100237 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300238{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200239 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300240 struct wmi_vdev_install_key_arg arg = {
241 .vdev_id = arvif->vdev_id,
242 .key_idx = key->keyidx,
243 .key_len = key->keylen,
244 .key_data = key->key,
Michal Kazior370e5672015-02-18 14:02:26 +0100245 .key_flags = flags,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300246 .macaddr = macaddr,
247 };
248
Michal Kazior548db542013-07-05 16:15:15 +0300249 lockdep_assert_held(&arvif->ar->conf_mutex);
250
Kalle Valo5e3dd152013-06-12 20:52:10 +0300251 switch (key->cipher) {
252 case WLAN_CIPHER_SUITE_CCMP:
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200253 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM];
Marek Kwaczynskie4e82e92015-01-24 12:14:53 +0200254 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300255 break;
256 case WLAN_CIPHER_SUITE_TKIP:
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200257 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_TKIP];
Kalle Valo5e3dd152013-06-12 20:52:10 +0300258 arg.key_txmic_len = 8;
259 arg.key_rxmic_len = 8;
260 break;
261 case WLAN_CIPHER_SUITE_WEP40:
262 case WLAN_CIPHER_SUITE_WEP104:
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200263 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_WEP];
Kalle Valo5e3dd152013-06-12 20:52:10 +0300264 break;
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -0700265 case WLAN_CIPHER_SUITE_CCMP_256:
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200266 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM];
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -0700267 break;
268 case WLAN_CIPHER_SUITE_GCMP:
269 case WLAN_CIPHER_SUITE_GCMP_256:
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200270 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_GCM];
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -0700271 break;
272 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
273 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
274 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
Johannes Berg3cb10942015-01-22 21:38:45 +0100275 case WLAN_CIPHER_SUITE_AES_CMAC:
Bartosz Markowskid7131c02015-03-10 14:32:19 +0100276 WARN_ON(1);
277 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300278 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200279 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300280 return -EOPNOTSUPP;
281 }
282
Kalle Valob9e284e2015-10-05 17:56:35 +0300283 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
David Liuccec9032015-07-24 20:25:32 +0300284 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
David Liuccec9032015-07-24 20:25:32 +0300285
Kalle Valo5e3dd152013-06-12 20:52:10 +0300286 if (cmd == DISABLE_KEY) {
Abhishek Ambure7d94f862019-02-08 14:55:26 +0200287 arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_NONE];
Kalle Valo5e3dd152013-06-12 20:52:10 +0300288 arg.key_data = NULL;
289 }
290
291 return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
292}
293
294static int ath10k_install_key(struct ath10k_vif *arvif,
295 struct ieee80211_key_conf *key,
296 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100297 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300298{
299 struct ath10k *ar = arvif->ar;
300 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300301 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300302
Michal Kazior548db542013-07-05 16:15:15 +0300303 lockdep_assert_held(&ar->conf_mutex);
304
Wolfram Sang16735d02013-11-14 14:32:02 -0800305 reinit_completion(&ar->install_key_done);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300306
David Liuccec9032015-07-24 20:25:32 +0300307 if (arvif->nohwcrypt)
308 return 1;
309
Michal Kazior370e5672015-02-18 14:02:26 +0100310 ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300311 if (ret)
312 return ret;
313
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300314 time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);
315 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300316 return -ETIMEDOUT;
317
318 return 0;
319}
320
321static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
322 const u8 *addr)
323{
324 struct ath10k *ar = arvif->ar;
325 struct ath10k_peer *peer;
326 int ret;
327 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100328 u32 flags;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300329
330 lockdep_assert_held(&ar->conf_mutex);
331
Michal Kazior8674d902015-08-13 14:10:46 +0200332 if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP &&
Peter Oh7c97b722015-12-03 09:50:55 -0800333 arvif->vif->type != NL80211_IFTYPE_ADHOC &&
334 arvif->vif->type != NL80211_IFTYPE_MESH_POINT))
Michal Kazior8674d902015-08-13 14:10:46 +0200335 return -EINVAL;
336
Kalle Valo5e3dd152013-06-12 20:52:10 +0300337 spin_lock_bh(&ar->data_lock);
338 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
339 spin_unlock_bh(&ar->data_lock);
340
341 if (!peer)
342 return -ENOENT;
343
344 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
345 if (arvif->wep_keys[i] == NULL)
346 continue;
Michal Kazior370e5672015-02-18 14:02:26 +0100347
Michal Kazior8674d902015-08-13 14:10:46 +0200348 switch (arvif->vif->type) {
349 case NL80211_IFTYPE_AP:
350 flags = WMI_KEY_PAIRWISE;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300351
Michal Kazior8674d902015-08-13 14:10:46 +0200352 if (arvif->def_wep_key_idx == i)
353 flags |= WMI_KEY_TX_USAGE;
Michal Kaziorce90b272015-04-10 13:23:21 +0000354
Michal Kazior8674d902015-08-13 14:10:46 +0200355 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
356 SET_KEY, addr, flags);
357 if (ret < 0)
358 return ret;
359 break;
360 case NL80211_IFTYPE_ADHOC:
361 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
362 SET_KEY, addr,
363 WMI_KEY_PAIRWISE);
364 if (ret < 0)
365 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300366
Michal Kazior8674d902015-08-13 14:10:46 +0200367 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
368 SET_KEY, addr, WMI_KEY_GROUP);
369 if (ret < 0)
370 return ret;
371 break;
372 default:
373 WARN_ON(1);
374 return -EINVAL;
375 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300376
Sujith Manoharanae167132014-11-25 11:46:59 +0530377 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300378 peer->keys[i] = arvif->wep_keys[i];
Sujith Manoharanae167132014-11-25 11:46:59 +0530379 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300380 }
381
Michal Kaziorce90b272015-04-10 13:23:21 +0000382 /* In some cases (notably with static WEP IBSS with multiple keys)
383 * multicast Tx becomes broken. Both pairwise and groupwise keys are
384 * installed already. Using WMI_KEY_TX_USAGE in different combinations
385 * didn't seem help. Using def_keyid vdev parameter seems to be
386 * effective so use that.
387 *
388 * FIXME: Revisit. Perhaps this can be done in a less hacky way.
389 */
Michal Kazior8674d902015-08-13 14:10:46 +0200390 if (arvif->vif->type != NL80211_IFTYPE_ADHOC)
391 return 0;
392
Michal Kaziorce90b272015-04-10 13:23:21 +0000393 if (arvif->def_wep_key_idx == -1)
394 return 0;
395
396 ret = ath10k_wmi_vdev_set_param(arvif->ar,
397 arvif->vdev_id,
398 arvif->ar->wmi.vdev_param->def_keyid,
399 arvif->def_wep_key_idx);
400 if (ret) {
401 ath10k_warn(ar, "failed to re-set def wpa key idxon vdev %i: %d\n",
402 arvif->vdev_id, ret);
403 return ret;
404 }
405
Kalle Valo5e3dd152013-06-12 20:52:10 +0300406 return 0;
407}
408
409static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
410 const u8 *addr)
411{
412 struct ath10k *ar = arvif->ar;
413 struct ath10k_peer *peer;
414 int first_errno = 0;
415 int ret;
416 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100417 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300418
419 lockdep_assert_held(&ar->conf_mutex);
420
421 spin_lock_bh(&ar->data_lock);
422 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
423 spin_unlock_bh(&ar->data_lock);
424
425 if (!peer)
426 return -ENOENT;
427
428 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
429 if (peer->keys[i] == NULL)
430 continue;
431
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200432 /* key flags are not required to delete the key */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300433 ret = ath10k_install_key(arvif, peer->keys[i],
Michal Kazior370e5672015-02-18 14:02:26 +0100434 DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300435 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300436 first_errno = ret;
437
David Liuccec9032015-07-24 20:25:32 +0300438 if (ret < 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200439 ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300440 i, ret);
441
Sujith Manoharanae167132014-11-25 11:46:59 +0530442 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300443 peer->keys[i] = NULL;
Sujith Manoharanae167132014-11-25 11:46:59 +0530444 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300445 }
446
447 return first_errno;
448}
449
Sujith Manoharan504f6cd2014-11-25 11:46:58 +0530450bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
451 u8 keyidx)
452{
453 struct ath10k_peer *peer;
454 int i;
455
456 lockdep_assert_held(&ar->data_lock);
457
458 /* We don't know which vdev this peer belongs to,
459 * since WMI doesn't give us that information.
460 *
461 * FIXME: multi-bss needs to be handled.
462 */
463 peer = ath10k_peer_find(ar, 0, addr);
464 if (!peer)
465 return false;
466
467 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
468 if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)
469 return true;
470 }
471
472 return false;
473}
474
Kalle Valo5e3dd152013-06-12 20:52:10 +0300475static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
476 struct ieee80211_key_conf *key)
477{
478 struct ath10k *ar = arvif->ar;
479 struct ath10k_peer *peer;
480 u8 addr[ETH_ALEN];
481 int first_errno = 0;
482 int ret;
483 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100484 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300485
486 lockdep_assert_held(&ar->conf_mutex);
487
488 for (;;) {
489 /* since ath10k_install_key we can't hold data_lock all the
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +0100490 * time, so we try to remove the keys incrementally
491 */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300492 spin_lock_bh(&ar->data_lock);
493 i = 0;
494 list_for_each_entry(peer, &ar->peers, list) {
495 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
496 if (peer->keys[i] == key) {
Kalle Valob25f32c2014-09-14 12:50:49 +0300497 ether_addr_copy(addr, peer->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300498 peer->keys[i] = NULL;
499 break;
500 }
501 }
502
503 if (i < ARRAY_SIZE(peer->keys))
504 break;
505 }
506 spin_unlock_bh(&ar->data_lock);
507
508 if (i == ARRAY_SIZE(peer->keys))
509 break;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200510 /* key flags are not required to delete the key */
Michal Kazior370e5672015-02-18 14:02:26 +0100511 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300512 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300513 first_errno = ret;
514
515 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200516 ath10k_warn(ar, "failed to remove key for %pM: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +0200517 addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300518 }
519
520 return first_errno;
521}
522
Michal Kaziorad325cb2015-02-18 14:02:27 +0100523static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
524 struct ieee80211_key_conf *key)
525{
526 struct ath10k *ar = arvif->ar;
527 struct ath10k_peer *peer;
528 int ret;
529
530 lockdep_assert_held(&ar->conf_mutex);
531
532 list_for_each_entry(peer, &ar->peers, list) {
Kalle Valoc178da52016-04-13 14:13:49 +0300533 if (ether_addr_equal(peer->addr, arvif->vif->addr))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100534 continue;
535
Kalle Valoc178da52016-04-13 14:13:49 +0300536 if (ether_addr_equal(peer->addr, arvif->bssid))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100537 continue;
538
539 if (peer->keys[key->keyidx] == key)
540 continue;
541
542 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
543 arvif->vdev_id, key->keyidx);
544
545 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
546 if (ret) {
547 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
548 arvif->vdev_id, peer->addr, ret);
549 return ret;
550 }
551 }
552
553 return 0;
554}
555
Kalle Valo5e3dd152013-06-12 20:52:10 +0300556/*********************/
557/* General utilities */
558/*********************/
559
560static inline enum wmi_phy_mode
561chan_to_phymode(const struct cfg80211_chan_def *chandef)
562{
563 enum wmi_phy_mode phymode = MODE_UNKNOWN;
564
565 switch (chandef->chan->band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +0200566 case NL80211_BAND_2GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300567 switch (chandef->width) {
568 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800569 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
570 phymode = MODE_11B;
571 else
572 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300573 break;
574 case NL80211_CHAN_WIDTH_20:
575 phymode = MODE_11NG_HT20;
576 break;
577 case NL80211_CHAN_WIDTH_40:
578 phymode = MODE_11NG_HT40;
579 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400580 case NL80211_CHAN_WIDTH_5:
581 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300582 case NL80211_CHAN_WIDTH_80:
583 case NL80211_CHAN_WIDTH_80P80:
584 case NL80211_CHAN_WIDTH_160:
585 phymode = MODE_UNKNOWN;
586 break;
587 }
588 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +0200589 case NL80211_BAND_5GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300590 switch (chandef->width) {
591 case NL80211_CHAN_WIDTH_20_NOHT:
592 phymode = MODE_11A;
593 break;
594 case NL80211_CHAN_WIDTH_20:
595 phymode = MODE_11NA_HT20;
596 break;
597 case NL80211_CHAN_WIDTH_40:
598 phymode = MODE_11NA_HT40;
599 break;
600 case NL80211_CHAN_WIDTH_80:
601 phymode = MODE_11AC_VHT80;
602 break;
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +0200603 case NL80211_CHAN_WIDTH_160:
604 phymode = MODE_11AC_VHT160;
605 break;
606 case NL80211_CHAN_WIDTH_80P80:
607 phymode = MODE_11AC_VHT80_80;
608 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400609 case NL80211_CHAN_WIDTH_5:
610 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300611 phymode = MODE_UNKNOWN;
612 break;
613 }
614 break;
615 default:
616 break;
617 }
618
619 WARN_ON(phymode == MODE_UNKNOWN);
620 return phymode;
621}
622
623static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
624{
625/*
626 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
627 * 0 for no restriction
628 * 1 for 1/4 us
629 * 2 for 1/2 us
630 * 3 for 1 us
631 * 4 for 2 us
632 * 5 for 4 us
633 * 6 for 8 us
634 * 7 for 16 us
635 */
636 switch (mpdudensity) {
637 case 0:
638 return 0;
639 case 1:
640 case 2:
641 case 3:
642 /* Our lower layer calculations limit our precision to
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +0100643 * 1 microsecond
644 */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300645 return 1;
646 case 4:
647 return 2;
648 case 5:
649 return 4;
650 case 6:
651 return 8;
652 case 7:
653 return 16;
654 default:
655 return 0;
656 }
657}
658
Michal Kazior500ff9f2015-03-31 10:26:21 +0000659int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
660 struct cfg80211_chan_def *def)
661{
662 struct ieee80211_chanctx_conf *conf;
663
664 rcu_read_lock();
665 conf = rcu_dereference(vif->chanctx_conf);
666 if (!conf) {
667 rcu_read_unlock();
668 return -ENOENT;
669 }
670
671 *def = conf->def;
672 rcu_read_unlock();
673
674 return 0;
675}
676
677static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,
678 struct ieee80211_chanctx_conf *conf,
679 void *data)
680{
681 int *num = data;
682
683 (*num)++;
684}
685
686static int ath10k_mac_num_chanctxs(struct ath10k *ar)
687{
688 int num = 0;
689
690 ieee80211_iter_chan_contexts_atomic(ar->hw,
691 ath10k_mac_num_chanctxs_iter,
692 &num);
693
694 return num;
695}
696
697static void
698ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
699 struct ieee80211_chanctx_conf *conf,
700 void *data)
701{
702 struct cfg80211_chan_def **def = data;
703
704 *def = &conf->def;
705}
706
Michal Kazior69427262016-03-06 16:14:30 +0200707static int ath10k_peer_create(struct ath10k *ar,
708 struct ieee80211_vif *vif,
709 struct ieee80211_sta *sta,
710 u32 vdev_id,
711 const u8 *addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300712 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300713{
Michal Kaziore04cafb2015-08-05 12:15:24 +0200714 struct ath10k_vif *arvif;
Michal Kazior69427262016-03-06 16:14:30 +0200715 struct ath10k_peer *peer;
Michal Kaziore04cafb2015-08-05 12:15:24 +0200716 int num_peers = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300717 int ret;
718
719 lockdep_assert_held(&ar->conf_mutex);
720
Michal Kaziore04cafb2015-08-05 12:15:24 +0200721 num_peers = ar->num_peers;
722
723 /* Each vdev consumes a peer entry as well */
724 list_for_each_entry(arvif, &ar->arvifs, list)
725 num_peers++;
726
727 if (num_peers >= ar->max_num_peers)
Michal Kaziorcfd10612014-11-25 15:16:05 +0100728 return -ENOBUFS;
729
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300730 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800731 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200732 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200733 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300734 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800735 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300736
737 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800738 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200739 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200740 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300741 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800742 }
Michal Kazior292a7532014-11-25 15:16:04 +0100743
Michal Kazior69427262016-03-06 16:14:30 +0200744 spin_lock_bh(&ar->data_lock);
745
746 peer = ath10k_peer_find(ar, vdev_id, addr);
747 if (!peer) {
Ben Greearfee48cf2016-04-01 14:12:12 -0700748 spin_unlock_bh(&ar->data_lock);
Michal Kazior69427262016-03-06 16:14:30 +0200749 ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n",
750 addr, vdev_id);
751 ath10k_wmi_peer_delete(ar, vdev_id, addr);
Michal Kazior69427262016-03-06 16:14:30 +0200752 return -ENOENT;
753 }
754
755 peer->vif = vif;
756 peer->sta = sta;
757
758 spin_unlock_bh(&ar->data_lock);
759
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100760 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300761
762 return 0;
763}
764
Kalle Valo5a13e762014-01-20 11:01:46 +0200765static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
766{
767 struct ath10k *ar = arvif->ar;
768 u32 param;
769 int ret;
770
771 param = ar->wmi.pdev_param->sta_kickout_th;
772 ret = ath10k_wmi_pdev_set_param(ar, param,
773 ATH10K_KICKOUT_THRESHOLD);
774 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200775 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200776 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200777 return ret;
778 }
779
780 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
781 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
782 ATH10K_KEEPALIVE_MIN_IDLE);
783 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200784 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200785 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200786 return ret;
787 }
788
789 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
790 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
791 ATH10K_KEEPALIVE_MAX_IDLE);
792 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200793 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200794 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200795 return ret;
796 }
797
798 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
799 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
800 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
801 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200802 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200803 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200804 return ret;
805 }
806
807 return 0;
808}
809
Vivek Natarajanacab6402014-11-26 09:06:12 +0200810static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200811{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200812 struct ath10k *ar = arvif->ar;
813 u32 vdev_param;
814
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200815 vdev_param = ar->wmi.vdev_param->rts_threshold;
816 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200817}
818
Kalle Valo5e3dd152013-06-12 20:52:10 +0300819static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
820{
821 int ret;
822
823 lockdep_assert_held(&ar->conf_mutex);
824
825 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
826 if (ret)
827 return ret;
828
829 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
830 if (ret)
831 return ret;
832
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100833 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100834
Kalle Valo5e3dd152013-06-12 20:52:10 +0300835 return 0;
836}
837
838static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
839{
840 struct ath10k_peer *peer, *tmp;
Michal Kazior69427262016-03-06 16:14:30 +0200841 int peer_id;
Ben Greear6d68f792016-06-30 15:23:53 +0300842 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300843
844 lockdep_assert_held(&ar->conf_mutex);
845
846 spin_lock_bh(&ar->data_lock);
847 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
848 if (peer->vdev_id != vdev_id)
849 continue;
850
Michal Kazior7aa7a722014-08-25 12:09:38 +0200851 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300852 peer->addr, vdev_id);
853
Michal Kazior69427262016-03-06 16:14:30 +0200854 for_each_set_bit(peer_id, peer->peer_ids,
855 ATH10K_MAX_NUM_PEER_IDS) {
856 ar->peer_map[peer_id] = NULL;
857 }
858
Ben Greear6d68f792016-06-30 15:23:53 +0300859 /* Double check that peer is properly un-referenced from
860 * the peer_map
861 */
862 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
863 if (ar->peer_map[i] == peer) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +0530864 ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
Ben Greear6d68f792016-06-30 15:23:53 +0300865 peer->addr, peer, i);
866 ar->peer_map[i] = NULL;
867 }
868 }
869
Kalle Valo5e3dd152013-06-12 20:52:10 +0300870 list_del(&peer->list);
871 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100872 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300873 }
874 spin_unlock_bh(&ar->data_lock);
875}
876
Michal Kaziora96d7742013-07-16 09:38:56 +0200877static void ath10k_peer_cleanup_all(struct ath10k *ar)
878{
879 struct ath10k_peer *peer, *tmp;
Ben Greear6d68f792016-06-30 15:23:53 +0300880 int i;
Michal Kaziora96d7742013-07-16 09:38:56 +0200881
882 lockdep_assert_held(&ar->conf_mutex);
883
884 spin_lock_bh(&ar->data_lock);
885 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
886 list_del(&peer->list);
887 kfree(peer);
888 }
Ben Greear6d68f792016-06-30 15:23:53 +0300889
890 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
891 ar->peer_map[i] = NULL;
892
Michal Kaziora96d7742013-07-16 09:38:56 +0200893 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100894
895 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100896 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200897}
898
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300899static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
900 struct ieee80211_sta *sta,
901 enum wmi_tdls_peer_state state)
902{
903 int ret;
904 struct wmi_tdls_peer_update_cmd_arg arg = {};
905 struct wmi_tdls_peer_capab_arg cap = {};
906 struct wmi_channel_arg chan_arg = {};
907
908 lockdep_assert_held(&ar->conf_mutex);
909
910 arg.vdev_id = vdev_id;
911 arg.peer_state = state;
912 ether_addr_copy(arg.addr, sta->addr);
913
914 cap.peer_max_sp = sta->max_sp;
915 cap.peer_uapsd_queues = sta->uapsd_queues;
916
917 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
918 !sta->tdls_initiator)
919 cap.is_peer_responder = 1;
920
921 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
922 if (ret) {
923 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
924 arg.addr, vdev_id, ret);
925 return ret;
926 }
927
928 return 0;
929}
930
Kalle Valo5e3dd152013-06-12 20:52:10 +0300931/************************/
932/* Interface management */
933/************************/
934
Michal Kazior64badcb2014-09-18 11:18:02 +0300935void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
936{
937 struct ath10k *ar = arvif->ar;
938
939 lockdep_assert_held(&ar->data_lock);
940
941 if (!arvif->beacon)
942 return;
943
944 if (!arvif->beacon_buf)
945 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
946 arvif->beacon->len, DMA_TO_DEVICE);
947
Michal Kazioraf213192015-01-29 14:29:52 +0200948 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
949 arvif->beacon_state != ATH10K_BEACON_SENT))
950 return;
951
Michal Kazior64badcb2014-09-18 11:18:02 +0300952 dev_kfree_skb_any(arvif->beacon);
953
954 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200955 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300956}
957
958static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
959{
960 struct ath10k *ar = arvif->ar;
961
962 lockdep_assert_held(&ar->data_lock);
963
964 ath10k_mac_vif_beacon_free(arvif);
965
966 if (arvif->beacon_buf) {
967 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
968 arvif->beacon_buf, arvif->beacon_paddr);
969 arvif->beacon_buf = NULL;
970 }
971}
972
Kalle Valo5e3dd152013-06-12 20:52:10 +0300973static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
974{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300975 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300976
Michal Kazior548db542013-07-05 16:15:15 +0300977 lockdep_assert_held(&ar->conf_mutex);
978
Michal Kazior7962b0d2014-10-28 10:34:38 +0100979 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
980 return -ESHUTDOWN;
981
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300982 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
983 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
984 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300985 return -ETIMEDOUT;
986
Ben Greear833fd342018-09-06 19:46:20 +0300987 return ar->last_wmi_vdev_start_status;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300988}
989
Michal Kazior1bbc0972014-04-08 09:45:47 +0300990static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300991{
Michal Kazior500ff9f2015-03-31 10:26:21 +0000992 struct cfg80211_chan_def *chandef = NULL;
Maninder Singh19be9e92015-07-16 09:25:33 +0530993 struct ieee80211_channel *channel = NULL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300994 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300995 int ret = 0;
996
997 lockdep_assert_held(&ar->conf_mutex);
998
Michal Kazior500ff9f2015-03-31 10:26:21 +0000999 ieee80211_iter_chan_contexts_atomic(ar->hw,
1000 ath10k_mac_get_any_chandef_iter,
1001 &chandef);
1002 if (WARN_ON_ONCE(!chandef))
1003 return -ENOENT;
1004
1005 channel = chandef->chan;
1006
Kalle Valo5e3dd152013-06-12 20:52:10 +03001007 arg.vdev_id = vdev_id;
1008 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +01001009 arg.channel.band_center_freq1 = chandef->center_freq1;
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02001010 arg.channel.band_center_freq2 = chandef->center_freq2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001011
1012 /* TODO setup this dynamically, what in case we
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01001013 * don't have any vifs?
1014 */
Michal Kaziorc930f742014-01-23 11:38:25 +01001015 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001016 arg.channel.chan_radar =
1017 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001018
Michal Kazior89c5c842013-10-23 04:02:13 -07001019 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07001020 arg.channel.max_power = channel->max_power * 2;
1021 arg.channel.max_reg_power = channel->max_reg_power * 2;
1022 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001023
Michal Kazior7962b0d2014-10-28 10:34:38 +01001024 reinit_completion(&ar->vdev_setup_done);
1025
Kalle Valo5e3dd152013-06-12 20:52:10 +03001026 ret = ath10k_wmi_vdev_start(ar, &arg);
1027 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001028 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001029 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001030 return ret;
1031 }
1032
1033 ret = ath10k_vdev_setup_sync(ar);
1034 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001035 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001036 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001037 return ret;
1038 }
1039
1040 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
1041 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001042 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001043 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001044 goto vdev_stop;
1045 }
1046
1047 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001048
Michal Kazior7aa7a722014-08-25 12:09:38 +02001049 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001050 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001051 return 0;
1052
1053vdev_stop:
1054 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1055 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001056 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001057 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001058
1059 return ret;
1060}
1061
Michal Kazior1bbc0972014-04-08 09:45:47 +03001062static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001063{
1064 int ret = 0;
1065
1066 lockdep_assert_held(&ar->conf_mutex);
1067
Marek Puzyniak52fa0192013-09-24 14:06:24 +02001068 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
1069 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001070 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001071 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001072
Michal Kazior7962b0d2014-10-28 10:34:38 +01001073 reinit_completion(&ar->vdev_setup_done);
1074
Kalle Valo5e3dd152013-06-12 20:52:10 +03001075 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1076 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001077 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001078 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001079
1080 ret = ath10k_vdev_setup_sync(ar);
1081 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +02001082 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001083 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001084
Michal Kazior7aa7a722014-08-25 12:09:38 +02001085 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001086 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001087 return ret;
1088}
1089
Michal Kazior1bbc0972014-04-08 09:45:47 +03001090static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001091{
1092 int bit, ret = 0;
1093
1094 lockdep_assert_held(&ar->conf_mutex);
1095
Ben Greeara9aefb32014-08-12 11:02:19 +03001096 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001097 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03001098 return -ENOMEM;
1099 }
1100
Ben Greear16c11172014-09-23 14:17:16 -07001101 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +03001102
Ben Greear16c11172014-09-23 14:17:16 -07001103 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001104
1105 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
1106 WMI_VDEV_TYPE_MONITOR,
1107 0, ar->mac_addr);
1108 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001109 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001110 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +03001111 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001112 }
1113
Ben Greear16c11172014-09-23 14:17:16 -07001114 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +02001115 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001116 ar->monitor_vdev_id);
1117
Kalle Valo5e3dd152013-06-12 20:52:10 +03001118 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001119}
1120
Michal Kazior1bbc0972014-04-08 09:45:47 +03001121static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001122{
1123 int ret = 0;
1124
1125 lockdep_assert_held(&ar->conf_mutex);
1126
Kalle Valo5e3dd152013-06-12 20:52:10 +03001127 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
1128 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001129 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001130 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001131 return ret;
1132 }
1133
Ben Greear16c11172014-09-23 14:17:16 -07001134 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001135
Michal Kazior7aa7a722014-08-25 12:09:38 +02001136 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001137 ar->monitor_vdev_id);
1138 return ret;
1139}
1140
Michal Kazior1bbc0972014-04-08 09:45:47 +03001141static int ath10k_monitor_start(struct ath10k *ar)
1142{
1143 int ret;
1144
1145 lockdep_assert_held(&ar->conf_mutex);
1146
Michal Kazior1bbc0972014-04-08 09:45:47 +03001147 ret = ath10k_monitor_vdev_create(ar);
1148 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001149 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001150 return ret;
1151 }
1152
1153 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
1154 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001155 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001156 ath10k_monitor_vdev_delete(ar);
1157 return ret;
1158 }
1159
1160 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001161 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +03001162
1163 return 0;
1164}
1165
Michal Kazior19337472014-08-28 12:58:16 +02001166static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +03001167{
1168 int ret;
1169
1170 lockdep_assert_held(&ar->conf_mutex);
1171
Michal Kazior1bbc0972014-04-08 09:45:47 +03001172 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001173 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001174 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001175 return ret;
1176 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001177
1178 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001179 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001180 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001181 return ret;
1182 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001183
1184 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001185 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +02001186
1187 return 0;
1188}
1189
Michal Kazior500ff9f2015-03-31 10:26:21 +00001190static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1191{
1192 int num_ctx;
1193
1194 /* At least one chanctx is required to derive a channel to start
1195 * monitor vdev on.
1196 */
1197 num_ctx = ath10k_mac_num_chanctxs(ar);
1198 if (num_ctx == 0)
1199 return false;
1200
1201 /* If there's already an existing special monitor interface then don't
1202 * bother creating another monitor vdev.
1203 */
1204 if (ar->monitor_arvif)
1205 return false;
1206
1207 return ar->monitor ||
Manoharan, Rajkumar705d7aa2016-11-23 16:58:11 +02001208 (!test_bit(ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST,
1209 ar->running_fw->fw_file.fw_features) &&
1210 (ar->filter_flags & FIF_OTHER_BSS)) ||
Michal Kazior500ff9f2015-03-31 10:26:21 +00001211 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1212}
1213
1214static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1215{
1216 int num_ctx;
1217
1218 num_ctx = ath10k_mac_num_chanctxs(ar);
1219
1220 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1221 * shouldn't allow this but make sure to prevent handling the following
1222 * case anyway since multi-channel DFS hasn't been tested at all.
1223 */
1224 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1225 return false;
1226
1227 return true;
1228}
1229
Michal Kazior19337472014-08-28 12:58:16 +02001230static int ath10k_monitor_recalc(struct ath10k *ar)
1231{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001232 bool needed;
1233 bool allowed;
1234 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001235
1236 lockdep_assert_held(&ar->conf_mutex);
1237
Michal Kazior500ff9f2015-03-31 10:26:21 +00001238 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1239 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001240
1241 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001242 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1243 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001244
Michal Kazior500ff9f2015-03-31 10:26:21 +00001245 if (WARN_ON(needed && !allowed)) {
1246 if (ar->monitor_started) {
1247 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1248
1249 ret = ath10k_monitor_stop(ar);
1250 if (ret)
Kalle Valo2a995082015-10-05 17:56:37 +03001251 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",
1252 ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001253 /* not serious */
1254 }
1255
1256 return -EPERM;
1257 }
1258
1259 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001260 return 0;
1261
Michal Kazior500ff9f2015-03-31 10:26:21 +00001262 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001263 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001264 else
1265 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001266}
1267
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02001268static bool ath10k_mac_can_set_cts_prot(struct ath10k_vif *arvif)
1269{
1270 struct ath10k *ar = arvif->ar;
1271
1272 lockdep_assert_held(&ar->conf_mutex);
1273
1274 if (!arvif->is_started) {
1275 ath10k_dbg(ar, ATH10K_DBG_MAC, "defer cts setup, vdev is not ready yet\n");
1276 return false;
1277 }
1278
1279 return true;
1280}
1281
1282static int ath10k_mac_set_cts_prot(struct ath10k_vif *arvif)
1283{
1284 struct ath10k *ar = arvif->ar;
1285 u32 vdev_param;
1286
1287 lockdep_assert_held(&ar->conf_mutex);
1288
1289 vdev_param = ar->wmi.vdev_param->protection_mode;
1290
1291 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_protection %d\n",
1292 arvif->vdev_id, arvif->use_cts_prot);
1293
1294 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1295 arvif->use_cts_prot ? 1 : 0);
1296}
1297
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001298static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1299{
1300 struct ath10k *ar = arvif->ar;
1301 u32 vdev_param, rts_cts = 0;
1302
1303 lockdep_assert_held(&ar->conf_mutex);
1304
1305 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1306
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001307 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001308
1309 if (arvif->num_legacy_stations > 0)
1310 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1311 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001312 else
1313 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1314 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001315
Bartosz Markowski86176902016-12-15 11:23:24 +02001316 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d recalc rts/cts prot %d\n",
1317 arvif->vdev_id, rts_cts);
1318
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001319 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1320 rts_cts);
1321}
1322
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001323static int ath10k_start_cac(struct ath10k *ar)
1324{
1325 int ret;
1326
1327 lockdep_assert_held(&ar->conf_mutex);
1328
1329 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1330
Michal Kazior19337472014-08-28 12:58:16 +02001331 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001332 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001333 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001334 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1335 return ret;
1336 }
1337
Michal Kazior7aa7a722014-08-25 12:09:38 +02001338 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001339 ar->monitor_vdev_id);
1340
1341 return 0;
1342}
1343
1344static int ath10k_stop_cac(struct ath10k *ar)
1345{
1346 lockdep_assert_held(&ar->conf_mutex);
1347
1348 /* CAC is not running - do nothing */
1349 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1350 return 0;
1351
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001352 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001353 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001354
Michal Kazior7aa7a722014-08-25 12:09:38 +02001355 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001356
1357 return 0;
1358}
1359
Michal Kazior500ff9f2015-03-31 10:26:21 +00001360static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1361 struct ieee80211_chanctx_conf *conf,
1362 void *data)
1363{
1364 bool *ret = data;
1365
1366 if (!*ret && conf->radar_enabled)
1367 *ret = true;
1368}
1369
1370static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1371{
1372 bool has_radar = false;
1373
1374 ieee80211_iter_chan_contexts_atomic(ar->hw,
1375 ath10k_mac_has_radar_iter,
1376 &has_radar);
1377
1378 return has_radar;
1379}
1380
Michal Kaziord6500972014-04-08 09:56:09 +03001381static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001382{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001383 int ret;
1384
1385 lockdep_assert_held(&ar->conf_mutex);
1386
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001387 ath10k_stop_cac(ar);
1388
Michal Kazior500ff9f2015-03-31 10:26:21 +00001389 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001390 return;
1391
Michal Kaziord6500972014-04-08 09:56:09 +03001392 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001393 return;
1394
1395 ret = ath10k_start_cac(ar);
1396 if (ret) {
1397 /*
1398 * Not possible to start CAC on current channel so starting
1399 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1400 * by indicating that radar was detected.
1401 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001402 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001403 ieee80211_radar_detected(ar->hw);
1404 }
1405}
1406
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301407static int ath10k_vdev_stop(struct ath10k_vif *arvif)
Michal Kazior72654fa2014-04-08 09:56:09 +03001408{
1409 struct ath10k *ar = arvif->ar;
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301410 int ret;
1411
1412 lockdep_assert_held(&ar->conf_mutex);
1413
1414 reinit_completion(&ar->vdev_setup_done);
1415
1416 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1417 if (ret) {
1418 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1419 arvif->vdev_id, ret);
1420 return ret;
1421 }
1422
1423 ret = ath10k_vdev_setup_sync(ar);
1424 if (ret) {
Colin Ian King23de5792017-06-25 22:29:32 +01001425 ath10k_warn(ar, "failed to synchronize setup for vdev %i: %d\n",
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301426 arvif->vdev_id, ret);
1427 return ret;
1428 }
1429
1430 WARN_ON(ar->num_started_vdevs == 0);
1431
1432 if (ar->num_started_vdevs != 0) {
1433 ar->num_started_vdevs--;
1434 ath10k_recalc_radar_detection(ar);
1435 }
1436
1437 return ret;
1438}
1439
Michal Kazior500ff9f2015-03-31 10:26:21 +00001440static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1441 const struct cfg80211_chan_def *chandef,
1442 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001443{
1444 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001445 struct wmi_vdev_start_request_arg arg = {};
1446 int ret = 0;
1447
1448 lockdep_assert_held(&ar->conf_mutex);
1449
1450 reinit_completion(&ar->vdev_setup_done);
1451
1452 arg.vdev_id = arvif->vdev_id;
1453 arg.dtim_period = arvif->dtim_period;
1454 arg.bcn_intval = arvif->beacon_interval;
1455
1456 arg.channel.freq = chandef->chan->center_freq;
1457 arg.channel.band_center_freq1 = chandef->center_freq1;
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02001458 arg.channel.band_center_freq2 = chandef->center_freq2;
Michal Kazior72654fa2014-04-08 09:56:09 +03001459 arg.channel.mode = chan_to_phymode(chandef);
1460
1461 arg.channel.min_power = 0;
1462 arg.channel.max_power = chandef->chan->max_power * 2;
1463 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1464 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1465
1466 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1467 arg.ssid = arvif->u.ap.ssid;
1468 arg.ssid_len = arvif->u.ap.ssid_len;
1469 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1470
1471 /* For now allow DFS for AP mode */
1472 arg.channel.chan_radar =
1473 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1474 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1475 arg.ssid = arvif->vif->bss_conf.ssid;
1476 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1477 }
1478
Michal Kazior7aa7a722014-08-25 12:09:38 +02001479 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001480 "mac vdev %d start center_freq %d phymode %s\n",
1481 arg.vdev_id, arg.channel.freq,
1482 ath10k_wmi_phymode_str(arg.channel.mode));
1483
Michal Kaziordc55e302014-07-29 12:53:36 +03001484 if (restart)
1485 ret = ath10k_wmi_vdev_restart(ar, &arg);
1486 else
1487 ret = ath10k_wmi_vdev_start(ar, &arg);
1488
Michal Kazior72654fa2014-04-08 09:56:09 +03001489 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001490 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001491 arg.vdev_id, ret);
1492 return ret;
1493 }
1494
1495 ret = ath10k_vdev_setup_sync(ar);
1496 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001497 ath10k_warn(ar,
1498 "failed to synchronize setup for vdev %i restart %d: %d\n",
1499 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001500 return ret;
1501 }
1502
Michal Kaziord6500972014-04-08 09:56:09 +03001503 ar->num_started_vdevs++;
1504 ath10k_recalc_radar_detection(ar);
1505
Michal Kazior72654fa2014-04-08 09:56:09 +03001506 return ret;
1507}
1508
Michal Kazior500ff9f2015-03-31 10:26:21 +00001509static int ath10k_vdev_start(struct ath10k_vif *arvif,
1510 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001511{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001512 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001513}
1514
Michal Kazior500ff9f2015-03-31 10:26:21 +00001515static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1516 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001517{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001518 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kazior72654fa2014-04-08 09:56:09 +03001519}
1520
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001521static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1522 struct sk_buff *bcn)
1523{
1524 struct ath10k *ar = arvif->ar;
1525 struct ieee80211_mgmt *mgmt;
1526 const u8 *p2p_ie;
1527 int ret;
1528
Peter Oh08c27be2016-01-28 13:54:09 -08001529 if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001530 return 0;
1531
1532 mgmt = (void *)bcn->data;
1533 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1534 mgmt->u.beacon.variable,
1535 bcn->len - (mgmt->u.beacon.variable -
1536 bcn->data));
1537 if (!p2p_ie)
1538 return -ENOENT;
1539
1540 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1541 if (ret) {
1542 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1543 arvif->vdev_id, ret);
1544 return ret;
1545 }
1546
1547 return 0;
1548}
1549
1550static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1551 u8 oui_type, size_t ie_offset)
1552{
1553 size_t len;
1554 const u8 *next;
1555 const u8 *end;
1556 u8 *ie;
1557
1558 if (WARN_ON(skb->len < ie_offset))
1559 return -EINVAL;
1560
1561 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1562 skb->data + ie_offset,
1563 skb->len - ie_offset);
1564 if (!ie)
1565 return -ENOENT;
1566
1567 len = ie[1] + 2;
1568 end = skb->data + skb->len;
1569 next = ie + len;
1570
1571 if (WARN_ON(next > end))
1572 return -EINVAL;
1573
1574 memmove(ie, next, end - next);
1575 skb_trim(skb, skb->len - len);
1576
1577 return 0;
1578}
1579
1580static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1581{
1582 struct ath10k *ar = arvif->ar;
1583 struct ieee80211_hw *hw = ar->hw;
1584 struct ieee80211_vif *vif = arvif->vif;
1585 struct ieee80211_mutable_offsets offs = {};
1586 struct sk_buff *bcn;
1587 int ret;
1588
1589 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1590 return 0;
1591
Michal Kazior81a9a172015-03-05 16:02:17 +02001592 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1593 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1594 return 0;
1595
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001596 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1597 if (!bcn) {
1598 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1599 return -EPERM;
1600 }
1601
1602 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1603 if (ret) {
1604 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1605 kfree_skb(bcn);
1606 return ret;
1607 }
1608
1609 /* P2P IE is inserted by firmware automatically (as configured above)
1610 * so remove it from the base beacon template to avoid duplicate P2P
1611 * IEs in beacon frames.
1612 */
1613 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1614 offsetof(struct ieee80211_mgmt,
1615 u.beacon.variable));
1616
1617 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1618 0, NULL, 0);
1619 kfree_skb(bcn);
1620
1621 if (ret) {
1622 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1623 ret);
1624 return ret;
1625 }
1626
1627 return 0;
1628}
1629
1630static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1631{
1632 struct ath10k *ar = arvif->ar;
1633 struct ieee80211_hw *hw = ar->hw;
1634 struct ieee80211_vif *vif = arvif->vif;
1635 struct sk_buff *prb;
1636 int ret;
1637
1638 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1639 return 0;
1640
Michal Kazior81a9a172015-03-05 16:02:17 +02001641 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1642 return 0;
1643
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001644 prb = ieee80211_proberesp_get(hw, vif);
1645 if (!prb) {
1646 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1647 return -EPERM;
1648 }
1649
1650 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1651 kfree_skb(prb);
1652
1653 if (ret) {
1654 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1655 ret);
1656 return ret;
1657 }
1658
1659 return 0;
1660}
1661
Michal Kazior500ff9f2015-03-31 10:26:21 +00001662static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1663{
1664 struct ath10k *ar = arvif->ar;
1665 struct cfg80211_chan_def def;
1666 int ret;
1667
1668 /* When originally vdev is started during assign_vif_chanctx() some
1669 * information is missing, notably SSID. Firmware revisions with beacon
1670 * offloading require the SSID to be provided during vdev (re)start to
1671 * handle hidden SSID properly.
1672 *
1673 * Vdev restart must be done after vdev has been both started and
1674 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1675 * deliver vdev restart response event causing timeouts during vdev
1676 * syncing in ath10k.
1677 *
1678 * Note: The vdev down/up and template reinstallation could be skipped
1679 * since only wmi-tlv firmware are known to have beacon offload and
1680 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1681 * response delivery. It's probably more robust to keep it as is.
1682 */
1683 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1684 return 0;
1685
1686 if (WARN_ON(!arvif->is_started))
1687 return -EINVAL;
1688
1689 if (WARN_ON(!arvif->is_up))
1690 return -EINVAL;
1691
1692 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1693 return -EINVAL;
1694
1695 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1696 if (ret) {
1697 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1698 arvif->vdev_id, ret);
1699 return ret;
1700 }
1701
1702 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1703 * firmware will crash upon vdev up.
1704 */
1705
1706 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1707 if (ret) {
1708 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1709 return ret;
1710 }
1711
1712 ret = ath10k_mac_setup_prb_tmpl(arvif);
1713 if (ret) {
1714 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1715 return ret;
1716 }
1717
1718 ret = ath10k_vdev_restart(arvif, &def);
1719 if (ret) {
1720 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1721 arvif->vdev_id, ret);
1722 return ret;
1723 }
1724
1725 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1726 arvif->bssid);
1727 if (ret) {
1728 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1729 arvif->vdev_id, ret);
1730 return ret;
1731 }
1732
1733 return 0;
1734}
1735
Kalle Valo5e3dd152013-06-12 20:52:10 +03001736static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001737 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001738{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001739 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001740 int ret = 0;
1741
Michal Kazior548db542013-07-05 16:15:15 +03001742 lockdep_assert_held(&arvif->ar->conf_mutex);
1743
Kalle Valo5e3dd152013-06-12 20:52:10 +03001744 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001745 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1746 if (ret)
1747 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1748 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001749
Michal Kaziorc930f742014-01-23 11:38:25 +01001750 arvif->is_up = false;
1751
Michal Kazior748afc42014-01-23 12:48:21 +01001752 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001753 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001754 spin_unlock_bh(&arvif->ar->data_lock);
1755
Kalle Valo5e3dd152013-06-12 20:52:10 +03001756 return;
1757 }
1758
1759 arvif->tx_seq_no = 0x1000;
1760
Michal Kaziorc930f742014-01-23 11:38:25 +01001761 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001762 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001763
1764 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1765 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001766 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001767 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001768 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001769 return;
1770 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001771
Michal Kaziorc930f742014-01-23 11:38:25 +01001772 arvif->is_up = true;
1773
Michal Kazior500ff9f2015-03-31 10:26:21 +00001774 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1775 if (ret) {
1776 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1777 arvif->vdev_id, ret);
1778 return;
1779 }
1780
Michal Kazior7aa7a722014-08-25 12:09:38 +02001781 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001782}
1783
1784static void ath10k_control_ibss(struct ath10k_vif *arvif,
1785 struct ieee80211_bss_conf *info,
1786 const u8 self_peer[ETH_ALEN])
1787{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001788 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001789 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001790 int ret = 0;
1791
Michal Kazior548db542013-07-05 16:15:15 +03001792 lockdep_assert_held(&arvif->ar->conf_mutex);
1793
Kalle Valo5e3dd152013-06-12 20:52:10 +03001794 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001795 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001796 return;
1797
Joe Perches93803b32015-03-02 19:54:49 -08001798 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001799
1800 return;
1801 }
1802
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001803 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1804 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001805 ATH10K_DEFAULT_ATIM);
1806 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001807 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001808 arvif->vdev_id, ret);
1809}
1810
Michal Kazior9f9b5742014-12-12 12:41:36 +01001811static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1812{
1813 struct ath10k *ar = arvif->ar;
1814 u32 param;
1815 u32 value;
1816 int ret;
1817
1818 lockdep_assert_held(&arvif->ar->conf_mutex);
1819
1820 if (arvif->u.sta.uapsd)
1821 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1822 else
1823 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1824
1825 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1826 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1827 if (ret) {
1828 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1829 value, arvif->vdev_id, ret);
1830 return ret;
1831 }
1832
1833 return 0;
1834}
1835
1836static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1837{
1838 struct ath10k *ar = arvif->ar;
1839 u32 param;
1840 u32 value;
1841 int ret;
1842
1843 lockdep_assert_held(&arvif->ar->conf_mutex);
1844
1845 if (arvif->u.sta.uapsd)
1846 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1847 else
1848 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1849
1850 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1851 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1852 param, value);
1853 if (ret) {
1854 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1855 value, arvif->vdev_id, ret);
1856 return ret;
1857 }
1858
1859 return 0;
1860}
1861
Michal Kazior424f2632015-07-09 13:08:35 +02001862static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001863{
1864 struct ath10k_vif *arvif;
1865 int num = 0;
1866
1867 lockdep_assert_held(&ar->conf_mutex);
1868
1869 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001870 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001871 num++;
1872
1873 return num;
1874}
1875
Michal Kaziorad088bf2013-10-16 15:44:46 +03001876static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001877{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001878 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001879 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001880 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001881 enum wmi_sta_powersave_param param;
1882 enum wmi_sta_ps_mode psmode;
1883 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001884 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001885 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001886
Michal Kazior548db542013-07-05 16:15:15 +03001887 lockdep_assert_held(&arvif->ar->conf_mutex);
1888
Michal Kaziorad088bf2013-10-16 15:44:46 +03001889 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1890 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001891
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001892 enable_ps = arvif->ps;
1893
Michal Kazior424f2632015-07-09 13:08:35 +02001894 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001895 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
Kalle Valoc4cdf752016-04-20 19:45:18 +03001896 ar->running_fw->fw_file.fw_features)) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001897 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1898 arvif->vdev_id);
1899 enable_ps = false;
1900 }
1901
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001902 if (!arvif->is_started) {
1903 /* mac80211 can update vif powersave state while disconnected.
1904 * Firmware doesn't behave nicely and consumes more power than
1905 * necessary if PS is disabled on a non-started vdev. Hence
1906 * force-enable PS for non-running vdevs.
1907 */
1908 psmode = WMI_STA_PS_MODE_ENABLED;
1909 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001910 psmode = WMI_STA_PS_MODE_ENABLED;
1911 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1912
Michal Kazior526549a2014-12-12 12:41:37 +01001913 ps_timeout = conf->dynamic_ps_timeout;
1914 if (ps_timeout == 0) {
1915 /* Firmware doesn't like 0 */
1916 ps_timeout = ieee80211_tu_to_usec(
1917 vif->bss_conf.beacon_int) / 1000;
1918 }
1919
Michal Kaziorad088bf2013-10-16 15:44:46 +03001920 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001921 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001922 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001923 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001924 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001925 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001926 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001927 } else {
1928 psmode = WMI_STA_PS_MODE_DISABLED;
1929 }
1930
Michal Kazior7aa7a722014-08-25 12:09:38 +02001931 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001932 arvif->vdev_id, psmode ? "enable" : "disable");
1933
Michal Kaziorad088bf2013-10-16 15:44:46 +03001934 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1935 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001936 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001937 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001938 return ret;
1939 }
1940
1941 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001942}
1943
Michal Kazior46725b152015-01-28 09:57:49 +02001944static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1945{
1946 struct ath10k *ar = arvif->ar;
1947 struct wmi_sta_keepalive_arg arg = {};
1948 int ret;
1949
1950 lockdep_assert_held(&arvif->ar->conf_mutex);
1951
1952 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1953 return 0;
1954
1955 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1956 return 0;
1957
1958 /* Some firmware revisions have a bug and ignore the `enabled` field.
1959 * Instead use the interval to disable the keepalive.
1960 */
1961 arg.vdev_id = arvif->vdev_id;
1962 arg.enabled = 1;
1963 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1964 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1965
1966 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1967 if (ret) {
1968 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1969 arvif->vdev_id, ret);
1970 return ret;
1971 }
1972
1973 return 0;
1974}
1975
Michal Kazior81a9a172015-03-05 16:02:17 +02001976static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1977{
1978 struct ath10k *ar = arvif->ar;
1979 struct ieee80211_vif *vif = arvif->vif;
1980 int ret;
1981
Michal Kazior8513d952015-03-09 14:19:24 +01001982 lockdep_assert_held(&arvif->ar->conf_mutex);
1983
1984 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1985 return;
1986
Michal Kazior81a9a172015-03-05 16:02:17 +02001987 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1988 return;
1989
1990 if (!vif->csa_active)
1991 return;
1992
1993 if (!arvif->is_up)
1994 return;
1995
1996 if (!ieee80211_csa_is_complete(vif)) {
1997 ieee80211_csa_update_counter(vif);
1998
1999 ret = ath10k_mac_setup_bcn_tmpl(arvif);
2000 if (ret)
2001 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
2002 ret);
2003
2004 ret = ath10k_mac_setup_prb_tmpl(arvif);
2005 if (ret)
2006 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
2007 ret);
2008 } else {
2009 ieee80211_csa_finish(vif);
2010 }
2011}
2012
2013static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
2014{
2015 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
2016 ap_csa_work);
2017 struct ath10k *ar = arvif->ar;
2018
2019 mutex_lock(&ar->conf_mutex);
2020 ath10k_mac_vif_ap_csa_count_down(arvif);
2021 mutex_unlock(&ar->conf_mutex);
2022}
2023
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002024static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
2025 struct ieee80211_vif *vif)
2026{
2027 struct sk_buff *skb = data;
2028 struct ieee80211_mgmt *mgmt = (void *)skb->data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002029 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002030
2031 if (vif->type != NL80211_IFTYPE_STATION)
2032 return;
2033
2034 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
2035 return;
2036
2037 cancel_delayed_work(&arvif->connection_loss_work);
2038}
2039
2040void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
2041{
2042 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2043 IEEE80211_IFACE_ITER_NORMAL,
2044 ath10k_mac_handle_beacon_iter,
2045 skb);
2046}
2047
2048static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
2049 struct ieee80211_vif *vif)
2050{
2051 u32 *vdev_id = data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002052 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002053 struct ath10k *ar = arvif->ar;
2054 struct ieee80211_hw *hw = ar->hw;
2055
2056 if (arvif->vdev_id != *vdev_id)
2057 return;
2058
2059 if (!arvif->is_up)
2060 return;
2061
2062 ieee80211_beacon_loss(vif);
2063
2064 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
2065 * (done by mac80211) succeeds but beacons do not resume then it
2066 * doesn't make sense to continue operation. Queue connection loss work
2067 * which can be cancelled when beacon is received.
2068 */
2069 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
2070 ATH10K_CONNECTION_LOSS_HZ);
2071}
2072
2073void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
2074{
2075 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2076 IEEE80211_IFACE_ITER_NORMAL,
2077 ath10k_mac_handle_beacon_miss_iter,
2078 &vdev_id);
2079}
2080
2081static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
2082{
2083 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
2084 connection_loss_work.work);
2085 struct ieee80211_vif *vif = arvif->vif;
2086
2087 if (!arvif->is_up)
2088 return;
2089
2090 ieee80211_connection_loss(vif);
2091}
2092
Kalle Valo5e3dd152013-06-12 20:52:10 +03002093/**********************/
2094/* Station management */
2095/**********************/
2096
Michal Kazior590922a2014-10-21 10:10:29 +03002097static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
2098 struct ieee80211_vif *vif)
2099{
2100 /* Some firmware revisions have unstable STA powersave when listen
2101 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
2102 * generate NullFunc frames properly even if buffered frames have been
2103 * indicated in Beacon TIM. Firmware would seldom wake up to pull
2104 * buffered frames. Often pinging the device from AP would simply fail.
2105 *
2106 * As a workaround set it to 1.
2107 */
2108 if (vif->type == NL80211_IFTYPE_STATION)
2109 return 1;
2110
2111 return ar->hw->conf.listen_interval;
2112}
2113
Kalle Valo5e3dd152013-06-12 20:52:10 +03002114static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002115 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002116 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002117 struct wmi_peer_assoc_complete_arg *arg)
2118{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002119 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002120 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03002121
Michal Kazior548db542013-07-05 16:15:15 +03002122 lockdep_assert_held(&ar->conf_mutex);
2123
Michal Kaziorc51880e2015-03-30 09:51:57 +03002124 if (vif->type == NL80211_IFTYPE_STATION)
2125 aid = vif->bss_conf.aid;
2126 else
2127 aid = sta->aid;
2128
Kalle Valob25f32c2014-09-14 12:50:49 +03002129 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002130 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002131 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002132 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03002133 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002134 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03002135 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002136}
2137
2138static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002139 struct ieee80211_vif *vif,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002140 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002141 struct wmi_peer_assoc_complete_arg *arg)
2142{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002143 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002144 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002145 struct cfg80211_bss *bss;
2146 const u8 *rsnie = NULL;
2147 const u8 *wpaie = NULL;
2148
Michal Kazior548db542013-07-05 16:15:15 +03002149 lockdep_assert_held(&ar->conf_mutex);
2150
Michal Kazior500ff9f2015-03-31 10:26:21 +00002151 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2152 return;
2153
2154 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
2155 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002156 if (bss) {
2157 const struct cfg80211_bss_ies *ies;
2158
2159 rcu_read_lock();
2160 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
2161
2162 ies = rcu_dereference(bss->ies);
2163
2164 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03002165 WLAN_OUI_TYPE_MICROSOFT_WPA,
2166 ies->data,
2167 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002168 rcu_read_unlock();
2169 cfg80211_put_bss(ar->hw->wiphy, bss);
2170 }
2171
2172 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2173 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002174 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002175 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002176 }
2177
2178 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002179 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002180 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002181 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002182
2183 if (sta->mfp &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03002184 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT,
2185 ar->running_fw->fw_file.fw_features)) {
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002186 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002187 }
2188}
2189
2190static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002191 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002192 struct ieee80211_sta *sta,
2193 struct wmi_peer_assoc_complete_arg *arg)
2194{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002195 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002196 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002197 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002198 const struct ieee80211_supported_band *sband;
2199 const struct ieee80211_rate *rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002200 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002201 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002202 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002203 int i;
2204
Michal Kazior548db542013-07-05 16:15:15 +03002205 lockdep_assert_held(&ar->conf_mutex);
2206
Michal Kazior500ff9f2015-03-31 10:26:21 +00002207 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2208 return;
2209
Michal Kazior45c9abc2015-04-21 20:42:58 +03002210 band = def.chan->band;
2211 sband = ar->hw->wiphy->bands[band];
2212 ratemask = sta->supp_rates[band];
2213 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002214 rates = sband->bitrates;
2215
2216 rateset->num_rates = 0;
2217
2218 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2219 if (!(ratemask & 1))
2220 continue;
2221
Michal Kazior486017c2015-03-30 09:51:54 +03002222 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2223 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002224 rateset->num_rates++;
2225 }
2226}
2227
Michal Kazior45c9abc2015-04-21 20:42:58 +03002228static bool
2229ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2230{
2231 int nss;
2232
2233 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2234 if (ht_mcs_mask[nss])
2235 return false;
2236
2237 return true;
2238}
2239
2240static bool
2241ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2242{
2243 int nss;
2244
2245 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2246 if (vht_mcs_mask[nss])
2247 return false;
2248
2249 return true;
2250}
2251
Kalle Valo5e3dd152013-06-12 20:52:10 +03002252static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002253 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002254 struct ieee80211_sta *sta,
2255 struct wmi_peer_assoc_complete_arg *arg)
2256{
2257 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002258 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002259 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002260 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002261 const u8 *ht_mcs_mask;
2262 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002263 int i, n;
2264 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002265 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002266
Michal Kazior548db542013-07-05 16:15:15 +03002267 lockdep_assert_held(&ar->conf_mutex);
2268
Michal Kazior45c9abc2015-04-21 20:42:58 +03002269 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2270 return;
2271
Kalle Valo5e3dd152013-06-12 20:52:10 +03002272 if (!ht_cap->ht_supported)
2273 return;
2274
Michal Kazior45c9abc2015-04-21 20:42:58 +03002275 band = def.chan->band;
2276 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2277 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2278
2279 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2280 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2281 return;
2282
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002283 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002284 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2285 ht_cap->ampdu_factor)) - 1;
2286
2287 arg->peer_mpdu_density =
2288 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2289
2290 arg->peer_ht_caps = ht_cap->cap;
2291 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2292
2293 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002294 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002295
2296 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002297 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002298 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2299 }
2300
Michal Kazior45c9abc2015-04-21 20:42:58 +03002301 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2302 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2303 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002304
Michal Kazior45c9abc2015-04-21 20:42:58 +03002305 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2306 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2307 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002308
2309 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2310 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002311 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002312 }
2313
2314 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002315 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2316 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2317 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2318 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002319 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002320 }
2321
Kalle Valo5e3dd152013-06-12 20:52:10 +03002322 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2323 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2324 else if (ht_cap->mcs.rx_mask[1])
2325 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2326
Michal Kazior45c9abc2015-04-21 20:42:58 +03002327 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2328 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2329 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2330 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002331 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002332 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002333
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002334 /*
2335 * This is a workaround for HT-enabled STAs which break the spec
2336 * and have no HT capabilities RX mask (no HT RX MCS map).
2337 *
2338 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2339 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2340 *
2341 * Firmware asserts if such situation occurs.
2342 */
2343 if (n == 0) {
2344 arg->peer_ht_rates.num_rates = 8;
2345 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2346 arg->peer_ht_rates.rates[i] = i;
2347 } else {
2348 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002349 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002350 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002351
Michal Kazior7aa7a722014-08-25 12:09:38 +02002352 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002353 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002354 arg->peer_ht_rates.num_rates,
2355 arg->peer_num_spatial_streams);
2356}
2357
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002358static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2359 struct ath10k_vif *arvif,
2360 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002361{
2362 u32 uapsd = 0;
2363 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002364 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002365
Michal Kazior548db542013-07-05 16:15:15 +03002366 lockdep_assert_held(&ar->conf_mutex);
2367
Kalle Valo5e3dd152013-06-12 20:52:10 +03002368 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002369 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002370 sta->uapsd_queues, sta->max_sp);
2371
Kalle Valo5e3dd152013-06-12 20:52:10 +03002372 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2373 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2374 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2375 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2376 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2377 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2378 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2379 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2380 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2381 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2382 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2383 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2384
Kalle Valo5e3dd152013-06-12 20:52:10 +03002385 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2386 max_sp = sta->max_sp;
2387
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002388 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2389 sta->addr,
2390 WMI_AP_PS_PEER_PARAM_UAPSD,
2391 uapsd);
2392 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002393 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002394 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002395 return ret;
2396 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002397
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002398 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2399 sta->addr,
2400 WMI_AP_PS_PEER_PARAM_MAX_SP,
2401 max_sp);
2402 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002403 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002404 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002405 return ret;
2406 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002407
2408 /* TODO setup this based on STA listen interval and
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01002409 * beacon interval. Currently we don't know
2410 * sta->listen_interval - mac80211 patch required.
2411 * Currently use 10 seconds
2412 */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002413 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002414 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2415 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002416 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002417 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002418 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002419 return ret;
2420 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002421 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002422
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002423 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002424}
2425
Michal Kazior45c9abc2015-04-21 20:42:58 +03002426static u16
2427ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2428 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2429{
2430 int idx_limit;
2431 int nss;
2432 u16 mcs_map;
2433 u16 mcs;
2434
2435 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2436 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2437 vht_mcs_limit[nss];
2438
2439 if (mcs_map)
2440 idx_limit = fls(mcs_map) - 1;
2441 else
2442 idx_limit = -1;
2443
2444 switch (idx_limit) {
2445 case 0: /* fall through */
2446 case 1: /* fall through */
2447 case 2: /* fall through */
2448 case 3: /* fall through */
2449 case 4: /* fall through */
2450 case 5: /* fall through */
2451 case 6: /* fall through */
2452 default:
2453 /* see ath10k_mac_can_set_bitrate_mask() */
2454 WARN_ON(1);
2455 /* fall through */
2456 case -1:
2457 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2458 break;
2459 case 7:
2460 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2461 break;
2462 case 8:
2463 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2464 break;
2465 case 9:
2466 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2467 break;
2468 }
2469
2470 tx_mcs_set &= ~(0x3 << (nss * 2));
2471 tx_mcs_set |= mcs << (nss * 2);
2472 }
2473
2474 return tx_mcs_set;
2475}
2476
Kalle Valo5e3dd152013-06-12 20:52:10 +03002477static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002478 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002479 struct ieee80211_sta *sta,
2480 struct wmi_peer_assoc_complete_arg *arg)
2481{
2482 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002483 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002484 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002485 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002486 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002487 u8 ampdu_factor;
Venkateswara Rao Naralasettyfefcd112017-03-24 13:27:28 +05302488 u8 max_nss, vht_mcs;
2489 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002490
Michal Kazior500ff9f2015-03-31 10:26:21 +00002491 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2492 return;
2493
Kalle Valo5e3dd152013-06-12 20:52:10 +03002494 if (!vht_cap->vht_supported)
2495 return;
2496
Michal Kazior45c9abc2015-04-21 20:42:58 +03002497 band = def.chan->band;
2498 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2499
2500 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2501 return;
2502
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002503 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002504
Johannes Berg57fbcce2016-04-12 15:56:15 +02002505 if (def.chan->band == NL80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002506 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002507
Kalle Valo5e3dd152013-06-12 20:52:10 +03002508 arg->peer_vht_caps = vht_cap->cap;
2509
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002510 ampdu_factor = (vht_cap->cap &
2511 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2512 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2513
2514 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2515 * zero in VHT IE. Using it would result in degraded throughput.
2516 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01002517 * it if VHT max_mpdu is smaller.
2518 */
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002519 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2520 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2521 ampdu_factor)) - 1);
2522
Kalle Valo5e3dd152013-06-12 20:52:10 +03002523 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002524 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002525
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02002526 if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
2527 arg->peer_flags |= ar->wmi.peer_flags->bw160;
2528
Venkateswara Rao Naralasettyfefcd112017-03-24 13:27:28 +05302529 /* Calculate peer NSS capability from VHT capabilities if STA
2530 * supports VHT.
2531 */
2532 for (i = 0, max_nss = 0, vht_mcs = 0; i < NL80211_VHT_NSS_MAX; i++) {
2533 vht_mcs = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) >>
2534 (2 * i) & 3;
2535
2536 if ((vht_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED) &&
2537 vht_mcs_mask[i])
2538 max_nss = i + 1;
2539 }
2540 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002541 arg->peer_vht_rates.rx_max_rate =
2542 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2543 arg->peer_vht_rates.rx_mcs_set =
2544 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2545 arg->peer_vht_rates.tx_max_rate =
2546 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002547 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2548 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002549
Michal Kazior7aa7a722014-08-25 12:09:38 +02002550 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002551 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Ben Greearcc914a52017-06-16 10:37:45 +03002552
2553 if (arg->peer_vht_rates.rx_max_rate &&
2554 (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) {
2555 switch (arg->peer_vht_rates.rx_max_rate) {
2556 case 1560:
2557 /* Must be 2x2 at 160Mhz is all it can do. */
2558 arg->peer_bw_rxnss_override = 2;
2559 break;
2560 case 780:
2561 /* Can only do 1x1 at 160Mhz (Long Guard Interval) */
2562 arg->peer_bw_rxnss_override = 1;
2563 break;
2564 }
2565 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002566}
2567
2568static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002569 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002570 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002571 struct wmi_peer_assoc_complete_arg *arg)
2572{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002573 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior590922a2014-10-21 10:10:29 +03002574
Kalle Valo5e3dd152013-06-12 20:52:10 +03002575 switch (arvif->vdev_type) {
2576 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002577 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002578 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002579
2580 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002581 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002582 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2583 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002584 break;
2585 case WMI_VDEV_TYPE_STA:
Balaji Pothunoori07ffb442017-12-07 16:58:04 +02002586 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002587 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002588 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002589 case WMI_VDEV_TYPE_IBSS:
2590 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002591 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002592 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002593 default:
2594 break;
2595 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002596
2597 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002598 sta->addr, !!(arg->peer_flags &
2599 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002600}
2601
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002602static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002603{
Johannes Berg57fbcce2016-04-12 15:56:15 +02002604 return sta->supp_rates[NL80211_BAND_2GHZ] >>
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002605 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002606}
2607
Kalle Valo06efdbe2017-01-12 13:02:11 +02002608static enum wmi_phy_mode ath10k_mac_get_phymode_vht(struct ath10k *ar,
2609 struct ieee80211_sta *sta)
2610{
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02002611 if (sta->bandwidth == IEEE80211_STA_RX_BW_160) {
2612 switch (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
2613 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
2614 return MODE_11AC_VHT160;
2615 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
2616 return MODE_11AC_VHT80_80;
2617 default:
2618 /* not sure if this is a valid case? */
2619 return MODE_11AC_VHT160;
2620 }
2621 }
2622
Kalle Valo06efdbe2017-01-12 13:02:11 +02002623 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2624 return MODE_11AC_VHT80;
2625
2626 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2627 return MODE_11AC_VHT40;
2628
2629 if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2630 return MODE_11AC_VHT20;
2631
2632 return MODE_UNKNOWN;
2633}
2634
Kalle Valo5e3dd152013-06-12 20:52:10 +03002635static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002636 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002637 struct ieee80211_sta *sta,
2638 struct wmi_peer_assoc_complete_arg *arg)
2639{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002640 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002641 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002642 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002643 const u8 *ht_mcs_mask;
2644 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002645 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2646
Michal Kazior500ff9f2015-03-31 10:26:21 +00002647 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2648 return;
2649
Michal Kazior45c9abc2015-04-21 20:42:58 +03002650 band = def.chan->band;
2651 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2652 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2653
2654 switch (band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02002655 case NL80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002656 if (sta->vht_cap.vht_supported &&
2657 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002658 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2659 phymode = MODE_11AC_VHT40;
2660 else
2661 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002662 } else if (sta->ht_cap.ht_supported &&
2663 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002664 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2665 phymode = MODE_11NG_HT40;
2666 else
2667 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002668 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002669 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002670 } else {
2671 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002672 }
2673
2674 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002675 case NL80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002676 /*
2677 * Check VHT first.
2678 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002679 if (sta->vht_cap.vht_supported &&
2680 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Kalle Valo06efdbe2017-01-12 13:02:11 +02002681 phymode = ath10k_mac_get_phymode_vht(ar, sta);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002682 } else if (sta->ht_cap.ht_supported &&
2683 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2684 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002685 phymode = MODE_11NA_HT40;
2686 else
2687 phymode = MODE_11NA_HT20;
2688 } else {
2689 phymode = MODE_11A;
2690 }
2691
2692 break;
2693 default:
2694 break;
2695 }
2696
Michal Kazior7aa7a722014-08-25 12:09:38 +02002697 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002698 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002699
Kalle Valo5e3dd152013-06-12 20:52:10 +03002700 arg->peer_phymode = phymode;
2701 WARN_ON(phymode == MODE_UNKNOWN);
2702}
2703
Kalle Valob9ada652013-10-16 15:44:46 +03002704static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002705 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002706 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002707 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002708{
Michal Kazior548db542013-07-05 16:15:15 +03002709 lockdep_assert_held(&ar->conf_mutex);
2710
Kalle Valob9ada652013-10-16 15:44:46 +03002711 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002712
Michal Kazior590922a2014-10-21 10:10:29 +03002713 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002714 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002715 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002716 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002717 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002718 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2719 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002720
Kalle Valob9ada652013-10-16 15:44:46 +03002721 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002722}
2723
Michal Kazior90046f52014-02-14 14:45:51 +01002724static const u32 ath10k_smps_map[] = {
2725 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2726 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2727 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2728 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2729};
2730
2731static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2732 const u8 *addr,
2733 const struct ieee80211_sta_ht_cap *ht_cap)
2734{
2735 int smps;
2736
2737 if (!ht_cap->ht_supported)
2738 return 0;
2739
2740 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2741 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2742
2743 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2744 return -EINVAL;
2745
2746 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2747 WMI_PEER_SMPS_STATE,
2748 ath10k_smps_map[smps]);
2749}
2750
Michal Kazior139e1702015-02-15 16:50:42 +02002751static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2752 struct ieee80211_vif *vif,
2753 struct ieee80211_sta_vht_cap vht_cap)
2754{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002755 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior139e1702015-02-15 16:50:42 +02002756 int ret;
2757 u32 param;
2758 u32 value;
2759
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302760 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2761 return 0;
2762
Michal Kazior139e1702015-02-15 16:50:42 +02002763 if (!(ar->vht_cap_info &
2764 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2765 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2766 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2767 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2768 return 0;
2769
2770 param = ar->wmi.vdev_param->txbf;
2771 value = 0;
2772
2773 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2774 return 0;
2775
2776 /* The following logic is correct. If a remote STA advertises support
2777 * for being a beamformer then we should enable us being a beamformee.
2778 */
2779
2780 if (ar->vht_cap_info &
2781 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2782 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2783 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2784 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2785
2786 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2787 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2788 }
2789
2790 if (ar->vht_cap_info &
2791 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2792 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2793 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2794 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2795
2796 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2797 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2798 }
2799
2800 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2801 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2802
2803 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2804 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2805
2806 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2807 if (ret) {
2808 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2809 value, ret);
2810 return ret;
2811 }
2812
2813 return 0;
2814}
2815
Kalle Valo5e3dd152013-06-12 20:52:10 +03002816/* can be called only in mac80211 callbacks due to `key_count` usage */
2817static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2818 struct ieee80211_vif *vif,
2819 struct ieee80211_bss_conf *bss_conf)
2820{
2821 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002822 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior90046f52014-02-14 14:45:51 +01002823 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002824 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002825 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002826 struct ieee80211_sta *ap_sta;
2827 int ret;
2828
Michal Kazior548db542013-07-05 16:15:15 +03002829 lockdep_assert_held(&ar->conf_mutex);
2830
Michal Kazior077efc82014-10-21 10:10:29 +03002831 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2832 arvif->vdev_id, arvif->bssid, arvif->aid);
2833
Kalle Valo5e3dd152013-06-12 20:52:10 +03002834 rcu_read_lock();
2835
2836 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2837 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002838 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002839 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002840 rcu_read_unlock();
2841 return;
2842 }
2843
Michal Kazior90046f52014-02-14 14:45:51 +01002844 /* ap_sta must be accessed only within rcu section which must be left
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01002845 * before calling ath10k_setup_peer_smps() which might sleep.
2846 */
Michal Kazior90046f52014-02-14 14:45:51 +01002847 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002848 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002849
Michal Kazior590922a2014-10-21 10:10:29 +03002850 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002851 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002852 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002853 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002854 rcu_read_unlock();
2855 return;
2856 }
2857
2858 rcu_read_unlock();
2859
Kalle Valob9ada652013-10-16 15:44:46 +03002860 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2861 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002862 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002863 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002864 return;
2865 }
2866
Michal Kazior90046f52014-02-14 14:45:51 +01002867 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2868 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002869 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002870 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002871 return;
2872 }
2873
Michal Kazior139e1702015-02-15 16:50:42 +02002874 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2875 if (ret) {
2876 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2877 arvif->vdev_id, bss_conf->bssid, ret);
2878 return;
2879 }
2880
Michal Kazior7aa7a722014-08-25 12:09:38 +02002881 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002882 "mac vdev %d up (associated) bssid %pM aid %d\n",
2883 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2884
Michal Kazior077efc82014-10-21 10:10:29 +03002885 WARN_ON(arvif->is_up);
2886
Michal Kaziorc930f742014-01-23 11:38:25 +01002887 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002888 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002889
2890 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2891 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002892 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002893 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002894 return;
2895 }
2896
2897 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002898
2899 /* Workaround: Some firmware revisions (tested with qca6174
2900 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2901 * poked with peer param command.
2902 */
2903 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2904 WMI_PEER_DUMMY_VAR, 1);
2905 if (ret) {
2906 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2907 arvif->bssid, arvif->vdev_id, ret);
2908 return;
2909 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002910}
2911
Kalle Valo5e3dd152013-06-12 20:52:10 +03002912static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2913 struct ieee80211_vif *vif)
2914{
2915 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002916 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior139e1702015-02-15 16:50:42 +02002917 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002918 int ret;
2919
Michal Kazior548db542013-07-05 16:15:15 +03002920 lockdep_assert_held(&ar->conf_mutex);
2921
Michal Kazior077efc82014-10-21 10:10:29 +03002922 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2923 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002924
Kalle Valo5e3dd152013-06-12 20:52:10 +03002925 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002926 if (ret)
Ben Greearaa66ba02016-09-26 21:56:25 +03002927 ath10k_warn(ar, "failed to down vdev %i: %d\n",
Michal Kazior077efc82014-10-21 10:10:29 +03002928 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002929
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002930 arvif->def_wep_key_idx = -1;
2931
Michal Kazior139e1702015-02-15 16:50:42 +02002932 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2933 if (ret) {
2934 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2935 arvif->vdev_id, ret);
2936 return;
2937 }
2938
Michal Kaziorc930f742014-01-23 11:38:25 +01002939 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002940
2941 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002942}
2943
Michal Kazior590922a2014-10-21 10:10:29 +03002944static int ath10k_station_assoc(struct ath10k *ar,
2945 struct ieee80211_vif *vif,
2946 struct ieee80211_sta *sta,
2947 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002948{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002949 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valob9ada652013-10-16 15:44:46 +03002950 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002951 int ret = 0;
2952
Michal Kazior548db542013-07-05 16:15:15 +03002953 lockdep_assert_held(&ar->conf_mutex);
2954
Michal Kazior590922a2014-10-21 10:10:29 +03002955 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002956 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002957 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002958 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002959 return ret;
2960 }
2961
2962 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2963 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002964 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002965 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002966 return ret;
2967 }
2968
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002969 /* Re-assoc is run only to update supported rates for given station. It
2970 * doesn't make much sense to reconfigure the peer completely.
2971 */
2972 if (!reassoc) {
2973 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2974 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002975 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002976 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002977 arvif->vdev_id, ret);
2978 return ret;
2979 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002980
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002981 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2982 if (ret) {
2983 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2984 sta->addr, arvif->vdev_id, ret);
2985 return ret;
2986 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002987
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002988 if (!sta->wme) {
2989 arvif->num_legacy_stations++;
2990 ret = ath10k_recalc_rtscts_prot(arvif);
2991 if (ret) {
2992 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2993 arvif->vdev_id, ret);
2994 return ret;
2995 }
2996 }
2997
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002998 /* Plumb cached keys only for static WEP */
Yingying Tangc3816c92018-03-28 12:15:23 +03002999 if ((arvif->def_wep_key_idx != -1) && (!sta->tdls)) {
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02003000 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
3001 if (ret) {
3002 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
3003 arvif->vdev_id, ret);
3004 return ret;
3005 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003006 }
3007 }
3008
Kalle Valo5e3dd152013-06-12 20:52:10 +03003009 return ret;
3010}
3011
Michal Kazior590922a2014-10-21 10:10:29 +03003012static int ath10k_station_disassoc(struct ath10k *ar,
3013 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003014 struct ieee80211_sta *sta)
3015{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003016 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003017 int ret = 0;
3018
3019 lockdep_assert_held(&ar->conf_mutex);
3020
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02003021 if (!sta->wme) {
3022 arvif->num_legacy_stations--;
3023 ret = ath10k_recalc_rtscts_prot(arvif);
3024 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003025 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02003026 arvif->vdev_id, ret);
3027 return ret;
3028 }
3029 }
3030
Kalle Valo5e3dd152013-06-12 20:52:10 +03003031 ret = ath10k_clear_peer_keys(arvif, sta->addr);
3032 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003033 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003034 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003035 return ret;
3036 }
3037
3038 return ret;
3039}
3040
3041/**************/
3042/* Regulatory */
3043/**************/
3044
3045static int ath10k_update_channel_list(struct ath10k *ar)
3046{
3047 struct ieee80211_hw *hw = ar->hw;
3048 struct ieee80211_supported_band **bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02003049 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003050 struct ieee80211_channel *channel;
3051 struct wmi_scan_chan_list_arg arg = {0};
3052 struct wmi_channel_arg *ch;
3053 bool passive;
3054 int len;
3055 int ret;
3056 int i;
3057
Michal Kazior548db542013-07-05 16:15:15 +03003058 lockdep_assert_held(&ar->conf_mutex);
3059
Kalle Valo5e3dd152013-06-12 20:52:10 +03003060 bands = hw->wiphy->bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02003061 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003062 if (!bands[band])
3063 continue;
3064
3065 for (i = 0; i < bands[band]->n_channels; i++) {
3066 if (bands[band]->channels[i].flags &
3067 IEEE80211_CHAN_DISABLED)
3068 continue;
3069
3070 arg.n_channels++;
3071 }
3072 }
3073
3074 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
3075 arg.channels = kzalloc(len, GFP_KERNEL);
3076 if (!arg.channels)
3077 return -ENOMEM;
3078
3079 ch = arg.channels;
Johannes Berg57fbcce2016-04-12 15:56:15 +02003080 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003081 if (!bands[band])
3082 continue;
3083
3084 for (i = 0; i < bands[band]->n_channels; i++) {
3085 channel = &bands[band]->channels[i];
3086
3087 if (channel->flags & IEEE80211_CHAN_DISABLED)
3088 continue;
3089
Eduardo Abinader98029772016-06-30 15:23:55 +03003090 ch->allow_ht = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003091
3092 /* FIXME: when should we really allow VHT? */
3093 ch->allow_vht = true;
3094
3095 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02003096 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003097
3098 ch->ht40plus =
3099 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
3100
Marek Puzyniake8a50f82013-11-20 09:59:47 +02003101 ch->chan_radar =
3102 !!(channel->flags & IEEE80211_CHAN_RADAR);
3103
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02003104 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003105 ch->passive = passive;
3106
Sven Eckelmann3f259112018-07-26 15:59:48 +02003107 /* the firmware is ignoring the "radar" flag of the
3108 * channel and is scanning actively using Probe Requests
3109 * on "Radar detection"/DFS channels which are not
3110 * marked as "available"
3111 */
3112 ch->passive |= ch->chan_radar;
3113
Kalle Valo5e3dd152013-06-12 20:52:10 +03003114 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02003115 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07003116 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07003117 ch->max_power = channel->max_power * 2;
3118 ch->max_reg_power = channel->max_reg_power * 2;
3119 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003120 ch->reg_class_id = 0; /* FIXME */
3121
3122 /* FIXME: why use only legacy modes, why not any
3123 * HT/VHT modes? Would that even make any
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01003124 * difference?
3125 */
Johannes Berg57fbcce2016-04-12 15:56:15 +02003126 if (channel->band == NL80211_BAND_2GHZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003127 ch->mode = MODE_11G;
3128 else
3129 ch->mode = MODE_11A;
3130
3131 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
3132 continue;
3133
Michal Kazior7aa7a722014-08-25 12:09:38 +02003134 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03003135 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
3136 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003137 ch->freq, ch->max_power, ch->max_reg_power,
3138 ch->max_antenna_gain, ch->mode);
3139
3140 ch++;
3141 }
3142 }
3143
3144 ret = ath10k_wmi_scan_chan_list(ar, &arg);
3145 kfree(arg.channels);
3146
3147 return ret;
3148}
3149
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003150static enum wmi_dfs_region
3151ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
3152{
3153 switch (dfs_region) {
3154 case NL80211_DFS_UNSET:
3155 return WMI_UNINIT_DFS_DOMAIN;
3156 case NL80211_DFS_FCC:
3157 return WMI_FCC_DFS_DOMAIN;
3158 case NL80211_DFS_ETSI:
3159 return WMI_ETSI_DFS_DOMAIN;
3160 case NL80211_DFS_JP:
3161 return WMI_MKK4_DFS_DOMAIN;
3162 }
3163 return WMI_UNINIT_DFS_DOMAIN;
3164}
3165
Michal Kaziorf7843d72013-07-16 09:38:52 +02003166static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003167{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003168 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003169 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003170 enum wmi_dfs_region wmi_dfs_reg;
3171 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003172
Michal Kaziorf7843d72013-07-16 09:38:52 +02003173 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003174
3175 ret = ath10k_update_channel_list(ar);
3176 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003177 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003178
3179 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003180
Masahiro Yamada97f26452016-08-03 13:45:50 -07003181 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003182 nl_dfs_reg = ar->dfs_detector->region;
3183 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
3184 } else {
3185 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
3186 }
3187
Kalle Valo5e3dd152013-06-12 20:52:10 +03003188 /* Target allows setting up per-band regdomain but ath_common provides
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01003189 * a combined one only
3190 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003191 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02003192 regpair->reg_domain,
3193 regpair->reg_domain, /* 2ghz */
3194 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003195 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003196 regpair->reg_5ghz_ctl,
3197 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003198 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003199 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02003200}
Michal Kazior548db542013-07-05 16:15:15 +03003201
Kalle Valo46bc92b2017-03-16 11:11:02 +02003202static void ath10k_mac_update_channel_list(struct ath10k *ar,
3203 struct ieee80211_supported_band *band)
Tamizh chelvam523f6702017-02-23 18:48:22 +05303204{
3205 int i;
3206
3207 if (ar->low_5ghz_chan && ar->high_5ghz_chan) {
3208 for (i = 0; i < band->n_channels; i++) {
3209 if (band->channels[i].center_freq < ar->low_5ghz_chan ||
3210 band->channels[i].center_freq > ar->high_5ghz_chan)
3211 band->channels[i].flags |=
3212 IEEE80211_CHAN_DISABLED;
3213 }
3214 }
3215}
3216
Michal Kaziorf7843d72013-07-16 09:38:52 +02003217static void ath10k_reg_notifier(struct wiphy *wiphy,
3218 struct regulatory_request *request)
3219{
3220 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
3221 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003222 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003223
3224 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3225
Masahiro Yamada97f26452016-08-03 13:45:50 -07003226 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003227 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003228 request->dfs_region);
3229 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3230 request->dfs_region);
3231 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003232 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003233 request->dfs_region);
3234 }
3235
Michal Kaziorf7843d72013-07-16 09:38:52 +02003236 mutex_lock(&ar->conf_mutex);
3237 if (ar->state == ATH10K_STATE_ON)
3238 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003239 mutex_unlock(&ar->conf_mutex);
Tamizh chelvam523f6702017-02-23 18:48:22 +05303240
3241 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
3242 ath10k_mac_update_channel_list(ar,
Kalle Valo46bc92b2017-03-16 11:11:02 +02003243 ar->hw->wiphy->bands[NL80211_BAND_5GHZ]);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003244}
3245
Sriram R6f6eb1b2018-05-15 14:39:49 +05303246static void ath10k_stop_radar_confirmation(struct ath10k *ar)
3247{
3248 spin_lock_bh(&ar->data_lock);
3249 ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_STOPPED;
3250 spin_unlock_bh(&ar->data_lock);
3251
3252 cancel_work_sync(&ar->radar_confirmation_work);
3253}
3254
Kalle Valo5e3dd152013-06-12 20:52:10 +03003255/***************/
3256/* TX handlers */
3257/***************/
3258
Michal Kaziora30c7d02016-03-06 16:14:23 +02003259enum ath10k_mac_tx_path {
3260 ATH10K_MAC_TX_HTT,
3261 ATH10K_MAC_TX_HTT_MGMT,
3262 ATH10K_MAC_TX_WMI_MGMT,
3263 ATH10K_MAC_TX_UNKNOWN,
3264};
3265
Michal Kazior96d828d2015-03-31 10:26:23 +00003266void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3267{
3268 lockdep_assert_held(&ar->htt.tx_lock);
3269
3270 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3271 ar->tx_paused |= BIT(reason);
3272 ieee80211_stop_queues(ar->hw);
3273}
3274
3275static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3276 struct ieee80211_vif *vif)
3277{
3278 struct ath10k *ar = data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003279 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior96d828d2015-03-31 10:26:23 +00003280
3281 if (arvif->tx_paused)
3282 return;
3283
3284 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3285}
3286
3287void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3288{
3289 lockdep_assert_held(&ar->htt.tx_lock);
3290
3291 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3292 ar->tx_paused &= ~BIT(reason);
3293
3294 if (ar->tx_paused)
3295 return;
3296
3297 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3298 IEEE80211_IFACE_ITER_RESUME_ALL,
3299 ath10k_mac_tx_unlock_iter,
3300 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003301
3302 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003303}
3304
3305void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3306{
3307 struct ath10k *ar = arvif->ar;
3308
3309 lockdep_assert_held(&ar->htt.tx_lock);
3310
3311 WARN_ON(reason >= BITS_PER_LONG);
3312 arvif->tx_paused |= BIT(reason);
3313 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3314}
3315
3316void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3317{
3318 struct ath10k *ar = arvif->ar;
3319
3320 lockdep_assert_held(&ar->htt.tx_lock);
3321
3322 WARN_ON(reason >= BITS_PER_LONG);
3323 arvif->tx_paused &= ~BIT(reason);
3324
3325 if (ar->tx_paused)
3326 return;
3327
3328 if (arvif->tx_paused)
3329 return;
3330
3331 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3332}
3333
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003334static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3335 enum wmi_tlv_tx_pause_id pause_id,
3336 enum wmi_tlv_tx_pause_action action)
3337{
3338 struct ath10k *ar = arvif->ar;
3339
3340 lockdep_assert_held(&ar->htt.tx_lock);
3341
Michal Kazioracd0b272015-07-09 13:08:38 +02003342 switch (action) {
3343 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3344 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003345 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003346 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3347 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3348 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003349 default:
Bartosz Markowski209b2a62016-09-28 15:11:58 +03003350 ath10k_dbg(ar, ATH10K_DBG_BOOT,
3351 "received unknown tx pause action %d on vdev %i, ignoring\n",
Michal Kazioracd0b272015-07-09 13:08:38 +02003352 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003353 break;
3354 }
3355}
3356
3357struct ath10k_mac_tx_pause {
3358 u32 vdev_id;
3359 enum wmi_tlv_tx_pause_id pause_id;
3360 enum wmi_tlv_tx_pause_action action;
3361};
3362
3363static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3364 struct ieee80211_vif *vif)
3365{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003366 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003367 struct ath10k_mac_tx_pause *arg = data;
3368
Michal Kazioracd0b272015-07-09 13:08:38 +02003369 if (arvif->vdev_id != arg->vdev_id)
3370 return;
3371
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003372 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3373}
3374
Michal Kazioracd0b272015-07-09 13:08:38 +02003375void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3376 enum wmi_tlv_tx_pause_id pause_id,
3377 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003378{
3379 struct ath10k_mac_tx_pause arg = {
3380 .vdev_id = vdev_id,
3381 .pause_id = pause_id,
3382 .action = action,
3383 };
3384
3385 spin_lock_bh(&ar->htt.tx_lock);
3386 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3387 IEEE80211_IFACE_ITER_RESUME_ALL,
3388 ath10k_mac_handle_tx_pause_iter,
3389 &arg);
3390 spin_unlock_bh(&ar->htt.tx_lock);
3391}
3392
Michal Kaziord740d8f2015-03-30 09:51:51 +03003393static enum ath10k_hw_txrx_mode
Michal Kazior6a2636d2015-11-18 06:59:16 +01003394ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3395 struct ieee80211_vif *vif,
3396 struct ieee80211_sta *sta,
3397 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003398{
3399 const struct ieee80211_hdr *hdr = (void *)skb->data;
3400 __le16 fc = hdr->frame_control;
3401
3402 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3403 return ATH10K_HW_TXRX_RAW;
3404
3405 if (ieee80211_is_mgmt(fc))
3406 return ATH10K_HW_TXRX_MGMT;
3407
3408 /* Workaround:
3409 *
3410 * NullFunc frames are mostly used to ping if a client or AP are still
3411 * reachable and responsive. This implies tx status reports must be
3412 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3413 * come to a conclusion that the other end disappeared and tear down
3414 * BSS connection or it can never disconnect from BSS/client (which is
3415 * the case).
3416 *
3417 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3418 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3419 * which seems to deliver correct tx reports for NullFunc frames. The
3420 * downside of using it is it ignores client powersave state so it can
3421 * end up disconnecting sleeping clients in AP mode. It should fix STA
3422 * mode though because AP don't sleep.
3423 */
3424 if (ar->htt.target_version_major < 3 &&
3425 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03003426 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3427 ar->running_fw->fw_file.fw_features))
Michal Kaziord740d8f2015-03-30 09:51:51 +03003428 return ATH10K_HW_TXRX_MGMT;
3429
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003430 /* Workaround:
3431 *
3432 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3433 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3434 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003435 *
3436 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003437 */
3438 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3439 return ATH10K_HW_TXRX_ETHERNET;
3440
David Liuccec9032015-07-24 20:25:32 +03003441 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3442 return ATH10K_HW_TXRX_RAW;
3443
Michal Kaziord740d8f2015-03-30 09:51:51 +03003444 return ATH10K_HW_TXRX_NATIVE_WIFI;
3445}
3446
David Liuccec9032015-07-24 20:25:32 +03003447static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003448 struct sk_buff *skb)
3449{
3450 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3451 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003452 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3453 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003454
3455 if (!ieee80211_has_protected(hdr->frame_control))
3456 return false;
3457
David Liuccec9032015-07-24 20:25:32 +03003458 if ((info->flags & mask) == mask)
3459 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003460
David Liuccec9032015-07-24 20:25:32 +03003461 if (vif)
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003462 return !((struct ath10k_vif *)vif->drv_priv)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003463
David Liuccec9032015-07-24 20:25:32 +03003464 return true;
3465}
3466
Michal Kazior4b604552014-07-21 21:03:09 +03003467/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3468 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003469 */
Michal Kazior4b604552014-07-21 21:03:09 +03003470static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003471{
3472 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003473 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003474 u8 *qos_ctl;
3475
3476 if (!ieee80211_is_data_qos(hdr->frame_control))
3477 return;
3478
3479 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003480 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3481 skb->data, (void *)qos_ctl - (void *)skb->data);
3482 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003483
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003484 /* Some firmware revisions don't handle sending QoS NullFunc well.
3485 * These frames are mainly used for CQM purposes so it doesn't really
3486 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003487 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003488 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003489 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003490 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003491
3492 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003493}
3494
Michal Kaziord740d8f2015-03-30 09:51:51 +03003495static void ath10k_tx_h_8023(struct sk_buff *skb)
3496{
3497 struct ieee80211_hdr *hdr;
3498 struct rfc1042_hdr *rfc1042;
3499 struct ethhdr *eth;
3500 size_t hdrlen;
3501 u8 da[ETH_ALEN];
3502 u8 sa[ETH_ALEN];
3503 __be16 type;
3504
3505 hdr = (void *)skb->data;
3506 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3507 rfc1042 = (void *)skb->data + hdrlen;
3508
3509 ether_addr_copy(da, ieee80211_get_DA(hdr));
3510 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3511 type = rfc1042->snap_type;
3512
3513 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3514 skb_push(skb, sizeof(*eth));
3515
3516 eth = (void *)skb->data;
3517 ether_addr_copy(eth->h_dest, da);
3518 ether_addr_copy(eth->h_source, sa);
3519 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003520}
3521
Michal Kazior4b604552014-07-21 21:03:09 +03003522static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3523 struct ieee80211_vif *vif,
3524 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003525{
3526 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003527 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003528
3529 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003530 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003531 return;
3532
3533 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3534 spin_lock_bh(&ar->data_lock);
3535 if (arvif->u.ap.noa_data)
3536 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3537 GFP_ATOMIC))
Johannes Berg59ae1d12017-06-16 14:29:20 +02003538 skb_put_data(skb, arvif->u.ap.noa_data,
3539 arvif->u.ap.noa_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003540 spin_unlock_bh(&ar->data_lock);
3541 }
3542}
3543
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003544static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3545 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003546 struct ieee80211_txq *txq,
Kan Yand1ce37b2019-02-11 18:47:52 +02003547 struct sk_buff *skb, u16 airtime)
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003548{
3549 struct ieee80211_hdr *hdr = (void *)skb->data;
3550 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3551
3552 cb->flags = 0;
3553 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3554 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3555
3556 if (ieee80211_is_mgmt(hdr->frame_control))
3557 cb->flags |= ATH10K_SKB_F_MGMT;
3558
3559 if (ieee80211_is_data_qos(hdr->frame_control))
3560 cb->flags |= ATH10K_SKB_F_QOS;
3561
3562 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003563 cb->txq = txq;
Kan Yand1ce37b2019-02-11 18:47:52 +02003564 cb->airtime_est = airtime;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003565}
3566
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303567bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003568{
3569 /* FIXME: Not really sure since when the behaviour changed. At some
3570 * point new firmware stopped requiring creation of peer entries for
3571 * offchannel tx (and actually creating them causes issues with wmi-htc
3572 * tx credit replenishment and reliability). Assuming it's at least 3.4
3573 * because that's when the `freq` was introduced to TX_FRM HTT command.
3574 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303575 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303576 ar->htt.target_version_minor >= 4 &&
Kalle Valo77561f92016-04-20 19:45:47 +03003577 ar->running_fw->fw_file.htt_op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003578}
3579
Michal Kaziord740d8f2015-03-30 09:51:51 +03003580static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003581{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003582 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003583 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003584
Michal Kaziord740d8f2015-03-30 09:51:51 +03003585 spin_lock_bh(&ar->data_lock);
3586
3587 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3588 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3589 ret = -ENOSPC;
3590 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003591 }
3592
Michal Kaziord740d8f2015-03-30 09:51:51 +03003593 __skb_queue_tail(q, skb);
3594 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3595
3596unlock:
3597 spin_unlock_bh(&ar->data_lock);
3598
3599 return ret;
3600}
3601
Michal Kaziora30c7d02016-03-06 16:14:23 +02003602static enum ath10k_mac_tx_path
3603ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3604 struct sk_buff *skb,
3605 enum ath10k_hw_txrx_mode txmode)
3606{
3607 switch (txmode) {
3608 case ATH10K_HW_TXRX_RAW:
3609 case ATH10K_HW_TXRX_NATIVE_WIFI:
3610 case ATH10K_HW_TXRX_ETHERNET:
3611 return ATH10K_MAC_TX_HTT;
3612 case ATH10K_HW_TXRX_MGMT:
3613 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Rakesh Pillai229329f2017-12-11 19:52:52 +05303614 ar->running_fw->fw_file.fw_features) ||
3615 test_bit(WMI_SERVICE_MGMT_TX_WMI,
3616 ar->wmi.svc_map))
Michal Kaziora30c7d02016-03-06 16:14:23 +02003617 return ATH10K_MAC_TX_WMI_MGMT;
3618 else if (ar->htt.target_version_major >= 3)
3619 return ATH10K_MAC_TX_HTT;
3620 else
3621 return ATH10K_MAC_TX_HTT_MGMT;
3622 }
3623
3624 return ATH10K_MAC_TX_UNKNOWN;
3625}
3626
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003627static int ath10k_mac_tx_submit(struct ath10k *ar,
3628 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003629 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003630 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003631{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003632 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003633 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003634
3635 switch (txpath) {
3636 case ATH10K_MAC_TX_HTT:
Erik Stromdahl5df6e132018-04-15 14:22:27 +02003637 ret = ath10k_htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003638 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003639 case ATH10K_MAC_TX_HTT_MGMT:
3640 ret = ath10k_htt_mgmt_tx(htt, skb);
3641 break;
3642 case ATH10K_MAC_TX_WMI_MGMT:
3643 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3644 break;
3645 case ATH10K_MAC_TX_UNKNOWN:
3646 WARN_ON_ONCE(1);
3647 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003648 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003649 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003650
3651 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003652 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3653 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003654 ieee80211_free_txskb(ar->hw, skb);
3655 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003656
3657 return ret;
3658}
3659
3660/* This function consumes the sk_buff regardless of return value as far as
3661 * caller is concerned so no freeing is necessary afterwards.
3662 */
3663static int ath10k_mac_tx(struct ath10k *ar,
3664 struct ieee80211_vif *vif,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003665 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003666 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003667 struct sk_buff *skb)
3668{
3669 struct ieee80211_hw *hw = ar->hw;
3670 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3671 int ret;
3672
3673 /* We should disable CCK RATE due to P2P */
3674 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3675 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3676
3677 switch (txmode) {
3678 case ATH10K_HW_TXRX_MGMT:
3679 case ATH10K_HW_TXRX_NATIVE_WIFI:
3680 ath10k_tx_h_nwifi(hw, skb);
3681 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3682 ath10k_tx_h_seq_no(vif, skb);
3683 break;
3684 case ATH10K_HW_TXRX_ETHERNET:
3685 ath10k_tx_h_8023(skb);
3686 break;
3687 case ATH10K_HW_TXRX_RAW:
3688 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3689 WARN_ON_ONCE(1);
3690 ieee80211_free_txskb(hw, skb);
3691 return -ENOTSUPP;
3692 }
3693 }
3694
3695 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3696 if (!ath10k_mac_tx_frm_has_freq(ar)) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303697 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %pK\n",
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003698 skb);
3699
3700 skb_queue_tail(&ar->offchan_tx_queue, skb);
3701 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3702 return 0;
3703 }
3704 }
3705
Michal Kazior6421969f2016-03-06 16:14:25 +02003706 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003707 if (ret) {
3708 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3709 return ret;
3710 }
3711
3712 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003713}
3714
3715void ath10k_offchan_tx_purge(struct ath10k *ar)
3716{
3717 struct sk_buff *skb;
3718
3719 for (;;) {
3720 skb = skb_dequeue(&ar->offchan_tx_queue);
3721 if (!skb)
3722 break;
3723
3724 ieee80211_free_txskb(ar->hw, skb);
3725 }
3726}
3727
3728void ath10k_offchan_tx_work(struct work_struct *work)
3729{
3730 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3731 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003732 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003733 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003734 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003735 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003736 struct ieee80211_vif *vif;
3737 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003738 struct sk_buff *skb;
3739 const u8 *peer_addr;
3740 int vdev_id;
3741 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003742 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003743 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003744
3745 /* FW requirement: We must create a peer before FW will send out
3746 * an offchannel frame. Otherwise the frame will be stuck and
3747 * never transmitted. We delete the peer upon tx completion.
3748 * It is unlikely that a peer for offchannel tx will already be
3749 * present. However it may be in some rare cases so account for that.
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01003750 * Otherwise we might remove a legitimate peer and break stuff.
3751 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003752
3753 for (;;) {
3754 skb = skb_dequeue(&ar->offchan_tx_queue);
3755 if (!skb)
3756 break;
3757
3758 mutex_lock(&ar->conf_mutex);
3759
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303760 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003761 skb);
3762
3763 hdr = (struct ieee80211_hdr *)skb->data;
3764 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003765
3766 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003767 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003768 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3769 spin_unlock_bh(&ar->data_lock);
3770
3771 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003772 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003773 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003774 peer_addr, vdev_id);
3775
3776 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003777 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3778 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003779 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003780 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003781 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003782 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003783 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003784 }
3785
3786 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003787 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003788 ar->offchan_tx_skb = skb;
3789 spin_unlock_bh(&ar->data_lock);
3790
Michal Kazior8a933962015-11-18 06:59:17 +01003791 /* It's safe to access vif and sta - conf_mutex guarantees that
3792 * sta_state() and remove_interface() are locked exclusively
3793 * out wrt to this offchannel worker.
3794 */
3795 arvif = ath10k_get_arvif(ar, vdev_id);
3796 if (arvif) {
3797 vif = arvif->vif;
3798 sta = ieee80211_find_sta(vif, peer_addr);
3799 } else {
3800 vif = NULL;
3801 sta = NULL;
3802 }
3803
3804 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003805 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003806
Mohammed Shafi Shajakhana7773b5d2016-12-27 19:02:35 +05303807 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003808 if (ret) {
3809 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3810 ret);
3811 /* not serious */
3812 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003813
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003814 time_left =
3815 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3816 if (time_left == 0)
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303817 ath10k_warn(ar, "timed out waiting for offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003818 skb);
3819
Michal Kazioradaeed72015-08-05 12:15:23 +02003820 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003821 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3822 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003823 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003824 peer_addr, vdev_id, ret);
3825 }
3826
3827 mutex_unlock(&ar->conf_mutex);
3828 }
3829}
3830
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003831void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3832{
3833 struct sk_buff *skb;
3834
3835 for (;;) {
3836 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3837 if (!skb)
3838 break;
3839
3840 ieee80211_free_txskb(ar->hw, skb);
3841 }
3842}
3843
3844void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3845{
3846 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3847 struct sk_buff *skb;
Rakesh Pillai38a13902018-02-27 19:09:07 +02003848 dma_addr_t paddr;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003849 int ret;
3850
3851 for (;;) {
3852 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3853 if (!skb)
3854 break;
3855
Rakesh Pillai38a13902018-02-27 19:09:07 +02003856 if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF,
3857 ar->running_fw->fw_file.fw_features)) {
3858 paddr = dma_map_single(ar->dev, skb->data,
3859 skb->len, DMA_TO_DEVICE);
3860 if (!paddr)
3861 continue;
3862 ret = ath10k_wmi_mgmt_tx_send(ar, skb, paddr);
3863 if (ret) {
3864 ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n",
3865 ret);
3866 dma_unmap_single(ar->dev, paddr, skb->len,
Rakesh Pillai6e8a8992019-01-25 09:51:06 +05303867 DMA_TO_DEVICE);
Rakesh Pillai38a13902018-02-27 19:09:07 +02003868 ieee80211_free_txskb(ar->hw, skb);
3869 }
3870 } else {
3871 ret = ath10k_wmi_mgmt_tx(ar, skb);
3872 if (ret) {
3873 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
3874 ret);
3875 ieee80211_free_txskb(ar->hw, skb);
3876 }
Michal Kazior5fb5e412013-10-28 07:18:13 +01003877 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003878 }
3879}
3880
Michal Kazior29946872016-03-06 16:14:34 +02003881static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3882{
Bob Copelanda66cd732016-06-29 19:29:25 +03003883 struct ath10k_txq *artxq;
Michal Kazior29946872016-03-06 16:14:34 +02003884
3885 if (!txq)
3886 return;
3887
Bob Copelanda66cd732016-06-29 19:29:25 +03003888 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003889 INIT_LIST_HEAD(&artxq->list);
3890}
3891
3892static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3893{
Michal Kaziordd4717b2016-03-06 16:14:39 +02003894 struct ath10k_skb_cb *cb;
3895 struct sk_buff *msdu;
3896 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003897
3898 if (!txq)
3899 return;
3900
Michal Kaziordd4717b2016-03-06 16:14:39 +02003901 spin_lock_bh(&ar->htt.tx_lock);
3902 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3903 cb = ATH10K_SKB_CB(msdu);
3904 if (cb->txq == txq)
3905 cb->txq = NULL;
3906 }
3907 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003908}
3909
Michal Kazior426e10e2016-03-06 16:14:43 +02003910struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
3911 u16 peer_id,
3912 u8 tid)
3913{
3914 struct ath10k_peer *peer;
3915
3916 lockdep_assert_held(&ar->data_lock);
3917
3918 peer = ar->peer_map[peer_id];
3919 if (!peer)
3920 return NULL;
3921
Michal Kazior0a744d92017-01-12 16:14:30 +01003922 if (peer->removed)
3923 return NULL;
3924
Michal Kazior426e10e2016-03-06 16:14:43 +02003925 if (peer->sta)
3926 return peer->sta->txq[tid];
3927 else if (peer->vif)
3928 return peer->vif->txq;
3929 else
3930 return NULL;
3931}
3932
Michal Kazior29946872016-03-06 16:14:34 +02003933static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3934 struct ieee80211_txq *txq)
3935{
Michal Kazior426e10e2016-03-06 16:14:43 +02003936 struct ath10k *ar = hw->priv;
3937 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3938
3939 /* No need to get locks */
Michal Kazior426e10e2016-03-06 16:14:43 +02003940 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3941 return true;
3942
3943 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3944 return true;
3945
3946 if (artxq->num_fw_queued < artxq->num_push_allowed)
3947 return true;
3948
3949 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003950}
3951
Kan Yand1ce37b2019-02-11 18:47:52 +02003952/* Return estimated airtime in microsecond, which is calculated using last
3953 * reported TX rate. This is just a rough estimation because host driver has no
3954 * knowledge of the actual transmit rate, retries or aggregation. If actual
3955 * airtime can be reported by firmware, then delta between estimated and actual
3956 * airtime can be adjusted from deficit.
3957 */
3958#define IEEE80211_ATF_OVERHEAD 100 /* IFS + some slot time */
3959#define IEEE80211_ATF_OVERHEAD_IFS 16 /* IFS only */
3960static u16 ath10k_mac_update_airtime(struct ath10k *ar,
3961 struct ieee80211_txq *txq,
3962 struct sk_buff *skb)
3963{
3964 struct ath10k_sta *arsta;
3965 u32 pktlen;
3966 u16 airtime = 0;
3967
3968 if (!txq || !txq->sta)
3969 return airtime;
3970
3971 spin_lock_bh(&ar->data_lock);
3972 arsta = (struct ath10k_sta *)txq->sta->drv_priv;
3973
3974 pktlen = skb->len + 38; /* Assume MAC header 30, SNAP 8 for most case */
3975 if (arsta->last_tx_bitrate) {
3976 /* airtime in us, last_tx_bitrate in 100kbps */
3977 airtime = (pktlen * 8 * (1000 / 100))
3978 / arsta->last_tx_bitrate;
3979 /* overhead for media access time and IFS */
3980 airtime += IEEE80211_ATF_OVERHEAD_IFS;
3981 } else {
3982 /* This is mostly for throttle excessive BC/MC frames, and the
3983 * airtime/rate doesn't need be exact. Airtime of BC/MC frames
3984 * in 2G get some discount, which helps prevent very low rate
3985 * frames from being blocked for too long.
3986 */
3987 airtime = (pktlen * 8 * (1000 / 100)) / 60; /* 6M */
3988 airtime += IEEE80211_ATF_OVERHEAD;
3989 }
3990 spin_unlock_bh(&ar->data_lock);
3991
3992 return airtime;
3993}
3994
Michal Kazior426e10e2016-03-06 16:14:43 +02003995int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3996 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02003997{
Michal Kazior29946872016-03-06 16:14:34 +02003998 struct ath10k *ar = hw->priv;
3999 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02004000 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02004001 struct ieee80211_vif *vif = txq->vif;
4002 struct ieee80211_sta *sta = txq->sta;
4003 enum ath10k_hw_txrx_mode txmode;
4004 enum ath10k_mac_tx_path txpath;
4005 struct sk_buff *skb;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304006 struct ieee80211_hdr *hdr;
Michal Kazior426e10e2016-03-06 16:14:43 +02004007 size_t skb_len;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304008 bool is_mgmt, is_presp;
Michal Kazior29946872016-03-06 16:14:34 +02004009 int ret;
Kan Yand1ce37b2019-02-11 18:47:52 +02004010 u16 airtime;
Michal Kazior29946872016-03-06 16:14:34 +02004011
4012 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304013 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02004014 spin_unlock_bh(&ar->htt.tx_lock);
4015
4016 if (ret)
4017 return ret;
4018
4019 skb = ieee80211_tx_dequeue(hw, txq);
4020 if (!skb) {
4021 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304022 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02004023 spin_unlock_bh(&ar->htt.tx_lock);
4024
4025 return -ENOENT;
4026 }
4027
Kan Yand1ce37b2019-02-11 18:47:52 +02004028 airtime = ath10k_mac_update_airtime(ar, txq, skb);
4029 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
Michal Kazior29946872016-03-06 16:14:34 +02004030
Michal Kazior426e10e2016-03-06 16:14:43 +02004031 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02004032 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
4033 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304034 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
4035
4036 if (is_mgmt) {
4037 hdr = (struct ieee80211_hdr *)skb->data;
4038 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4039
4040 spin_lock_bh(&ar->htt.tx_lock);
4041 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4042
4043 if (ret) {
4044 ath10k_htt_tx_dec_pending(htt);
4045 spin_unlock_bh(&ar->htt.tx_lock);
4046 return ret;
4047 }
4048 spin_unlock_bh(&ar->htt.tx_lock);
4049 }
Michal Kazior29946872016-03-06 16:14:34 +02004050
Mohammed Shafi Shajakhana7773b5d2016-12-27 19:02:35 +05304051 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
Michal Kazior29946872016-03-06 16:14:34 +02004052 if (unlikely(ret)) {
4053 ath10k_warn(ar, "failed to push frame: %d\n", ret);
4054
4055 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304056 ath10k_htt_tx_dec_pending(htt);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304057 if (is_mgmt)
4058 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02004059 spin_unlock_bh(&ar->htt.tx_lock);
4060
4061 return ret;
4062 }
4063
Michal Kazior3cc0fef2016-03-06 16:14:41 +02004064 spin_lock_bh(&ar->htt.tx_lock);
4065 artxq->num_fw_queued++;
4066 spin_unlock_bh(&ar->htt.tx_lock);
4067
Michal Kazior426e10e2016-03-06 16:14:43 +02004068 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02004069}
4070
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004071static int ath10k_mac_schedule_txq(struct ieee80211_hw *hw, u32 ac)
Michal Kazior29946872016-03-06 16:14:34 +02004072{
Michal Kazior29946872016-03-06 16:14:34 +02004073 struct ieee80211_txq *txq;
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004074 int ret = 0;
Michal Kazior29946872016-03-06 16:14:34 +02004075
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004076 ieee80211_txq_schedule_start(hw, ac);
4077 while ((txq = ieee80211_next_txq(hw, ac))) {
4078 while (ath10k_mac_tx_can_push(hw, txq)) {
Michal Kazior29946872016-03-06 16:14:34 +02004079 ret = ath10k_mac_tx_push_txq(hw, txq);
4080 if (ret < 0)
4081 break;
4082 }
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004083 ieee80211_return_txq(hw, txq);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004084 ath10k_htt_tx_txq_update(hw, txq);
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004085 if (ret == -EBUSY)
Michal Kazior29946872016-03-06 16:14:34 +02004086 break;
Michal Kazior29946872016-03-06 16:14:34 +02004087 }
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004088 ieee80211_txq_schedule_end(hw, ac);
Michal Kazior29946872016-03-06 16:14:34 +02004089
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004090 return ret;
4091}
4092
4093void ath10k_mac_tx_push_pending(struct ath10k *ar)
4094{
4095 struct ieee80211_hw *hw = ar->hw;
4096 u32 ac;
4097
4098 if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)
4099 return;
4100
4101 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
4102 return;
4103
4104 rcu_read_lock();
4105 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
4106 if (ath10k_mac_schedule_txq(hw, ac) == -EBUSY)
4107 break;
4108 }
Michal Kazior29946872016-03-06 16:14:34 +02004109 rcu_read_unlock();
Michal Kazior29946872016-03-06 16:14:34 +02004110}
Niklas Cassel3f049502018-06-18 17:00:49 +03004111EXPORT_SYMBOL(ath10k_mac_tx_push_pending);
Michal Kazior29946872016-03-06 16:14:34 +02004112
Kalle Valo5e3dd152013-06-12 20:52:10 +03004113/************/
4114/* Scanning */
4115/************/
4116
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004117void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004118{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004119 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004120
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004121 switch (ar->scan.state) {
4122 case ATH10K_SCAN_IDLE:
4123 break;
4124 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01004125 case ATH10K_SCAN_ABORTING:
Avraham Stern7947d3e2016-07-05 15:23:12 +03004126 if (!ar->scan.is_roc) {
4127 struct cfg80211_scan_info info = {
4128 .aborted = (ar->scan.state ==
4129 ATH10K_SCAN_ABORTING),
4130 };
4131
4132 ieee80211_scan_completed(ar->hw, &info);
4133 } else if (ar->scan.roc_notify) {
Michal Kaziord710e752015-07-09 13:08:36 +02004134 ieee80211_remain_on_channel_expired(ar->hw);
Avraham Stern7947d3e2016-07-05 15:23:12 +03004135 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004136 /* fall through */
4137 case ATH10K_SCAN_STARTING:
4138 ar->scan.state = ATH10K_SCAN_IDLE;
4139 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01004140 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004141 ath10k_offchan_tx_purge(ar);
4142 cancel_delayed_work(&ar->scan.timeout);
Daniel Wagner881ed542016-08-18 15:12:06 +02004143 complete(&ar->scan.completed);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004144 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004145 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004146}
Kalle Valo5e3dd152013-06-12 20:52:10 +03004147
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004148void ath10k_scan_finish(struct ath10k *ar)
4149{
4150 spin_lock_bh(&ar->data_lock);
4151 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004152 spin_unlock_bh(&ar->data_lock);
4153}
4154
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004155static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004156{
4157 struct wmi_stop_scan_arg arg = {
4158 .req_id = 1, /* FIXME */
4159 .req_type = WMI_SCAN_STOP_ONE,
4160 .u.scan_id = ATH10K_SCAN_ID,
4161 };
4162 int ret;
4163
4164 lockdep_assert_held(&ar->conf_mutex);
4165
Kalle Valo5e3dd152013-06-12 20:52:10 +03004166 ret = ath10k_wmi_stop_scan(ar, &arg);
4167 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004168 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004169 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004170 }
4171
Kalle Valo14e105c2016-04-13 14:13:21 +03004172 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004173 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004174 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004175 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004176 } else if (ret > 0) {
4177 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004178 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004179
4180out:
4181 /* Scan state should be updated upon scan completion but in case
4182 * firmware fails to deliver the event (for whatever reason) it is
4183 * desired to clean up scan state anyway. Firmware may have just
4184 * dropped the scan completion event delivery due to transport pipe
4185 * being overflown with data and/or it can recover on its own before
4186 * next scan request is submitted.
4187 */
4188 spin_lock_bh(&ar->data_lock);
4189 if (ar->scan.state != ATH10K_SCAN_IDLE)
4190 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004191 spin_unlock_bh(&ar->data_lock);
4192
4193 return ret;
4194}
4195
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004196static void ath10k_scan_abort(struct ath10k *ar)
4197{
4198 int ret;
4199
4200 lockdep_assert_held(&ar->conf_mutex);
4201
4202 spin_lock_bh(&ar->data_lock);
4203
4204 switch (ar->scan.state) {
4205 case ATH10K_SCAN_IDLE:
4206 /* This can happen if timeout worker kicked in and called
4207 * abortion while scan completion was being processed.
4208 */
4209 break;
4210 case ATH10K_SCAN_STARTING:
4211 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02004212 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004213 ath10k_scan_state_str(ar->scan.state),
4214 ar->scan.state);
4215 break;
4216 case ATH10K_SCAN_RUNNING:
4217 ar->scan.state = ATH10K_SCAN_ABORTING;
4218 spin_unlock_bh(&ar->data_lock);
4219
4220 ret = ath10k_scan_stop(ar);
4221 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004222 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004223
4224 spin_lock_bh(&ar->data_lock);
4225 break;
4226 }
4227
4228 spin_unlock_bh(&ar->data_lock);
4229}
4230
4231void ath10k_scan_timeout_work(struct work_struct *work)
4232{
4233 struct ath10k *ar = container_of(work, struct ath10k,
4234 scan.timeout.work);
4235
4236 mutex_lock(&ar->conf_mutex);
4237 ath10k_scan_abort(ar);
4238 mutex_unlock(&ar->conf_mutex);
4239}
4240
Kalle Valo5e3dd152013-06-12 20:52:10 +03004241static int ath10k_start_scan(struct ath10k *ar,
4242 const struct wmi_start_scan_arg *arg)
4243{
4244 int ret;
4245
4246 lockdep_assert_held(&ar->conf_mutex);
4247
4248 ret = ath10k_wmi_start_scan(ar, arg);
4249 if (ret)
4250 return ret;
4251
Kalle Valo14e105c2016-04-13 14:13:21 +03004252 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004253 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004254 ret = ath10k_scan_stop(ar);
4255 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004256 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004257
4258 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004259 }
4260
Ben Greear2f9eec02015-02-15 16:50:38 +02004261 /* If we failed to start the scan, return error code at
4262 * this point. This is probably due to some issue in the
4263 * firmware, but no need to wedge the driver due to that...
4264 */
4265 spin_lock_bh(&ar->data_lock);
4266 if (ar->scan.state == ATH10K_SCAN_IDLE) {
4267 spin_unlock_bh(&ar->data_lock);
4268 return -EINVAL;
4269 }
4270 spin_unlock_bh(&ar->data_lock);
4271
Kalle Valo5e3dd152013-06-12 20:52:10 +03004272 return 0;
4273}
4274
4275/**********************/
4276/* mac80211 callbacks */
4277/**********************/
4278
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004279static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4280 struct ieee80211_tx_control *control,
4281 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004282{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004283 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02004284 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03004285 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4286 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004287 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02004288 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02004289 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01004290 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02004291 enum ath10k_mac_tx_path txpath;
4292 bool is_htt;
4293 bool is_mgmt;
4294 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004295 int ret;
Kan Yand1ce37b2019-02-11 18:47:52 +02004296 u16 airtime;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004297
Kan Yand1ce37b2019-02-11 18:47:52 +02004298 airtime = ath10k_mac_update_airtime(ar, txq, skb);
4299 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004300
Michal Kazior8a933962015-11-18 06:59:17 +01004301 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004302 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
4303 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
4304 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304305 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004306
Michal Kazior6421969f2016-03-06 16:14:25 +02004307 if (is_htt) {
4308 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004309 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4310
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304311 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004312 if (ret) {
4313 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4314 ret);
4315 spin_unlock_bh(&ar->htt.tx_lock);
4316 ieee80211_free_txskb(ar->hw, skb);
4317 return;
4318 }
4319
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304320 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4321 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304322 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4323 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304324 ath10k_htt_tx_dec_pending(htt);
4325 spin_unlock_bh(&ar->htt.tx_lock);
4326 ieee80211_free_txskb(ar->hw, skb);
4327 return;
4328 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004329 spin_unlock_bh(&ar->htt.tx_lock);
4330 }
4331
Mohammed Shafi Shajakhana7773b5d2016-12-27 19:02:35 +05304332 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004333 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004334 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004335 if (is_htt) {
4336 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304337 ath10k_htt_tx_dec_pending(htt);
4338 if (is_mgmt)
4339 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004340 spin_unlock_bh(&ar->htt.tx_lock);
4341 }
4342 return;
4343 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004344}
4345
Michal Kazior29946872016-03-06 16:14:34 +02004346static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4347 struct ieee80211_txq *txq)
4348{
4349 struct ath10k *ar = hw->priv;
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004350 int ret;
4351 u8 ac;
Michal Kazior29946872016-03-06 16:14:34 +02004352
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004353 ath10k_htt_tx_txq_update(hw, txq);
4354 if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)
4355 return;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304356
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004357 ac = txq->ac;
4358 ieee80211_txq_schedule_start(hw, ac);
4359 txq = ieee80211_next_txq(hw, ac);
4360 if (!txq)
4361 goto out;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304362
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004363 while (ath10k_mac_tx_can_push(hw, txq)) {
4364 ret = ath10k_mac_tx_push_txq(hw, txq);
Erik Stromdahle3148cc2018-05-06 15:25:00 +02004365 if (ret < 0)
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304366 break;
4367 }
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004368 ieee80211_return_txq(hw, txq);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004369 ath10k_htt_tx_txq_update(hw, txq);
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004370out:
4371 ieee80211_txq_schedule_end(hw, ac);
Michal Kazior29946872016-03-06 16:14:34 +02004372}
4373
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004374/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004375void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004376{
4377 /* make sure rcu-protected mac80211 tx path itself is drained */
4378 synchronize_net();
4379
4380 ath10k_offchan_tx_purge(ar);
4381 ath10k_mgmt_over_wmi_tx_purge(ar);
4382
4383 cancel_work_sync(&ar->offchan_tx_work);
4384 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4385}
4386
Michal Kazioraffd3212013-07-16 09:54:35 +02004387void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004388{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004389 struct ath10k_vif *arvif;
4390
Michal Kazior818bdd12013-07-16 09:38:57 +02004391 lockdep_assert_held(&ar->conf_mutex);
4392
Michal Kazior19337472014-08-28 12:58:16 +02004393 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4394 ar->filter_flags = 0;
4395 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004396 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004397
4398 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004399 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004400
4401 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004402 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004403
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004404 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004405 ath10k_peer_cleanup_all(ar);
Sriram R6f6eb1b2018-05-15 14:39:49 +05304406 ath10k_stop_radar_confirmation(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004407 ath10k_core_stop(ar);
4408 ath10k_hif_power_down(ar);
4409
4410 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004411 list_for_each_entry(arvif, &ar->arvifs, list)
4412 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004413 spin_unlock_bh(&ar->data_lock);
4414}
4415
Ben Greear46acf7bb2014-05-16 17:15:38 +03004416static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4417{
4418 struct ath10k *ar = hw->priv;
4419
4420 mutex_lock(&ar->conf_mutex);
4421
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304422 *tx_ant = ar->cfg_tx_chainmask;
4423 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03004424
4425 mutex_unlock(&ar->conf_mutex);
4426
4427 return 0;
4428}
4429
Ben Greear5572a952014-11-24 16:22:10 +02004430static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4431{
4432 /* It is not clear that allowing gaps in chainmask
4433 * is helpful. Probably it will not do what user
4434 * is hoping for, so warn in that case.
4435 */
4436 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4437 return;
4438
4439 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4440 dbg, cm);
4441}
4442
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304443static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4444{
4445 int nsts = ar->vht_cap_info;
4446
4447 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4448 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4449
4450 /* If firmware does not deliver to host number of space-time
4451 * streams supported, assume it support up to 4 BF STS and return
4452 * the value for VHT CAP: nsts-1)
4453 */
4454 if (nsts == 0)
4455 return 3;
4456
4457 return nsts;
4458}
4459
4460static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4461{
4462 int sound_dim = ar->vht_cap_info;
4463
4464 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4465 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4466
4467 /* If the sounding dimension is not advertised by the firmware,
4468 * let's use a default value of 1
4469 */
4470 if (sound_dim == 0)
4471 return 1;
4472
4473 return sound_dim;
4474}
4475
4476static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4477{
4478 struct ieee80211_sta_vht_cap vht_cap = {0};
Ben Greearcc914a52017-06-16 10:37:45 +03004479 struct ath10k_hw_params *hw = &ar->hw_params;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304480 u16 mcs_map;
4481 u32 val;
4482 int i;
4483
4484 vht_cap.vht_supported = 1;
4485 vht_cap.cap = ar->vht_cap_info;
4486
4487 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4488 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4489 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4490 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4491 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4492
4493 vht_cap.cap |= val;
4494 }
4495
4496 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4497 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4498 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4499 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4500 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4501
4502 vht_cap.cap |= val;
4503 }
4504
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02004505 /* Currently the firmware seems to be buggy, don't enable 80+80
4506 * mode until that's resolved.
4507 */
4508 if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) &&
Ben Greeare509e592017-06-16 10:37:44 +03004509 (ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == 0)
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02004510 vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
4511
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304512 mcs_map = 0;
4513 for (i = 0; i < 8; i++) {
4514 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4515 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4516 else
4517 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4518 }
4519
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004520 if (ar->cfg_tx_chainmask <= 1)
4521 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4522
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304523 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4524 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4525
Ben Greearcc914a52017-06-16 10:37:45 +03004526 /* If we are supporting 160Mhz or 80+80, then the NIC may be able to do
4527 * a restricted NSS for 160 or 80+80 vs what it can do for 80Mhz. Give
4528 * user-space a clue if that is the case.
4529 */
4530 if ((vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) &&
4531 (hw->vht160_mcs_rx_highest != 0 ||
4532 hw->vht160_mcs_tx_highest != 0)) {
4533 vht_cap.vht_mcs.rx_highest = cpu_to_le16(hw->vht160_mcs_rx_highest);
4534 vht_cap.vht_mcs.tx_highest = cpu_to_le16(hw->vht160_mcs_tx_highest);
4535 }
4536
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304537 return vht_cap;
4538}
4539
4540static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4541{
4542 int i;
4543 struct ieee80211_sta_ht_cap ht_cap = {0};
4544
4545 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4546 return ht_cap;
4547
4548 ht_cap.ht_supported = 1;
4549 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4550 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4551 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4552 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004553 ht_cap.cap |=
4554 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304555
4556 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4557 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4558
4559 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4560 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4561
4562 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4563 u32 smps;
4564
4565 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4566 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4567
4568 ht_cap.cap |= smps;
4569 }
4570
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004571 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304572 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4573
4574 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4575 u32 stbc;
4576
4577 stbc = ar->ht_cap_info;
4578 stbc &= WMI_HT_CAP_RX_STBC;
4579 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4580 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4581 stbc &= IEEE80211_HT_CAP_RX_STBC;
4582
4583 ht_cap.cap |= stbc;
4584 }
4585
Surabhi Vishnoiff488d02019-02-01 11:04:22 +05304586 if (ar->ht_cap_info & WMI_HT_CAP_LDPC || (ar->ht_cap_info &
4587 WMI_HT_CAP_RX_LDPC && (ar->ht_cap_info & WMI_HT_CAP_TX_LDPC)))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304588 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4589
4590 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4591 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4592
4593 /* max AMSDU is implicitly taken from vht_cap_info */
4594 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4595 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4596
4597 for (i = 0; i < ar->num_rf_chains; i++) {
4598 if (ar->cfg_rx_chainmask & BIT(i))
4599 ht_cap.mcs.rx_mask[i] = 0xFF;
4600 }
4601
4602 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4603
4604 return ht_cap;
4605}
4606
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304607static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4608{
4609 struct ieee80211_supported_band *band;
4610 struct ieee80211_sta_vht_cap vht_cap;
4611 struct ieee80211_sta_ht_cap ht_cap;
4612
4613 ht_cap = ath10k_get_ht_cap(ar);
4614 vht_cap = ath10k_create_vht_cap(ar);
4615
4616 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004617 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304618 band->ht_cap = ht_cap;
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304619 }
4620 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004621 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304622 band->ht_cap = ht_cap;
4623 band->vht_cap = vht_cap;
4624 }
4625}
4626
Ben Greear46acf7bb2014-05-16 17:15:38 +03004627static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4628{
4629 int ret;
4630
4631 lockdep_assert_held(&ar->conf_mutex);
4632
Ben Greear5572a952014-11-24 16:22:10 +02004633 ath10k_check_chain_mask(ar, tx_ant, "tx");
4634 ath10k_check_chain_mask(ar, rx_ant, "rx");
4635
Ben Greear46acf7bb2014-05-16 17:15:38 +03004636 ar->cfg_tx_chainmask = tx_ant;
4637 ar->cfg_rx_chainmask = rx_ant;
4638
4639 if ((ar->state != ATH10K_STATE_ON) &&
4640 (ar->state != ATH10K_STATE_RESTARTED))
4641 return 0;
4642
4643 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4644 tx_ant);
4645 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004646 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03004647 ret, tx_ant);
4648 return ret;
4649 }
4650
4651 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4652 rx_ant);
4653 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004654 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03004655 ret, rx_ant);
4656 return ret;
4657 }
4658
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304659 /* Reload HT/VHT capability */
4660 ath10k_mac_setup_ht_vht_cap(ar);
4661
Ben Greear46acf7bb2014-05-16 17:15:38 +03004662 return 0;
4663}
4664
4665static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4666{
4667 struct ath10k *ar = hw->priv;
4668 int ret;
4669
4670 mutex_lock(&ar->conf_mutex);
4671 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4672 mutex_unlock(&ar->conf_mutex);
4673 return ret;
4674}
4675
Bhagavathi Perumal S84758d42018-12-20 14:26:00 +02004676static int __ath10k_fetch_bb_timing_dt(struct ath10k *ar,
4677 struct wmi_bb_timing_cfg_arg *bb_timing)
4678{
4679 struct device_node *node;
4680 const char *fem_name;
4681 int ret;
4682
4683 node = ar->dev->of_node;
4684 if (!node)
4685 return -ENOENT;
4686
4687 ret = of_property_read_string_index(node, "ext-fem-name", 0, &fem_name);
4688 if (ret)
4689 return -ENOENT;
4690
4691 /*
4692 * If external Front End module used in hardware, then default base band timing
4693 * parameter cannot be used since they were fine tuned for reference hardware,
4694 * so choosing different value suitable for that external FEM.
4695 */
4696 if (!strcmp("microsemi-lx5586", fem_name)) {
4697 bb_timing->bb_tx_timing = 0x00;
4698 bb_timing->bb_xpa_timing = 0x0101;
4699 } else {
4700 return -ENOENT;
4701 }
4702
4703 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot bb_tx_timing 0x%x bb_xpa_timing 0x%x\n",
4704 bb_timing->bb_tx_timing, bb_timing->bb_xpa_timing);
4705 return 0;
4706}
4707
Kalle Valo5e3dd152013-06-12 20:52:10 +03004708static int ath10k_start(struct ieee80211_hw *hw)
4709{
4710 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304711 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004712 int ret = 0;
Bhagavathi Perumal S84758d42018-12-20 14:26:00 +02004713 struct wmi_bb_timing_cfg_arg bb_timing = {0};
Kalle Valo5e3dd152013-06-12 20:52:10 +03004714
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004715 /*
4716 * This makes sense only when restarting hw. It is harmless to call
Mohammed Shafi Shajakhan6dfdbfc2016-04-26 14:41:36 +03004717 * unconditionally. This is necessary to make sure no HTT/WMI tx
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004718 * commands will be submitted while restarting.
4719 */
4720 ath10k_drain_tx(ar);
4721
Michal Kazior548db542013-07-05 16:15:15 +03004722 mutex_lock(&ar->conf_mutex);
4723
Michal Kaziorc5058f52014-05-26 12:46:03 +03004724 switch (ar->state) {
4725 case ATH10K_STATE_OFF:
4726 ar->state = ATH10K_STATE_ON;
4727 break;
4728 case ATH10K_STATE_RESTARTING:
Michal Kaziorc5058f52014-05-26 12:46:03 +03004729 ar->state = ATH10K_STATE_RESTARTED;
4730 break;
4731 case ATH10K_STATE_ON:
4732 case ATH10K_STATE_RESTARTED:
4733 case ATH10K_STATE_WEDGED:
4734 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004735 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004736 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004737 case ATH10K_STATE_UTF:
4738 ret = -EBUSY;
4739 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004740 }
4741
Rakesh Pillai3c545a22019-02-08 15:50:10 +02004742 ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02004743 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004744 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004745 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004746 }
4747
Kalle Valo7ebf7212016-04-20 19:44:51 +03004748 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
4749 &ar->normal_mode_fw);
Michal Kazior818bdd12013-07-16 09:38:57 +02004750 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004751 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004752 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004753 }
4754
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304755 param = ar->wmi.pdev_param->pmf_qos;
4756 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004757 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004758 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004759 goto err_core_stop;
4760 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004761
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304762 param = ar->wmi.pdev_param->dynamic_bw;
4763 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004764 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004765 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004766 goto err_core_stop;
4767 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004768
Rakesh Pillaif1157692018-10-02 23:33:13 +05304769 if (test_bit(WMI_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi.svc_map)) {
4770 ret = ath10k_wmi_scan_prob_req_oui(ar, ar->mac_addr);
4771 if (ret) {
4772 ath10k_err(ar, "failed to set prob req oui: %i\n", ret);
4773 goto err_core_stop;
4774 }
4775 }
4776
Michal Kaziorcf327842015-03-31 10:26:25 +00004777 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4778 ret = ath10k_wmi_adaptive_qcs(ar, true);
4779 if (ret) {
4780 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4781 ret);
4782 goto err_core_stop;
4783 }
4784 }
4785
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004786 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304787 param = ar->wmi.pdev_param->burst_enable;
4788 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004789 if (ret) {
4790 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4791 goto err_core_stop;
4792 }
4793 }
4794
Govind Singhd5cded12018-04-17 17:37:01 +05304795 param = ar->wmi.pdev_param->idle_ps_config;
4796 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
4797 if (ret && ret != -EOPNOTSUPP) {
4798 ath10k_warn(ar, "failed to enable idle_ps_config: %d\n", ret);
4799 goto err_core_stop;
4800 }
4801
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304802 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7bb2014-05-16 17:15:38 +03004803
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004804 /*
4805 * By default FW set ARP frames ac to voice (6). In that case ARP
4806 * exchange is not working properly for UAPSD enabled AP. ARP requests
4807 * which arrives with access category 0 are processed by network stack
4808 * and send back with access category 0, but FW changes access category
4809 * to 6. Set ARP frames access category to best effort (0) solves
4810 * this problem.
4811 */
4812
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304813 param = ar->wmi.pdev_param->arp_ac_override;
4814 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004815 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004816 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004817 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004818 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004819 }
4820
Maharaja62f77f02015-10-21 11:49:18 +03004821 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
Kalle Valoc4cdf752016-04-20 19:45:18 +03004822 ar->running_fw->fw_file.fw_features)) {
Maharaja62f77f02015-10-21 11:49:18 +03004823 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4824 WMI_CCA_DETECT_LEVEL_AUTO,
4825 WMI_CCA_DETECT_MARGIN_AUTO);
4826 if (ret) {
4827 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4828 ret);
4829 goto err_core_stop;
4830 }
4831 }
4832
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304833 param = ar->wmi.pdev_param->ani_enable;
4834 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304835 if (ret) {
4836 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4837 ret);
4838 goto err_core_stop;
4839 }
4840
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304841 ar->ani_enabled = true;
4842
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304843 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304844 param = ar->wmi.pdev_param->peer_stats_update_period;
4845 ret = ath10k_wmi_pdev_set_param(ar, param,
4846 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4847 if (ret) {
4848 ath10k_warn(ar,
4849 "failed to set peer stats period : %d\n",
4850 ret);
4851 goto err_core_stop;
4852 }
4853 }
4854
Rajkumar Manoharan39136242016-05-27 20:15:59 +05304855 param = ar->wmi.pdev_param->enable_btcoex;
4856 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
4857 test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
4858 ar->running_fw->fw_file.fw_features)) {
4859 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4860 if (ret) {
4861 ath10k_warn(ar,
4862 "failed to set btcoex param: %d\n", ret);
4863 goto err_core_stop;
4864 }
4865 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
4866 }
4867
Bhagavathi Perumal S84758d42018-12-20 14:26:00 +02004868 if (test_bit(WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT, ar->wmi.svc_map)) {
4869 ret = __ath10k_fetch_bb_timing_dt(ar, &bb_timing);
4870 if (!ret) {
4871 ret = ath10k_wmi_pdev_bb_timing(ar, &bb_timing);
4872 if (ret) {
4873 ath10k_warn(ar,
4874 "failed to set bb timings: %d\n",
4875 ret);
4876 goto err_core_stop;
4877 }
4878 }
4879 }
4880
Michal Kaziord6500972014-04-08 09:56:09 +03004881 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004882 ath10k_regd_update(ar);
4883
Simon Wunderlich855aed12014-08-02 09:12:54 +03004884 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304885 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004886
Sriram R6f6eb1b2018-05-15 14:39:49 +05304887 ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_IDLE;
4888
Michal Kaziorae254432014-05-26 12:46:02 +03004889 mutex_unlock(&ar->conf_mutex);
4890 return 0;
4891
4892err_core_stop:
4893 ath10k_core_stop(ar);
4894
4895err_power_down:
4896 ath10k_hif_power_down(ar);
4897
4898err_off:
4899 ar->state = ATH10K_STATE_OFF;
4900
4901err:
Michal Kazior548db542013-07-05 16:15:15 +03004902 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004903 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004904}
4905
4906static void ath10k_stop(struct ieee80211_hw *hw)
4907{
4908 struct ath10k *ar = hw->priv;
4909
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004910 ath10k_drain_tx(ar);
4911
Michal Kazior548db542013-07-05 16:15:15 +03004912 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004913 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004914 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004915 ar->state = ATH10K_STATE_OFF;
4916 }
Michal Kazior548db542013-07-05 16:15:15 +03004917 mutex_unlock(&ar->conf_mutex);
4918
Mohammed Shafi Shajakhand94475c2017-03-31 17:28:41 +05304919 cancel_work_sync(&ar->set_coverage_class_work);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004920 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004921 cancel_work_sync(&ar->restart_work);
4922}
4923
Michal Kaziorad088bf2013-10-16 15:44:46 +03004924static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004925{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004926 struct ath10k_vif *arvif;
4927 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004928
4929 lockdep_assert_held(&ar->conf_mutex);
4930
Michal Kaziorad088bf2013-10-16 15:44:46 +03004931 list_for_each_entry(arvif, &ar->arvifs, list) {
4932 ret = ath10k_mac_vif_setup_ps(arvif);
4933 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004934 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004935 break;
4936 }
4937 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004938
Michal Kaziorad088bf2013-10-16 15:44:46 +03004939 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004940}
4941
Michal Kazior7d9d5582014-10-21 10:40:15 +03004942static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4943{
4944 int ret;
4945 u32 param;
4946
4947 lockdep_assert_held(&ar->conf_mutex);
4948
4949 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4950
4951 param = ar->wmi.pdev_param->txpower_limit2g;
4952 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4953 if (ret) {
4954 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4955 txpower, ret);
4956 return ret;
4957 }
4958
4959 param = ar->wmi.pdev_param->txpower_limit5g;
4960 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4961 if (ret) {
4962 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4963 txpower, ret);
4964 return ret;
4965 }
4966
4967 return 0;
4968}
4969
4970static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4971{
4972 struct ath10k_vif *arvif;
4973 int ret, txpower = -1;
4974
4975 lockdep_assert_held(&ar->conf_mutex);
4976
4977 list_for_each_entry(arvif, &ar->arvifs, list) {
Ryan Hsu88407be2016-12-13 14:55:19 -08004978 if (arvif->txpower <= 0)
4979 continue;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004980
4981 if (txpower == -1)
4982 txpower = arvif->txpower;
4983 else
4984 txpower = min(txpower, arvif->txpower);
4985 }
4986
Ryan Hsu88407be2016-12-13 14:55:19 -08004987 if (txpower == -1)
4988 return 0;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004989
4990 ret = ath10k_mac_txpower_setup(ar, txpower);
4991 if (ret) {
4992 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4993 txpower, ret);
4994 return ret;
4995 }
4996
4997 return 0;
4998}
4999
Kalle Valo5e3dd152013-06-12 20:52:10 +03005000static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
5001{
Kalle Valo5e3dd152013-06-12 20:52:10 +03005002 struct ath10k *ar = hw->priv;
5003 struct ieee80211_conf *conf = &hw->conf;
5004 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005005
5006 mutex_lock(&ar->conf_mutex);
5007
Michal Kazioraffd3212013-07-16 09:54:35 +02005008 if (changed & IEEE80211_CONF_CHANGE_PS)
5009 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005010
5011 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02005012 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
5013 ret = ath10k_monitor_recalc(ar);
5014 if (ret)
5015 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005016 }
5017
5018 mutex_unlock(&ar->conf_mutex);
5019 return ret;
5020}
5021
Ben Greear5572a952014-11-24 16:22:10 +02005022static u32 get_nss_from_chainmask(u16 chain_mask)
5023{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05305024 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02005025 return 4;
5026 else if ((chain_mask & 0x7) == 0x7)
5027 return 3;
5028 else if ((chain_mask & 0x3) == 0x3)
5029 return 2;
5030 return 1;
5031}
5032
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305033static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
5034{
5035 u32 value = 0;
5036 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02005037 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02005038 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305039
5040 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
5041 return 0;
5042
Bartosz Markowski707a0c82015-09-02 13:20:19 +02005043 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305044 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
5045 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02005046 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305047
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02005048 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305049 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
5050 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02005051 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305052
5053 if (!value)
5054 return 0;
5055
5056 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
5057 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
5058
5059 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
5060 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
5061 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
5062
5063 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
5064 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
5065
5066 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
5067 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
5068 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
5069
5070 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
5071 ar->wmi.vdev_param->txbf, value);
5072}
5073
Kalle Valo5e3dd152013-06-12 20:52:10 +03005074/*
5075 * TODO:
5076 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
5077 * because we will send mgmt frames without CCK. This requirement
5078 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
5079 * in the TX packet.
5080 */
5081static int ath10k_add_interface(struct ieee80211_hw *hw,
5082 struct ieee80211_vif *vif)
5083{
5084 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005085 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005086 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005087 enum wmi_sta_powersave_param param;
5088 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02005089 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005090 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00005091 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005092 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005093
Johannes Berg848955c2014-11-11 12:48:42 +01005094 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
5095
Kalle Valo5e3dd152013-06-12 20:52:10 +03005096 mutex_lock(&ar->conf_mutex);
5097
Michal Kazior0dbd09e2013-07-31 10:55:14 +02005098 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02005099 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02005100
Kalle Valo5e3dd152013-06-12 20:52:10 +03005101 arvif->ar = ar;
5102 arvif->vif = vif;
5103
Ben Greeare63b33f2013-10-22 14:54:14 -07005104 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02005105 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005106 INIT_DELAYED_WORK(&arvif->connection_loss_work,
5107 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03005108
Michal Kazior45c9abc2015-04-21 20:42:58 +03005109 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
5110 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
5111 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
5112 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
5113 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
5114 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
5115 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005116
Michal Kaziore04cafb2015-08-05 12:15:24 +02005117 if (ar->num_peers >= ar->max_num_peers) {
5118 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02005119 ret = -ENOBUFS;
5120 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02005121 }
5122
Ben Greeara9aefb32014-08-12 11:02:19 +03005123 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005124 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03005125 ret = -EBUSY;
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005126 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005127 }
Ben Greear16c11172014-09-23 14:17:16 -07005128 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005129
Ben Greear16c11172014-09-23 14:17:16 -07005130 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
5131 bit, ar->free_vdev_map);
5132
5133 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08005134 arvif->vdev_subtype =
5135 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005136
Kalle Valo5e3dd152013-06-12 20:52:10 +03005137 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01005138 case NL80211_IFTYPE_P2P_DEVICE:
5139 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08005140 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5141 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01005142 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005143 case NL80211_IFTYPE_UNSPECIFIED:
5144 case NL80211_IFTYPE_STATION:
5145 arvif->vdev_type = WMI_VDEV_TYPE_STA;
5146 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08005147 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5148 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005149 break;
5150 case NL80211_IFTYPE_ADHOC:
5151 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
5152 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005153 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08005154 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08005155 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5156 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08005157 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005158 ret = -EINVAL;
5159 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
5160 goto err;
5161 }
5162 arvif->vdev_type = WMI_VDEV_TYPE_AP;
5163 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005164 case NL80211_IFTYPE_AP:
5165 arvif->vdev_type = WMI_VDEV_TYPE_AP;
5166
5167 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08005168 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5169 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005170 break;
5171 case NL80211_IFTYPE_MONITOR:
5172 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
5173 break;
5174 default:
5175 WARN_ON(1);
5176 break;
5177 }
5178
Michal Kazior96d828d2015-03-31 10:26:23 +00005179 /* Using vdev_id as queue number will make it very easy to do per-vif
5180 * tx queue locking. This shouldn't wrap due to interface combinations
5181 * but do a modulo for correctness sake and prevent using offchannel tx
5182 * queues for regular vif tx.
5183 */
5184 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
5185 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
5186 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
5187
Michal Kazior64badcb2014-09-18 11:18:02 +03005188 /* Some firmware revisions don't wait for beacon tx completion before
5189 * sending another SWBA event. This could lead to hardware using old
5190 * (freed) beacon data in some cases, e.g. tx credit starvation
5191 * combined with missed TBTT. This is very very rare.
5192 *
5193 * On non-IOMMU-enabled hosts this could be a possible security issue
5194 * because hw could beacon some random data on the air. On
5195 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
5196 * device would crash.
5197 *
5198 * Since there are no beacon tx completions (implicit nor explicit)
5199 * propagated to host the only workaround for this is to allocate a
5200 * DMA-coherent buffer for a lifetime of a vif and use it for all
5201 * beacon tx commands. Worst case for this approach is some beacons may
5202 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
5203 */
5204 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005205 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03005206 vif->type == NL80211_IFTYPE_AP) {
Luis Chamberlain750afb02019-01-04 09:23:09 +01005207 arvif->beacon_buf = dma_alloc_coherent(ar->dev,
5208 IEEE80211_MAX_FRAME_LEN,
5209 &arvif->beacon_paddr,
5210 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03005211 if (!arvif->beacon_buf) {
5212 ret = -ENOMEM;
5213 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
5214 ret);
5215 goto err;
5216 }
5217 }
David Liuccec9032015-07-24 20:25:32 +03005218 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
5219 arvif->nohwcrypt = true;
5220
5221 if (arvif->nohwcrypt &&
5222 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
5223 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
5224 goto err;
5225 }
Michal Kazior64badcb2014-09-18 11:18:02 +03005226
5227 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
5228 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
5229 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03005230
5231 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
5232 arvif->vdev_subtype, vif->addr);
5233 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005234 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005235 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005236 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005237 }
5238
Sathishkumar Muruganandam68c295f2018-12-20 09:53:30 +02005239 if (test_bit(WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,
5240 ar->wmi.svc_map)) {
5241 vdev_param = ar->wmi.vdev_param->disable_4addr_src_lrn;
5242 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5243 WMI_VDEV_DISABLE_4_ADDR_SRC_LRN);
5244 if (ret && ret != -EOPNOTSUPP) {
5245 ath10k_warn(ar, "failed to disable 4addr src lrn vdev %i: %d\n",
5246 arvif->vdev_id, ret);
5247 }
5248 }
5249
Ben Greear16c11172014-09-23 14:17:16 -07005250 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305251 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005252 list_add(&arvif->list, &ar->arvifs);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305253 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005254
Michal Kazior46725b152015-01-28 09:57:49 +02005255 /* It makes no sense to have firmware do keepalives. mac80211 already
5256 * takes care of this with idle connection polling.
5257 */
5258 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005259 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02005260 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005261 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005262 goto err_vdev_delete;
5263 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005264
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005265 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005266
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005267 vdev_param = ar->wmi.vdev_param->tx_encap_type;
5268 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005269 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02005270 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005271 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005272 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005273 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005274 goto err_vdev_delete;
5275 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005276
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05305277 /* Configuring number of spatial stream for monitor interface is causing
5278 * target assert in qca9888 and qca6174.
5279 */
5280 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02005281 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
5282
5283 vdev_param = ar->wmi.vdev_param->nss;
5284 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5285 nss);
5286 if (ret) {
5287 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
5288 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
5289 ret);
5290 goto err_vdev_delete;
5291 }
5292 }
5293
Michal Kaziore57e0572015-03-24 13:14:03 +00005294 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5295 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02005296 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
5297 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005298 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00005299 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005300 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005301 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005302 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005303
5304 spin_lock_bh(&ar->data_lock);
5305
5306 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
5307 if (!peer) {
5308 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5309 vif->addr, arvif->vdev_id);
5310 spin_unlock_bh(&ar->data_lock);
5311 ret = -ENOENT;
5312 goto err_peer_delete;
5313 }
5314
5315 arvif->peer_id = find_first_bit(peer->peer_ids,
5316 ATH10K_MAX_NUM_PEER_IDS);
5317
5318 spin_unlock_bh(&ar->data_lock);
5319 } else {
5320 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00005321 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01005322
Michal Kaziore57e0572015-03-24 13:14:03 +00005323 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02005324 ret = ath10k_mac_set_kickout(arvif);
5325 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005326 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005327 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02005328 goto err_peer_delete;
5329 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005330 }
5331
5332 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
5333 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
5334 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5335 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5336 param, value);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005337 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005338 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005339 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005340 goto err_peer_delete;
5341 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005342
Michal Kazior9f9b5742014-12-12 12:41:36 +01005343 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005344 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005345 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005346 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005347 goto err_peer_delete;
5348 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005349
Michal Kazior9f9b5742014-12-12 12:41:36 +01005350 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005351 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005352 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005353 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005354 goto err_peer_delete;
5355 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005356 }
5357
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305358 ret = ath10k_mac_set_txbf_conf(arvif);
5359 if (ret) {
5360 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
5361 arvif->vdev_id, ret);
5362 goto err_peer_delete;
5363 }
5364
Michal Kazior424121c2013-07-22 14:13:31 +02005365 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005366 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005367 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03005368 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005369 goto err_peer_delete;
5370 }
Michal Kazior679c54a2013-07-05 16:15:04 +03005371
Michal Kazior7d9d5582014-10-21 10:40:15 +03005372 arvif->txpower = vif->bss_conf.txpower;
5373 ret = ath10k_mac_txpower_recalc(ar);
5374 if (ret) {
5375 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5376 goto err_peer_delete;
5377 }
5378
Pradeep Kumar Chitrapu059104b2019-02-11 18:47:54 +02005379 if (test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map)) {
5380 vdev_param = ar->wmi.vdev_param->rtt_responder_role;
5381 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5382 arvif->ftm_responder);
5383
5384 /* It is harmless to not set FTM role. Do not warn */
5385 if (ret && ret != -EOPNOTSUPP)
5386 ath10k_warn(ar, "failed to set vdev %i FTM Responder: %d\n",
5387 arvif->vdev_id, ret);
5388 }
5389
Michal Kazior500ff9f2015-03-31 10:26:21 +00005390 if (vif->type == NL80211_IFTYPE_MONITOR) {
5391 ar->monitor_arvif = arvif;
5392 ret = ath10k_monitor_recalc(ar);
5393 if (ret) {
5394 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5395 goto err_peer_delete;
5396 }
5397 }
5398
Michal Kazior6d2d51e2015-08-07 09:08:21 +02005399 spin_lock_bh(&ar->htt.tx_lock);
5400 if (!ar->tx_paused)
5401 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
5402 spin_unlock_bh(&ar->htt.tx_lock);
5403
Kalle Valo5e3dd152013-06-12 20:52:10 +03005404 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005405 return 0;
5406
5407err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00005408 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5409 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005410 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
5411
5412err_vdev_delete:
5413 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07005414 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305415 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005416 list_del(&arvif->list);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305417 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005418
5419err:
Michal Kazior64badcb2014-09-18 11:18:02 +03005420 if (arvif->beacon_buf) {
5421 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
5422 arvif->beacon_buf, arvif->beacon_paddr);
5423 arvif->beacon_buf = NULL;
5424 }
5425
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005426 mutex_unlock(&ar->conf_mutex);
5427
Kalle Valo5e3dd152013-06-12 20:52:10 +03005428 return ret;
5429}
5430
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005431static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
5432{
5433 int i;
5434
5435 for (i = 0; i < BITS_PER_LONG; i++)
5436 ath10k_mac_vif_tx_unlock(arvif, i);
5437}
5438
Kalle Valo5e3dd152013-06-12 20:52:10 +03005439static void ath10k_remove_interface(struct ieee80211_hw *hw,
5440 struct ieee80211_vif *vif)
5441{
5442 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005443 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior69427262016-03-06 16:14:30 +02005444 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005445 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005446 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005447
Michal Kazior81a9a172015-03-05 16:02:17 +02005448 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005449 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005450
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305451 mutex_lock(&ar->conf_mutex);
5452
Michal Kaziored543882013-09-13 14:16:56 +02005453 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03005454 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02005455 spin_unlock_bh(&ar->data_lock);
5456
Simon Wunderlich855aed12014-08-02 09:12:54 +03005457 ret = ath10k_spectral_vif_stop(arvif);
5458 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005459 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005460 arvif->vdev_id, ret);
5461
Ben Greear16c11172014-09-23 14:17:16 -07005462 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305463 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005464 list_del(&arvif->list);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305465 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005466
Michal Kaziore57e0572015-03-24 13:14:03 +00005467 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5468 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005469 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5470 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005471 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005472 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005473 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005474
5475 kfree(arvif->u.ap.noa_data);
5476 }
5477
Michal Kazior7aa7a722014-08-25 12:09:38 +02005478 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005479 arvif->vdev_id);
5480
Kalle Valo5e3dd152013-06-12 20:52:10 +03005481 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5482 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005483 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005484 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005485
Michal Kazior2c512052015-02-15 16:50:40 +02005486 /* Some firmware revisions don't notify host about self-peer removal
5487 * until after associated vdev is deleted.
5488 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005489 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5490 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005491 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5492 vif->addr);
5493 if (ret)
5494 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5495 arvif->vdev_id, ret);
5496
5497 spin_lock_bh(&ar->data_lock);
5498 ar->num_peers--;
5499 spin_unlock_bh(&ar->data_lock);
5500 }
5501
Michal Kazior69427262016-03-06 16:14:30 +02005502 spin_lock_bh(&ar->data_lock);
5503 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5504 peer = ar->peer_map[i];
5505 if (!peer)
5506 continue;
5507
5508 if (peer->vif == vif) {
5509 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5510 vif->addr, arvif->vdev_id);
5511 peer->vif = NULL;
5512 }
5513 }
5514 spin_unlock_bh(&ar->data_lock);
5515
Kalle Valo5e3dd152013-06-12 20:52:10 +03005516 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005517 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005518
Michal Kazior500ff9f2015-03-31 10:26:21 +00005519 if (vif->type == NL80211_IFTYPE_MONITOR) {
5520 ar->monitor_arvif = NULL;
5521 ret = ath10k_monitor_recalc(ar);
5522 if (ret)
5523 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5524 }
5525
Ryan Hsud679fa12016-12-22 14:31:46 -08005526 ret = ath10k_mac_txpower_recalc(ar);
5527 if (ret)
5528 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5529
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005530 spin_lock_bh(&ar->htt.tx_lock);
5531 ath10k_mac_vif_tx_unlock_all(arvif);
5532 spin_unlock_bh(&ar->htt.tx_lock);
5533
Michal Kazior29946872016-03-06 16:14:34 +02005534 ath10k_mac_txq_unref(ar, vif->txq);
5535
Kalle Valo5e3dd152013-06-12 20:52:10 +03005536 mutex_unlock(&ar->conf_mutex);
5537}
5538
5539/*
5540 * FIXME: Has to be verified.
5541 */
5542#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005543 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005544 FIF_CONTROL | \
5545 FIF_PSPOLL | \
5546 FIF_OTHER_BSS | \
5547 FIF_BCN_PRBRESP_PROMISC | \
5548 FIF_PROBE_REQ | \
5549 FIF_FCSFAIL)
5550
5551static void ath10k_configure_filter(struct ieee80211_hw *hw,
5552 unsigned int changed_flags,
5553 unsigned int *total_flags,
5554 u64 multicast)
5555{
5556 struct ath10k *ar = hw->priv;
5557 int ret;
5558
5559 mutex_lock(&ar->conf_mutex);
5560
5561 changed_flags &= SUPPORTED_FILTERS;
5562 *total_flags &= SUPPORTED_FILTERS;
5563 ar->filter_flags = *total_flags;
5564
Michal Kazior19337472014-08-28 12:58:16 +02005565 ret = ath10k_monitor_recalc(ar);
5566 if (ret)
Colin Ian King7f03d302016-08-26 19:08:52 +01005567 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005568
5569 mutex_unlock(&ar->conf_mutex);
5570}
5571
5572static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5573 struct ieee80211_vif *vif,
5574 struct ieee80211_bss_conf *info,
5575 u32 changed)
5576{
5577 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005578 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005579 struct cfg80211_chan_def def;
Kalle Valoaf762c02014-09-14 12:50:17 +03005580 u32 vdev_param, pdev_param, slottime, preamble;
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005581 u16 bitrate, hw_value;
Sriram Rf279294e2018-09-10 11:09:40 +05305582 u8 rate, basic_rate_idx;
5583 int rateidx, ret = 0, hw_rate_code;
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005584 enum nl80211_band band;
Sriram Rf279294e2018-09-10 11:09:40 +05305585 const struct ieee80211_supported_band *sband;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005586
5587 mutex_lock(&ar->conf_mutex);
5588
5589 if (changed & BSS_CHANGED_IBSS)
5590 ath10k_control_ibss(arvif, info, vif->addr);
5591
5592 if (changed & BSS_CHANGED_BEACON_INT) {
5593 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005594 vdev_param = ar->wmi.vdev_param->beacon_interval;
5595 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005596 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005597 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005598 "mac vdev %d beacon_interval %d\n",
5599 arvif->vdev_id, arvif->beacon_interval);
5600
Kalle Valo5e3dd152013-06-12 20:52:10 +03005601 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005602 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005603 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005604 }
5605
5606 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005607 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005608 "vdev %d set beacon tx mode to staggered\n",
5609 arvif->vdev_id);
5610
Bartosz Markowski226a3392013-09-26 17:47:16 +02005611 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5612 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005613 WMI_BEACON_STAGGERED_MODE);
5614 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005615 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005616 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005617
5618 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5619 if (ret)
5620 ath10k_warn(ar, "failed to update beacon template: %d\n",
5621 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005622
5623 if (ieee80211_vif_is_mesh(vif)) {
5624 /* mesh doesn't use SSID but firmware needs it */
5625 strncpy(arvif->u.ap.ssid, "mesh",
5626 sizeof(arvif->u.ap.ssid));
5627 arvif->u.ap.ssid_len = 4;
5628 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005629 }
5630
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005631 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5632 ret = ath10k_mac_setup_prb_tmpl(arvif);
5633 if (ret)
5634 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5635 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005636 }
5637
Michal Kaziorba2479f2015-01-24 12:14:51 +02005638 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005639 arvif->dtim_period = info->dtim_period;
5640
Michal Kazior7aa7a722014-08-25 12:09:38 +02005641 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005642 "mac vdev %d dtim_period %d\n",
5643 arvif->vdev_id, arvif->dtim_period);
5644
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005645 vdev_param = ar->wmi.vdev_param->dtim_period;
5646 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005647 arvif->dtim_period);
5648 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005649 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005650 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005651 }
5652
5653 if (changed & BSS_CHANGED_SSID &&
5654 vif->type == NL80211_IFTYPE_AP) {
5655 arvif->u.ap.ssid_len = info->ssid_len;
5656 if (info->ssid_len)
5657 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5658 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5659 }
5660
Michal Kazior077efc82014-10-21 10:10:29 +03005661 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5662 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005663
Pradeep Kumar Chitrapu059104b2019-02-11 18:47:54 +02005664 if (changed & BSS_CHANGED_FTM_RESPONDER &&
5665 arvif->ftm_responder != info->ftm_responder &&
5666 test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map)) {
5667 arvif->ftm_responder = info->ftm_responder;
5668
5669 vdev_param = ar->wmi.vdev_param->rtt_responder_role;
5670 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5671 arvif->ftm_responder);
5672
5673 ath10k_dbg(ar, ATH10K_DBG_MAC,
5674 "mac vdev %d ftm_responder %d:ret %d\n",
5675 arvif->vdev_id, arvif->ftm_responder, ret);
5676 }
5677
Kalle Valo5e3dd152013-06-12 20:52:10 +03005678 if (changed & BSS_CHANGED_BEACON_ENABLED)
5679 ath10k_control_beaconing(arvif, info);
5680
5681 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005682 arvif->use_cts_prot = info->use_cts_prot;
Kalle Valo60c3daa2013-09-08 17:56:07 +03005683
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005684 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005685 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005686 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005687 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005688
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02005689 if (ath10k_mac_can_set_cts_prot(arvif)) {
5690 ret = ath10k_mac_set_cts_prot(arvif);
5691 if (ret)
5692 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
5693 arvif->vdev_id, ret);
5694 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005695 }
5696
5697 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005698 if (info->use_short_slot)
5699 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5700
5701 else
5702 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5703
Michal Kazior7aa7a722014-08-25 12:09:38 +02005704 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005705 arvif->vdev_id, slottime);
5706
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005707 vdev_param = ar->wmi.vdev_param->slot_time;
5708 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005709 slottime);
5710 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005711 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005712 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005713 }
5714
5715 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005716 if (info->use_short_preamble)
5717 preamble = WMI_VDEV_PREAMBLE_SHORT;
5718 else
5719 preamble = WMI_VDEV_PREAMBLE_LONG;
5720
Michal Kazior7aa7a722014-08-25 12:09:38 +02005721 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005722 "mac vdev %d preamble %dn",
5723 arvif->vdev_id, preamble);
5724
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005725 vdev_param = ar->wmi.vdev_param->preamble;
5726 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005727 preamble);
5728 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005729 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005730 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005731 }
5732
5733 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005734 if (info->assoc) {
5735 /* Workaround: Make sure monitor vdev is not running
5736 * when associating to prevent some firmware revisions
5737 * (e.g. 10.1 and 10.2) from crashing.
5738 */
5739 if (ar->monitor_started)
5740 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005741 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005742 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005743 } else {
5744 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005745 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005746 }
5747
Michal Kazior7d9d5582014-10-21 10:40:15 +03005748 if (changed & BSS_CHANGED_TXPOWER) {
5749 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5750 arvif->vdev_id, info->txpower);
5751
5752 arvif->txpower = info->txpower;
5753 ret = ath10k_mac_txpower_recalc(ar);
5754 if (ret)
5755 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5756 }
5757
Michal Kaziorbf14e652014-12-12 12:41:38 +01005758 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005759 arvif->ps = vif->bss_conf.ps;
5760
5761 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005762 if (ret)
5763 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5764 arvif->vdev_id, ret);
5765 }
5766
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005767 if (changed & BSS_CHANGED_MCAST_RATE &&
5768 !WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def))) {
5769 band = def.chan->band;
5770 rateidx = vif->bss_conf.mcast_rate[band] - 1;
5771
5772 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
5773 rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
5774
5775 bitrate = ath10k_wmi_legacy_rates[rateidx].bitrate;
5776 hw_value = ath10k_wmi_legacy_rates[rateidx].hw_value;
5777 if (ath10k_mac_bitrate_is_cck(bitrate))
5778 preamble = WMI_RATE_PREAMBLE_CCK;
5779 else
5780 preamble = WMI_RATE_PREAMBLE_OFDM;
5781
5782 rate = ATH10K_HW_RATECODE(hw_value, 0, preamble);
5783
5784 ath10k_dbg(ar, ATH10K_DBG_MAC,
5785 "mac vdev %d mcast_rate %x\n",
5786 arvif->vdev_id, rate);
5787
5788 vdev_param = ar->wmi.vdev_param->mcast_data_rate;
5789 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
5790 vdev_param, rate);
5791 if (ret)
5792 ath10k_warn(ar,
5793 "failed to set mcast rate on vdev %i: %d\n",
5794 arvif->vdev_id, ret);
5795
5796 vdev_param = ar->wmi.vdev_param->bcast_data_rate;
5797 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
5798 vdev_param, rate);
5799 if (ret)
5800 ath10k_warn(ar,
5801 "failed to set bcast rate on vdev %i: %d\n",
5802 arvif->vdev_id, ret);
5803 }
5804
Sriram Rf279294e2018-09-10 11:09:40 +05305805 if (changed & BSS_CHANGED_BASIC_RATES) {
5806 if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) {
5807 mutex_unlock(&ar->conf_mutex);
5808 return;
5809 }
5810
Sriram R34e141e2018-10-03 08:43:50 +05305811 sband = ar->hw->wiphy->bands[def.chan->band];
5812 basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
5813 bitrate = sband->bitrates[basic_rate_idx].bitrate;
Sriram Rf279294e2018-09-10 11:09:40 +05305814
Sriram R34e141e2018-10-03 08:43:50 +05305815 hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
5816 if (hw_rate_code < 0) {
5817 ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
5818 mutex_unlock(&ar->conf_mutex);
5819 return;
5820 }
Sriram Rf279294e2018-09-10 11:09:40 +05305821
Sriram R34e141e2018-10-03 08:43:50 +05305822 vdev_param = ar->wmi.vdev_param->mgmt_rate;
5823 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5824 hw_rate_code);
5825 if (ret)
5826 ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
Sriram Rf279294e2018-09-10 11:09:40 +05305827 }
5828
Kalle Valo5e3dd152013-06-12 20:52:10 +03005829 mutex_unlock(&ar->conf_mutex);
5830}
5831
Benjamin Bergebee76f2016-09-28 15:11:58 +03005832static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, s16 value)
5833{
5834 struct ath10k *ar = hw->priv;
5835
5836 /* This function should never be called if setting the coverage class
5837 * is not supported on this hardware.
5838 */
5839 if (!ar->hw_params.hw_ops->set_coverage_class) {
5840 WARN_ON_ONCE(1);
5841 return;
5842 }
5843 ar->hw_params.hw_ops->set_coverage_class(ar, value);
5844}
5845
Anilkumar Kollidd0f9cd2017-10-27 11:12:27 +03005846struct ath10k_mac_tdls_iter_data {
5847 u32 num_tdls_stations;
5848 struct ieee80211_vif *curr_vif;
5849};
5850
5851static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5852 struct ieee80211_sta *sta)
5853{
5854 struct ath10k_mac_tdls_iter_data *iter_data = data;
5855 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5856 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5857
5858 if (sta->tdls && sta_vif == iter_data->curr_vif)
5859 iter_data->num_tdls_stations++;
5860}
5861
5862static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5863 struct ieee80211_vif *vif)
5864{
5865 struct ath10k_mac_tdls_iter_data data = {};
5866
5867 data.curr_vif = vif;
5868
5869 ieee80211_iterate_stations_atomic(hw,
5870 ath10k_mac_tdls_vif_stations_count_iter,
5871 &data);
5872 return data.num_tdls_stations;
5873}
5874
Kalle Valo5e3dd152013-06-12 20:52:10 +03005875static int ath10k_hw_scan(struct ieee80211_hw *hw,
5876 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005877 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005878{
5879 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005880 struct ath10k_vif *arvif = (void *)vif->drv_priv;
David Spinadelc56ef672014-02-05 15:21:13 +02005881 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005882 struct wmi_start_scan_arg arg;
5883 int ret = 0;
5884 int i;
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03005885 u32 scan_timeout;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005886
5887 mutex_lock(&ar->conf_mutex);
5888
Anilkumar Kollia6080932017-10-27 11:12:28 +03005889 if (ath10k_mac_tdls_vif_stations_count(hw, vif) > 0) {
5890 ret = -EBUSY;
5891 goto exit;
5892 }
5893
Kalle Valo5e3dd152013-06-12 20:52:10 +03005894 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005895 switch (ar->scan.state) {
5896 case ATH10K_SCAN_IDLE:
5897 reinit_completion(&ar->scan.started);
5898 reinit_completion(&ar->scan.completed);
5899 ar->scan.state = ATH10K_SCAN_STARTING;
5900 ar->scan.is_roc = false;
5901 ar->scan.vdev_id = arvif->vdev_id;
5902 ret = 0;
5903 break;
5904 case ATH10K_SCAN_STARTING:
5905 case ATH10K_SCAN_RUNNING:
5906 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005907 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005908 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005909 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005910 spin_unlock_bh(&ar->data_lock);
5911
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005912 if (ret)
5913 goto exit;
5914
Kalle Valo5e3dd152013-06-12 20:52:10 +03005915 memset(&arg, 0, sizeof(arg));
5916 ath10k_wmi_start_scan_init(ar, &arg);
5917 arg.vdev_id = arvif->vdev_id;
5918 arg.scan_id = ATH10K_SCAN_ID;
5919
Kalle Valo5e3dd152013-06-12 20:52:10 +03005920 if (req->ie_len) {
5921 arg.ie_len = req->ie_len;
5922 memcpy(arg.ie, req->ie, arg.ie_len);
5923 }
5924
5925 if (req->n_ssids) {
5926 arg.n_ssids = req->n_ssids;
5927 for (i = 0; i < arg.n_ssids; i++) {
5928 arg.ssids[i].len = req->ssids[i].ssid_len;
5929 arg.ssids[i].ssid = req->ssids[i].ssid;
5930 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005931 } else {
5932 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005933 }
5934
Carl Huang60e1d0f2018-04-19 19:39:40 +03005935 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
5936 arg.scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ;
5937 ether_addr_copy(arg.mac_addr.addr, req->mac_addr);
5938 ether_addr_copy(arg.mac_mask.addr, req->mac_addr_mask);
5939 }
5940
Kalle Valo5e3dd152013-06-12 20:52:10 +03005941 if (req->n_channels) {
5942 arg.n_channels = req->n_channels;
5943 for (i = 0; i < arg.n_channels; i++)
5944 arg.channels[i] = req->channels[i]->center_freq;
5945 }
5946
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03005947 /* if duration is set, default dwell times will be overwritten */
5948 if (req->duration) {
5949 arg.dwell_time_active = req->duration;
5950 arg.dwell_time_passive = req->duration;
5951 arg.burst_duration_ms = req->duration;
5952
5953 scan_timeout = min_t(u32, arg.max_rest_time *
5954 (arg.n_channels - 1) + (req->duration +
5955 ATH10K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) *
5956 arg.n_channels, arg.max_scan_time + 200);
5957
5958 } else {
5959 /* Add a 200ms margin to account for event/command processing */
5960 scan_timeout = arg.max_scan_time + 200;
5961 }
5962
Kalle Valo5e3dd152013-06-12 20:52:10 +03005963 ret = ath10k_start_scan(ar, &arg);
5964 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005965 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005966 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005967 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005968 spin_unlock_bh(&ar->data_lock);
5969 }
5970
Michal Kazior634349b2015-09-03 10:43:45 +02005971 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03005972 msecs_to_jiffies(scan_timeout));
Michal Kazior634349b2015-09-03 10:43:45 +02005973
Kalle Valo5e3dd152013-06-12 20:52:10 +03005974exit:
5975 mutex_unlock(&ar->conf_mutex);
5976 return ret;
5977}
5978
5979static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5980 struct ieee80211_vif *vif)
5981{
5982 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005983
5984 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005985 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005986 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01005987
5988 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005989}
5990
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005991static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
5992 struct ath10k_vif *arvif,
5993 enum set_key_cmd cmd,
5994 struct ieee80211_key_conf *key)
5995{
5996 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
5997 int ret;
5998
5999 /* 10.1 firmware branch requires default key index to be set to group
6000 * key index after installing it. Otherwise FW/HW Txes corrupted
6001 * frames with multi-vif APs. This is not required for main firmware
6002 * branch (e.g. 636).
6003 *
Michal Kazior8461baf2015-04-10 13:23:22 +00006004 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
6005 *
6006 * FIXME: It remains unknown if this is required for multi-vif STA
6007 * interfaces on 10.1.
6008 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006009
Michal Kazior8461baf2015-04-10 13:23:22 +00006010 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
6011 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006012 return;
6013
6014 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
6015 return;
6016
6017 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
6018 return;
6019
6020 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
6021 return;
6022
6023 if (cmd != SET_KEY)
6024 return;
6025
6026 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
6027 key->keyidx);
6028 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006029 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02006030 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006031}
6032
Kalle Valo5e3dd152013-06-12 20:52:10 +03006033static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
6034 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
6035 struct ieee80211_key_conf *key)
6036{
6037 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006038 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006039 struct ath10k_peer *peer;
6040 const u8 *peer_addr;
6041 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
6042 key->cipher == WLAN_CIPHER_SUITE_WEP104;
6043 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00006044 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01006045 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00006046 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006047
Bartosz Markowskid7131c02015-03-10 14:32:19 +01006048 /* this one needs to be done in software */
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07006049 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
6050 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
6051 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 ||
6052 key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)
Bartosz Markowskid7131c02015-03-10 14:32:19 +01006053 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006054
David Liuccec9032015-07-24 20:25:32 +03006055 if (arvif->nohwcrypt)
6056 return 1;
6057
Kalle Valo5e3dd152013-06-12 20:52:10 +03006058 if (key->keyidx > WMI_MAX_KEY_INDEX)
6059 return -ENOSPC;
6060
6061 mutex_lock(&ar->conf_mutex);
6062
6063 if (sta)
6064 peer_addr = sta->addr;
6065 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
6066 peer_addr = vif->bss_conf.bssid;
6067 else
6068 peer_addr = vif->addr;
6069
6070 key->hw_key_idx = key->keyidx;
6071
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03006072 if (is_wep) {
6073 if (cmd == SET_KEY)
6074 arvif->wep_keys[key->keyidx] = key;
6075 else
6076 arvif->wep_keys[key->keyidx] = NULL;
6077 }
6078
Kalle Valo5e3dd152013-06-12 20:52:10 +03006079 /* the peer should not disappear in mid-way (unless FW goes awry) since
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01006080 * we already hold conf_mutex. we just make sure its there now.
6081 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006082 spin_lock_bh(&ar->data_lock);
6083 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
6084 spin_unlock_bh(&ar->data_lock);
6085
6086 if (!peer) {
6087 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006088 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03006089 peer_addr);
6090 ret = -EOPNOTSUPP;
6091 goto exit;
6092 } else {
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01006093 /* if the peer doesn't exist there is no key to disable anymore */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006094 goto exit;
6095 }
6096 }
6097
Michal Kazior7cc45732015-03-09 14:24:17 +01006098 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
6099 flags |= WMI_KEY_PAIRWISE;
6100 else
6101 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006102
Kalle Valo5e3dd152013-06-12 20:52:10 +03006103 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006104 if (cmd == DISABLE_KEY)
6105 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01006106
Michal Kaziorad325cb2015-02-18 14:02:27 +01006107 /* When WEP keys are uploaded it's possible that there are
6108 * stations associated already (e.g. when merging) without any
6109 * keys. Static WEP needs an explicit per-peer key upload.
6110 */
6111 if (vif->type == NL80211_IFTYPE_ADHOC &&
6112 cmd == SET_KEY)
6113 ath10k_mac_vif_update_wep_key(arvif, key);
6114
Michal Kazior370e5672015-02-18 14:02:26 +01006115 /* 802.1x never sets the def_wep_key_idx so each set_key()
6116 * call changes default tx key.
6117 *
6118 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
6119 * after first set_key().
6120 */
6121 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
6122 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006123 }
6124
Michal Kazior370e5672015-02-18 14:02:26 +01006125 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006126 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03006127 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02006128 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02006129 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006130 goto exit;
6131 }
6132
Michal Kazior29a10002015-04-10 13:05:58 +00006133 /* mac80211 sets static WEP keys as groupwise while firmware requires
6134 * them to be installed twice as both pairwise and groupwise.
6135 */
6136 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
6137 flags2 = flags;
6138 flags2 &= ~WMI_KEY_GROUP;
6139 flags2 |= WMI_KEY_PAIRWISE;
6140
6141 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
6142 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03006143 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00006144 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
6145 arvif->vdev_id, peer_addr, ret);
6146 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
6147 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03006148 if (ret2) {
6149 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00006150 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
6151 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03006152 }
Michal Kazior29a10002015-04-10 13:05:58 +00006153 goto exit;
6154 }
6155 }
6156
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006157 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
6158
Kalle Valo5e3dd152013-06-12 20:52:10 +03006159 spin_lock_bh(&ar->data_lock);
6160 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
6161 if (peer && cmd == SET_KEY)
6162 peer->keys[key->keyidx] = key;
6163 else if (peer && cmd == DISABLE_KEY)
6164 peer->keys[key->keyidx] = NULL;
6165 else if (peer == NULL)
6166 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006167 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006168 spin_unlock_bh(&ar->data_lock);
6169
Yingying Tang9cdd0052018-03-28 12:15:35 +03006170 if (sta && sta->tdls)
6171 ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
6172 WMI_PEER_AUTHORIZE, 1);
6173
Kalle Valo5e3dd152013-06-12 20:52:10 +03006174exit:
6175 mutex_unlock(&ar->conf_mutex);
6176 return ret;
6177}
6178
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006179static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
6180 struct ieee80211_vif *vif,
6181 int keyidx)
6182{
6183 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006184 struct ath10k_vif *arvif = (void *)vif->drv_priv;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006185 int ret;
6186
6187 mutex_lock(&arvif->ar->conf_mutex);
6188
6189 if (arvif->ar->state != ATH10K_STATE_ON)
6190 goto unlock;
6191
6192 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
6193 arvif->vdev_id, keyidx);
6194
6195 ret = ath10k_wmi_vdev_set_param(arvif->ar,
6196 arvif->vdev_id,
6197 arvif->ar->wmi.vdev_param->def_keyid,
6198 keyidx);
6199
6200 if (ret) {
6201 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
6202 arvif->vdev_id,
6203 ret);
6204 goto unlock;
6205 }
6206
6207 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01006208
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006209unlock:
6210 mutex_unlock(&arvif->ar->conf_mutex);
6211}
6212
Michal Kazior9797feb2014-02-14 14:49:48 +01006213static void ath10k_sta_rc_update_wk(struct work_struct *wk)
6214{
6215 struct ath10k *ar;
6216 struct ath10k_vif *arvif;
6217 struct ath10k_sta *arsta;
6218 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006219 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02006220 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006221 const u8 *ht_mcs_mask;
6222 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01006223 u32 changed, bw, nss, smps;
6224 int err;
6225
6226 arsta = container_of(wk, struct ath10k_sta, update_wk);
6227 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
6228 arvif = arsta->arvif;
6229 ar = arvif->ar;
6230
Michal Kazior45c9abc2015-04-21 20:42:58 +03006231 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
6232 return;
6233
6234 band = def.chan->band;
6235 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
6236 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
6237
Michal Kazior9797feb2014-02-14 14:49:48 +01006238 spin_lock_bh(&ar->data_lock);
6239
6240 changed = arsta->changed;
6241 arsta->changed = 0;
6242
6243 bw = arsta->bw;
6244 nss = arsta->nss;
6245 smps = arsta->smps;
6246
6247 spin_unlock_bh(&ar->data_lock);
6248
6249 mutex_lock(&ar->conf_mutex);
6250
Michal Kazior45c9abc2015-04-21 20:42:58 +03006251 nss = max_t(u32, 1, nss);
6252 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6253 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6254
Michal Kazior9797feb2014-02-14 14:49:48 +01006255 if (changed & IEEE80211_RC_BW_CHANGED) {
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006256 enum wmi_phy_mode mode;
6257
6258 mode = chan_to_phymode(&def);
6259 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d phymode %d\n",
Kalle Valoebfac1d2018-07-30 21:56:43 +03006260 sta->addr, bw, mode);
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006261
6262 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
Kalle Valoebfac1d2018-07-30 21:56:43 +03006263 WMI_PEER_PHYMODE, mode);
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006264 if (err) {
6265 ath10k_warn(ar, "failed to update STA %pM peer phymode %d: %d\n",
Kalle Valoebfac1d2018-07-30 21:56:43 +03006266 sta->addr, mode, err);
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006267 goto exit;
6268 }
Michal Kazior9797feb2014-02-14 14:49:48 +01006269
6270 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
6271 WMI_PEER_CHAN_WIDTH, bw);
6272 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006273 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006274 sta->addr, bw, err);
6275 }
6276
6277 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006278 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006279 sta->addr, nss);
6280
6281 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
6282 WMI_PEER_NSS, nss);
6283 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006284 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006285 sta->addr, nss, err);
6286 }
6287
6288 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006289 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006290 sta->addr, smps);
6291
6292 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
6293 WMI_PEER_SMPS_STATE, smps);
6294 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006295 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006296 sta->addr, smps, err);
6297 }
6298
Karthikeyan Periyasamy55cc11d2018-03-27 11:25:29 +03006299 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
6300 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006301 sta->addr);
6302
Michal Kazior590922a2014-10-21 10:10:29 +03006303 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006304 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006305 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006306 sta->addr);
6307 }
6308
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006309exit:
Michal Kazior9797feb2014-02-14 14:49:48 +01006310 mutex_unlock(&ar->conf_mutex);
6311}
6312
Marek Puzyniak7c354242015-03-30 09:51:52 +03006313static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
6314 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006315{
6316 struct ath10k *ar = arvif->ar;
6317
6318 lockdep_assert_held(&ar->conf_mutex);
6319
Marek Puzyniak7c354242015-03-30 09:51:52 +03006320 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006321 return 0;
6322
6323 if (ar->num_stations >= ar->max_num_stations)
6324 return -ENOBUFS;
6325
6326 ar->num_stations++;
6327
6328 return 0;
6329}
6330
Marek Puzyniak7c354242015-03-30 09:51:52 +03006331static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
6332 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006333{
6334 struct ath10k *ar = arvif->ar;
6335
6336 lockdep_assert_held(&ar->conf_mutex);
6337
Marek Puzyniak7c354242015-03-30 09:51:52 +03006338 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006339 return;
6340
6341 ar->num_stations--;
6342}
6343
Kalle Valo5e3dd152013-06-12 20:52:10 +03006344static int ath10k_sta_state(struct ieee80211_hw *hw,
6345 struct ieee80211_vif *vif,
6346 struct ieee80211_sta *sta,
6347 enum ieee80211_sta_state old_state,
6348 enum ieee80211_sta_state new_state)
6349{
6350 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006351 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior9797feb2014-02-14 14:49:48 +01006352 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006353 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006354 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02006355 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006356
Michal Kazior76f90022014-02-25 09:29:57 +02006357 if (old_state == IEEE80211_STA_NOTEXIST &&
6358 new_state == IEEE80211_STA_NONE) {
6359 memset(arsta, 0, sizeof(*arsta));
6360 arsta->arvif = arvif;
Maharaja Kennadyrajand70c0d42018-09-18 12:04:27 +05306361 arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
Michal Kazior76f90022014-02-25 09:29:57 +02006362 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02006363
6364 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6365 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02006366 }
6367
Michal Kazior9797feb2014-02-14 14:49:48 +01006368 /* cancel must be done outside the mutex to avoid deadlock */
6369 if ((old_state == IEEE80211_STA_NONE &&
6370 new_state == IEEE80211_STA_NOTEXIST))
6371 cancel_work_sync(&arsta->update_wk);
6372
Kalle Valo5e3dd152013-06-12 20:52:10 +03006373 mutex_lock(&ar->conf_mutex);
6374
6375 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03006376 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006377 /*
6378 * New station addition.
6379 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006380 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
6381 u32 num_tdls_stations;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006382
Michal Kaziorcfd10612014-11-25 15:16:05 +01006383 ath10k_dbg(ar, ATH10K_DBG_MAC,
6384 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
6385 arvif->vdev_id, sta->addr,
6386 ar->num_stations + 1, ar->max_num_stations,
6387 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006388
Ryan Hsu9a993cc2017-05-31 14:21:28 +03006389 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
Ryan Hsu9a993cc2017-05-31 14:21:28 +03006390
6391 if (sta->tdls) {
6392 if (num_tdls_stations >= ar->max_num_tdls_vdevs) {
6393 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
6394 arvif->vdev_id,
6395 ar->max_num_tdls_vdevs);
6396 ret = -ELNRNG;
6397 goto exit;
6398 }
6399 peer_type = WMI_PEER_TYPE_TDLS;
6400 }
6401
Marek Puzyniak7c354242015-03-30 09:51:52 +03006402 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01006403 if (ret) {
6404 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
6405 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006406 goto exit;
6407 }
6408
Zhi Chen386f97e2018-12-20 14:25:18 +02006409 if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {
6410 arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats),
6411 GFP_KERNEL);
6412 if (!arsta->tx_stats) {
6413 ret = -ENOMEM;
6414 goto exit;
6415 }
6416 }
6417
Michal Kazior69427262016-03-06 16:14:30 +02006418 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
6419 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01006420 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006421 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 -08006422 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03006423 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006424 kfree(arsta->tx_stats);
Michal Kaziora52c0282014-11-25 15:16:03 +01006425 goto exit;
6426 }
Michal Kazior077efc82014-10-21 10:10:29 +03006427
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006428 spin_lock_bh(&ar->data_lock);
6429
6430 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
6431 if (!peer) {
6432 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
6433 vif->addr, arvif->vdev_id);
6434 spin_unlock_bh(&ar->data_lock);
6435 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6436 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006437 kfree(arsta->tx_stats);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006438 ret = -ENOENT;
6439 goto exit;
6440 }
6441
6442 arsta->peer_id = find_first_bit(peer->peer_ids,
6443 ATH10K_MAX_NUM_PEER_IDS);
6444
6445 spin_unlock_bh(&ar->data_lock);
6446
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006447 if (!sta->tdls)
6448 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03006449
Ryan Hsu9a993cc2017-05-31 14:21:28 +03006450 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6451 WMI_TDLS_ENABLE_ACTIVE);
6452 if (ret) {
6453 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6454 arvif->vdev_id, ret);
6455 ath10k_peer_delete(ar, arvif->vdev_id,
6456 sta->addr);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006457 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006458 kfree(arsta->tx_stats);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006459 goto exit;
6460 }
6461
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006462 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6463 WMI_TDLS_PEER_STATE_PEERING);
6464 if (ret) {
6465 ath10k_warn(ar,
6466 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
6467 sta->addr, arvif->vdev_id, ret);
6468 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6469 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006470 kfree(arsta->tx_stats);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006471
6472 if (num_tdls_stations != 0)
6473 goto exit;
6474 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6475 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03006476 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006477 } else if ((old_state == IEEE80211_STA_NONE &&
6478 new_state == IEEE80211_STA_NOTEXIST)) {
6479 /*
6480 * Existing station deletion.
6481 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006482 ath10k_dbg(ar, ATH10K_DBG_MAC,
Ben Greear30404202016-08-18 18:26:35 -07006483 "mac vdev %d peer delete %pM sta %pK (sta gone)\n",
6484 arvif->vdev_id, sta->addr, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006485
Manikanta Pubbisetty424ea0d2017-11-06 13:39:31 +05306486 if (sta->tdls) {
6487 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id,
6488 sta,
6489 WMI_TDLS_PEER_STATE_TEARDOWN);
6490 if (ret)
6491 ath10k_warn(ar, "failed to update tdls peer state for %pM state %d: %i\n",
6492 sta->addr,
6493 WMI_TDLS_PEER_STATE_TEARDOWN, ret);
6494 }
6495
Kalle Valo5e3dd152013-06-12 20:52:10 +03006496 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6497 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006498 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006499 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006500
Marek Puzyniak7c354242015-03-30 09:51:52 +03006501 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006502
Michal Kazior69427262016-03-06 16:14:30 +02006503 spin_lock_bh(&ar->data_lock);
6504 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
6505 peer = ar->peer_map[i];
6506 if (!peer)
6507 continue;
6508
6509 if (peer->sta == sta) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05306510 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 +03006511 sta->addr, peer, i, arvif->vdev_id);
Michal Kazior69427262016-03-06 16:14:30 +02006512 peer->sta = NULL;
Ben Greeard0eeafa2016-06-30 15:23:59 +03006513
6514 /* Clean up the peer object as well since we
6515 * must have failed to do this above.
6516 */
6517 list_del(&peer->list);
6518 ar->peer_map[i] = NULL;
6519 kfree(peer);
6520 ar->num_peers--;
Michal Kazior69427262016-03-06 16:14:30 +02006521 }
6522 }
6523 spin_unlock_bh(&ar->data_lock);
6524
Karthikeyan Periyasamy553a7cc2018-12-20 09:53:17 +02006525 if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {
6526 kfree(arsta->tx_stats);
6527 arsta->tx_stats = NULL;
6528 }
6529
Michal Kazior29946872016-03-06 16:14:34 +02006530 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6531 ath10k_mac_txq_unref(ar, sta->txq[i]);
6532
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006533 if (!sta->tdls)
6534 goto exit;
6535
6536 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
6537 goto exit;
6538
6539 /* This was the last tdls peer in current vif */
6540 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6541 WMI_TDLS_DISABLE);
6542 if (ret) {
6543 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6544 arvif->vdev_id, ret);
6545 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006546 } else if (old_state == IEEE80211_STA_AUTH &&
6547 new_state == IEEE80211_STA_ASSOC &&
6548 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006549 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03006550 vif->type == NL80211_IFTYPE_ADHOC)) {
6551 /*
6552 * New association.
6553 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006554 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006555 sta->addr);
6556
Michal Kazior590922a2014-10-21 10:10:29 +03006557 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006558 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006559 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006560 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006561 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006562 new_state == IEEE80211_STA_AUTHORIZED &&
6563 sta->tdls) {
6564 /*
6565 * Tdls station authorized.
6566 */
6567 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
6568 sta->addr);
6569
6570 ret = ath10k_station_assoc(ar, vif, sta, false);
6571 if (ret) {
6572 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
6573 sta->addr, arvif->vdev_id, ret);
6574 goto exit;
6575 }
6576
6577 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6578 WMI_TDLS_PEER_STATE_CONNECTED);
6579 if (ret)
6580 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
6581 sta->addr, arvif->vdev_id, ret);
6582 } else if (old_state == IEEE80211_STA_ASSOC &&
6583 new_state == IEEE80211_STA_AUTH &&
6584 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006585 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006586 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006587 /*
6588 * Disassociation.
6589 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006590 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006591 sta->addr);
6592
Michal Kazior590922a2014-10-21 10:10:29 +03006593 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006594 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006595 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006596 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006597 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006598exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006599 mutex_unlock(&ar->conf_mutex);
6600 return ret;
6601}
6602
6603static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006604 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006605{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006606 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006607 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6608 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006609 u32 value = 0;
6610 int ret = 0;
6611
Michal Kazior548db542013-07-05 16:15:15 +03006612 lockdep_assert_held(&ar->conf_mutex);
6613
Kalle Valo5e3dd152013-06-12 20:52:10 +03006614 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6615 return 0;
6616
6617 switch (ac) {
6618 case IEEE80211_AC_VO:
6619 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6620 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006621 prio = 7;
6622 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006623 break;
6624 case IEEE80211_AC_VI:
6625 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6626 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006627 prio = 5;
6628 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006629 break;
6630 case IEEE80211_AC_BE:
6631 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6632 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006633 prio = 2;
6634 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006635 break;
6636 case IEEE80211_AC_BK:
6637 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6638 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006639 prio = 0;
6640 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006641 break;
6642 }
6643
6644 if (enable)
6645 arvif->u.sta.uapsd |= value;
6646 else
6647 arvif->u.sta.uapsd &= ~value;
6648
6649 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6650 WMI_STA_PS_PARAM_UAPSD,
6651 arvif->u.sta.uapsd);
6652 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006653 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006654 goto exit;
6655 }
6656
6657 if (arvif->u.sta.uapsd)
6658 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6659 else
6660 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6661
6662 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6663 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6664 value);
6665 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006666 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006667
Michal Kazior9f9b5742014-12-12 12:41:36 +01006668 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6669 if (ret) {
6670 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6671 arvif->vdev_id, ret);
6672 return ret;
6673 }
6674
6675 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6676 if (ret) {
6677 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6678 arvif->vdev_id, ret);
6679 return ret;
6680 }
6681
Michal Kaziorb0e56152015-01-24 12:14:52 +02006682 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6683 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6684 /* Only userspace can make an educated decision when to send
6685 * trigger frame. The following effectively disables u-UAPSD
6686 * autotrigger in firmware (which is enabled by default
6687 * provided the autotrigger service is available).
6688 */
6689
6690 arg.wmm_ac = acc;
6691 arg.user_priority = prio;
6692 arg.service_interval = 0;
6693 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6694 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6695
6696 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6697 arvif->bssid, &arg, 1);
6698 if (ret) {
6699 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6700 ret);
6701 return ret;
6702 }
6703 }
6704
Kalle Valo5e3dd152013-06-12 20:52:10 +03006705exit:
6706 return ret;
6707}
6708
6709static int ath10k_conf_tx(struct ieee80211_hw *hw,
6710 struct ieee80211_vif *vif, u16 ac,
6711 const struct ieee80211_tx_queue_params *params)
6712{
6713 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006714 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006715 struct wmi_wmm_params_arg *p = NULL;
6716 int ret;
6717
6718 mutex_lock(&ar->conf_mutex);
6719
6720 switch (ac) {
6721 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006722 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006723 break;
6724 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006725 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006726 break;
6727 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006728 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006729 break;
6730 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006731 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006732 break;
6733 }
6734
6735 if (WARN_ON(!p)) {
6736 ret = -EINVAL;
6737 goto exit;
6738 }
6739
6740 p->cwmin = params->cw_min;
6741 p->cwmax = params->cw_max;
6742 p->aifs = params->aifs;
6743
6744 /*
6745 * The channel time duration programmed in the HW is in absolute
6746 * microseconds, while mac80211 gives the txop in units of
6747 * 32 microseconds.
6748 */
6749 p->txop = params->txop * 32;
6750
Michal Kazior7fc979a2015-01-28 09:57:28 +02006751 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6752 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6753 &arvif->wmm_params);
6754 if (ret) {
6755 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6756 arvif->vdev_id, ret);
6757 goto exit;
6758 }
6759 } else {
6760 /* This won't work well with multi-interface cases but it's
6761 * better than nothing.
6762 */
6763 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6764 if (ret) {
6765 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6766 goto exit;
6767 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006768 }
6769
6770 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6771 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006772 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006773
6774exit:
6775 mutex_unlock(&ar->conf_mutex);
6776 return ret;
6777}
6778
Kalle Valo14e105c2016-04-13 14:13:21 +03006779#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006780
6781static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6782 struct ieee80211_vif *vif,
6783 struct ieee80211_channel *chan,
6784 int duration,
6785 enum ieee80211_roc_type type)
6786{
6787 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006788 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006789 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006790 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006791 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006792
6793 mutex_lock(&ar->conf_mutex);
6794
Anilkumar Kollia6080932017-10-27 11:12:28 +03006795 if (ath10k_mac_tdls_vif_stations_count(hw, vif) > 0) {
6796 ret = -EBUSY;
6797 goto exit;
6798 }
6799
Kalle Valo5e3dd152013-06-12 20:52:10 +03006800 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006801 switch (ar->scan.state) {
6802 case ATH10K_SCAN_IDLE:
6803 reinit_completion(&ar->scan.started);
6804 reinit_completion(&ar->scan.completed);
6805 reinit_completion(&ar->scan.on_channel);
6806 ar->scan.state = ATH10K_SCAN_STARTING;
6807 ar->scan.is_roc = true;
6808 ar->scan.vdev_id = arvif->vdev_id;
6809 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006810 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006811 ret = 0;
6812 break;
6813 case ATH10K_SCAN_STARTING:
6814 case ATH10K_SCAN_RUNNING:
6815 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006816 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006817 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006818 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006819 spin_unlock_bh(&ar->data_lock);
6820
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006821 if (ret)
6822 goto exit;
6823
Michal Kaziorfcf98442015-03-31 11:03:47 +00006824 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006825
Kalle Valo5e3dd152013-06-12 20:52:10 +03006826 memset(&arg, 0, sizeof(arg));
6827 ath10k_wmi_start_scan_init(ar, &arg);
6828 arg.vdev_id = arvif->vdev_id;
6829 arg.scan_id = ATH10K_SCAN_ID;
6830 arg.n_channels = 1;
6831 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006832 arg.dwell_time_active = scan_time_msec;
6833 arg.dwell_time_passive = scan_time_msec;
6834 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006835 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6836 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006837 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006838
6839 ret = ath10k_start_scan(ar, &arg);
6840 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006841 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006842 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006843 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006844 spin_unlock_bh(&ar->data_lock);
6845 goto exit;
6846 }
6847
Kalle Valo14e105c2016-04-13 14:13:21 +03006848 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006849 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006850 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006851
6852 ret = ath10k_scan_stop(ar);
6853 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006854 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006855
Kalle Valo5e3dd152013-06-12 20:52:10 +03006856 ret = -ETIMEDOUT;
6857 goto exit;
6858 }
6859
Michal Kaziorfcf98442015-03-31 11:03:47 +00006860 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6861 msecs_to_jiffies(duration));
6862
Kalle Valo5e3dd152013-06-12 20:52:10 +03006863 ret = 0;
6864exit:
6865 mutex_unlock(&ar->conf_mutex);
6866 return ret;
6867}
6868
6869static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6870{
6871 struct ath10k *ar = hw->priv;
6872
6873 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006874
6875 spin_lock_bh(&ar->data_lock);
6876 ar->scan.roc_notify = false;
6877 spin_unlock_bh(&ar->data_lock);
6878
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006879 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006880
Kalle Valo5e3dd152013-06-12 20:52:10 +03006881 mutex_unlock(&ar->conf_mutex);
6882
Michal Kazior4eb2e162014-10-28 10:23:09 +01006883 cancel_delayed_work_sync(&ar->scan.timeout);
6884
Kalle Valo5e3dd152013-06-12 20:52:10 +03006885 return 0;
6886}
6887
6888/*
6889 * Both RTS and Fragmentation threshold are interface-specific
6890 * in ath10k, but device-specific in mac80211.
6891 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006892
6893static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6894{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006895 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006896 struct ath10k_vif *arvif;
6897 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006898
Michal Kaziorad088bf2013-10-16 15:44:46 +03006899 mutex_lock(&ar->conf_mutex);
6900 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006901 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006902 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006903
Michal Kaziorad088bf2013-10-16 15:44:46 +03006904 ret = ath10k_mac_set_rts(arvif, value);
6905 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006906 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006907 arvif->vdev_id, ret);
6908 break;
6909 }
6910 }
6911 mutex_unlock(&ar->conf_mutex);
6912
6913 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006914}
6915
Michal Kazior92092fe2015-08-03 11:16:43 +02006916static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6917{
6918 /* Even though there's a WMI enum for fragmentation threshold no known
6919 * firmware actually implements it. Moreover it is not possible to rely
6920 * frame fragmentation to mac80211 because firmware clears the "more
6921 * fragments" bit in frame control making it impossible for remote
6922 * devices to reassemble frames.
6923 *
6924 * Hence implement a dummy callback just to say fragmentation isn't
6925 * supported. This effectively prevents mac80211 from doing frame
6926 * fragmentation in software.
6927 */
6928 return -EOPNOTSUPP;
6929}
6930
Wen Gong828853a2018-08-28 19:48:42 +03006931void ath10k_mac_wait_tx_complete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006932{
Michal Kazioraffd3212013-07-16 09:54:35 +02006933 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006934 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006935
6936 /* mac80211 doesn't care if we really xmit queued frames or not
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01006937 * we'll collect those frames either way if we stop/delete vdevs
6938 */
Michal Kazior548db542013-07-05 16:15:15 +03006939
Michal Kazioraffd3212013-07-16 09:54:35 +02006940 if (ar->state == ATH10K_STATE_WEDGED)
Wen Gong828853a2018-08-28 19:48:42 +03006941 return;
Michal Kazioraffd3212013-07-16 09:54:35 +02006942
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006943 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006944 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006945
Michal Kazioredb82362013-07-05 16:15:14 +03006946 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006947 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006948 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006949
Michal Kazior7962b0d2014-10-28 10:34:38 +01006950 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6951 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6952 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006953
6954 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006955 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006956
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006957 if (time_left == 0 || skip)
6958 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6959 skip, ar->state, time_left);
Wen Gong828853a2018-08-28 19:48:42 +03006960}
Michal Kazior548db542013-07-05 16:15:15 +03006961
Wen Gong828853a2018-08-28 19:48:42 +03006962static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6963 u32 queues, bool drop)
6964{
6965 struct ath10k *ar = hw->priv;
Wen Gong9de41622018-10-08 17:02:43 +08006966 struct ath10k_vif *arvif;
6967 u32 bitmap;
Wen Gong828853a2018-08-28 19:48:42 +03006968
Wen Gong9de41622018-10-08 17:02:43 +08006969 if (drop) {
Brian Norrisd987f782018-11-07 16:40:35 -08006970 if (vif && vif->type == NL80211_IFTYPE_STATION) {
Wen Gong9de41622018-10-08 17:02:43 +08006971 bitmap = ~(1 << WMI_MGMT_TID);
6972 list_for_each_entry(arvif, &ar->arvifs, list) {
6973 if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
6974 ath10k_wmi_peer_flush(ar, arvif->vdev_id,
6975 arvif->bssid, bitmap);
6976 }
6977 }
Wen Gong828853a2018-08-28 19:48:42 +03006978 return;
Wen Gong9de41622018-10-08 17:02:43 +08006979 }
Wen Gong828853a2018-08-28 19:48:42 +03006980
6981 mutex_lock(&ar->conf_mutex);
6982 ath10k_mac_wait_tx_complete(ar);
Michal Kazior548db542013-07-05 16:15:15 +03006983 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006984}
6985
6986/* TODO: Implement this function properly
6987 * For now it is needed to reply to Probe Requests in IBSS mode.
6988 * Propably we need this information from FW.
6989 */
6990static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
6991{
6992 return 1;
6993}
6994
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006995static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
6996 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02006997{
6998 struct ath10k *ar = hw->priv;
6999
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007000 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
7001 return;
7002
Michal Kazioraffd3212013-07-16 09:54:35 +02007003 mutex_lock(&ar->conf_mutex);
7004
7005 /* If device failed to restart it will be in a different state, e.g.
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01007006 * ATH10K_STATE_WEDGED
7007 */
Michal Kazioraffd3212013-07-16 09:54:35 +02007008 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007009 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02007010 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01007011 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02007012 }
7013
7014 mutex_unlock(&ar->conf_mutex);
7015}
7016
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05307017static void
7018ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
7019 struct ieee80211_channel *channel)
7020{
7021 int ret;
7022 enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
7023
7024 lockdep_assert_held(&ar->conf_mutex);
7025
7026 if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
7027 (ar->rx_channel != channel))
7028 return;
7029
7030 if (ar->scan.state != ATH10K_SCAN_IDLE) {
7031 ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
7032 return;
7033 }
7034
7035 reinit_completion(&ar->bss_survey_done);
7036
7037 ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
7038 if (ret) {
7039 ath10k_warn(ar, "failed to send pdev bss chan info request\n");
7040 return;
7041 }
7042
7043 ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
7044 if (!ret) {
7045 ath10k_warn(ar, "bss channel survey timed out\n");
7046 return;
7047 }
7048}
7049
Michal Kazior2e1dea42013-07-31 10:32:40 +02007050static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
7051 struct survey_info *survey)
7052{
7053 struct ath10k *ar = hw->priv;
7054 struct ieee80211_supported_band *sband;
7055 struct survey_info *ar_survey = &ar->survey[idx];
7056 int ret = 0;
7057
7058 mutex_lock(&ar->conf_mutex);
7059
Johannes Berg57fbcce2016-04-12 15:56:15 +02007060 sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02007061 if (sband && idx >= sband->n_channels) {
7062 idx -= sband->n_channels;
7063 sband = NULL;
7064 }
7065
7066 if (!sband)
Johannes Berg57fbcce2016-04-12 15:56:15 +02007067 sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02007068
7069 if (!sband || idx >= sband->n_channels) {
7070 ret = -ENOENT;
7071 goto exit;
7072 }
7073
Ashok Raj Nagarajan77eb3d62016-09-02 10:59:53 +05307074 ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05307075
Michal Kazior2e1dea42013-07-31 10:32:40 +02007076 spin_lock_bh(&ar->data_lock);
7077 memcpy(survey, ar_survey, sizeof(*survey));
7078 spin_unlock_bh(&ar->data_lock);
7079
7080 survey->channel = &sband->channels[idx];
7081
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03007082 if (ar->rx_channel == survey->channel)
7083 survey->filled |= SURVEY_INFO_IN_USE;
7084
Michal Kazior2e1dea42013-07-31 10:32:40 +02007085exit:
7086 mutex_unlock(&ar->conf_mutex);
7087 return ret;
7088}
7089
Michal Kazior3ae54222015-03-31 10:49:20 +00007090static bool
7091ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007092 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00007093 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007094{
Michal Kazior3ae54222015-03-31 10:49:20 +00007095 int num_rates = 0;
7096 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007097
Michal Kazior3ae54222015-03-31 10:49:20 +00007098 num_rates += hweight32(mask->control[band].legacy);
7099
7100 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
7101 num_rates += hweight8(mask->control[band].ht_mcs[i]);
7102
7103 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
7104 num_rates += hweight16(mask->control[band].vht_mcs[i]);
7105
7106 return num_rates == 1;
7107}
7108
7109static bool
7110ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007111 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00007112 const struct cfg80211_bitrate_mask *mask,
7113 int *nss)
7114{
7115 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
7116 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
7117 u8 ht_nss_mask = 0;
7118 u8 vht_nss_mask = 0;
7119 int i;
7120
7121 if (mask->control[band].legacy)
7122 return false;
7123
7124 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
7125 if (mask->control[band].ht_mcs[i] == 0)
7126 continue;
7127 else if (mask->control[band].ht_mcs[i] ==
7128 sband->ht_cap.mcs.rx_mask[i])
7129 ht_nss_mask |= BIT(i);
7130 else
7131 return false;
7132 }
7133
7134 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
7135 if (mask->control[band].vht_mcs[i] == 0)
7136 continue;
7137 else if (mask->control[band].vht_mcs[i] ==
7138 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
7139 vht_nss_mask |= BIT(i);
7140 else
7141 return false;
7142 }
7143
7144 if (ht_nss_mask != vht_nss_mask)
7145 return false;
7146
7147 if (ht_nss_mask == 0)
7148 return false;
7149
7150 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
7151 return false;
7152
7153 *nss = fls(ht_nss_mask);
7154
7155 return true;
7156}
7157
7158static int
7159ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007160 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00007161 const struct cfg80211_bitrate_mask *mask,
7162 u8 *rate, u8 *nss)
7163{
Michal Kazior3ae54222015-03-31 10:49:20 +00007164 int rate_idx;
7165 int i;
7166 u16 bitrate;
7167 u8 preamble;
7168 u8 hw_rate;
7169
7170 if (hweight32(mask->control[band].legacy) == 1) {
7171 rate_idx = ffs(mask->control[band].legacy) - 1;
7172
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03007173 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
7174 rate_idx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
7175
7176 hw_rate = ath10k_wmi_legacy_rates[rate_idx].hw_value;
7177 bitrate = ath10k_wmi_legacy_rates[rate_idx].bitrate;
Michal Kazior3ae54222015-03-31 10:49:20 +00007178
7179 if (ath10k_mac_bitrate_is_cck(bitrate))
7180 preamble = WMI_RATE_PREAMBLE_CCK;
7181 else
7182 preamble = WMI_RATE_PREAMBLE_OFDM;
7183
7184 *nss = 1;
7185 *rate = preamble << 6 |
7186 (*nss - 1) << 4 |
7187 hw_rate << 0;
7188
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007189 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007190 }
7191
Michal Kazior3ae54222015-03-31 10:49:20 +00007192 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
7193 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
7194 *nss = i + 1;
7195 *rate = WMI_RATE_PREAMBLE_HT << 6 |
7196 (*nss - 1) << 4 |
7197 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007198
Michal Kazior3ae54222015-03-31 10:49:20 +00007199 return 0;
7200 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007201 }
7202
Michal Kazior3ae54222015-03-31 10:49:20 +00007203 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
7204 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
7205 *nss = i + 1;
7206 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
7207 (*nss - 1) << 4 |
7208 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007209
Michal Kazior3ae54222015-03-31 10:49:20 +00007210 return 0;
7211 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007212 }
7213
Michal Kazior3ae54222015-03-31 10:49:20 +00007214 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007215}
7216
Michal Kazior3ae54222015-03-31 10:49:20 +00007217static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307218 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007219{
7220 struct ath10k *ar = arvif->ar;
7221 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00007222 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007223
Michal Kazior3ae54222015-03-31 10:49:20 +00007224 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007225
Michal Kazior3ae54222015-03-31 10:49:20 +00007226 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
7227 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007228
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007229 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00007230 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007231 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007232 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00007233 rate, ret);
7234 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007235 }
7236
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007237 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00007238 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007239 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00007240 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
7241 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007242 }
7243
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007244 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00007245 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007246 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00007247 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
7248 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007249 }
7250
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307251 vdev_param = ar->wmi.vdev_param->ldpc;
7252 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
7253 if (ret) {
7254 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
7255 return ret;
7256 }
7257
Michal Kazior3ae54222015-03-31 10:49:20 +00007258 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007259}
7260
Michal Kazior45c9abc2015-04-21 20:42:58 +03007261static bool
7262ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007263 enum nl80211_band band,
Michal Kazior45c9abc2015-04-21 20:42:58 +03007264 const struct cfg80211_bitrate_mask *mask)
7265{
7266 int i;
7267 u16 vht_mcs;
7268
7269 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
7270 * to express all VHT MCS rate masks. Effectively only the following
7271 * ranges can be used: none, 0-7, 0-8 and 0-9.
7272 */
7273 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
7274 vht_mcs = mask->control[band].vht_mcs[i];
7275
7276 switch (vht_mcs) {
7277 case 0:
7278 case BIT(8) - 1:
7279 case BIT(9) - 1:
7280 case BIT(10) - 1:
7281 break;
7282 default:
7283 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
7284 return false;
7285 }
7286 }
7287
7288 return true;
7289}
7290
7291static void ath10k_mac_set_bitrate_mask_iter(void *data,
7292 struct ieee80211_sta *sta)
7293{
7294 struct ath10k_vif *arvif = data;
7295 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
7296 struct ath10k *ar = arvif->ar;
7297
7298 if (arsta->arvif != arvif)
7299 return;
7300
7301 spin_lock_bh(&ar->data_lock);
7302 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
7303 spin_unlock_bh(&ar->data_lock);
7304
7305 ieee80211_queue_work(ar->hw, &arsta->update_wk);
7306}
7307
Michal Kazior3ae54222015-03-31 10:49:20 +00007308static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
7309 struct ieee80211_vif *vif,
7310 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007311{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007312 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007313 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007314 struct ath10k *ar = arvif->ar;
Johannes Berg57fbcce2016-04-12 15:56:15 +02007315 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007316 const u8 *ht_mcs_mask;
7317 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00007318 u8 rate;
7319 u8 nss;
7320 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307321 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00007322 int single_nss;
7323 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007324
Michal Kazior500ff9f2015-03-31 10:26:21 +00007325 if (ath10k_mac_vif_chan(vif, &def))
7326 return -EPERM;
7327
Michal Kazior500ff9f2015-03-31 10:26:21 +00007328 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007329 ht_mcs_mask = mask->control[band].ht_mcs;
7330 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307331 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007332
Michal Kazior3ae54222015-03-31 10:49:20 +00007333 sgi = mask->control[band].gi;
7334 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007335 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007336
Michal Kazior3ae54222015-03-31 10:49:20 +00007337 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
7338 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
7339 &rate, &nss);
7340 if (ret) {
7341 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
7342 arvif->vdev_id, ret);
7343 return ret;
7344 }
7345 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
7346 &single_nss)) {
7347 rate = WMI_FIXED_RATE_NONE;
7348 nss = single_nss;
7349 } else {
7350 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007351 nss = min(ar->num_rf_chains,
7352 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
7353 ath10k_mac_max_vht_nss(vht_mcs_mask)));
7354
7355 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
7356 return -EINVAL;
7357
7358 mutex_lock(&ar->conf_mutex);
7359
7360 arvif->bitrate_mask = *mask;
7361 ieee80211_iterate_stations_atomic(ar->hw,
7362 ath10k_mac_set_bitrate_mask_iter,
7363 arvif);
7364
7365 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007366 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007367
7368 mutex_lock(&ar->conf_mutex);
7369
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307370 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007371 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00007372 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
7373 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007374 goto exit;
7375 }
7376
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007377exit:
7378 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00007379
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007380 return ret;
7381}
7382
Michal Kazior9797feb2014-02-14 14:49:48 +01007383static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
7384 struct ieee80211_vif *vif,
7385 struct ieee80211_sta *sta,
7386 u32 changed)
7387{
7388 struct ath10k *ar = hw->priv;
7389 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Karthikeyan Periyasamy8b2d93d2018-03-12 17:09:40 +05307390 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7391 struct ath10k_peer *peer;
Michal Kazior9797feb2014-02-14 14:49:48 +01007392 u32 bw, smps;
7393
7394 spin_lock_bh(&ar->data_lock);
7395
Karthikeyan Periyasamy8b2d93d2018-03-12 17:09:40 +05307396 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
7397 if (!peer) {
7398 spin_unlock_bh(&ar->data_lock);
7399 ath10k_warn(ar, "mac sta rc update failed to find peer %pM on vdev %i\n",
7400 sta->addr, arvif->vdev_id);
7401 return;
7402 }
7403
Michal Kazior7aa7a722014-08-25 12:09:38 +02007404 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01007405 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
7406 sta->addr, changed, sta->bandwidth, sta->rx_nss,
7407 sta->smps_mode);
7408
7409 if (changed & IEEE80211_RC_BW_CHANGED) {
7410 bw = WMI_PEER_CHWIDTH_20MHZ;
7411
7412 switch (sta->bandwidth) {
7413 case IEEE80211_STA_RX_BW_20:
7414 bw = WMI_PEER_CHWIDTH_20MHZ;
7415 break;
7416 case IEEE80211_STA_RX_BW_40:
7417 bw = WMI_PEER_CHWIDTH_40MHZ;
7418 break;
7419 case IEEE80211_STA_RX_BW_80:
7420 bw = WMI_PEER_CHWIDTH_80MHZ;
7421 break;
7422 case IEEE80211_STA_RX_BW_160:
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02007423 bw = WMI_PEER_CHWIDTH_160MHZ;
7424 break;
7425 default:
Masanari Iidad939be32015-02-27 23:52:31 +09007426 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02007427 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01007428 bw = WMI_PEER_CHWIDTH_20MHZ;
7429 break;
7430 }
7431
7432 arsta->bw = bw;
7433 }
7434
7435 if (changed & IEEE80211_RC_NSS_CHANGED)
7436 arsta->nss = sta->rx_nss;
7437
7438 if (changed & IEEE80211_RC_SMPS_CHANGED) {
7439 smps = WMI_PEER_SMPS_PS_NONE;
7440
7441 switch (sta->smps_mode) {
7442 case IEEE80211_SMPS_AUTOMATIC:
7443 case IEEE80211_SMPS_OFF:
7444 smps = WMI_PEER_SMPS_PS_NONE;
7445 break;
7446 case IEEE80211_SMPS_STATIC:
7447 smps = WMI_PEER_SMPS_STATIC;
7448 break;
7449 case IEEE80211_SMPS_DYNAMIC:
7450 smps = WMI_PEER_SMPS_DYNAMIC;
7451 break;
7452 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02007453 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02007454 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01007455 smps = WMI_PEER_SMPS_PS_NONE;
7456 break;
7457 }
7458
7459 arsta->smps = smps;
7460 }
7461
Michal Kazior9797feb2014-02-14 14:49:48 +01007462 arsta->changed |= changed;
7463
7464 spin_unlock_bh(&ar->data_lock);
7465
7466 ieee80211_queue_work(hw, &arsta->update_wk);
7467}
7468
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007469static void ath10k_offset_tsf(struct ieee80211_hw *hw,
7470 struct ieee80211_vif *vif, s64 tsf_offset)
Peter Oh9f0b7e72016-04-04 16:19:14 -07007471{
7472 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007473 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007474 u32 offset, vdev_param;
Peter Oh9f0b7e72016-04-04 16:19:14 -07007475 int ret;
7476
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007477 if (tsf_offset < 0) {
7478 vdev_param = ar->wmi.vdev_param->dec_tsf;
7479 offset = -tsf_offset;
7480 } else {
7481 vdev_param = ar->wmi.vdev_param->inc_tsf;
7482 offset = tsf_offset;
7483 }
7484
Peter Oh9f0b7e72016-04-04 16:19:14 -07007485 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007486 vdev_param, offset);
7487
Peter Oh9f0b7e72016-04-04 16:19:14 -07007488 if (ret && ret != -EOPNOTSUPP)
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007489 ath10k_warn(ar, "failed to set tsf offset %d cmd %d: %d\n",
7490 offset, vdev_param, ret);
Peter Oh9f0b7e72016-04-04 16:19:14 -07007491}
7492
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007493static int ath10k_ampdu_action(struct ieee80211_hw *hw,
7494 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02007495 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007496{
Michal Kazior7aa7a722014-08-25 12:09:38 +02007497 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007498 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Sara Sharon50ea05e2015-12-30 16:06:04 +02007499 struct ieee80211_sta *sta = params->sta;
7500 enum ieee80211_ampdu_mlme_action action = params->action;
7501 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007502
Michal Kazior7aa7a722014-08-25 12:09:38 +02007503 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 +02007504 arvif->vdev_id, sta->addr, tid, action);
7505
7506 switch (action) {
7507 case IEEE80211_AMPDU_RX_START:
7508 case IEEE80211_AMPDU_RX_STOP:
7509 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
7510 * creation/removal. Do we need to verify this?
7511 */
7512 return 0;
7513 case IEEE80211_AMPDU_TX_START:
7514 case IEEE80211_AMPDU_TX_STOP_CONT:
7515 case IEEE80211_AMPDU_TX_STOP_FLUSH:
7516 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
7517 case IEEE80211_AMPDU_TX_OPERATIONAL:
7518 /* Firmware offloads Tx aggregation entirely so deny mac80211
7519 * Tx aggregation requests.
7520 */
7521 return -EOPNOTSUPP;
7522 }
7523
7524 return -EINVAL;
7525}
7526
Michal Kazior500ff9f2015-03-31 10:26:21 +00007527static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007528ath10k_mac_update_rx_channel(struct ath10k *ar,
7529 struct ieee80211_chanctx_conf *ctx,
7530 struct ieee80211_vif_chanctx_switch *vifs,
7531 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00007532{
7533 struct cfg80211_chan_def *def = NULL;
7534
7535 /* Both locks are required because ar->rx_channel is modified. This
7536 * allows readers to hold either lock.
7537 */
7538 lockdep_assert_held(&ar->conf_mutex);
7539 lockdep_assert_held(&ar->data_lock);
7540
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007541 WARN_ON(ctx && vifs);
Mohammed Shafi Shajakhanc73f8c02017-03-08 13:52:06 +02007542 WARN_ON(vifs && !n_vifs);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007543
Michal Kazior500ff9f2015-03-31 10:26:21 +00007544 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
7545 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
7546 * ppdu on Rx may reduce performance on low-end systems. It should be
7547 * possible to make tables/hashmaps to speed the lookup up (be vary of
7548 * cpu data cache lines though regarding sizes) but to keep the initial
7549 * implementation simple and less intrusive fallback to the slow lookup
7550 * only for multi-channel cases. Single-channel cases will remain to
7551 * use the old channel derival and thus performance should not be
7552 * affected much.
7553 */
7554 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007555 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00007556 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03007557 ath10k_mac_get_any_chandef_iter,
7558 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007559
7560 if (vifs)
7561 def = &vifs[0].new_ctx->def;
7562
Michal Kazior500ff9f2015-03-31 10:26:21 +00007563 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05307564 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
7565 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
7566 /* During driver restart due to firmware assert, since mac80211
7567 * already has valid channel context for given radio, channel
7568 * context iteration return num_chanctx > 0. So fix rx_channel
7569 * when restart is in progress.
7570 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007571 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007572 } else {
7573 ar->rx_channel = NULL;
7574 }
7575 rcu_read_unlock();
7576}
7577
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007578static void
7579ath10k_mac_update_vif_chan(struct ath10k *ar,
7580 struct ieee80211_vif_chanctx_switch *vifs,
7581 int n_vifs)
7582{
7583 struct ath10k_vif *arvif;
7584 int ret;
7585 int i;
7586
7587 lockdep_assert_held(&ar->conf_mutex);
7588
7589 /* First stop monitor interface. Some FW versions crash if there's a
7590 * lone monitor interface.
7591 */
7592 if (ar->monitor_started)
7593 ath10k_monitor_stop(ar);
7594
7595 for (i = 0; i < n_vifs; i++) {
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007596 arvif = (void *)vifs[i].vif->drv_priv;
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007597
7598 ath10k_dbg(ar, ATH10K_DBG_MAC,
7599 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
7600 arvif->vdev_id,
7601 vifs[i].old_ctx->def.chan->center_freq,
7602 vifs[i].new_ctx->def.chan->center_freq,
7603 vifs[i].old_ctx->def.width,
7604 vifs[i].new_ctx->def.width);
7605
7606 if (WARN_ON(!arvif->is_started))
7607 continue;
7608
7609 if (WARN_ON(!arvif->is_up))
7610 continue;
7611
7612 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7613 if (ret) {
7614 ath10k_warn(ar, "failed to down vdev %d: %d\n",
7615 arvif->vdev_id, ret);
7616 continue;
7617 }
7618 }
7619
7620 /* All relevant vdevs are downed and associated channel resources
7621 * should be available for the channel switch now.
7622 */
7623
7624 spin_lock_bh(&ar->data_lock);
7625 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
7626 spin_unlock_bh(&ar->data_lock);
7627
7628 for (i = 0; i < n_vifs; i++) {
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007629 arvif = (void *)vifs[i].vif->drv_priv;
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007630
7631 if (WARN_ON(!arvif->is_started))
7632 continue;
7633
7634 if (WARN_ON(!arvif->is_up))
7635 continue;
7636
7637 ret = ath10k_mac_setup_bcn_tmpl(arvif);
7638 if (ret)
7639 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
7640 ret);
7641
7642 ret = ath10k_mac_setup_prb_tmpl(arvif);
7643 if (ret)
7644 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
7645 ret);
7646
7647 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7648 if (ret) {
7649 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7650 arvif->vdev_id, ret);
7651 continue;
7652 }
7653
7654 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7655 arvif->bssid);
7656 if (ret) {
7657 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7658 arvif->vdev_id, ret);
7659 continue;
7660 }
7661 }
7662
7663 ath10k_monitor_recalc(ar);
7664}
7665
Michal Kazior500ff9f2015-03-31 10:26:21 +00007666static int
7667ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7668 struct ieee80211_chanctx_conf *ctx)
7669{
7670 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007671
7672 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307673 "mac chanctx add freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007674 ctx->def.chan->center_freq, ctx->def.width, ctx);
7675
7676 mutex_lock(&ar->conf_mutex);
7677
7678 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007679 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007680 spin_unlock_bh(&ar->data_lock);
7681
7682 ath10k_recalc_radar_detection(ar);
7683 ath10k_monitor_recalc(ar);
7684
7685 mutex_unlock(&ar->conf_mutex);
7686
7687 return 0;
7688}
7689
7690static void
7691ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7692 struct ieee80211_chanctx_conf *ctx)
7693{
7694 struct ath10k *ar = hw->priv;
7695
7696 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307697 "mac chanctx remove freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007698 ctx->def.chan->center_freq, ctx->def.width, ctx);
7699
7700 mutex_lock(&ar->conf_mutex);
7701
7702 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007703 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007704 spin_unlock_bh(&ar->data_lock);
7705
7706 ath10k_recalc_radar_detection(ar);
7707 ath10k_monitor_recalc(ar);
7708
7709 mutex_unlock(&ar->conf_mutex);
7710}
7711
Michal Kazior9713e3d2015-09-03 10:44:52 +02007712struct ath10k_mac_change_chanctx_arg {
7713 struct ieee80211_chanctx_conf *ctx;
7714 struct ieee80211_vif_chanctx_switch *vifs;
7715 int n_vifs;
7716 int next_vif;
7717};
7718
7719static void
7720ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
7721 struct ieee80211_vif *vif)
7722{
7723 struct ath10k_mac_change_chanctx_arg *arg = data;
7724
7725 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
7726 return;
7727
7728 arg->n_vifs++;
7729}
7730
7731static void
7732ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
7733 struct ieee80211_vif *vif)
7734{
7735 struct ath10k_mac_change_chanctx_arg *arg = data;
7736 struct ieee80211_chanctx_conf *ctx;
7737
7738 ctx = rcu_access_pointer(vif->chanctx_conf);
7739 if (ctx != arg->ctx)
7740 return;
7741
7742 if (WARN_ON(arg->next_vif == arg->n_vifs))
7743 return;
7744
7745 arg->vifs[arg->next_vif].vif = vif;
7746 arg->vifs[arg->next_vif].old_ctx = ctx;
7747 arg->vifs[arg->next_vif].new_ctx = ctx;
7748 arg->next_vif++;
7749}
7750
Michal Kazior500ff9f2015-03-31 10:26:21 +00007751static void
7752ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7753 struct ieee80211_chanctx_conf *ctx,
7754 u32 changed)
7755{
7756 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007757 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007758
7759 mutex_lock(&ar->conf_mutex);
7760
7761 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307762 "mac chanctx change freq %hu width %d ptr %pK changed %x\n",
Michal Kazior089ab7a2015-06-03 12:16:55 +02007763 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007764
7765 /* This shouldn't really happen because channel switching should use
7766 * switch_vif_chanctx().
7767 */
7768 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7769 goto unlock;
7770
Michal Kazior9713e3d2015-09-03 10:44:52 +02007771 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7772 ieee80211_iterate_active_interfaces_atomic(
7773 hw,
7774 IEEE80211_IFACE_ITER_NORMAL,
7775 ath10k_mac_change_chanctx_cnt_iter,
7776 &arg);
7777 if (arg.n_vifs == 0)
7778 goto radar;
7779
7780 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7781 GFP_KERNEL);
7782 if (!arg.vifs)
7783 goto radar;
7784
7785 ieee80211_iterate_active_interfaces_atomic(
7786 hw,
7787 IEEE80211_IFACE_ITER_NORMAL,
7788 ath10k_mac_change_chanctx_fill_iter,
7789 &arg);
7790 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7791 kfree(arg.vifs);
7792 }
7793
7794radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007795 ath10k_recalc_radar_detection(ar);
7796
7797 /* FIXME: How to configure Rx chains properly? */
7798
7799 /* No other actions are actually necessary. Firmware maintains channel
7800 * definitions per vdev internally and there's no host-side channel
7801 * context abstraction to configure, e.g. channel width.
7802 */
7803
7804unlock:
7805 mutex_unlock(&ar->conf_mutex);
7806}
7807
7808static int
7809ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7810 struct ieee80211_vif *vif,
7811 struct ieee80211_chanctx_conf *ctx)
7812{
7813 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007814 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7815 int ret;
7816
7817 mutex_lock(&ar->conf_mutex);
7818
7819 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307820 "mac chanctx assign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007821 ctx, arvif->vdev_id);
7822
7823 if (WARN_ON(arvif->is_started)) {
7824 mutex_unlock(&ar->conf_mutex);
7825 return -EBUSY;
7826 }
7827
Michal Kazior089ab7a2015-06-03 12:16:55 +02007828 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007829 if (ret) {
7830 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7831 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007832 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007833 goto err;
7834 }
7835
7836 arvif->is_started = true;
7837
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007838 ret = ath10k_mac_vif_setup_ps(arvif);
7839 if (ret) {
7840 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7841 arvif->vdev_id, ret);
7842 goto err_stop;
7843 }
7844
Michal Kazior500ff9f2015-03-31 10:26:21 +00007845 if (vif->type == NL80211_IFTYPE_MONITOR) {
7846 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7847 if (ret) {
7848 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7849 arvif->vdev_id, ret);
7850 goto err_stop;
7851 }
7852
7853 arvif->is_up = true;
7854 }
7855
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02007856 if (ath10k_mac_can_set_cts_prot(arvif)) {
7857 ret = ath10k_mac_set_cts_prot(arvif);
7858 if (ret)
7859 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
7860 arvif->vdev_id, ret);
7861 }
7862
Anilkumar Kollie8123bb2017-12-05 19:01:25 +05307863 if (ath10k_peer_stats_enabled(ar)) {
7864 ar->pktlog_filter |= ATH10K_PKTLOG_PEER_STATS;
7865 ret = ath10k_wmi_pdev_pktlog_enable(ar,
7866 ar->pktlog_filter);
7867 if (ret) {
7868 ath10k_warn(ar, "failed to enable pktlog %d\n", ret);
7869 goto err_stop;
7870 }
7871 }
7872
Michal Kazior500ff9f2015-03-31 10:26:21 +00007873 mutex_unlock(&ar->conf_mutex);
7874 return 0;
7875
7876err_stop:
7877 ath10k_vdev_stop(arvif);
7878 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007879 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007880
7881err:
7882 mutex_unlock(&ar->conf_mutex);
7883 return ret;
7884}
7885
7886static void
7887ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7888 struct ieee80211_vif *vif,
7889 struct ieee80211_chanctx_conf *ctx)
7890{
7891 struct ath10k *ar = hw->priv;
7892 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7893 int ret;
7894
7895 mutex_lock(&ar->conf_mutex);
7896
7897 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307898 "mac chanctx unassign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007899 ctx, arvif->vdev_id);
7900
7901 WARN_ON(!arvif->is_started);
7902
7903 if (vif->type == NL80211_IFTYPE_MONITOR) {
7904 WARN_ON(!arvif->is_up);
7905
7906 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7907 if (ret)
7908 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7909 arvif->vdev_id, ret);
7910
7911 arvif->is_up = false;
7912 }
7913
7914 ret = ath10k_vdev_stop(arvif);
7915 if (ret)
7916 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7917 arvif->vdev_id, ret);
7918
7919 arvif->is_started = false;
7920
7921 mutex_unlock(&ar->conf_mutex);
7922}
7923
7924static int
7925ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7926 struct ieee80211_vif_chanctx_switch *vifs,
7927 int n_vifs,
7928 enum ieee80211_chanctx_switch_mode mode)
7929{
7930 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007931
7932 mutex_lock(&ar->conf_mutex);
7933
7934 ath10k_dbg(ar, ATH10K_DBG_MAC,
7935 "mac chanctx switch n_vifs %d mode %d\n",
7936 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007937 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007938
7939 mutex_unlock(&ar->conf_mutex);
7940 return 0;
7941}
7942
Michal Kazior0a744d92017-01-12 16:14:30 +01007943static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,
7944 struct ieee80211_vif *vif,
7945 struct ieee80211_sta *sta)
7946{
7947 struct ath10k *ar;
7948 struct ath10k_peer *peer;
7949
7950 ar = hw->priv;
7951
7952 list_for_each_entry(peer, &ar->peers, list)
7953 if (peer->sta == sta)
7954 peer->removed = true;
7955}
7956
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05307957static void ath10k_sta_statistics(struct ieee80211_hw *hw,
7958 struct ieee80211_vif *vif,
7959 struct ieee80211_sta *sta,
7960 struct station_info *sinfo)
7961{
7962 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
7963 struct ath10k *ar = arsta->arvif->ar;
7964
7965 if (!ath10k_peer_stats_enabled(ar))
7966 return;
7967
7968 sinfo->rx_duration = arsta->rx_duration;
Omer Efrat22d0d2f2018-06-17 13:07:13 +03007969 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05307970
7971 if (!arsta->txrate.legacy && !arsta->txrate.nss)
7972 return;
7973
7974 if (arsta->txrate.legacy) {
7975 sinfo->txrate.legacy = arsta->txrate.legacy;
7976 } else {
7977 sinfo->txrate.mcs = arsta->txrate.mcs;
7978 sinfo->txrate.nss = arsta->txrate.nss;
7979 sinfo->txrate.bw = arsta->txrate.bw;
7980 }
7981 sinfo->txrate.flags = arsta->txrate.flags;
Omer Efrat22d0d2f2018-06-17 13:07:13 +03007982 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05307983}
7984
Kalle Valo5e3dd152013-06-12 20:52:10 +03007985static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01007986 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02007987 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007988 .start = ath10k_start,
7989 .stop = ath10k_stop,
7990 .config = ath10k_config,
7991 .add_interface = ath10k_add_interface,
7992 .remove_interface = ath10k_remove_interface,
7993 .configure_filter = ath10k_configure_filter,
7994 .bss_info_changed = ath10k_bss_info_changed,
Benjamin Bergebee76f2016-09-28 15:11:58 +03007995 .set_coverage_class = ath10k_mac_op_set_coverage_class,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007996 .hw_scan = ath10k_hw_scan,
7997 .cancel_hw_scan = ath10k_cancel_hw_scan,
7998 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02007999 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03008000 .sta_state = ath10k_sta_state,
8001 .conf_tx = ath10k_conf_tx,
8002 .remain_on_channel = ath10k_remain_on_channel,
8003 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
8004 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02008005 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03008006 .flush = ath10k_flush,
8007 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7bb2014-05-16 17:15:38 +03008008 .set_antenna = ath10k_set_antenna,
8009 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02008010 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02008011 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00008012 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01008013 .sta_rc_update = ath10k_sta_rc_update,
Pedersen, Thomas973324f2016-09-28 16:56:29 -07008014 .offset_tsf = ath10k_offset_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02008015 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03008016 .get_et_sset_count = ath10k_debug_get_et_sset_count,
8017 .get_et_stats = ath10k_debug_get_et_stats,
8018 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00008019 .add_chanctx = ath10k_mac_op_add_chanctx,
8020 .remove_chanctx = ath10k_mac_op_remove_chanctx,
8021 .change_chanctx = ath10k_mac_op_change_chanctx,
8022 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
8023 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
8024 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Michal Kazior0a744d92017-01-12 16:14:30 +01008025 .sta_pre_rcu_remove = ath10k_mac_op_sta_pre_rcu_remove,
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05308026 .sta_statistics = ath10k_sta_statistics,
Kalle Valo43d2a302014-09-10 18:23:30 +03008027
8028 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
8029
Michal Kazior8cd13ca2013-07-16 09:38:54 +02008030#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02008031 .suspend = ath10k_wow_op_suspend,
8032 .resume = ath10k_wow_op_resume,
Ryan Hsu393b7062017-08-31 15:36:16 +03008033 .set_wakeup = ath10k_wow_op_set_wakeup,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02008034#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02008035#ifdef CONFIG_MAC80211_DEBUGFS
8036 .sta_add_debugfs = ath10k_sta_add_debugfs,
8037#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03008038};
8039
Kalle Valo5e3dd152013-06-12 20:52:10 +03008040#define CHAN2G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02008041 .band = NL80211_BAND_2GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03008042 .hw_value = (_channel), \
8043 .center_freq = (_freq), \
8044 .flags = (_flags), \
8045 .max_antenna_gain = 0, \
8046 .max_power = 30, \
8047}
8048
8049#define CHAN5G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02008050 .band = NL80211_BAND_5GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03008051 .hw_value = (_channel), \
8052 .center_freq = (_freq), \
8053 .flags = (_flags), \
8054 .max_antenna_gain = 0, \
8055 .max_power = 30, \
8056}
8057
8058static const struct ieee80211_channel ath10k_2ghz_channels[] = {
8059 CHAN2G(1, 2412, 0),
8060 CHAN2G(2, 2417, 0),
8061 CHAN2G(3, 2422, 0),
8062 CHAN2G(4, 2427, 0),
8063 CHAN2G(5, 2432, 0),
8064 CHAN2G(6, 2437, 0),
8065 CHAN2G(7, 2442, 0),
8066 CHAN2G(8, 2447, 0),
8067 CHAN2G(9, 2452, 0),
8068 CHAN2G(10, 2457, 0),
8069 CHAN2G(11, 2462, 0),
8070 CHAN2G(12, 2467, 0),
8071 CHAN2G(13, 2472, 0),
8072 CHAN2G(14, 2484, 0),
8073};
8074
8075static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02008076 CHAN5G(36, 5180, 0),
8077 CHAN5G(40, 5200, 0),
8078 CHAN5G(44, 5220, 0),
8079 CHAN5G(48, 5240, 0),
8080 CHAN5G(52, 5260, 0),
8081 CHAN5G(56, 5280, 0),
8082 CHAN5G(60, 5300, 0),
8083 CHAN5G(64, 5320, 0),
8084 CHAN5G(100, 5500, 0),
8085 CHAN5G(104, 5520, 0),
8086 CHAN5G(108, 5540, 0),
8087 CHAN5G(112, 5560, 0),
8088 CHAN5G(116, 5580, 0),
8089 CHAN5G(120, 5600, 0),
8090 CHAN5G(124, 5620, 0),
8091 CHAN5G(128, 5640, 0),
8092 CHAN5G(132, 5660, 0),
8093 CHAN5G(136, 5680, 0),
8094 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07008095 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02008096 CHAN5G(149, 5745, 0),
8097 CHAN5G(153, 5765, 0),
8098 CHAN5G(157, 5785, 0),
8099 CHAN5G(161, 5805, 0),
8100 CHAN5G(165, 5825, 0),
Mohammed Shafi Shajakhan34c30b02016-12-27 20:53:35 +05308101 CHAN5G(169, 5845, 0),
Ben Greear38441fb2018-01-02 16:51:01 -08008102 CHAN5G(173, 5865, 0),
8103 /* If you add more, you may need to change ATH10K_MAX_5G_CHAN */
8104 /* And you will definitely need to change ATH10K_NUM_CHANS in core.h */
Kalle Valo5e3dd152013-06-12 20:52:10 +03008105};
8106
Michal Kaziore7b54192014-08-07 11:03:27 +02008107struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03008108{
8109 struct ieee80211_hw *hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03008110 struct ieee80211_ops *ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008111 struct ath10k *ar;
8112
Michal Kazior4ca18072016-07-18 23:22:18 +03008113 ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);
8114 if (!ops)
Kalle Valo5e3dd152013-06-12 20:52:10 +03008115 return NULL;
8116
Michal Kazior4ca18072016-07-18 23:22:18 +03008117 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);
8118 if (!hw) {
8119 kfree(ops);
8120 return NULL;
8121 }
8122
Kalle Valo5e3dd152013-06-12 20:52:10 +03008123 ar = hw->priv;
8124 ar->hw = hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03008125 ar->ops = ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008126
8127 return ar;
8128}
8129
8130void ath10k_mac_destroy(struct ath10k *ar)
8131{
Michal Kazior4ca18072016-07-18 23:22:18 +03008132 struct ieee80211_ops *ops = ar->ops;
8133
Kalle Valo5e3dd152013-06-12 20:52:10 +03008134 ieee80211_free_hw(ar->hw);
Michal Kazior4ca18072016-07-18 23:22:18 +03008135 kfree(ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008136}
8137
8138static const struct ieee80211_iface_limit ath10k_if_limits[] = {
8139 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308140 .max = 8,
8141 .types = BIT(NL80211_IFTYPE_STATION)
8142 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02008143 },
8144 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308145 .max = 3,
8146 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02008147 },
8148 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308149 .max = 1,
8150 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01008151 },
8152 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308153 .max = 7,
8154 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008155#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308156 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008157#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02008158 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03008159};
8160
Bartosz Markowskif2595092013-12-10 16:20:39 +01008161static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008162 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308163 .max = 8,
8164 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008165#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308166 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008167#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008168 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308169 {
8170 .max = 1,
8171 .types = BIT(NL80211_IFTYPE_STATION)
8172 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008173};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008174
8175static const struct ieee80211_iface_combination ath10k_if_comb[] = {
8176 {
8177 .limits = ath10k_if_limits,
8178 .n_limits = ARRAY_SIZE(ath10k_if_limits),
8179 .max_interfaces = 8,
8180 .num_different_channels = 1,
8181 .beacon_int_infra_match = true,
8182 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01008183};
8184
8185static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008186 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01008187 .limits = ath10k_10x_if_limits,
8188 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008189 .max_interfaces = 8,
8190 .num_different_channels = 1,
8191 .beacon_int_infra_match = true,
Anilkumar Kolli8ebee732018-03-28 12:19:40 +03008192 .beacon_int_min_gcd = 1,
Bartosz Markowskif2595092013-12-10 16:20:39 +01008193#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008194 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
8195 BIT(NL80211_CHAN_WIDTH_20) |
8196 BIT(NL80211_CHAN_WIDTH_40) |
8197 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008198#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01008199 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03008200};
8201
Michal Kaziorcf327842015-03-31 10:26:25 +00008202static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
8203 {
8204 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02008205 .types = BIT(NL80211_IFTYPE_STATION),
8206 },
8207 {
8208 .max = 2,
8209 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008210#ifdef CONFIG_MAC80211_MESH
8211 BIT(NL80211_IFTYPE_MESH_POINT) |
8212#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00008213 BIT(NL80211_IFTYPE_P2P_CLIENT) |
8214 BIT(NL80211_IFTYPE_P2P_GO),
8215 },
8216 {
8217 .max = 1,
8218 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
8219 },
8220};
8221
Michal Kaziored25b112015-07-09 13:08:39 +02008222static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
8223 {
8224 .max = 2,
8225 .types = BIT(NL80211_IFTYPE_STATION),
8226 },
8227 {
8228 .max = 2,
8229 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
8230 },
8231 {
8232 .max = 1,
8233 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008234#ifdef CONFIG_MAC80211_MESH
8235 BIT(NL80211_IFTYPE_MESH_POINT) |
8236#endif
Michal Kaziored25b112015-07-09 13:08:39 +02008237 BIT(NL80211_IFTYPE_P2P_GO),
8238 },
8239 {
8240 .max = 1,
8241 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
8242 },
8243};
8244
Michal Kaziorcf327842015-03-31 10:26:25 +00008245static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
8246 {
8247 .max = 1,
8248 .types = BIT(NL80211_IFTYPE_STATION),
8249 },
8250 {
8251 .max = 1,
8252 .types = BIT(NL80211_IFTYPE_ADHOC),
8253 },
8254};
8255
8256/* FIXME: This is not thouroughly tested. These combinations may over- or
8257 * underestimate hw/fw capabilities.
8258 */
8259static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
8260 {
8261 .limits = ath10k_tlv_if_limit,
8262 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02008263 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00008264 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
8265 },
8266 {
8267 .limits = ath10k_tlv_if_limit_ibss,
8268 .num_different_channels = 1,
8269 .max_interfaces = 2,
8270 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
8271 },
8272};
8273
8274static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
8275 {
8276 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02008277 .num_different_channels = 1,
8278 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00008279 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
8280 },
8281 {
Michal Kaziored25b112015-07-09 13:08:39 +02008282 .limits = ath10k_tlv_qcs_if_limit,
8283 .num_different_channels = 2,
8284 .max_interfaces = 4,
8285 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
8286 },
8287 {
Michal Kaziorcf327842015-03-31 10:26:25 +00008288 .limits = ath10k_tlv_if_limit_ibss,
8289 .num_different_channels = 1,
8290 .max_interfaces = 2,
8291 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
8292 },
8293};
8294
Raja Manicf36fef2015-06-22 20:22:25 +05308295static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
8296 {
8297 .max = 1,
8298 .types = BIT(NL80211_IFTYPE_STATION),
8299 },
8300 {
8301 .max = 16,
8302 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008303#ifdef CONFIG_MAC80211_MESH
8304 | BIT(NL80211_IFTYPE_MESH_POINT)
8305#endif
Raja Manicf36fef2015-06-22 20:22:25 +05308306 },
8307};
8308
8309static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
8310 {
8311 .limits = ath10k_10_4_if_limits,
8312 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
8313 .max_interfaces = 16,
8314 .num_different_channels = 1,
8315 .beacon_int_infra_match = true,
Anilkumar Kolli8ebee732018-03-28 12:19:40 +03008316 .beacon_int_min_gcd = 1,
Raja Manicf36fef2015-06-22 20:22:25 +05308317#ifdef CONFIG_ATH10K_DFS_CERTIFIED
8318 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
8319 BIT(NL80211_CHAN_WIDTH_20) |
8320 BIT(NL80211_CHAN_WIDTH_40) |
8321 BIT(NL80211_CHAN_WIDTH_80),
8322#endif
8323 },
8324};
8325
Maharaja Kennadyrajan46005632018-09-18 17:37:26 +05308326static const struct
8327ieee80211_iface_combination ath10k_10_4_bcn_int_if_comb[] = {
8328 {
8329 .limits = ath10k_10_4_if_limits,
8330 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
8331 .max_interfaces = 16,
8332 .num_different_channels = 1,
8333 .beacon_int_infra_match = true,
8334 .beacon_int_min_gcd = 100,
8335#ifdef CONFIG_ATH10K_DFS_CERTIFIED
8336 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
8337 BIT(NL80211_CHAN_WIDTH_20) |
8338 BIT(NL80211_CHAN_WIDTH_40) |
8339 BIT(NL80211_CHAN_WIDTH_80),
8340#endif
8341 },
8342};
8343
Kalle Valo5e3dd152013-06-12 20:52:10 +03008344static void ath10k_get_arvif_iter(void *data, u8 *mac,
8345 struct ieee80211_vif *vif)
8346{
8347 struct ath10k_vif_iter *arvif_iter = data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02008348 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008349
8350 if (arvif->vdev_id == arvif_iter->vdev_id)
8351 arvif_iter->arvif = arvif;
8352}
8353
8354struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
8355{
8356 struct ath10k_vif_iter arvif_iter;
8357 u32 flags;
8358
8359 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
8360 arvif_iter.vdev_id = vdev_id;
8361
8362 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
8363 ieee80211_iterate_active_interfaces_atomic(ar->hw,
8364 flags,
8365 ath10k_get_arvif_iter,
8366 &arvif_iter);
8367 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008368 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008369 return NULL;
8370 }
8371
8372 return arvif_iter.arvif;
8373}
8374
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008375#define WRD_METHOD "WRDD"
8376#define WRDD_WIFI (0x07)
8377
8378static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_object *wrdd)
8379{
8380 union acpi_object *mcc_pkg;
8381 union acpi_object *domain_type;
8382 union acpi_object *mcc_value;
8383 u32 i;
8384
8385 if (wrdd->type != ACPI_TYPE_PACKAGE ||
8386 wrdd->package.count < 2 ||
8387 wrdd->package.elements[0].type != ACPI_TYPE_INTEGER ||
8388 wrdd->package.elements[0].integer.value != 0) {
8389 ath10k_warn(ar, "ignoring malformed/unsupported wrdd structure\n");
8390 return 0;
8391 }
8392
8393 for (i = 1; i < wrdd->package.count; ++i) {
8394 mcc_pkg = &wrdd->package.elements[i];
8395
8396 if (mcc_pkg->type != ACPI_TYPE_PACKAGE)
8397 continue;
8398 if (mcc_pkg->package.count < 2)
8399 continue;
8400 if (mcc_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
8401 mcc_pkg->package.elements[1].type != ACPI_TYPE_INTEGER)
8402 continue;
8403
8404 domain_type = &mcc_pkg->package.elements[0];
8405 if (domain_type->integer.value != WRDD_WIFI)
8406 continue;
8407
8408 mcc_value = &mcc_pkg->package.elements[1];
8409 return mcc_value->integer.value;
8410 }
8411 return 0;
8412}
8413
8414static int ath10k_mac_get_wrdd_regulatory(struct ath10k *ar, u16 *rd)
8415{
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008416 acpi_handle root_handle;
8417 acpi_handle handle;
8418 struct acpi_buffer wrdd = {ACPI_ALLOCATE_BUFFER, NULL};
8419 acpi_status status;
8420 u32 alpha2_code;
8421 char alpha2[3];
8422
Brian Norris79169f12018-11-02 10:17:48 -07008423 root_handle = ACPI_HANDLE(ar->dev);
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008424 if (!root_handle)
8425 return -EOPNOTSUPP;
8426
8427 status = acpi_get_handle(root_handle, (acpi_string)WRD_METHOD, &handle);
8428 if (ACPI_FAILURE(status)) {
8429 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8430 "failed to get wrd method %d\n", status);
8431 return -EIO;
8432 }
8433
8434 status = acpi_evaluate_object(handle, NULL, NULL, &wrdd);
8435 if (ACPI_FAILURE(status)) {
8436 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8437 "failed to call wrdc %d\n", status);
8438 return -EIO;
8439 }
8440
8441 alpha2_code = ath10k_mac_wrdd_get_mcc(ar, wrdd.pointer);
8442 kfree(wrdd.pointer);
8443 if (!alpha2_code)
8444 return -EIO;
8445
8446 alpha2[0] = (alpha2_code >> 8) & 0xff;
8447 alpha2[1] = (alpha2_code >> 0) & 0xff;
8448 alpha2[2] = '\0';
8449
8450 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8451 "regulatory hint from WRDD (alpha2-code): %s\n", alpha2);
8452
8453 *rd = ath_regd_find_country_by_name(alpha2);
8454 if (*rd == 0xffff)
8455 return -EIO;
8456
8457 *rd |= COUNTRY_ERD_FLAG;
8458 return 0;
8459}
8460
8461static int ath10k_mac_init_rd(struct ath10k *ar)
8462{
8463 int ret;
8464 u16 rd;
8465
8466 ret = ath10k_mac_get_wrdd_regulatory(ar, &rd);
8467 if (ret) {
8468 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8469 "fallback to eeprom programmed regulatory settings\n");
8470 rd = ar->hw_eeprom_rd;
8471 }
8472
8473 ar->ath_common.regulatory.current_rd = rd;
8474 return 0;
8475}
8476
Kalle Valo5e3dd152013-06-12 20:52:10 +03008477int ath10k_mac_register(struct ath10k *ar)
8478{
Johannes Berg3cb10942015-01-22 21:38:45 +01008479 static const u32 cipher_suites[] = {
8480 WLAN_CIPHER_SUITE_WEP40,
8481 WLAN_CIPHER_SUITE_WEP104,
8482 WLAN_CIPHER_SUITE_TKIP,
8483 WLAN_CIPHER_SUITE_CCMP,
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07008484
8485 /* Do not add hardware supported ciphers before this line.
8486 * Allow software encryption for all chips. Don't forget to
8487 * update n_cipher_suites below.
8488 */
Johannes Berg3cb10942015-01-22 21:38:45 +01008489 WLAN_CIPHER_SUITE_AES_CMAC,
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07008490 WLAN_CIPHER_SUITE_BIP_CMAC_256,
8491 WLAN_CIPHER_SUITE_BIP_GMAC_128,
8492 WLAN_CIPHER_SUITE_BIP_GMAC_256,
8493
8494 /* Only QCA99x0 and QCA4019 varients support GCMP-128, GCMP-256
8495 * and CCMP-256 in hardware.
8496 */
8497 WLAN_CIPHER_SUITE_GCMP,
8498 WLAN_CIPHER_SUITE_GCMP_256,
8499 WLAN_CIPHER_SUITE_CCMP_256,
Johannes Berg3cb10942015-01-22 21:38:45 +01008500 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03008501 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008502 void *channels;
8503 int ret;
8504
Brian Norris234e4302018-09-07 10:21:57 -07008505 if (!is_valid_ether_addr(ar->mac_addr)) {
8506 ath10k_warn(ar, "invalid MAC address; choosing random\n");
8507 eth_random_addr(ar->mac_addr);
8508 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008509 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
8510
8511 SET_IEEE80211_DEV(ar->hw, ar->dev);
8512
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00008513 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
8514 ARRAY_SIZE(ath10k_5ghz_channels)) !=
8515 ATH10K_NUM_CHANS);
8516
Kalle Valo5e3dd152013-06-12 20:52:10 +03008517 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
8518 channels = kmemdup(ath10k_2ghz_channels,
8519 sizeof(ath10k_2ghz_channels),
8520 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02008521 if (!channels) {
8522 ret = -ENOMEM;
8523 goto err_free;
8524 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008525
Johannes Berg57fbcce2016-04-12 15:56:15 +02008526 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03008527 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
8528 band->channels = channels;
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +03008529
8530 if (ar->hw_params.cck_rate_map_rev2) {
8531 band->n_bitrates = ath10k_g_rates_rev2_size;
8532 band->bitrates = ath10k_g_rates_rev2;
8533 } else {
8534 band->n_bitrates = ath10k_g_rates_size;
8535 band->bitrates = ath10k_g_rates;
8536 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008537
Johannes Berg57fbcce2016-04-12 15:56:15 +02008538 ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008539 }
8540
8541 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
8542 channels = kmemdup(ath10k_5ghz_channels,
8543 sizeof(ath10k_5ghz_channels),
8544 GFP_KERNEL);
8545 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02008546 ret = -ENOMEM;
8547 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008548 }
8549
Johannes Berg57fbcce2016-04-12 15:56:15 +02008550 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03008551 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
8552 band->channels = channels;
8553 band->n_bitrates = ath10k_a_rates_size;
8554 band->bitrates = ath10k_a_rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02008555 ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008556 }
8557
Sven Eckelmann34d56292018-08-24 15:04:59 +03008558 wiphy_read_of_freq_limits(ar->hw->wiphy);
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05308559 ath10k_mac_setup_ht_vht_cap(ar);
8560
Kalle Valo5e3dd152013-06-12 20:52:10 +03008561 ar->hw->wiphy->interface_modes =
8562 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008563 BIT(NL80211_IFTYPE_AP) |
8564 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01008565
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05308566 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
8567 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03008568
Kalle Valoc4cdf752016-04-20 19:45:18 +03008569 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))
Bartosz Markowskid3541812013-12-10 16:20:40 +01008570 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01008571 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01008572 BIT(NL80211_IFTYPE_P2P_CLIENT) |
8573 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008574
Johannes Berg30686bf2015-06-02 21:39:54 +02008575 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
Venkateswara Naralasetty36d9cdb2017-10-04 12:22:57 +03008576
8577 if (!test_bit(ATH10K_FW_FEATURE_NO_PS,
8578 ar->running_fw->fw_file.fw_features)) {
8579 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
8580 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
8581 }
8582
Johannes Berg30686bf2015-06-02 21:39:54 +02008583 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
8584 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
8585 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
8586 ieee80211_hw_set(ar->hw, AP_LINK_PS);
8587 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02008588 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
8589 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
8590 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
8591 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
8592 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
8593 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Sara Sharonf3fe4e92016-10-18 23:12:11 +03008594 ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
Rajkumar Manoharanff32eeb2016-09-06 12:38:41 +05308595 ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008596
David Liuccec9032015-07-24 20:25:32 +03008597 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8598 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
8599
Eliad Peller0d8614b2014-09-10 14:07:36 +03008600 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00008601 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03008602
Kalle Valo5e3dd152013-06-12 20:52:10 +03008603 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03008604 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008605
8606 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02008607 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
8608 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008609 }
8610
8611 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
8612 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
8613
Wen Gongce834e22018-10-04 08:45:31 +03008614 if (test_bit(WMI_SERVICE_NLO, ar->wmi.svc_map)) {
8615 ar->hw->wiphy->max_sched_scan_reqs = 1;
8616 ar->hw->wiphy->max_sched_scan_ssids = WMI_PNO_MAX_SUPP_NETWORKS;
8617 ar->hw->wiphy->max_match_sets = WMI_PNO_MAX_SUPP_NETWORKS;
8618 ar->hw->wiphy->max_sched_scan_ie_len = WMI_PNO_MAX_IE_LENGTH;
8619 ar->hw->wiphy->max_sched_scan_plans = WMI_PNO_MAX_SCHED_SCAN_PLANS;
8620 ar->hw->wiphy->max_sched_scan_plan_interval =
8621 WMI_PNO_MAX_SCHED_SCAN_PLAN_INT;
8622 ar->hw->wiphy->max_sched_scan_plan_iterations =
8623 WMI_PNO_MAX_SCHED_SCAN_PLAN_ITRNS;
8624 }
8625
Kalle Valo5e3dd152013-06-12 20:52:10 +03008626 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01008627 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02008628 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008629
Kalle Valo5e3dd152013-06-12 20:52:10 +03008630 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
8631
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02008632 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
8633 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
8634
8635 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
8636 * that userspace (e.g. wpa_supplicant/hostapd) can generate
8637 * correct Probe Responses. This is more of a hack advert..
8638 */
8639 ar->hw->wiphy->probe_resp_offload |=
8640 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
8641 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
8642 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
8643 }
8644
Manikanta Pubbisettyadd6cd82017-07-28 15:15:42 +03008645 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map) ||
8646 test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, ar->wmi.svc_map)) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03008647 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
Balaji Pothunoori14d65772017-12-21 20:00:42 +05308648 if (test_bit(WMI_SERVICE_TDLS_WIDER_BANDWIDTH, ar->wmi.svc_map))
8649 ieee80211_hw_set(ar->hw, TDLS_WIDER_BW);
Manikanta Pubbisettyadd6cd82017-07-28 15:15:42 +03008650 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03008651
Yingying Tang802ca332018-03-28 12:12:52 +03008652 if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
8653 ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA);
8654
Kalle Valo5e3dd152013-06-12 20:52:10 +03008655 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01008656 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008657 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
8658
8659 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05308660 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
8661 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02008662
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01008663 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
8664
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02008665 ret = ath10k_wow_init(ar);
8666 if (ret) {
8667 ath10k_warn(ar, "failed to init wow: %d\n", ret);
8668 goto err_free;
8669 }
8670
Janusz Dziedzicc7025342015-06-15 14:46:41 +03008671 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03008672 wiphy_ext_feature_set(ar->hw->wiphy,
8673 NL80211_EXT_FEATURE_SET_SCAN_DWELL);
Janusz Dziedzicc7025342015-06-15 14:46:41 +03008674
Balaji Pothunoori6bc17952018-09-10 11:54:30 +05308675 if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map) ||
8676 test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, ar->wmi.svc_map))
Balaji Pothunooric7fd8d22018-09-04 12:52:18 +03008677 wiphy_ext_feature_set(ar->hw->wiphy,
Balaji Pothunoori6bc17952018-09-10 11:54:30 +05308678 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
Balaji Pothunooric7fd8d22018-09-04 12:52:18 +03008679
Kan Yand1ce37b2019-02-11 18:47:52 +02008680 if (ath10k_peer_stats_enabled(ar))
8681 wiphy_ext_feature_set(ar->hw->wiphy,
8682 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
Pradeep Kumar Chitrapu059104b2019-02-11 18:47:54 +02008683
8684 if (test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map))
8685 wiphy_ext_feature_set(ar->hw->wiphy,
8686 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
8687
Kalle Valo5e3dd152013-06-12 20:52:10 +03008688 /*
8689 * on LL hardware queues are managed entirely by the FW
8690 * so we only advertise to mac we can do the queues thing
8691 */
Michal Kazior96d828d2015-03-31 10:26:23 +00008692 ar->hw->queues = IEEE80211_MAX_QUEUES;
8693
8694 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
8695 * something that vdev_ids can't reach so that we don't stop the queue
8696 * accidentally.
8697 */
8698 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008699
Kalle Valobf3c13a2016-04-20 19:45:33 +03008700 switch (ar->running_fw->fw_file.wmi_op_version) {
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008701 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01008702 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
8703 ar->hw->wiphy->n_iface_combinations =
8704 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03008705 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008706 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00008707 case ATH10K_FW_WMI_OP_VERSION_TLV:
8708 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
8709 ar->hw->wiphy->iface_combinations =
8710 ath10k_tlv_qcs_if_comb;
8711 ar->hw->wiphy->n_iface_combinations =
8712 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
8713 } else {
8714 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
8715 ar->hw->wiphy->n_iface_combinations =
8716 ARRAY_SIZE(ath10k_tlv_if_comb);
8717 }
8718 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
8719 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008720 case ATH10K_FW_WMI_OP_VERSION_10_1:
8721 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02008722 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008723 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
8724 ar->hw->wiphy->n_iface_combinations =
8725 ARRAY_SIZE(ath10k_10x_if_comb);
8726 break;
Raja Mani9bd21322015-06-22 20:10:09 +05308727 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05308728 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
8729 ar->hw->wiphy->n_iface_combinations =
8730 ARRAY_SIZE(ath10k_10_4_if_comb);
Maharaja Kennadyrajan46005632018-09-18 17:37:26 +05308731 if (test_bit(WMI_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT,
8732 ar->wmi.svc_map)) {
8733 ar->hw->wiphy->iface_combinations =
8734 ath10k_10_4_bcn_int_if_comb;
8735 ar->hw->wiphy->n_iface_combinations =
8736 ARRAY_SIZE(ath10k_10_4_bcn_int_if_comb);
8737 }
Raja Mani9bd21322015-06-22 20:10:09 +05308738 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008739 case ATH10K_FW_WMI_OP_VERSION_UNSET:
8740 case ATH10K_FW_WMI_OP_VERSION_MAX:
8741 WARN_ON(1);
8742 ret = -EINVAL;
8743 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01008744 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008745
David Liuccec9032015-07-24 20:25:32 +03008746 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8747 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02008748
Masahiro Yamada97f26452016-08-03 13:45:50 -07008749 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008750 /* Init ath dfs pattern detector */
8751 ar->ath_common.debug_mask = ATH_DBG_DFS;
8752 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
8753 NL80211_DFS_UNSET);
8754
8755 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02008756 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008757 }
8758
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008759 ret = ath10k_mac_init_rd(ar);
8760 if (ret) {
8761 ath10k_err(ar, "failed to derive regdom: %d\n", ret);
8762 goto err_dfs_detector_exit;
8763 }
8764
Benjamin Bergebee76f2016-09-28 15:11:58 +03008765 /* Disable set_coverage_class for chipsets that do not support it. */
8766 if (!ar->hw_params.hw_ops->set_coverage_class)
8767 ar->ops->set_coverage_class = NULL;
8768
Kalle Valo5e3dd152013-06-12 20:52:10 +03008769 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
8770 ath10k_reg_notifier);
8771 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008772 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008773 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008774 }
8775
Carl Huang60e1d0f2018-04-19 19:39:40 +03008776 if (test_bit(WMI_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi.svc_map)) {
Carl Huang60e1d0f2018-04-19 19:39:40 +03008777 ar->hw->wiphy->features |=
8778 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
8779 }
8780
Johannes Berg3cb10942015-01-22 21:38:45 +01008781 ar->hw->wiphy->cipher_suites = cipher_suites;
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07008782
8783 /* QCA988x and QCA6174 family chips do not support CCMP-256, GCMP-128
8784 * and GCMP-256 ciphers in hardware. Fetch number of ciphers supported
8785 * from chip specific hw_param table.
8786 */
8787 if (!ar->hw_params.n_cipher_suites ||
8788 ar->hw_params.n_cipher_suites > ARRAY_SIZE(cipher_suites)) {
8789 ath10k_err(ar, "invalid hw_params.n_cipher_suites %d\n",
8790 ar->hw_params.n_cipher_suites);
8791 ar->hw_params.n_cipher_suites = 8;
8792 }
8793 ar->hw->wiphy->n_cipher_suites = ar->hw_params.n_cipher_suites;
Johannes Berg3cb10942015-01-22 21:38:45 +01008794
Andrew Zaborowskiae44b502017-02-10 04:50:23 +01008795 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
8796
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02008797 ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
8798
Kalle Valo5e3dd152013-06-12 20:52:10 +03008799 ret = ieee80211_register_hw(ar->hw);
8800 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008801 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008802 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008803 }
8804
8805 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
8806 ret = regulatory_hint(ar->hw->wiphy,
8807 ar->ath_common.regulatory.alpha2);
8808 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02008809 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008810 }
8811
8812 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02008813
8814err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03008815 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07008816
8817err_dfs_detector_exit:
Masahiro Yamada97f26452016-08-03 13:45:50 -07008818 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Jeff Johnson0e339442015-10-08 09:15:53 -07008819 ar->dfs_detector->exit(ar->dfs_detector);
8820
Michal Kaziord6015b22013-07-22 14:13:30 +02008821err_free:
Johannes Berg57fbcce2016-04-12 15:56:15 +02008822 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8823 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Michal Kaziord6015b22013-07-22 14:13:30 +02008824
Jeff Johnson0e339442015-10-08 09:15:53 -07008825 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008826 return ret;
8827}
8828
8829void ath10k_mac_unregister(struct ath10k *ar)
8830{
8831 ieee80211_unregister_hw(ar->hw);
8832
Masahiro Yamada97f26452016-08-03 13:45:50 -07008833 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008834 ar->dfs_detector->exit(ar->dfs_detector);
8835
Johannes Berg57fbcce2016-04-12 15:56:15 +02008836 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8837 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008838
8839 SET_IEEE80211_DEV(ar->hw, NULL);
8840}