blob: 22774e12750708991cfecb417747708a4d0c6250 [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;
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003400 const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003401 __le16 fc = hdr->frame_control;
3402
3403 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3404 return ATH10K_HW_TXRX_RAW;
3405
3406 if (ieee80211_is_mgmt(fc))
3407 return ATH10K_HW_TXRX_MGMT;
3408
3409 /* Workaround:
3410 *
3411 * NullFunc frames are mostly used to ping if a client or AP are still
3412 * reachable and responsive. This implies tx status reports must be
3413 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3414 * come to a conclusion that the other end disappeared and tear down
3415 * BSS connection or it can never disconnect from BSS/client (which is
3416 * the case).
3417 *
3418 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3419 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3420 * which seems to deliver correct tx reports for NullFunc frames. The
3421 * downside of using it is it ignores client powersave state so it can
3422 * end up disconnecting sleeping clients in AP mode. It should fix STA
3423 * mode though because AP don't sleep.
3424 */
3425 if (ar->htt.target_version_major < 3 &&
3426 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03003427 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3428 ar->running_fw->fw_file.fw_features))
Michal Kaziord740d8f2015-03-30 09:51:51 +03003429 return ATH10K_HW_TXRX_MGMT;
3430
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003431 /* Workaround:
3432 *
3433 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3434 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3435 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003436 *
3437 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003438 */
3439 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3440 return ATH10K_HW_TXRX_ETHERNET;
3441
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003442 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) ||
3443 skb_cb->flags & ATH10K_SKB_F_RAW_TX)
David Liuccec9032015-07-24 20:25:32 +03003444 return ATH10K_HW_TXRX_RAW;
3445
Michal Kaziord740d8f2015-03-30 09:51:51 +03003446 return ATH10K_HW_TXRX_NATIVE_WIFI;
3447}
3448
David Liuccec9032015-07-24 20:25:32 +03003449static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003450 struct sk_buff *skb)
3451{
3452 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3453 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003454 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3455 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003456
3457 if (!ieee80211_has_protected(hdr->frame_control))
3458 return false;
3459
David Liuccec9032015-07-24 20:25:32 +03003460 if ((info->flags & mask) == mask)
3461 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003462
David Liuccec9032015-07-24 20:25:32 +03003463 if (vif)
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003464 return !((struct ath10k_vif *)vif->drv_priv)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003465
David Liuccec9032015-07-24 20:25:32 +03003466 return true;
3467}
3468
Michal Kazior4b604552014-07-21 21:03:09 +03003469/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3470 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003471 */
Michal Kazior4b604552014-07-21 21:03:09 +03003472static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003473{
3474 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003475 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003476 u8 *qos_ctl;
3477
3478 if (!ieee80211_is_data_qos(hdr->frame_control))
3479 return;
3480
3481 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003482 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3483 skb->data, (void *)qos_ctl - (void *)skb->data);
3484 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003485
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003486 /* Some firmware revisions don't handle sending QoS NullFunc well.
3487 * These frames are mainly used for CQM purposes so it doesn't really
3488 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003489 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003490 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003491 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003492 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003493
3494 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003495}
3496
Michal Kaziord740d8f2015-03-30 09:51:51 +03003497static void ath10k_tx_h_8023(struct sk_buff *skb)
3498{
3499 struct ieee80211_hdr *hdr;
3500 struct rfc1042_hdr *rfc1042;
3501 struct ethhdr *eth;
3502 size_t hdrlen;
3503 u8 da[ETH_ALEN];
3504 u8 sa[ETH_ALEN];
3505 __be16 type;
3506
3507 hdr = (void *)skb->data;
3508 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3509 rfc1042 = (void *)skb->data + hdrlen;
3510
3511 ether_addr_copy(da, ieee80211_get_DA(hdr));
3512 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3513 type = rfc1042->snap_type;
3514
3515 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3516 skb_push(skb, sizeof(*eth));
3517
3518 eth = (void *)skb->data;
3519 ether_addr_copy(eth->h_dest, da);
3520 ether_addr_copy(eth->h_source, sa);
3521 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003522}
3523
Michal Kazior4b604552014-07-21 21:03:09 +03003524static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3525 struct ieee80211_vif *vif,
3526 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003527{
3528 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003529 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003530
3531 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003532 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003533 return;
3534
3535 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3536 spin_lock_bh(&ar->data_lock);
3537 if (arvif->u.ap.noa_data)
3538 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3539 GFP_ATOMIC))
Johannes Berg59ae1d12017-06-16 14:29:20 +02003540 skb_put_data(skb, arvif->u.ap.noa_data,
3541 arvif->u.ap.noa_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003542 spin_unlock_bh(&ar->data_lock);
3543 }
3544}
3545
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003546static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3547 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003548 struct ieee80211_txq *txq,
Kan Yand1ce37b2019-02-11 18:47:52 +02003549 struct sk_buff *skb, u16 airtime)
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003550{
3551 struct ieee80211_hdr *hdr = (void *)skb->data;
3552 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003553 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3554 bool is_data = ieee80211_is_data(hdr->frame_control) ||
3555 ieee80211_is_data_qos(hdr->frame_control);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003556
3557 cb->flags = 0;
3558 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3559 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3560
3561 if (ieee80211_is_mgmt(hdr->frame_control))
3562 cb->flags |= ATH10K_SKB_F_MGMT;
3563
3564 if (ieee80211_is_data_qos(hdr->frame_control))
3565 cb->flags |= ATH10K_SKB_F_QOS;
3566
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003567 /* Data frames encrypted in software will be posted to firmware
3568 * with tx encap mode set to RAW. Ex: Multicast traffic generated
3569 * for a specific VLAN group will always be encrypted in software.
3570 */
3571 if (is_data && ieee80211_has_protected(hdr->frame_control) &&
3572 !info->control.hw_key) {
3573 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3574 cb->flags |= ATH10K_SKB_F_RAW_TX;
3575 }
3576
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003577 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003578 cb->txq = txq;
Kan Yand1ce37b2019-02-11 18:47:52 +02003579 cb->airtime_est = airtime;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003580}
3581
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303582bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003583{
3584 /* FIXME: Not really sure since when the behaviour changed. At some
3585 * point new firmware stopped requiring creation of peer entries for
3586 * offchannel tx (and actually creating them causes issues with wmi-htc
3587 * tx credit replenishment and reliability). Assuming it's at least 3.4
3588 * because that's when the `freq` was introduced to TX_FRM HTT command.
3589 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303590 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303591 ar->htt.target_version_minor >= 4 &&
Kalle Valo77561f92016-04-20 19:45:47 +03003592 ar->running_fw->fw_file.htt_op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003593}
3594
Michal Kaziord740d8f2015-03-30 09:51:51 +03003595static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003596{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003597 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003598 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003599
Michal Kaziord740d8f2015-03-30 09:51:51 +03003600 spin_lock_bh(&ar->data_lock);
3601
3602 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3603 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3604 ret = -ENOSPC;
3605 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003606 }
3607
Michal Kaziord740d8f2015-03-30 09:51:51 +03003608 __skb_queue_tail(q, skb);
3609 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3610
3611unlock:
3612 spin_unlock_bh(&ar->data_lock);
3613
3614 return ret;
3615}
3616
Michal Kaziora30c7d02016-03-06 16:14:23 +02003617static enum ath10k_mac_tx_path
3618ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3619 struct sk_buff *skb,
3620 enum ath10k_hw_txrx_mode txmode)
3621{
3622 switch (txmode) {
3623 case ATH10K_HW_TXRX_RAW:
3624 case ATH10K_HW_TXRX_NATIVE_WIFI:
3625 case ATH10K_HW_TXRX_ETHERNET:
3626 return ATH10K_MAC_TX_HTT;
3627 case ATH10K_HW_TXRX_MGMT:
3628 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Rakesh Pillai229329f2017-12-11 19:52:52 +05303629 ar->running_fw->fw_file.fw_features) ||
3630 test_bit(WMI_SERVICE_MGMT_TX_WMI,
3631 ar->wmi.svc_map))
Michal Kaziora30c7d02016-03-06 16:14:23 +02003632 return ATH10K_MAC_TX_WMI_MGMT;
3633 else if (ar->htt.target_version_major >= 3)
3634 return ATH10K_MAC_TX_HTT;
3635 else
3636 return ATH10K_MAC_TX_HTT_MGMT;
3637 }
3638
3639 return ATH10K_MAC_TX_UNKNOWN;
3640}
3641
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003642static int ath10k_mac_tx_submit(struct ath10k *ar,
3643 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003644 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003645 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003646{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003647 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003648 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003649
3650 switch (txpath) {
3651 case ATH10K_MAC_TX_HTT:
Erik Stromdahl5df6e132018-04-15 14:22:27 +02003652 ret = ath10k_htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003653 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003654 case ATH10K_MAC_TX_HTT_MGMT:
3655 ret = ath10k_htt_mgmt_tx(htt, skb);
3656 break;
3657 case ATH10K_MAC_TX_WMI_MGMT:
3658 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3659 break;
3660 case ATH10K_MAC_TX_UNKNOWN:
3661 WARN_ON_ONCE(1);
3662 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003663 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003664 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003665
3666 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003667 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3668 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003669 ieee80211_free_txskb(ar->hw, skb);
3670 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003671
3672 return ret;
3673}
3674
3675/* This function consumes the sk_buff regardless of return value as far as
3676 * caller is concerned so no freeing is necessary afterwards.
3677 */
3678static int ath10k_mac_tx(struct ath10k *ar,
3679 struct ieee80211_vif *vif,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003680 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003681 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003682 struct sk_buff *skb)
3683{
3684 struct ieee80211_hw *hw = ar->hw;
3685 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003686 const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003687 int ret;
3688
3689 /* We should disable CCK RATE due to P2P */
3690 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3691 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3692
3693 switch (txmode) {
3694 case ATH10K_HW_TXRX_MGMT:
3695 case ATH10K_HW_TXRX_NATIVE_WIFI:
3696 ath10k_tx_h_nwifi(hw, skb);
3697 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3698 ath10k_tx_h_seq_no(vif, skb);
3699 break;
3700 case ATH10K_HW_TXRX_ETHERNET:
3701 ath10k_tx_h_8023(skb);
3702 break;
3703 case ATH10K_HW_TXRX_RAW:
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02003704 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) &&
3705 !(skb_cb->flags & ATH10K_SKB_F_RAW_TX)) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003706 WARN_ON_ONCE(1);
3707 ieee80211_free_txskb(hw, skb);
3708 return -ENOTSUPP;
3709 }
3710 }
3711
3712 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3713 if (!ath10k_mac_tx_frm_has_freq(ar)) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303714 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %pK\n",
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003715 skb);
3716
3717 skb_queue_tail(&ar->offchan_tx_queue, skb);
3718 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3719 return 0;
3720 }
3721 }
3722
Michal Kazior6421969f2016-03-06 16:14:25 +02003723 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003724 if (ret) {
3725 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3726 return ret;
3727 }
3728
3729 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003730}
3731
3732void ath10k_offchan_tx_purge(struct ath10k *ar)
3733{
3734 struct sk_buff *skb;
3735
3736 for (;;) {
3737 skb = skb_dequeue(&ar->offchan_tx_queue);
3738 if (!skb)
3739 break;
3740
3741 ieee80211_free_txskb(ar->hw, skb);
3742 }
3743}
3744
3745void ath10k_offchan_tx_work(struct work_struct *work)
3746{
3747 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3748 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003749 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003750 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003751 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003752 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003753 struct ieee80211_vif *vif;
3754 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003755 struct sk_buff *skb;
3756 const u8 *peer_addr;
3757 int vdev_id;
3758 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003759 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003760 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003761
3762 /* FW requirement: We must create a peer before FW will send out
3763 * an offchannel frame. Otherwise the frame will be stuck and
3764 * never transmitted. We delete the peer upon tx completion.
3765 * It is unlikely that a peer for offchannel tx will already be
3766 * present. However it may be in some rare cases so account for that.
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01003767 * Otherwise we might remove a legitimate peer and break stuff.
3768 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003769
3770 for (;;) {
3771 skb = skb_dequeue(&ar->offchan_tx_queue);
3772 if (!skb)
3773 break;
3774
3775 mutex_lock(&ar->conf_mutex);
3776
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303777 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003778 skb);
3779
3780 hdr = (struct ieee80211_hdr *)skb->data;
3781 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003782
3783 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003784 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003785 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3786 spin_unlock_bh(&ar->data_lock);
3787
3788 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003789 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003790 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003791 peer_addr, vdev_id);
3792
3793 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003794 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3795 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003796 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003797 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003798 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003799 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003800 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003801 }
3802
3803 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003804 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003805 ar->offchan_tx_skb = skb;
3806 spin_unlock_bh(&ar->data_lock);
3807
Michal Kazior8a933962015-11-18 06:59:17 +01003808 /* It's safe to access vif and sta - conf_mutex guarantees that
3809 * sta_state() and remove_interface() are locked exclusively
3810 * out wrt to this offchannel worker.
3811 */
3812 arvif = ath10k_get_arvif(ar, vdev_id);
3813 if (arvif) {
3814 vif = arvif->vif;
3815 sta = ieee80211_find_sta(vif, peer_addr);
3816 } else {
3817 vif = NULL;
3818 sta = NULL;
3819 }
3820
3821 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003822 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003823
Mohammed Shafi Shajakhana7773b5d2016-12-27 19:02:35 +05303824 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003825 if (ret) {
3826 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3827 ret);
3828 /* not serious */
3829 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003830
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003831 time_left =
3832 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3833 if (time_left == 0)
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303834 ath10k_warn(ar, "timed out waiting for offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003835 skb);
3836
Michal Kazioradaeed72015-08-05 12:15:23 +02003837 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003838 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3839 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003840 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003841 peer_addr, vdev_id, ret);
3842 }
3843
3844 mutex_unlock(&ar->conf_mutex);
3845 }
3846}
3847
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003848void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3849{
3850 struct sk_buff *skb;
3851
3852 for (;;) {
3853 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3854 if (!skb)
3855 break;
3856
3857 ieee80211_free_txskb(ar->hw, skb);
3858 }
3859}
3860
3861void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3862{
3863 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3864 struct sk_buff *skb;
Rakesh Pillai38a13902018-02-27 19:09:07 +02003865 dma_addr_t paddr;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003866 int ret;
3867
3868 for (;;) {
3869 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3870 if (!skb)
3871 break;
3872
Rakesh Pillai38a13902018-02-27 19:09:07 +02003873 if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF,
3874 ar->running_fw->fw_file.fw_features)) {
3875 paddr = dma_map_single(ar->dev, skb->data,
3876 skb->len, DMA_TO_DEVICE);
3877 if (!paddr)
3878 continue;
3879 ret = ath10k_wmi_mgmt_tx_send(ar, skb, paddr);
3880 if (ret) {
3881 ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n",
3882 ret);
3883 dma_unmap_single(ar->dev, paddr, skb->len,
Rakesh Pillai6e8a8992019-01-25 09:51:06 +05303884 DMA_TO_DEVICE);
Rakesh Pillai38a13902018-02-27 19:09:07 +02003885 ieee80211_free_txskb(ar->hw, skb);
3886 }
3887 } else {
3888 ret = ath10k_wmi_mgmt_tx(ar, skb);
3889 if (ret) {
3890 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
3891 ret);
3892 ieee80211_free_txskb(ar->hw, skb);
3893 }
Michal Kazior5fb5e412013-10-28 07:18:13 +01003894 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003895 }
3896}
3897
Michal Kazior29946872016-03-06 16:14:34 +02003898static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3899{
Bob Copelanda66cd732016-06-29 19:29:25 +03003900 struct ath10k_txq *artxq;
Michal Kazior29946872016-03-06 16:14:34 +02003901
3902 if (!txq)
3903 return;
3904
Bob Copelanda66cd732016-06-29 19:29:25 +03003905 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003906 INIT_LIST_HEAD(&artxq->list);
3907}
3908
3909static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3910{
Michal Kaziordd4717b2016-03-06 16:14:39 +02003911 struct ath10k_skb_cb *cb;
3912 struct sk_buff *msdu;
3913 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003914
3915 if (!txq)
3916 return;
3917
Michal Kaziordd4717b2016-03-06 16:14:39 +02003918 spin_lock_bh(&ar->htt.tx_lock);
3919 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3920 cb = ATH10K_SKB_CB(msdu);
3921 if (cb->txq == txq)
3922 cb->txq = NULL;
3923 }
3924 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003925}
3926
Michal Kazior426e10e2016-03-06 16:14:43 +02003927struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
3928 u16 peer_id,
3929 u8 tid)
3930{
3931 struct ath10k_peer *peer;
3932
3933 lockdep_assert_held(&ar->data_lock);
3934
3935 peer = ar->peer_map[peer_id];
3936 if (!peer)
3937 return NULL;
3938
Michal Kazior0a744d92017-01-12 16:14:30 +01003939 if (peer->removed)
3940 return NULL;
3941
Michal Kazior426e10e2016-03-06 16:14:43 +02003942 if (peer->sta)
3943 return peer->sta->txq[tid];
3944 else if (peer->vif)
3945 return peer->vif->txq;
3946 else
3947 return NULL;
3948}
3949
Michal Kazior29946872016-03-06 16:14:34 +02003950static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3951 struct ieee80211_txq *txq)
3952{
Michal Kazior426e10e2016-03-06 16:14:43 +02003953 struct ath10k *ar = hw->priv;
3954 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3955
3956 /* No need to get locks */
Michal Kazior426e10e2016-03-06 16:14:43 +02003957 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3958 return true;
3959
3960 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3961 return true;
3962
3963 if (artxq->num_fw_queued < artxq->num_push_allowed)
3964 return true;
3965
3966 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003967}
3968
Kan Yand1ce37b2019-02-11 18:47:52 +02003969/* Return estimated airtime in microsecond, which is calculated using last
3970 * reported TX rate. This is just a rough estimation because host driver has no
3971 * knowledge of the actual transmit rate, retries or aggregation. If actual
3972 * airtime can be reported by firmware, then delta between estimated and actual
3973 * airtime can be adjusted from deficit.
3974 */
3975#define IEEE80211_ATF_OVERHEAD 100 /* IFS + some slot time */
3976#define IEEE80211_ATF_OVERHEAD_IFS 16 /* IFS only */
3977static u16 ath10k_mac_update_airtime(struct ath10k *ar,
3978 struct ieee80211_txq *txq,
3979 struct sk_buff *skb)
3980{
3981 struct ath10k_sta *arsta;
3982 u32 pktlen;
3983 u16 airtime = 0;
3984
3985 if (!txq || !txq->sta)
3986 return airtime;
3987
3988 spin_lock_bh(&ar->data_lock);
3989 arsta = (struct ath10k_sta *)txq->sta->drv_priv;
3990
3991 pktlen = skb->len + 38; /* Assume MAC header 30, SNAP 8 for most case */
3992 if (arsta->last_tx_bitrate) {
3993 /* airtime in us, last_tx_bitrate in 100kbps */
3994 airtime = (pktlen * 8 * (1000 / 100))
3995 / arsta->last_tx_bitrate;
3996 /* overhead for media access time and IFS */
3997 airtime += IEEE80211_ATF_OVERHEAD_IFS;
3998 } else {
3999 /* This is mostly for throttle excessive BC/MC frames, and the
4000 * airtime/rate doesn't need be exact. Airtime of BC/MC frames
4001 * in 2G get some discount, which helps prevent very low rate
4002 * frames from being blocked for too long.
4003 */
4004 airtime = (pktlen * 8 * (1000 / 100)) / 60; /* 6M */
4005 airtime += IEEE80211_ATF_OVERHEAD;
4006 }
4007 spin_unlock_bh(&ar->data_lock);
4008
4009 return airtime;
4010}
4011
Michal Kazior426e10e2016-03-06 16:14:43 +02004012int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
4013 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02004014{
Michal Kazior29946872016-03-06 16:14:34 +02004015 struct ath10k *ar = hw->priv;
4016 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02004017 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02004018 struct ieee80211_vif *vif = txq->vif;
4019 struct ieee80211_sta *sta = txq->sta;
4020 enum ath10k_hw_txrx_mode txmode;
4021 enum ath10k_mac_tx_path txpath;
4022 struct sk_buff *skb;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304023 struct ieee80211_hdr *hdr;
Michal Kazior426e10e2016-03-06 16:14:43 +02004024 size_t skb_len;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304025 bool is_mgmt, is_presp;
Michal Kazior29946872016-03-06 16:14:34 +02004026 int ret;
Kan Yand1ce37b2019-02-11 18:47:52 +02004027 u16 airtime;
Michal Kazior29946872016-03-06 16:14:34 +02004028
4029 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304030 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02004031 spin_unlock_bh(&ar->htt.tx_lock);
4032
4033 if (ret)
4034 return ret;
4035
4036 skb = ieee80211_tx_dequeue(hw, txq);
4037 if (!skb) {
4038 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304039 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02004040 spin_unlock_bh(&ar->htt.tx_lock);
4041
4042 return -ENOENT;
4043 }
4044
Kan Yand1ce37b2019-02-11 18:47:52 +02004045 airtime = ath10k_mac_update_airtime(ar, txq, skb);
4046 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
Michal Kazior29946872016-03-06 16:14:34 +02004047
Michal Kazior426e10e2016-03-06 16:14:43 +02004048 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02004049 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
4050 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304051 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
4052
4053 if (is_mgmt) {
4054 hdr = (struct ieee80211_hdr *)skb->data;
4055 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4056
4057 spin_lock_bh(&ar->htt.tx_lock);
4058 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4059
4060 if (ret) {
4061 ath10k_htt_tx_dec_pending(htt);
4062 spin_unlock_bh(&ar->htt.tx_lock);
4063 return ret;
4064 }
4065 spin_unlock_bh(&ar->htt.tx_lock);
4066 }
Michal Kazior29946872016-03-06 16:14:34 +02004067
Mohammed Shafi Shajakhana7773b5d2016-12-27 19:02:35 +05304068 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
Michal Kazior29946872016-03-06 16:14:34 +02004069 if (unlikely(ret)) {
4070 ath10k_warn(ar, "failed to push frame: %d\n", ret);
4071
4072 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304073 ath10k_htt_tx_dec_pending(htt);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05304074 if (is_mgmt)
4075 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02004076 spin_unlock_bh(&ar->htt.tx_lock);
4077
4078 return ret;
4079 }
4080
Michal Kazior3cc0fef2016-03-06 16:14:41 +02004081 spin_lock_bh(&ar->htt.tx_lock);
4082 artxq->num_fw_queued++;
4083 spin_unlock_bh(&ar->htt.tx_lock);
4084
Michal Kazior426e10e2016-03-06 16:14:43 +02004085 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02004086}
4087
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004088static int ath10k_mac_schedule_txq(struct ieee80211_hw *hw, u32 ac)
Michal Kazior29946872016-03-06 16:14:34 +02004089{
Michal Kazior29946872016-03-06 16:14:34 +02004090 struct ieee80211_txq *txq;
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004091 int ret = 0;
Michal Kazior29946872016-03-06 16:14:34 +02004092
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004093 ieee80211_txq_schedule_start(hw, ac);
4094 while ((txq = ieee80211_next_txq(hw, ac))) {
4095 while (ath10k_mac_tx_can_push(hw, txq)) {
Michal Kazior29946872016-03-06 16:14:34 +02004096 ret = ath10k_mac_tx_push_txq(hw, txq);
4097 if (ret < 0)
4098 break;
4099 }
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004100 ieee80211_return_txq(hw, txq);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004101 ath10k_htt_tx_txq_update(hw, txq);
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004102 if (ret == -EBUSY)
Michal Kazior29946872016-03-06 16:14:34 +02004103 break;
Michal Kazior29946872016-03-06 16:14:34 +02004104 }
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004105 ieee80211_txq_schedule_end(hw, ac);
Michal Kazior29946872016-03-06 16:14:34 +02004106
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004107 return ret;
4108}
4109
4110void ath10k_mac_tx_push_pending(struct ath10k *ar)
4111{
4112 struct ieee80211_hw *hw = ar->hw;
4113 u32 ac;
4114
4115 if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)
4116 return;
4117
4118 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
4119 return;
4120
4121 rcu_read_lock();
4122 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
4123 if (ath10k_mac_schedule_txq(hw, ac) == -EBUSY)
4124 break;
4125 }
Michal Kazior29946872016-03-06 16:14:34 +02004126 rcu_read_unlock();
Michal Kazior29946872016-03-06 16:14:34 +02004127}
Niklas Cassel3f049502018-06-18 17:00:49 +03004128EXPORT_SYMBOL(ath10k_mac_tx_push_pending);
Michal Kazior29946872016-03-06 16:14:34 +02004129
Kalle Valo5e3dd152013-06-12 20:52:10 +03004130/************/
4131/* Scanning */
4132/************/
4133
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004134void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004135{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004136 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004137
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004138 switch (ar->scan.state) {
4139 case ATH10K_SCAN_IDLE:
4140 break;
4141 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01004142 case ATH10K_SCAN_ABORTING:
Avraham Stern7947d3e2016-07-05 15:23:12 +03004143 if (!ar->scan.is_roc) {
4144 struct cfg80211_scan_info info = {
4145 .aborted = (ar->scan.state ==
4146 ATH10K_SCAN_ABORTING),
4147 };
4148
4149 ieee80211_scan_completed(ar->hw, &info);
4150 } else if (ar->scan.roc_notify) {
Michal Kaziord710e752015-07-09 13:08:36 +02004151 ieee80211_remain_on_channel_expired(ar->hw);
Avraham Stern7947d3e2016-07-05 15:23:12 +03004152 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004153 /* fall through */
4154 case ATH10K_SCAN_STARTING:
4155 ar->scan.state = ATH10K_SCAN_IDLE;
4156 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01004157 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004158 ath10k_offchan_tx_purge(ar);
4159 cancel_delayed_work(&ar->scan.timeout);
Daniel Wagner881ed542016-08-18 15:12:06 +02004160 complete(&ar->scan.completed);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004161 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004162 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004163}
Kalle Valo5e3dd152013-06-12 20:52:10 +03004164
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004165void ath10k_scan_finish(struct ath10k *ar)
4166{
4167 spin_lock_bh(&ar->data_lock);
4168 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004169 spin_unlock_bh(&ar->data_lock);
4170}
4171
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004172static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004173{
4174 struct wmi_stop_scan_arg arg = {
4175 .req_id = 1, /* FIXME */
4176 .req_type = WMI_SCAN_STOP_ONE,
4177 .u.scan_id = ATH10K_SCAN_ID,
4178 };
4179 int ret;
4180
4181 lockdep_assert_held(&ar->conf_mutex);
4182
Kalle Valo5e3dd152013-06-12 20:52:10 +03004183 ret = ath10k_wmi_stop_scan(ar, &arg);
4184 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004185 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004186 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004187 }
4188
Kalle Valo14e105c2016-04-13 14:13:21 +03004189 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004190 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004191 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004192 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004193 } else if (ret > 0) {
4194 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004195 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004196
4197out:
4198 /* Scan state should be updated upon scan completion but in case
4199 * firmware fails to deliver the event (for whatever reason) it is
4200 * desired to clean up scan state anyway. Firmware may have just
4201 * dropped the scan completion event delivery due to transport pipe
4202 * being overflown with data and/or it can recover on its own before
4203 * next scan request is submitted.
4204 */
4205 spin_lock_bh(&ar->data_lock);
4206 if (ar->scan.state != ATH10K_SCAN_IDLE)
4207 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004208 spin_unlock_bh(&ar->data_lock);
4209
4210 return ret;
4211}
4212
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004213static void ath10k_scan_abort(struct ath10k *ar)
4214{
4215 int ret;
4216
4217 lockdep_assert_held(&ar->conf_mutex);
4218
4219 spin_lock_bh(&ar->data_lock);
4220
4221 switch (ar->scan.state) {
4222 case ATH10K_SCAN_IDLE:
4223 /* This can happen if timeout worker kicked in and called
4224 * abortion while scan completion was being processed.
4225 */
4226 break;
4227 case ATH10K_SCAN_STARTING:
4228 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02004229 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004230 ath10k_scan_state_str(ar->scan.state),
4231 ar->scan.state);
4232 break;
4233 case ATH10K_SCAN_RUNNING:
4234 ar->scan.state = ATH10K_SCAN_ABORTING;
4235 spin_unlock_bh(&ar->data_lock);
4236
4237 ret = ath10k_scan_stop(ar);
4238 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004239 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004240
4241 spin_lock_bh(&ar->data_lock);
4242 break;
4243 }
4244
4245 spin_unlock_bh(&ar->data_lock);
4246}
4247
4248void ath10k_scan_timeout_work(struct work_struct *work)
4249{
4250 struct ath10k *ar = container_of(work, struct ath10k,
4251 scan.timeout.work);
4252
4253 mutex_lock(&ar->conf_mutex);
4254 ath10k_scan_abort(ar);
4255 mutex_unlock(&ar->conf_mutex);
4256}
4257
Kalle Valo5e3dd152013-06-12 20:52:10 +03004258static int ath10k_start_scan(struct ath10k *ar,
4259 const struct wmi_start_scan_arg *arg)
4260{
4261 int ret;
4262
4263 lockdep_assert_held(&ar->conf_mutex);
4264
4265 ret = ath10k_wmi_start_scan(ar, arg);
4266 if (ret)
4267 return ret;
4268
Kalle Valo14e105c2016-04-13 14:13:21 +03004269 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004270 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004271 ret = ath10k_scan_stop(ar);
4272 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004273 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004274
4275 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004276 }
4277
Ben Greear2f9eec02015-02-15 16:50:38 +02004278 /* If we failed to start the scan, return error code at
4279 * this point. This is probably due to some issue in the
4280 * firmware, but no need to wedge the driver due to that...
4281 */
4282 spin_lock_bh(&ar->data_lock);
4283 if (ar->scan.state == ATH10K_SCAN_IDLE) {
4284 spin_unlock_bh(&ar->data_lock);
4285 return -EINVAL;
4286 }
4287 spin_unlock_bh(&ar->data_lock);
4288
Kalle Valo5e3dd152013-06-12 20:52:10 +03004289 return 0;
4290}
4291
4292/**********************/
4293/* mac80211 callbacks */
4294/**********************/
4295
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004296static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4297 struct ieee80211_tx_control *control,
4298 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004299{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004300 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02004301 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03004302 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4303 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004304 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02004305 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02004306 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01004307 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02004308 enum ath10k_mac_tx_path txpath;
4309 bool is_htt;
4310 bool is_mgmt;
4311 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004312 int ret;
Kan Yand1ce37b2019-02-11 18:47:52 +02004313 u16 airtime;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004314
Kan Yand1ce37b2019-02-11 18:47:52 +02004315 airtime = ath10k_mac_update_airtime(ar, txq, skb);
4316 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004317
Michal Kazior8a933962015-11-18 06:59:17 +01004318 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004319 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
4320 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
4321 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304322 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004323
Michal Kazior6421969f2016-03-06 16:14:25 +02004324 if (is_htt) {
4325 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004326 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4327
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304328 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004329 if (ret) {
4330 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4331 ret);
4332 spin_unlock_bh(&ar->htt.tx_lock);
4333 ieee80211_free_txskb(ar->hw, skb);
4334 return;
4335 }
4336
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304337 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4338 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304339 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4340 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304341 ath10k_htt_tx_dec_pending(htt);
4342 spin_unlock_bh(&ar->htt.tx_lock);
4343 ieee80211_free_txskb(ar->hw, skb);
4344 return;
4345 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004346 spin_unlock_bh(&ar->htt.tx_lock);
4347 }
4348
Mohammed Shafi Shajakhana7773b5d2016-12-27 19:02:35 +05304349 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004350 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004351 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004352 if (is_htt) {
4353 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304354 ath10k_htt_tx_dec_pending(htt);
4355 if (is_mgmt)
4356 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004357 spin_unlock_bh(&ar->htt.tx_lock);
4358 }
4359 return;
4360 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004361}
4362
Michal Kazior29946872016-03-06 16:14:34 +02004363static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4364 struct ieee80211_txq *txq)
4365{
4366 struct ath10k *ar = hw->priv;
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004367 int ret;
4368 u8 ac;
Michal Kazior29946872016-03-06 16:14:34 +02004369
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004370 ath10k_htt_tx_txq_update(hw, txq);
4371 if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)
4372 return;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304373
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004374 ac = txq->ac;
4375 ieee80211_txq_schedule_start(hw, ac);
4376 txq = ieee80211_next_txq(hw, ac);
4377 if (!txq)
4378 goto out;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304379
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004380 while (ath10k_mac_tx_can_push(hw, txq)) {
4381 ret = ath10k_mac_tx_push_txq(hw, txq);
Erik Stromdahle3148cc2018-05-06 15:25:00 +02004382 if (ret < 0)
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304383 break;
4384 }
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004385 ieee80211_return_txq(hw, txq);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004386 ath10k_htt_tx_txq_update(hw, txq);
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02004387out:
4388 ieee80211_txq_schedule_end(hw, ac);
Michal Kazior29946872016-03-06 16:14:34 +02004389}
4390
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004391/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004392void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004393{
4394 /* make sure rcu-protected mac80211 tx path itself is drained */
4395 synchronize_net();
4396
4397 ath10k_offchan_tx_purge(ar);
4398 ath10k_mgmt_over_wmi_tx_purge(ar);
4399
4400 cancel_work_sync(&ar->offchan_tx_work);
4401 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4402}
4403
Michal Kazioraffd3212013-07-16 09:54:35 +02004404void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004405{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004406 struct ath10k_vif *arvif;
4407
Michal Kazior818bdd12013-07-16 09:38:57 +02004408 lockdep_assert_held(&ar->conf_mutex);
4409
Michal Kazior19337472014-08-28 12:58:16 +02004410 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4411 ar->filter_flags = 0;
4412 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004413 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004414
4415 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004416 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004417
4418 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004419 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004420
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004421 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004422 ath10k_peer_cleanup_all(ar);
Sriram R6f6eb1b2018-05-15 14:39:49 +05304423 ath10k_stop_radar_confirmation(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004424 ath10k_core_stop(ar);
4425 ath10k_hif_power_down(ar);
4426
4427 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004428 list_for_each_entry(arvif, &ar->arvifs, list)
4429 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004430 spin_unlock_bh(&ar->data_lock);
4431}
4432
Ben Greear46acf7bb2014-05-16 17:15:38 +03004433static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4434{
4435 struct ath10k *ar = hw->priv;
4436
4437 mutex_lock(&ar->conf_mutex);
4438
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304439 *tx_ant = ar->cfg_tx_chainmask;
4440 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03004441
4442 mutex_unlock(&ar->conf_mutex);
4443
4444 return 0;
4445}
4446
Ben Greear5572a952014-11-24 16:22:10 +02004447static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4448{
4449 /* It is not clear that allowing gaps in chainmask
4450 * is helpful. Probably it will not do what user
4451 * is hoping for, so warn in that case.
4452 */
4453 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4454 return;
4455
4456 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4457 dbg, cm);
4458}
4459
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304460static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4461{
4462 int nsts = ar->vht_cap_info;
4463
4464 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4465 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4466
4467 /* If firmware does not deliver to host number of space-time
4468 * streams supported, assume it support up to 4 BF STS and return
4469 * the value for VHT CAP: nsts-1)
4470 */
4471 if (nsts == 0)
4472 return 3;
4473
4474 return nsts;
4475}
4476
4477static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4478{
4479 int sound_dim = ar->vht_cap_info;
4480
4481 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4482 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4483
4484 /* If the sounding dimension is not advertised by the firmware,
4485 * let's use a default value of 1
4486 */
4487 if (sound_dim == 0)
4488 return 1;
4489
4490 return sound_dim;
4491}
4492
4493static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4494{
4495 struct ieee80211_sta_vht_cap vht_cap = {0};
Ben Greearcc914a52017-06-16 10:37:45 +03004496 struct ath10k_hw_params *hw = &ar->hw_params;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304497 u16 mcs_map;
4498 u32 val;
4499 int i;
4500
4501 vht_cap.vht_supported = 1;
4502 vht_cap.cap = ar->vht_cap_info;
4503
4504 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4505 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4506 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4507 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4508 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4509
4510 vht_cap.cap |= val;
4511 }
4512
4513 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4514 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4515 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4516 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4517 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4518
4519 vht_cap.cap |= val;
4520 }
4521
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02004522 /* Currently the firmware seems to be buggy, don't enable 80+80
4523 * mode until that's resolved.
4524 */
4525 if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) &&
Ben Greeare509e592017-06-16 10:37:44 +03004526 (ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == 0)
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02004527 vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
4528
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304529 mcs_map = 0;
4530 for (i = 0; i < 8; i++) {
4531 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4532 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4533 else
4534 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4535 }
4536
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004537 if (ar->cfg_tx_chainmask <= 1)
4538 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4539
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304540 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4541 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4542
Ben Greearcc914a52017-06-16 10:37:45 +03004543 /* If we are supporting 160Mhz or 80+80, then the NIC may be able to do
4544 * a restricted NSS for 160 or 80+80 vs what it can do for 80Mhz. Give
4545 * user-space a clue if that is the case.
4546 */
4547 if ((vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) &&
4548 (hw->vht160_mcs_rx_highest != 0 ||
4549 hw->vht160_mcs_tx_highest != 0)) {
4550 vht_cap.vht_mcs.rx_highest = cpu_to_le16(hw->vht160_mcs_rx_highest);
4551 vht_cap.vht_mcs.tx_highest = cpu_to_le16(hw->vht160_mcs_tx_highest);
4552 }
4553
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304554 return vht_cap;
4555}
4556
4557static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4558{
4559 int i;
4560 struct ieee80211_sta_ht_cap ht_cap = {0};
4561
4562 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4563 return ht_cap;
4564
4565 ht_cap.ht_supported = 1;
4566 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4567 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4568 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4569 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004570 ht_cap.cap |=
4571 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304572
4573 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4574 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4575
4576 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4577 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4578
4579 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4580 u32 smps;
4581
4582 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4583 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4584
4585 ht_cap.cap |= smps;
4586 }
4587
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004588 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304589 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4590
4591 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4592 u32 stbc;
4593
4594 stbc = ar->ht_cap_info;
4595 stbc &= WMI_HT_CAP_RX_STBC;
4596 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4597 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4598 stbc &= IEEE80211_HT_CAP_RX_STBC;
4599
4600 ht_cap.cap |= stbc;
4601 }
4602
Surabhi Vishnoiff488d02019-02-01 11:04:22 +05304603 if (ar->ht_cap_info & WMI_HT_CAP_LDPC || (ar->ht_cap_info &
4604 WMI_HT_CAP_RX_LDPC && (ar->ht_cap_info & WMI_HT_CAP_TX_LDPC)))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304605 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4606
4607 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4608 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4609
4610 /* max AMSDU is implicitly taken from vht_cap_info */
4611 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4612 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4613
4614 for (i = 0; i < ar->num_rf_chains; i++) {
4615 if (ar->cfg_rx_chainmask & BIT(i))
4616 ht_cap.mcs.rx_mask[i] = 0xFF;
4617 }
4618
4619 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4620
4621 return ht_cap;
4622}
4623
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304624static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4625{
4626 struct ieee80211_supported_band *band;
4627 struct ieee80211_sta_vht_cap vht_cap;
4628 struct ieee80211_sta_ht_cap ht_cap;
4629
4630 ht_cap = ath10k_get_ht_cap(ar);
4631 vht_cap = ath10k_create_vht_cap(ar);
4632
4633 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004634 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304635 band->ht_cap = ht_cap;
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304636 }
4637 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004638 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304639 band->ht_cap = ht_cap;
4640 band->vht_cap = vht_cap;
4641 }
4642}
4643
Ben Greear46acf7bb2014-05-16 17:15:38 +03004644static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4645{
4646 int ret;
4647
4648 lockdep_assert_held(&ar->conf_mutex);
4649
Ben Greear5572a952014-11-24 16:22:10 +02004650 ath10k_check_chain_mask(ar, tx_ant, "tx");
4651 ath10k_check_chain_mask(ar, rx_ant, "rx");
4652
Ben Greear46acf7bb2014-05-16 17:15:38 +03004653 ar->cfg_tx_chainmask = tx_ant;
4654 ar->cfg_rx_chainmask = rx_ant;
4655
4656 if ((ar->state != ATH10K_STATE_ON) &&
4657 (ar->state != ATH10K_STATE_RESTARTED))
4658 return 0;
4659
4660 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4661 tx_ant);
4662 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004663 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03004664 ret, tx_ant);
4665 return ret;
4666 }
4667
4668 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4669 rx_ant);
4670 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004671 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03004672 ret, rx_ant);
4673 return ret;
4674 }
4675
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304676 /* Reload HT/VHT capability */
4677 ath10k_mac_setup_ht_vht_cap(ar);
4678
Ben Greear46acf7bb2014-05-16 17:15:38 +03004679 return 0;
4680}
4681
4682static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4683{
4684 struct ath10k *ar = hw->priv;
4685 int ret;
4686
4687 mutex_lock(&ar->conf_mutex);
4688 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4689 mutex_unlock(&ar->conf_mutex);
4690 return ret;
4691}
4692
Bhagavathi Perumal S84758d42018-12-20 14:26:00 +02004693static int __ath10k_fetch_bb_timing_dt(struct ath10k *ar,
4694 struct wmi_bb_timing_cfg_arg *bb_timing)
4695{
4696 struct device_node *node;
4697 const char *fem_name;
4698 int ret;
4699
4700 node = ar->dev->of_node;
4701 if (!node)
4702 return -ENOENT;
4703
4704 ret = of_property_read_string_index(node, "ext-fem-name", 0, &fem_name);
4705 if (ret)
4706 return -ENOENT;
4707
4708 /*
4709 * If external Front End module used in hardware, then default base band timing
4710 * parameter cannot be used since they were fine tuned for reference hardware,
4711 * so choosing different value suitable for that external FEM.
4712 */
4713 if (!strcmp("microsemi-lx5586", fem_name)) {
4714 bb_timing->bb_tx_timing = 0x00;
4715 bb_timing->bb_xpa_timing = 0x0101;
4716 } else {
4717 return -ENOENT;
4718 }
4719
4720 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot bb_tx_timing 0x%x bb_xpa_timing 0x%x\n",
4721 bb_timing->bb_tx_timing, bb_timing->bb_xpa_timing);
4722 return 0;
4723}
4724
Kalle Valo5e3dd152013-06-12 20:52:10 +03004725static int ath10k_start(struct ieee80211_hw *hw)
4726{
4727 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304728 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004729 int ret = 0;
Bhagavathi Perumal S84758d42018-12-20 14:26:00 +02004730 struct wmi_bb_timing_cfg_arg bb_timing = {0};
Kalle Valo5e3dd152013-06-12 20:52:10 +03004731
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004732 /*
4733 * This makes sense only when restarting hw. It is harmless to call
Mohammed Shafi Shajakhan6dfdbfc2016-04-26 14:41:36 +03004734 * unconditionally. This is necessary to make sure no HTT/WMI tx
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004735 * commands will be submitted while restarting.
4736 */
4737 ath10k_drain_tx(ar);
4738
Michal Kazior548db542013-07-05 16:15:15 +03004739 mutex_lock(&ar->conf_mutex);
4740
Michal Kaziorc5058f52014-05-26 12:46:03 +03004741 switch (ar->state) {
4742 case ATH10K_STATE_OFF:
4743 ar->state = ATH10K_STATE_ON;
4744 break;
4745 case ATH10K_STATE_RESTARTING:
Michal Kaziorc5058f52014-05-26 12:46:03 +03004746 ar->state = ATH10K_STATE_RESTARTED;
4747 break;
4748 case ATH10K_STATE_ON:
4749 case ATH10K_STATE_RESTARTED:
4750 case ATH10K_STATE_WEDGED:
4751 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004752 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004753 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004754 case ATH10K_STATE_UTF:
4755 ret = -EBUSY;
4756 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004757 }
4758
Rakesh Pillai3c545a22019-02-08 15:50:10 +02004759 ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02004760 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004761 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004762 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004763 }
4764
Kalle Valo7ebf7212016-04-20 19:44:51 +03004765 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
4766 &ar->normal_mode_fw);
Michal Kazior818bdd12013-07-16 09:38:57 +02004767 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004768 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004769 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004770 }
4771
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304772 param = ar->wmi.pdev_param->pmf_qos;
4773 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004774 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004775 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004776 goto err_core_stop;
4777 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004778
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304779 param = ar->wmi.pdev_param->dynamic_bw;
4780 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004781 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004782 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004783 goto err_core_stop;
4784 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004785
Rakesh Pillaif1157692018-10-02 23:33:13 +05304786 if (test_bit(WMI_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi.svc_map)) {
4787 ret = ath10k_wmi_scan_prob_req_oui(ar, ar->mac_addr);
4788 if (ret) {
4789 ath10k_err(ar, "failed to set prob req oui: %i\n", ret);
4790 goto err_core_stop;
4791 }
4792 }
4793
Michal Kaziorcf327842015-03-31 10:26:25 +00004794 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4795 ret = ath10k_wmi_adaptive_qcs(ar, true);
4796 if (ret) {
4797 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4798 ret);
4799 goto err_core_stop;
4800 }
4801 }
4802
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004803 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304804 param = ar->wmi.pdev_param->burst_enable;
4805 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004806 if (ret) {
4807 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4808 goto err_core_stop;
4809 }
4810 }
4811
Govind Singhd5cded12018-04-17 17:37:01 +05304812 param = ar->wmi.pdev_param->idle_ps_config;
4813 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
4814 if (ret && ret != -EOPNOTSUPP) {
4815 ath10k_warn(ar, "failed to enable idle_ps_config: %d\n", ret);
4816 goto err_core_stop;
4817 }
4818
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304819 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7bb2014-05-16 17:15:38 +03004820
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004821 /*
4822 * By default FW set ARP frames ac to voice (6). In that case ARP
4823 * exchange is not working properly for UAPSD enabled AP. ARP requests
4824 * which arrives with access category 0 are processed by network stack
4825 * and send back with access category 0, but FW changes access category
4826 * to 6. Set ARP frames access category to best effort (0) solves
4827 * this problem.
4828 */
4829
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304830 param = ar->wmi.pdev_param->arp_ac_override;
4831 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004832 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004833 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004834 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004835 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004836 }
4837
Maharaja62f77f02015-10-21 11:49:18 +03004838 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
Kalle Valoc4cdf752016-04-20 19:45:18 +03004839 ar->running_fw->fw_file.fw_features)) {
Maharaja62f77f02015-10-21 11:49:18 +03004840 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4841 WMI_CCA_DETECT_LEVEL_AUTO,
4842 WMI_CCA_DETECT_MARGIN_AUTO);
4843 if (ret) {
4844 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4845 ret);
4846 goto err_core_stop;
4847 }
4848 }
4849
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304850 param = ar->wmi.pdev_param->ani_enable;
4851 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304852 if (ret) {
4853 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4854 ret);
4855 goto err_core_stop;
4856 }
4857
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304858 ar->ani_enabled = true;
4859
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304860 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304861 param = ar->wmi.pdev_param->peer_stats_update_period;
4862 ret = ath10k_wmi_pdev_set_param(ar, param,
4863 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4864 if (ret) {
4865 ath10k_warn(ar,
4866 "failed to set peer stats period : %d\n",
4867 ret);
4868 goto err_core_stop;
4869 }
4870 }
4871
Rajkumar Manoharan39136242016-05-27 20:15:59 +05304872 param = ar->wmi.pdev_param->enable_btcoex;
4873 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
4874 test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
4875 ar->running_fw->fw_file.fw_features)) {
4876 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4877 if (ret) {
4878 ath10k_warn(ar,
4879 "failed to set btcoex param: %d\n", ret);
4880 goto err_core_stop;
4881 }
4882 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
4883 }
4884
Bhagavathi Perumal S84758d42018-12-20 14:26:00 +02004885 if (test_bit(WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT, ar->wmi.svc_map)) {
4886 ret = __ath10k_fetch_bb_timing_dt(ar, &bb_timing);
4887 if (!ret) {
4888 ret = ath10k_wmi_pdev_bb_timing(ar, &bb_timing);
4889 if (ret) {
4890 ath10k_warn(ar,
4891 "failed to set bb timings: %d\n",
4892 ret);
4893 goto err_core_stop;
4894 }
4895 }
4896 }
4897
Michal Kaziord6500972014-04-08 09:56:09 +03004898 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004899 ath10k_regd_update(ar);
4900
Simon Wunderlich855aed12014-08-02 09:12:54 +03004901 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304902 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004903
Sriram R6f6eb1b2018-05-15 14:39:49 +05304904 ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_IDLE;
4905
Michal Kaziorae254432014-05-26 12:46:02 +03004906 mutex_unlock(&ar->conf_mutex);
4907 return 0;
4908
4909err_core_stop:
4910 ath10k_core_stop(ar);
4911
4912err_power_down:
4913 ath10k_hif_power_down(ar);
4914
4915err_off:
4916 ar->state = ATH10K_STATE_OFF;
4917
4918err:
Michal Kazior548db542013-07-05 16:15:15 +03004919 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004920 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004921}
4922
4923static void ath10k_stop(struct ieee80211_hw *hw)
4924{
4925 struct ath10k *ar = hw->priv;
4926
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004927 ath10k_drain_tx(ar);
4928
Michal Kazior548db542013-07-05 16:15:15 +03004929 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004930 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004931 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004932 ar->state = ATH10K_STATE_OFF;
4933 }
Michal Kazior548db542013-07-05 16:15:15 +03004934 mutex_unlock(&ar->conf_mutex);
4935
Mohammed Shafi Shajakhand94475c2017-03-31 17:28:41 +05304936 cancel_work_sync(&ar->set_coverage_class_work);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004937 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004938 cancel_work_sync(&ar->restart_work);
4939}
4940
Michal Kaziorad088bf2013-10-16 15:44:46 +03004941static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004942{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004943 struct ath10k_vif *arvif;
4944 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004945
4946 lockdep_assert_held(&ar->conf_mutex);
4947
Michal Kaziorad088bf2013-10-16 15:44:46 +03004948 list_for_each_entry(arvif, &ar->arvifs, list) {
4949 ret = ath10k_mac_vif_setup_ps(arvif);
4950 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004951 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004952 break;
4953 }
4954 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004955
Michal Kaziorad088bf2013-10-16 15:44:46 +03004956 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004957}
4958
Michal Kazior7d9d5582014-10-21 10:40:15 +03004959static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4960{
4961 int ret;
4962 u32 param;
4963
4964 lockdep_assert_held(&ar->conf_mutex);
4965
4966 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4967
4968 param = ar->wmi.pdev_param->txpower_limit2g;
4969 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4970 if (ret) {
4971 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4972 txpower, ret);
4973 return ret;
4974 }
4975
4976 param = ar->wmi.pdev_param->txpower_limit5g;
4977 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4978 if (ret) {
4979 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4980 txpower, ret);
4981 return ret;
4982 }
4983
4984 return 0;
4985}
4986
4987static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4988{
4989 struct ath10k_vif *arvif;
4990 int ret, txpower = -1;
4991
4992 lockdep_assert_held(&ar->conf_mutex);
4993
4994 list_for_each_entry(arvif, &ar->arvifs, list) {
Ryan Hsu88407be2016-12-13 14:55:19 -08004995 if (arvif->txpower <= 0)
4996 continue;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004997
4998 if (txpower == -1)
4999 txpower = arvif->txpower;
5000 else
5001 txpower = min(txpower, arvif->txpower);
5002 }
5003
Ryan Hsu88407be2016-12-13 14:55:19 -08005004 if (txpower == -1)
5005 return 0;
Michal Kazior7d9d5582014-10-21 10:40:15 +03005006
5007 ret = ath10k_mac_txpower_setup(ar, txpower);
5008 if (ret) {
5009 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
5010 txpower, ret);
5011 return ret;
5012 }
5013
5014 return 0;
5015}
5016
Kalle Valo5e3dd152013-06-12 20:52:10 +03005017static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
5018{
Kalle Valo5e3dd152013-06-12 20:52:10 +03005019 struct ath10k *ar = hw->priv;
5020 struct ieee80211_conf *conf = &hw->conf;
5021 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005022
5023 mutex_lock(&ar->conf_mutex);
5024
Michal Kazioraffd3212013-07-16 09:54:35 +02005025 if (changed & IEEE80211_CONF_CHANGE_PS)
5026 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005027
5028 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02005029 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
5030 ret = ath10k_monitor_recalc(ar);
5031 if (ret)
5032 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005033 }
5034
5035 mutex_unlock(&ar->conf_mutex);
5036 return ret;
5037}
5038
Ben Greear5572a952014-11-24 16:22:10 +02005039static u32 get_nss_from_chainmask(u16 chain_mask)
5040{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05305041 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02005042 return 4;
5043 else if ((chain_mask & 0x7) == 0x7)
5044 return 3;
5045 else if ((chain_mask & 0x3) == 0x3)
5046 return 2;
5047 return 1;
5048}
5049
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305050static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
5051{
5052 u32 value = 0;
5053 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02005054 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02005055 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305056
5057 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
5058 return 0;
5059
Bartosz Markowski707a0c82015-09-02 13:20:19 +02005060 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305061 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
5062 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02005063 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305064
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02005065 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305066 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
5067 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02005068 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305069
5070 if (!value)
5071 return 0;
5072
5073 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
5074 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
5075
5076 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
5077 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
5078 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
5079
5080 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
5081 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
5082
5083 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
5084 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
5085 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
5086
5087 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
5088 ar->wmi.vdev_param->txbf, value);
5089}
5090
Kalle Valo5e3dd152013-06-12 20:52:10 +03005091/*
5092 * TODO:
5093 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
5094 * because we will send mgmt frames without CCK. This requirement
5095 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
5096 * in the TX packet.
5097 */
5098static int ath10k_add_interface(struct ieee80211_hw *hw,
5099 struct ieee80211_vif *vif)
5100{
5101 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005102 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005103 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005104 enum wmi_sta_powersave_param param;
5105 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02005106 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005107 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00005108 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005109 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005110
Johannes Berg848955c2014-11-11 12:48:42 +01005111 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
5112
Kalle Valo5e3dd152013-06-12 20:52:10 +03005113 mutex_lock(&ar->conf_mutex);
5114
Michal Kazior0dbd09e2013-07-31 10:55:14 +02005115 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02005116 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02005117
Kalle Valo5e3dd152013-06-12 20:52:10 +03005118 arvif->ar = ar;
5119 arvif->vif = vif;
5120
Ben Greeare63b33f2013-10-22 14:54:14 -07005121 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02005122 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005123 INIT_DELAYED_WORK(&arvif->connection_loss_work,
5124 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03005125
Michal Kazior45c9abc2015-04-21 20:42:58 +03005126 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
5127 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
5128 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
5129 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
5130 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
5131 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
5132 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005133
Michal Kaziore04cafb2015-08-05 12:15:24 +02005134 if (ar->num_peers >= ar->max_num_peers) {
5135 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02005136 ret = -ENOBUFS;
5137 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02005138 }
5139
Ben Greeara9aefb32014-08-12 11:02:19 +03005140 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005141 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03005142 ret = -EBUSY;
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005143 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005144 }
Ben Greear16c11172014-09-23 14:17:16 -07005145 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005146
Ben Greear16c11172014-09-23 14:17:16 -07005147 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
5148 bit, ar->free_vdev_map);
5149
5150 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08005151 arvif->vdev_subtype =
5152 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005153
Kalle Valo5e3dd152013-06-12 20:52:10 +03005154 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01005155 case NL80211_IFTYPE_P2P_DEVICE:
5156 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08005157 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5158 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01005159 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005160 case NL80211_IFTYPE_UNSPECIFIED:
5161 case NL80211_IFTYPE_STATION:
5162 arvif->vdev_type = WMI_VDEV_TYPE_STA;
5163 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08005164 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5165 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005166 break;
5167 case NL80211_IFTYPE_ADHOC:
5168 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
5169 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005170 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08005171 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08005172 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5173 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08005174 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005175 ret = -EINVAL;
5176 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
5177 goto err;
5178 }
5179 arvif->vdev_type = WMI_VDEV_TYPE_AP;
5180 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005181 case NL80211_IFTYPE_AP:
5182 arvif->vdev_type = WMI_VDEV_TYPE_AP;
5183
5184 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08005185 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5186 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005187 break;
5188 case NL80211_IFTYPE_MONITOR:
5189 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
5190 break;
5191 default:
5192 WARN_ON(1);
5193 break;
5194 }
5195
Michal Kazior96d828d2015-03-31 10:26:23 +00005196 /* Using vdev_id as queue number will make it very easy to do per-vif
5197 * tx queue locking. This shouldn't wrap due to interface combinations
5198 * but do a modulo for correctness sake and prevent using offchannel tx
5199 * queues for regular vif tx.
5200 */
5201 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
5202 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
5203 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
5204
Michal Kazior64badcb2014-09-18 11:18:02 +03005205 /* Some firmware revisions don't wait for beacon tx completion before
5206 * sending another SWBA event. This could lead to hardware using old
5207 * (freed) beacon data in some cases, e.g. tx credit starvation
5208 * combined with missed TBTT. This is very very rare.
5209 *
5210 * On non-IOMMU-enabled hosts this could be a possible security issue
5211 * because hw could beacon some random data on the air. On
5212 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
5213 * device would crash.
5214 *
5215 * Since there are no beacon tx completions (implicit nor explicit)
5216 * propagated to host the only workaround for this is to allocate a
5217 * DMA-coherent buffer for a lifetime of a vif and use it for all
5218 * beacon tx commands. Worst case for this approach is some beacons may
5219 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
5220 */
5221 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005222 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03005223 vif->type == NL80211_IFTYPE_AP) {
Luis Chamberlain750afb02019-01-04 09:23:09 +01005224 arvif->beacon_buf = dma_alloc_coherent(ar->dev,
5225 IEEE80211_MAX_FRAME_LEN,
5226 &arvif->beacon_paddr,
5227 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03005228 if (!arvif->beacon_buf) {
5229 ret = -ENOMEM;
5230 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
5231 ret);
5232 goto err;
5233 }
5234 }
David Liuccec9032015-07-24 20:25:32 +03005235 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
5236 arvif->nohwcrypt = true;
5237
5238 if (arvif->nohwcrypt &&
5239 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
5240 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
5241 goto err;
5242 }
Michal Kazior64badcb2014-09-18 11:18:02 +03005243
5244 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
5245 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
5246 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03005247
5248 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
5249 arvif->vdev_subtype, vif->addr);
5250 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005251 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005252 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005253 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005254 }
5255
Sathishkumar Muruganandam68c295f2018-12-20 09:53:30 +02005256 if (test_bit(WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,
5257 ar->wmi.svc_map)) {
5258 vdev_param = ar->wmi.vdev_param->disable_4addr_src_lrn;
5259 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5260 WMI_VDEV_DISABLE_4_ADDR_SRC_LRN);
5261 if (ret && ret != -EOPNOTSUPP) {
5262 ath10k_warn(ar, "failed to disable 4addr src lrn vdev %i: %d\n",
5263 arvif->vdev_id, ret);
5264 }
5265 }
5266
Ben Greear16c11172014-09-23 14:17:16 -07005267 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305268 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005269 list_add(&arvif->list, &ar->arvifs);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305270 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005271
Michal Kazior46725b152015-01-28 09:57:49 +02005272 /* It makes no sense to have firmware do keepalives. mac80211 already
5273 * takes care of this with idle connection polling.
5274 */
5275 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005276 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02005277 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005278 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005279 goto err_vdev_delete;
5280 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005281
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005282 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005283
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005284 vdev_param = ar->wmi.vdev_param->tx_encap_type;
5285 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005286 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02005287 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005288 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005289 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005290 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005291 goto err_vdev_delete;
5292 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005293
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05305294 /* Configuring number of spatial stream for monitor interface is causing
5295 * target assert in qca9888 and qca6174.
5296 */
5297 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02005298 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
5299
5300 vdev_param = ar->wmi.vdev_param->nss;
5301 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5302 nss);
5303 if (ret) {
5304 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
5305 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
5306 ret);
5307 goto err_vdev_delete;
5308 }
5309 }
5310
Michal Kaziore57e0572015-03-24 13:14:03 +00005311 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5312 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02005313 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
5314 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005315 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00005316 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005317 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005318 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005319 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005320
5321 spin_lock_bh(&ar->data_lock);
5322
5323 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
5324 if (!peer) {
5325 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5326 vif->addr, arvif->vdev_id);
5327 spin_unlock_bh(&ar->data_lock);
5328 ret = -ENOENT;
5329 goto err_peer_delete;
5330 }
5331
5332 arvif->peer_id = find_first_bit(peer->peer_ids,
5333 ATH10K_MAX_NUM_PEER_IDS);
5334
5335 spin_unlock_bh(&ar->data_lock);
5336 } else {
5337 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00005338 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01005339
Michal Kaziore57e0572015-03-24 13:14:03 +00005340 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02005341 ret = ath10k_mac_set_kickout(arvif);
5342 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005343 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005344 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02005345 goto err_peer_delete;
5346 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005347 }
5348
5349 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
5350 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
5351 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5352 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5353 param, value);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005354 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005355 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005356 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005357 goto err_peer_delete;
5358 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005359
Michal Kazior9f9b5742014-12-12 12:41:36 +01005360 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005361 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005362 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005363 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005364 goto err_peer_delete;
5365 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005366
Michal Kazior9f9b5742014-12-12 12:41:36 +01005367 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005368 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005369 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005370 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005371 goto err_peer_delete;
5372 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005373 }
5374
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305375 ret = ath10k_mac_set_txbf_conf(arvif);
5376 if (ret) {
5377 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
5378 arvif->vdev_id, ret);
5379 goto err_peer_delete;
5380 }
5381
Michal Kazior424121c2013-07-22 14:13:31 +02005382 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005383 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005384 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03005385 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005386 goto err_peer_delete;
5387 }
Michal Kazior679c54a2013-07-05 16:15:04 +03005388
Michal Kazior7d9d5582014-10-21 10:40:15 +03005389 arvif->txpower = vif->bss_conf.txpower;
5390 ret = ath10k_mac_txpower_recalc(ar);
5391 if (ret) {
5392 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5393 goto err_peer_delete;
5394 }
5395
Pradeep Kumar Chitrapu059104b2019-02-11 18:47:54 +02005396 if (test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map)) {
5397 vdev_param = ar->wmi.vdev_param->rtt_responder_role;
5398 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5399 arvif->ftm_responder);
5400
5401 /* It is harmless to not set FTM role. Do not warn */
5402 if (ret && ret != -EOPNOTSUPP)
5403 ath10k_warn(ar, "failed to set vdev %i FTM Responder: %d\n",
5404 arvif->vdev_id, ret);
5405 }
5406
Michal Kazior500ff9f2015-03-31 10:26:21 +00005407 if (vif->type == NL80211_IFTYPE_MONITOR) {
5408 ar->monitor_arvif = arvif;
5409 ret = ath10k_monitor_recalc(ar);
5410 if (ret) {
5411 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5412 goto err_peer_delete;
5413 }
5414 }
5415
Michal Kazior6d2d51e2015-08-07 09:08:21 +02005416 spin_lock_bh(&ar->htt.tx_lock);
5417 if (!ar->tx_paused)
5418 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
5419 spin_unlock_bh(&ar->htt.tx_lock);
5420
Kalle Valo5e3dd152013-06-12 20:52:10 +03005421 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005422 return 0;
5423
5424err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00005425 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5426 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005427 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
5428
5429err_vdev_delete:
5430 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07005431 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305432 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005433 list_del(&arvif->list);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305434 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005435
5436err:
Michal Kazior64badcb2014-09-18 11:18:02 +03005437 if (arvif->beacon_buf) {
5438 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
5439 arvif->beacon_buf, arvif->beacon_paddr);
5440 arvif->beacon_buf = NULL;
5441 }
5442
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005443 mutex_unlock(&ar->conf_mutex);
5444
Kalle Valo5e3dd152013-06-12 20:52:10 +03005445 return ret;
5446}
5447
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005448static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
5449{
5450 int i;
5451
5452 for (i = 0; i < BITS_PER_LONG; i++)
5453 ath10k_mac_vif_tx_unlock(arvif, i);
5454}
5455
Kalle Valo5e3dd152013-06-12 20:52:10 +03005456static void ath10k_remove_interface(struct ieee80211_hw *hw,
5457 struct ieee80211_vif *vif)
5458{
5459 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005460 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior69427262016-03-06 16:14:30 +02005461 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005462 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005463 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005464
Michal Kazior81a9a172015-03-05 16:02:17 +02005465 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005466 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005467
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305468 mutex_lock(&ar->conf_mutex);
5469
Michal Kaziored543882013-09-13 14:16:56 +02005470 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03005471 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02005472 spin_unlock_bh(&ar->data_lock);
5473
Simon Wunderlich855aed12014-08-02 09:12:54 +03005474 ret = ath10k_spectral_vif_stop(arvif);
5475 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005476 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005477 arvif->vdev_id, ret);
5478
Ben Greear16c11172014-09-23 14:17:16 -07005479 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305480 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005481 list_del(&arvif->list);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305482 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005483
Michal Kaziore57e0572015-03-24 13:14:03 +00005484 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5485 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005486 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5487 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005488 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005489 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005490 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005491
5492 kfree(arvif->u.ap.noa_data);
5493 }
5494
Michal Kazior7aa7a722014-08-25 12:09:38 +02005495 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005496 arvif->vdev_id);
5497
Kalle Valo5e3dd152013-06-12 20:52:10 +03005498 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5499 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005500 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005501 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005502
Michal Kazior2c512052015-02-15 16:50:40 +02005503 /* Some firmware revisions don't notify host about self-peer removal
5504 * until after associated vdev is deleted.
5505 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005506 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5507 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005508 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5509 vif->addr);
5510 if (ret)
5511 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5512 arvif->vdev_id, ret);
5513
5514 spin_lock_bh(&ar->data_lock);
5515 ar->num_peers--;
5516 spin_unlock_bh(&ar->data_lock);
5517 }
5518
Michal Kazior69427262016-03-06 16:14:30 +02005519 spin_lock_bh(&ar->data_lock);
5520 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5521 peer = ar->peer_map[i];
5522 if (!peer)
5523 continue;
5524
5525 if (peer->vif == vif) {
5526 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5527 vif->addr, arvif->vdev_id);
5528 peer->vif = NULL;
5529 }
5530 }
5531 spin_unlock_bh(&ar->data_lock);
5532
Kalle Valo5e3dd152013-06-12 20:52:10 +03005533 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005534 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005535
Michal Kazior500ff9f2015-03-31 10:26:21 +00005536 if (vif->type == NL80211_IFTYPE_MONITOR) {
5537 ar->monitor_arvif = NULL;
5538 ret = ath10k_monitor_recalc(ar);
5539 if (ret)
5540 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5541 }
5542
Ryan Hsud679fa12016-12-22 14:31:46 -08005543 ret = ath10k_mac_txpower_recalc(ar);
5544 if (ret)
5545 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5546
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005547 spin_lock_bh(&ar->htt.tx_lock);
5548 ath10k_mac_vif_tx_unlock_all(arvif);
5549 spin_unlock_bh(&ar->htt.tx_lock);
5550
Michal Kazior29946872016-03-06 16:14:34 +02005551 ath10k_mac_txq_unref(ar, vif->txq);
5552
Kalle Valo5e3dd152013-06-12 20:52:10 +03005553 mutex_unlock(&ar->conf_mutex);
5554}
5555
5556/*
5557 * FIXME: Has to be verified.
5558 */
5559#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005560 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005561 FIF_CONTROL | \
5562 FIF_PSPOLL | \
5563 FIF_OTHER_BSS | \
5564 FIF_BCN_PRBRESP_PROMISC | \
5565 FIF_PROBE_REQ | \
5566 FIF_FCSFAIL)
5567
5568static void ath10k_configure_filter(struct ieee80211_hw *hw,
5569 unsigned int changed_flags,
5570 unsigned int *total_flags,
5571 u64 multicast)
5572{
5573 struct ath10k *ar = hw->priv;
5574 int ret;
5575
5576 mutex_lock(&ar->conf_mutex);
5577
5578 changed_flags &= SUPPORTED_FILTERS;
5579 *total_flags &= SUPPORTED_FILTERS;
5580 ar->filter_flags = *total_flags;
5581
Michal Kazior19337472014-08-28 12:58:16 +02005582 ret = ath10k_monitor_recalc(ar);
5583 if (ret)
Colin Ian King7f03d302016-08-26 19:08:52 +01005584 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005585
5586 mutex_unlock(&ar->conf_mutex);
5587}
5588
5589static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5590 struct ieee80211_vif *vif,
5591 struct ieee80211_bss_conf *info,
5592 u32 changed)
5593{
5594 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005595 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005596 struct cfg80211_chan_def def;
Kalle Valoaf762c02014-09-14 12:50:17 +03005597 u32 vdev_param, pdev_param, slottime, preamble;
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005598 u16 bitrate, hw_value;
Sriram Rf279294e2018-09-10 11:09:40 +05305599 u8 rate, basic_rate_idx;
5600 int rateidx, ret = 0, hw_rate_code;
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005601 enum nl80211_band band;
Sriram Rf279294e2018-09-10 11:09:40 +05305602 const struct ieee80211_supported_band *sband;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005603
5604 mutex_lock(&ar->conf_mutex);
5605
5606 if (changed & BSS_CHANGED_IBSS)
5607 ath10k_control_ibss(arvif, info, vif->addr);
5608
5609 if (changed & BSS_CHANGED_BEACON_INT) {
5610 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005611 vdev_param = ar->wmi.vdev_param->beacon_interval;
5612 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005613 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005614 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005615 "mac vdev %d beacon_interval %d\n",
5616 arvif->vdev_id, arvif->beacon_interval);
5617
Kalle Valo5e3dd152013-06-12 20:52:10 +03005618 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005619 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005620 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005621 }
5622
5623 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005624 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005625 "vdev %d set beacon tx mode to staggered\n",
5626 arvif->vdev_id);
5627
Bartosz Markowski226a3392013-09-26 17:47:16 +02005628 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5629 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005630 WMI_BEACON_STAGGERED_MODE);
5631 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005632 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005633 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005634
5635 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5636 if (ret)
5637 ath10k_warn(ar, "failed to update beacon template: %d\n",
5638 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005639
5640 if (ieee80211_vif_is_mesh(vif)) {
5641 /* mesh doesn't use SSID but firmware needs it */
5642 strncpy(arvif->u.ap.ssid, "mesh",
5643 sizeof(arvif->u.ap.ssid));
5644 arvif->u.ap.ssid_len = 4;
5645 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005646 }
5647
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005648 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5649 ret = ath10k_mac_setup_prb_tmpl(arvif);
5650 if (ret)
5651 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5652 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005653 }
5654
Michal Kaziorba2479f2015-01-24 12:14:51 +02005655 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005656 arvif->dtim_period = info->dtim_period;
5657
Michal Kazior7aa7a722014-08-25 12:09:38 +02005658 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005659 "mac vdev %d dtim_period %d\n",
5660 arvif->vdev_id, arvif->dtim_period);
5661
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005662 vdev_param = ar->wmi.vdev_param->dtim_period;
5663 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005664 arvif->dtim_period);
5665 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005666 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005667 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005668 }
5669
5670 if (changed & BSS_CHANGED_SSID &&
5671 vif->type == NL80211_IFTYPE_AP) {
5672 arvif->u.ap.ssid_len = info->ssid_len;
5673 if (info->ssid_len)
5674 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5675 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5676 }
5677
Michal Kazior077efc82014-10-21 10:10:29 +03005678 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5679 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005680
Pradeep Kumar Chitrapu059104b2019-02-11 18:47:54 +02005681 if (changed & BSS_CHANGED_FTM_RESPONDER &&
5682 arvif->ftm_responder != info->ftm_responder &&
5683 test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map)) {
5684 arvif->ftm_responder = info->ftm_responder;
5685
5686 vdev_param = ar->wmi.vdev_param->rtt_responder_role;
5687 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5688 arvif->ftm_responder);
5689
5690 ath10k_dbg(ar, ATH10K_DBG_MAC,
5691 "mac vdev %d ftm_responder %d:ret %d\n",
5692 arvif->vdev_id, arvif->ftm_responder, ret);
5693 }
5694
Kalle Valo5e3dd152013-06-12 20:52:10 +03005695 if (changed & BSS_CHANGED_BEACON_ENABLED)
5696 ath10k_control_beaconing(arvif, info);
5697
5698 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005699 arvif->use_cts_prot = info->use_cts_prot;
Kalle Valo60c3daa2013-09-08 17:56:07 +03005700
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005701 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005702 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005703 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005704 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005705
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02005706 if (ath10k_mac_can_set_cts_prot(arvif)) {
5707 ret = ath10k_mac_set_cts_prot(arvif);
5708 if (ret)
5709 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
5710 arvif->vdev_id, ret);
5711 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005712 }
5713
5714 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005715 if (info->use_short_slot)
5716 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5717
5718 else
5719 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5720
Michal Kazior7aa7a722014-08-25 12:09:38 +02005721 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005722 arvif->vdev_id, slottime);
5723
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005724 vdev_param = ar->wmi.vdev_param->slot_time;
5725 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005726 slottime);
5727 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005728 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005729 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005730 }
5731
5732 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005733 if (info->use_short_preamble)
5734 preamble = WMI_VDEV_PREAMBLE_SHORT;
5735 else
5736 preamble = WMI_VDEV_PREAMBLE_LONG;
5737
Michal Kazior7aa7a722014-08-25 12:09:38 +02005738 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005739 "mac vdev %d preamble %dn",
5740 arvif->vdev_id, preamble);
5741
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005742 vdev_param = ar->wmi.vdev_param->preamble;
5743 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005744 preamble);
5745 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005746 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005747 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005748 }
5749
5750 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005751 if (info->assoc) {
5752 /* Workaround: Make sure monitor vdev is not running
5753 * when associating to prevent some firmware revisions
5754 * (e.g. 10.1 and 10.2) from crashing.
5755 */
5756 if (ar->monitor_started)
5757 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005758 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005759 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005760 } else {
5761 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005762 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005763 }
5764
Michal Kazior7d9d5582014-10-21 10:40:15 +03005765 if (changed & BSS_CHANGED_TXPOWER) {
5766 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5767 arvif->vdev_id, info->txpower);
5768
5769 arvif->txpower = info->txpower;
5770 ret = ath10k_mac_txpower_recalc(ar);
5771 if (ret)
5772 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5773 }
5774
Michal Kaziorbf14e652014-12-12 12:41:38 +01005775 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005776 arvif->ps = vif->bss_conf.ps;
5777
5778 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005779 if (ret)
5780 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5781 arvif->vdev_id, ret);
5782 }
5783
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03005784 if (changed & BSS_CHANGED_MCAST_RATE &&
5785 !WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def))) {
5786 band = def.chan->band;
5787 rateidx = vif->bss_conf.mcast_rate[band] - 1;
5788
5789 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
5790 rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
5791
5792 bitrate = ath10k_wmi_legacy_rates[rateidx].bitrate;
5793 hw_value = ath10k_wmi_legacy_rates[rateidx].hw_value;
5794 if (ath10k_mac_bitrate_is_cck(bitrate))
5795 preamble = WMI_RATE_PREAMBLE_CCK;
5796 else
5797 preamble = WMI_RATE_PREAMBLE_OFDM;
5798
5799 rate = ATH10K_HW_RATECODE(hw_value, 0, preamble);
5800
5801 ath10k_dbg(ar, ATH10K_DBG_MAC,
5802 "mac vdev %d mcast_rate %x\n",
5803 arvif->vdev_id, rate);
5804
5805 vdev_param = ar->wmi.vdev_param->mcast_data_rate;
5806 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
5807 vdev_param, rate);
5808 if (ret)
5809 ath10k_warn(ar,
5810 "failed to set mcast rate on vdev %i: %d\n",
5811 arvif->vdev_id, ret);
5812
5813 vdev_param = ar->wmi.vdev_param->bcast_data_rate;
5814 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
5815 vdev_param, rate);
5816 if (ret)
5817 ath10k_warn(ar,
5818 "failed to set bcast rate on vdev %i: %d\n",
5819 arvif->vdev_id, ret);
5820 }
5821
Sriram Rf279294e2018-09-10 11:09:40 +05305822 if (changed & BSS_CHANGED_BASIC_RATES) {
5823 if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) {
5824 mutex_unlock(&ar->conf_mutex);
5825 return;
5826 }
5827
Sriram R34e141e2018-10-03 08:43:50 +05305828 sband = ar->hw->wiphy->bands[def.chan->band];
5829 basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
5830 bitrate = sband->bitrates[basic_rate_idx].bitrate;
Sriram Rf279294e2018-09-10 11:09:40 +05305831
Sriram R34e141e2018-10-03 08:43:50 +05305832 hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
5833 if (hw_rate_code < 0) {
5834 ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
5835 mutex_unlock(&ar->conf_mutex);
5836 return;
5837 }
Sriram Rf279294e2018-09-10 11:09:40 +05305838
Sriram R34e141e2018-10-03 08:43:50 +05305839 vdev_param = ar->wmi.vdev_param->mgmt_rate;
5840 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5841 hw_rate_code);
5842 if (ret)
5843 ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
Sriram Rf279294e2018-09-10 11:09:40 +05305844 }
5845
Kalle Valo5e3dd152013-06-12 20:52:10 +03005846 mutex_unlock(&ar->conf_mutex);
5847}
5848
Benjamin Bergebee76f2016-09-28 15:11:58 +03005849static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, s16 value)
5850{
5851 struct ath10k *ar = hw->priv;
5852
5853 /* This function should never be called if setting the coverage class
5854 * is not supported on this hardware.
5855 */
5856 if (!ar->hw_params.hw_ops->set_coverage_class) {
5857 WARN_ON_ONCE(1);
5858 return;
5859 }
5860 ar->hw_params.hw_ops->set_coverage_class(ar, value);
5861}
5862
Anilkumar Kollidd0f9cd2017-10-27 11:12:27 +03005863struct ath10k_mac_tdls_iter_data {
5864 u32 num_tdls_stations;
5865 struct ieee80211_vif *curr_vif;
5866};
5867
5868static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5869 struct ieee80211_sta *sta)
5870{
5871 struct ath10k_mac_tdls_iter_data *iter_data = data;
5872 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5873 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5874
5875 if (sta->tdls && sta_vif == iter_data->curr_vif)
5876 iter_data->num_tdls_stations++;
5877}
5878
5879static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5880 struct ieee80211_vif *vif)
5881{
5882 struct ath10k_mac_tdls_iter_data data = {};
5883
5884 data.curr_vif = vif;
5885
5886 ieee80211_iterate_stations_atomic(hw,
5887 ath10k_mac_tdls_vif_stations_count_iter,
5888 &data);
5889 return data.num_tdls_stations;
5890}
5891
Kalle Valo5e3dd152013-06-12 20:52:10 +03005892static int ath10k_hw_scan(struct ieee80211_hw *hw,
5893 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005894 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005895{
5896 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005897 struct ath10k_vif *arvif = (void *)vif->drv_priv;
David Spinadelc56ef672014-02-05 15:21:13 +02005898 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005899 struct wmi_start_scan_arg arg;
5900 int ret = 0;
5901 int i;
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03005902 u32 scan_timeout;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005903
5904 mutex_lock(&ar->conf_mutex);
5905
Anilkumar Kollia6080932017-10-27 11:12:28 +03005906 if (ath10k_mac_tdls_vif_stations_count(hw, vif) > 0) {
5907 ret = -EBUSY;
5908 goto exit;
5909 }
5910
Kalle Valo5e3dd152013-06-12 20:52:10 +03005911 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005912 switch (ar->scan.state) {
5913 case ATH10K_SCAN_IDLE:
5914 reinit_completion(&ar->scan.started);
5915 reinit_completion(&ar->scan.completed);
5916 ar->scan.state = ATH10K_SCAN_STARTING;
5917 ar->scan.is_roc = false;
5918 ar->scan.vdev_id = arvif->vdev_id;
5919 ret = 0;
5920 break;
5921 case ATH10K_SCAN_STARTING:
5922 case ATH10K_SCAN_RUNNING:
5923 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005924 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005925 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005926 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005927 spin_unlock_bh(&ar->data_lock);
5928
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005929 if (ret)
5930 goto exit;
5931
Kalle Valo5e3dd152013-06-12 20:52:10 +03005932 memset(&arg, 0, sizeof(arg));
5933 ath10k_wmi_start_scan_init(ar, &arg);
5934 arg.vdev_id = arvif->vdev_id;
5935 arg.scan_id = ATH10K_SCAN_ID;
5936
Kalle Valo5e3dd152013-06-12 20:52:10 +03005937 if (req->ie_len) {
5938 arg.ie_len = req->ie_len;
5939 memcpy(arg.ie, req->ie, arg.ie_len);
5940 }
5941
5942 if (req->n_ssids) {
5943 arg.n_ssids = req->n_ssids;
5944 for (i = 0; i < arg.n_ssids; i++) {
5945 arg.ssids[i].len = req->ssids[i].ssid_len;
5946 arg.ssids[i].ssid = req->ssids[i].ssid;
5947 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005948 } else {
5949 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005950 }
5951
Carl Huang60e1d0f2018-04-19 19:39:40 +03005952 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
5953 arg.scan_ctrl_flags |= WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ;
5954 ether_addr_copy(arg.mac_addr.addr, req->mac_addr);
5955 ether_addr_copy(arg.mac_mask.addr, req->mac_addr_mask);
5956 }
5957
Kalle Valo5e3dd152013-06-12 20:52:10 +03005958 if (req->n_channels) {
5959 arg.n_channels = req->n_channels;
5960 for (i = 0; i < arg.n_channels; i++)
5961 arg.channels[i] = req->channels[i]->center_freq;
5962 }
5963
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03005964 /* if duration is set, default dwell times will be overwritten */
5965 if (req->duration) {
5966 arg.dwell_time_active = req->duration;
5967 arg.dwell_time_passive = req->duration;
5968 arg.burst_duration_ms = req->duration;
5969
5970 scan_timeout = min_t(u32, arg.max_rest_time *
5971 (arg.n_channels - 1) + (req->duration +
5972 ATH10K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) *
5973 arg.n_channels, arg.max_scan_time + 200);
5974
5975 } else {
5976 /* Add a 200ms margin to account for event/command processing */
5977 scan_timeout = arg.max_scan_time + 200;
5978 }
5979
Kalle Valo5e3dd152013-06-12 20:52:10 +03005980 ret = ath10k_start_scan(ar, &arg);
5981 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005982 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005983 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005984 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005985 spin_unlock_bh(&ar->data_lock);
5986 }
5987
Michal Kazior634349b2015-09-03 10:43:45 +02005988 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03005989 msecs_to_jiffies(scan_timeout));
Michal Kazior634349b2015-09-03 10:43:45 +02005990
Kalle Valo5e3dd152013-06-12 20:52:10 +03005991exit:
5992 mutex_unlock(&ar->conf_mutex);
5993 return ret;
5994}
5995
5996static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5997 struct ieee80211_vif *vif)
5998{
5999 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006000
6001 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006002 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006003 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01006004
6005 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006006}
6007
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006008static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
6009 struct ath10k_vif *arvif,
6010 enum set_key_cmd cmd,
6011 struct ieee80211_key_conf *key)
6012{
6013 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
6014 int ret;
6015
6016 /* 10.1 firmware branch requires default key index to be set to group
6017 * key index after installing it. Otherwise FW/HW Txes corrupted
6018 * frames with multi-vif APs. This is not required for main firmware
6019 * branch (e.g. 636).
6020 *
Michal Kazior8461baf2015-04-10 13:23:22 +00006021 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
6022 *
6023 * FIXME: It remains unknown if this is required for multi-vif STA
6024 * interfaces on 10.1.
6025 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006026
Michal Kazior8461baf2015-04-10 13:23:22 +00006027 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
6028 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006029 return;
6030
6031 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
6032 return;
6033
6034 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
6035 return;
6036
6037 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
6038 return;
6039
6040 if (cmd != SET_KEY)
6041 return;
6042
6043 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
6044 key->keyidx);
6045 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006046 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02006047 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006048}
6049
Kalle Valo5e3dd152013-06-12 20:52:10 +03006050static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
6051 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
6052 struct ieee80211_key_conf *key)
6053{
6054 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006055 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006056 struct ath10k_peer *peer;
6057 const u8 *peer_addr;
6058 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
6059 key->cipher == WLAN_CIPHER_SUITE_WEP104;
6060 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00006061 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01006062 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00006063 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006064
Bartosz Markowskid7131c02015-03-10 14:32:19 +01006065 /* this one needs to be done in software */
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07006066 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
6067 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
6068 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 ||
6069 key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)
Bartosz Markowskid7131c02015-03-10 14:32:19 +01006070 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006071
David Liuccec9032015-07-24 20:25:32 +03006072 if (arvif->nohwcrypt)
6073 return 1;
6074
Kalle Valo5e3dd152013-06-12 20:52:10 +03006075 if (key->keyidx > WMI_MAX_KEY_INDEX)
6076 return -ENOSPC;
6077
6078 mutex_lock(&ar->conf_mutex);
6079
6080 if (sta)
6081 peer_addr = sta->addr;
6082 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
6083 peer_addr = vif->bss_conf.bssid;
6084 else
6085 peer_addr = vif->addr;
6086
6087 key->hw_key_idx = key->keyidx;
6088
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03006089 if (is_wep) {
6090 if (cmd == SET_KEY)
6091 arvif->wep_keys[key->keyidx] = key;
6092 else
6093 arvif->wep_keys[key->keyidx] = NULL;
6094 }
6095
Kalle Valo5e3dd152013-06-12 20:52:10 +03006096 /* the peer should not disappear in mid-way (unless FW goes awry) since
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01006097 * we already hold conf_mutex. we just make sure its there now.
6098 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006099 spin_lock_bh(&ar->data_lock);
6100 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
6101 spin_unlock_bh(&ar->data_lock);
6102
6103 if (!peer) {
6104 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006105 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03006106 peer_addr);
6107 ret = -EOPNOTSUPP;
6108 goto exit;
6109 } else {
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01006110 /* if the peer doesn't exist there is no key to disable anymore */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006111 goto exit;
6112 }
6113 }
6114
Michal Kazior7cc45732015-03-09 14:24:17 +01006115 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
6116 flags |= WMI_KEY_PAIRWISE;
6117 else
6118 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006119
Kalle Valo5e3dd152013-06-12 20:52:10 +03006120 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006121 if (cmd == DISABLE_KEY)
6122 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01006123
Michal Kaziorad325cb2015-02-18 14:02:27 +01006124 /* When WEP keys are uploaded it's possible that there are
6125 * stations associated already (e.g. when merging) without any
6126 * keys. Static WEP needs an explicit per-peer key upload.
6127 */
6128 if (vif->type == NL80211_IFTYPE_ADHOC &&
6129 cmd == SET_KEY)
6130 ath10k_mac_vif_update_wep_key(arvif, key);
6131
Michal Kazior370e5672015-02-18 14:02:26 +01006132 /* 802.1x never sets the def_wep_key_idx so each set_key()
6133 * call changes default tx key.
6134 *
6135 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
6136 * after first set_key().
6137 */
6138 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
6139 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006140 }
6141
Michal Kazior370e5672015-02-18 14:02:26 +01006142 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006143 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03006144 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02006145 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02006146 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006147 goto exit;
6148 }
6149
Michal Kazior29a10002015-04-10 13:05:58 +00006150 /* mac80211 sets static WEP keys as groupwise while firmware requires
6151 * them to be installed twice as both pairwise and groupwise.
6152 */
6153 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
6154 flags2 = flags;
6155 flags2 &= ~WMI_KEY_GROUP;
6156 flags2 |= WMI_KEY_PAIRWISE;
6157
6158 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
6159 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03006160 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00006161 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
6162 arvif->vdev_id, peer_addr, ret);
6163 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
6164 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03006165 if (ret2) {
6166 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00006167 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
6168 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03006169 }
Michal Kazior29a10002015-04-10 13:05:58 +00006170 goto exit;
6171 }
6172 }
6173
Michal Kaziorcfb27d22013-12-02 09:06:36 +01006174 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
6175
Kalle Valo5e3dd152013-06-12 20:52:10 +03006176 spin_lock_bh(&ar->data_lock);
6177 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
6178 if (peer && cmd == SET_KEY)
6179 peer->keys[key->keyidx] = key;
6180 else if (peer && cmd == DISABLE_KEY)
6181 peer->keys[key->keyidx] = NULL;
6182 else if (peer == NULL)
6183 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006184 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006185 spin_unlock_bh(&ar->data_lock);
6186
Yingying Tang9cdd0052018-03-28 12:15:35 +03006187 if (sta && sta->tdls)
6188 ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
6189 WMI_PEER_AUTHORIZE, 1);
6190
Kalle Valo5e3dd152013-06-12 20:52:10 +03006191exit:
6192 mutex_unlock(&ar->conf_mutex);
6193 return ret;
6194}
6195
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006196static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
6197 struct ieee80211_vif *vif,
6198 int keyidx)
6199{
6200 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006201 struct ath10k_vif *arvif = (void *)vif->drv_priv;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006202 int ret;
6203
6204 mutex_lock(&arvif->ar->conf_mutex);
6205
6206 if (arvif->ar->state != ATH10K_STATE_ON)
6207 goto unlock;
6208
6209 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
6210 arvif->vdev_id, keyidx);
6211
6212 ret = ath10k_wmi_vdev_set_param(arvif->ar,
6213 arvif->vdev_id,
6214 arvif->ar->wmi.vdev_param->def_keyid,
6215 keyidx);
6216
6217 if (ret) {
6218 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
6219 arvif->vdev_id,
6220 ret);
6221 goto unlock;
6222 }
6223
6224 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01006225
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006226unlock:
6227 mutex_unlock(&arvif->ar->conf_mutex);
6228}
6229
Michal Kazior9797feb2014-02-14 14:49:48 +01006230static void ath10k_sta_rc_update_wk(struct work_struct *wk)
6231{
6232 struct ath10k *ar;
6233 struct ath10k_vif *arvif;
6234 struct ath10k_sta *arsta;
6235 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006236 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02006237 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006238 const u8 *ht_mcs_mask;
6239 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01006240 u32 changed, bw, nss, smps;
6241 int err;
6242
6243 arsta = container_of(wk, struct ath10k_sta, update_wk);
6244 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
6245 arvif = arsta->arvif;
6246 ar = arvif->ar;
6247
Michal Kazior45c9abc2015-04-21 20:42:58 +03006248 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
6249 return;
6250
6251 band = def.chan->band;
6252 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
6253 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
6254
Michal Kazior9797feb2014-02-14 14:49:48 +01006255 spin_lock_bh(&ar->data_lock);
6256
6257 changed = arsta->changed;
6258 arsta->changed = 0;
6259
6260 bw = arsta->bw;
6261 nss = arsta->nss;
6262 smps = arsta->smps;
6263
6264 spin_unlock_bh(&ar->data_lock);
6265
6266 mutex_lock(&ar->conf_mutex);
6267
Michal Kazior45c9abc2015-04-21 20:42:58 +03006268 nss = max_t(u32, 1, nss);
6269 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6270 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6271
Michal Kazior9797feb2014-02-14 14:49:48 +01006272 if (changed & IEEE80211_RC_BW_CHANGED) {
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006273 enum wmi_phy_mode mode;
6274
6275 mode = chan_to_phymode(&def);
6276 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d phymode %d\n",
Kalle Valoebfac1d2018-07-30 21:56:43 +03006277 sta->addr, bw, mode);
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006278
6279 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
Kalle Valoebfac1d2018-07-30 21:56:43 +03006280 WMI_PEER_PHYMODE, mode);
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006281 if (err) {
6282 ath10k_warn(ar, "failed to update STA %pM peer phymode %d: %d\n",
Kalle Valoebfac1d2018-07-30 21:56:43 +03006283 sta->addr, mode, err);
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006284 goto exit;
6285 }
Michal Kazior9797feb2014-02-14 14:49:48 +01006286
6287 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
6288 WMI_PEER_CHAN_WIDTH, bw);
6289 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006290 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006291 sta->addr, bw, err);
6292 }
6293
6294 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006295 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006296 sta->addr, nss);
6297
6298 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
6299 WMI_PEER_NSS, nss);
6300 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006301 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006302 sta->addr, nss, err);
6303 }
6304
6305 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006306 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006307 sta->addr, smps);
6308
6309 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
6310 WMI_PEER_SMPS_STATE, smps);
6311 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006312 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006313 sta->addr, smps, err);
6314 }
6315
Karthikeyan Periyasamy55cc11d2018-03-27 11:25:29 +03006316 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
6317 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006318 sta->addr);
6319
Michal Kazior590922a2014-10-21 10:10:29 +03006320 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006321 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006322 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006323 sta->addr);
6324 }
6325
Ryan Hsu9191fc2a2018-06-18 17:00:04 +03006326exit:
Michal Kazior9797feb2014-02-14 14:49:48 +01006327 mutex_unlock(&ar->conf_mutex);
6328}
6329
Marek Puzyniak7c354242015-03-30 09:51:52 +03006330static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
6331 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006332{
6333 struct ath10k *ar = arvif->ar;
6334
6335 lockdep_assert_held(&ar->conf_mutex);
6336
Marek Puzyniak7c354242015-03-30 09:51:52 +03006337 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006338 return 0;
6339
6340 if (ar->num_stations >= ar->max_num_stations)
6341 return -ENOBUFS;
6342
6343 ar->num_stations++;
6344
6345 return 0;
6346}
6347
Marek Puzyniak7c354242015-03-30 09:51:52 +03006348static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
6349 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006350{
6351 struct ath10k *ar = arvif->ar;
6352
6353 lockdep_assert_held(&ar->conf_mutex);
6354
Marek Puzyniak7c354242015-03-30 09:51:52 +03006355 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006356 return;
6357
6358 ar->num_stations--;
6359}
6360
Kalle Valo5e3dd152013-06-12 20:52:10 +03006361static int ath10k_sta_state(struct ieee80211_hw *hw,
6362 struct ieee80211_vif *vif,
6363 struct ieee80211_sta *sta,
6364 enum ieee80211_sta_state old_state,
6365 enum ieee80211_sta_state new_state)
6366{
6367 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006368 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior9797feb2014-02-14 14:49:48 +01006369 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006370 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006371 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02006372 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006373
Michal Kazior76f90022014-02-25 09:29:57 +02006374 if (old_state == IEEE80211_STA_NOTEXIST &&
6375 new_state == IEEE80211_STA_NONE) {
6376 memset(arsta, 0, sizeof(*arsta));
6377 arsta->arvif = arvif;
Maharaja Kennadyrajand70c0d42018-09-18 12:04:27 +05306378 arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
Michal Kazior76f90022014-02-25 09:29:57 +02006379 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02006380
6381 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6382 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02006383 }
6384
Michal Kazior9797feb2014-02-14 14:49:48 +01006385 /* cancel must be done outside the mutex to avoid deadlock */
6386 if ((old_state == IEEE80211_STA_NONE &&
6387 new_state == IEEE80211_STA_NOTEXIST))
6388 cancel_work_sync(&arsta->update_wk);
6389
Kalle Valo5e3dd152013-06-12 20:52:10 +03006390 mutex_lock(&ar->conf_mutex);
6391
6392 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03006393 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006394 /*
6395 * New station addition.
6396 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006397 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
6398 u32 num_tdls_stations;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006399
Michal Kaziorcfd10612014-11-25 15:16:05 +01006400 ath10k_dbg(ar, ATH10K_DBG_MAC,
6401 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
6402 arvif->vdev_id, sta->addr,
6403 ar->num_stations + 1, ar->max_num_stations,
6404 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006405
Ryan Hsu9a993cc2017-05-31 14:21:28 +03006406 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
Ryan Hsu9a993cc2017-05-31 14:21:28 +03006407
6408 if (sta->tdls) {
6409 if (num_tdls_stations >= ar->max_num_tdls_vdevs) {
6410 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
6411 arvif->vdev_id,
6412 ar->max_num_tdls_vdevs);
6413 ret = -ELNRNG;
6414 goto exit;
6415 }
6416 peer_type = WMI_PEER_TYPE_TDLS;
6417 }
6418
Marek Puzyniak7c354242015-03-30 09:51:52 +03006419 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01006420 if (ret) {
6421 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
6422 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006423 goto exit;
6424 }
6425
Zhi Chen386f97e2018-12-20 14:25:18 +02006426 if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {
6427 arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats),
6428 GFP_KERNEL);
6429 if (!arsta->tx_stats) {
6430 ret = -ENOMEM;
6431 goto exit;
6432 }
6433 }
6434
Michal Kazior69427262016-03-06 16:14:30 +02006435 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
6436 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01006437 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006438 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 -08006439 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03006440 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006441 kfree(arsta->tx_stats);
Michal Kaziora52c0282014-11-25 15:16:03 +01006442 goto exit;
6443 }
Michal Kazior077efc82014-10-21 10:10:29 +03006444
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006445 spin_lock_bh(&ar->data_lock);
6446
6447 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
6448 if (!peer) {
6449 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
6450 vif->addr, arvif->vdev_id);
6451 spin_unlock_bh(&ar->data_lock);
6452 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6453 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006454 kfree(arsta->tx_stats);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006455 ret = -ENOENT;
6456 goto exit;
6457 }
6458
6459 arsta->peer_id = find_first_bit(peer->peer_ids,
6460 ATH10K_MAX_NUM_PEER_IDS);
6461
6462 spin_unlock_bh(&ar->data_lock);
6463
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006464 if (!sta->tdls)
6465 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03006466
Ryan Hsu9a993cc2017-05-31 14:21:28 +03006467 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6468 WMI_TDLS_ENABLE_ACTIVE);
6469 if (ret) {
6470 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6471 arvif->vdev_id, ret);
6472 ath10k_peer_delete(ar, arvif->vdev_id,
6473 sta->addr);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006474 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006475 kfree(arsta->tx_stats);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006476 goto exit;
6477 }
6478
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006479 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6480 WMI_TDLS_PEER_STATE_PEERING);
6481 if (ret) {
6482 ath10k_warn(ar,
6483 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
6484 sta->addr, arvif->vdev_id, ret);
6485 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6486 ath10k_mac_dec_num_stations(arvif, sta);
Zhi Chen386f97e2018-12-20 14:25:18 +02006487 kfree(arsta->tx_stats);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006488
6489 if (num_tdls_stations != 0)
6490 goto exit;
6491 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6492 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03006493 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006494 } else if ((old_state == IEEE80211_STA_NONE &&
6495 new_state == IEEE80211_STA_NOTEXIST)) {
6496 /*
6497 * Existing station deletion.
6498 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006499 ath10k_dbg(ar, ATH10K_DBG_MAC,
Ben Greear30404202016-08-18 18:26:35 -07006500 "mac vdev %d peer delete %pM sta %pK (sta gone)\n",
6501 arvif->vdev_id, sta->addr, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006502
Manikanta Pubbisetty424ea0d2017-11-06 13:39:31 +05306503 if (sta->tdls) {
6504 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id,
6505 sta,
6506 WMI_TDLS_PEER_STATE_TEARDOWN);
6507 if (ret)
6508 ath10k_warn(ar, "failed to update tdls peer state for %pM state %d: %i\n",
6509 sta->addr,
6510 WMI_TDLS_PEER_STATE_TEARDOWN, ret);
6511 }
6512
Kalle Valo5e3dd152013-06-12 20:52:10 +03006513 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6514 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006515 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006516 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006517
Marek Puzyniak7c354242015-03-30 09:51:52 +03006518 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006519
Michal Kazior69427262016-03-06 16:14:30 +02006520 spin_lock_bh(&ar->data_lock);
6521 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
6522 peer = ar->peer_map[i];
6523 if (!peer)
6524 continue;
6525
6526 if (peer->sta == sta) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05306527 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 +03006528 sta->addr, peer, i, arvif->vdev_id);
Michal Kazior69427262016-03-06 16:14:30 +02006529 peer->sta = NULL;
Ben Greeard0eeafa2016-06-30 15:23:59 +03006530
6531 /* Clean up the peer object as well since we
6532 * must have failed to do this above.
6533 */
6534 list_del(&peer->list);
6535 ar->peer_map[i] = NULL;
6536 kfree(peer);
6537 ar->num_peers--;
Michal Kazior69427262016-03-06 16:14:30 +02006538 }
6539 }
6540 spin_unlock_bh(&ar->data_lock);
6541
Karthikeyan Periyasamy553a7cc2018-12-20 09:53:17 +02006542 if (ath10k_debug_is_extd_tx_stats_enabled(ar)) {
6543 kfree(arsta->tx_stats);
6544 arsta->tx_stats = NULL;
6545 }
6546
Michal Kazior29946872016-03-06 16:14:34 +02006547 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6548 ath10k_mac_txq_unref(ar, sta->txq[i]);
6549
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006550 if (!sta->tdls)
6551 goto exit;
6552
6553 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
6554 goto exit;
6555
6556 /* This was the last tdls peer in current vif */
6557 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6558 WMI_TDLS_DISABLE);
6559 if (ret) {
6560 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6561 arvif->vdev_id, ret);
6562 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006563 } else if (old_state == IEEE80211_STA_AUTH &&
6564 new_state == IEEE80211_STA_ASSOC &&
6565 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006566 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03006567 vif->type == NL80211_IFTYPE_ADHOC)) {
6568 /*
6569 * New association.
6570 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006571 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006572 sta->addr);
6573
Michal Kazior590922a2014-10-21 10:10:29 +03006574 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006575 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006576 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006577 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006578 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006579 new_state == IEEE80211_STA_AUTHORIZED &&
6580 sta->tdls) {
6581 /*
6582 * Tdls station authorized.
6583 */
6584 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
6585 sta->addr);
6586
6587 ret = ath10k_station_assoc(ar, vif, sta, false);
6588 if (ret) {
6589 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
6590 sta->addr, arvif->vdev_id, ret);
6591 goto exit;
6592 }
6593
6594 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6595 WMI_TDLS_PEER_STATE_CONNECTED);
6596 if (ret)
6597 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
6598 sta->addr, arvif->vdev_id, ret);
6599 } else if (old_state == IEEE80211_STA_ASSOC &&
6600 new_state == IEEE80211_STA_AUTH &&
6601 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006602 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006603 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006604 /*
6605 * Disassociation.
6606 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006607 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006608 sta->addr);
6609
Michal Kazior590922a2014-10-21 10:10:29 +03006610 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006611 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006612 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006613 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006614 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006615exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006616 mutex_unlock(&ar->conf_mutex);
6617 return ret;
6618}
6619
6620static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006621 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006622{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006623 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006624 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6625 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006626 u32 value = 0;
6627 int ret = 0;
6628
Michal Kazior548db542013-07-05 16:15:15 +03006629 lockdep_assert_held(&ar->conf_mutex);
6630
Kalle Valo5e3dd152013-06-12 20:52:10 +03006631 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6632 return 0;
6633
6634 switch (ac) {
6635 case IEEE80211_AC_VO:
6636 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6637 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006638 prio = 7;
6639 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006640 break;
6641 case IEEE80211_AC_VI:
6642 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6643 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006644 prio = 5;
6645 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006646 break;
6647 case IEEE80211_AC_BE:
6648 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6649 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006650 prio = 2;
6651 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006652 break;
6653 case IEEE80211_AC_BK:
6654 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6655 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006656 prio = 0;
6657 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006658 break;
6659 }
6660
6661 if (enable)
6662 arvif->u.sta.uapsd |= value;
6663 else
6664 arvif->u.sta.uapsd &= ~value;
6665
6666 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6667 WMI_STA_PS_PARAM_UAPSD,
6668 arvif->u.sta.uapsd);
6669 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006670 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006671 goto exit;
6672 }
6673
6674 if (arvif->u.sta.uapsd)
6675 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6676 else
6677 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6678
6679 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6680 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6681 value);
6682 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006683 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006684
Michal Kazior9f9b5742014-12-12 12:41:36 +01006685 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6686 if (ret) {
6687 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6688 arvif->vdev_id, ret);
6689 return ret;
6690 }
6691
6692 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6693 if (ret) {
6694 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6695 arvif->vdev_id, ret);
6696 return ret;
6697 }
6698
Michal Kaziorb0e56152015-01-24 12:14:52 +02006699 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6700 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6701 /* Only userspace can make an educated decision when to send
6702 * trigger frame. The following effectively disables u-UAPSD
6703 * autotrigger in firmware (which is enabled by default
6704 * provided the autotrigger service is available).
6705 */
6706
6707 arg.wmm_ac = acc;
6708 arg.user_priority = prio;
6709 arg.service_interval = 0;
6710 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6711 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6712
6713 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6714 arvif->bssid, &arg, 1);
6715 if (ret) {
6716 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6717 ret);
6718 return ret;
6719 }
6720 }
6721
Kalle Valo5e3dd152013-06-12 20:52:10 +03006722exit:
6723 return ret;
6724}
6725
6726static int ath10k_conf_tx(struct ieee80211_hw *hw,
6727 struct ieee80211_vif *vif, u16 ac,
6728 const struct ieee80211_tx_queue_params *params)
6729{
6730 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006731 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006732 struct wmi_wmm_params_arg *p = NULL;
6733 int ret;
6734
6735 mutex_lock(&ar->conf_mutex);
6736
6737 switch (ac) {
6738 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006739 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006740 break;
6741 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006742 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006743 break;
6744 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006745 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006746 break;
6747 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006748 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006749 break;
6750 }
6751
6752 if (WARN_ON(!p)) {
6753 ret = -EINVAL;
6754 goto exit;
6755 }
6756
6757 p->cwmin = params->cw_min;
6758 p->cwmax = params->cw_max;
6759 p->aifs = params->aifs;
6760
6761 /*
6762 * The channel time duration programmed in the HW is in absolute
6763 * microseconds, while mac80211 gives the txop in units of
6764 * 32 microseconds.
6765 */
6766 p->txop = params->txop * 32;
6767
Michal Kazior7fc979a2015-01-28 09:57:28 +02006768 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6769 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6770 &arvif->wmm_params);
6771 if (ret) {
6772 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6773 arvif->vdev_id, ret);
6774 goto exit;
6775 }
6776 } else {
6777 /* This won't work well with multi-interface cases but it's
6778 * better than nothing.
6779 */
6780 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6781 if (ret) {
6782 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6783 goto exit;
6784 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006785 }
6786
6787 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6788 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006789 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006790
6791exit:
6792 mutex_unlock(&ar->conf_mutex);
6793 return ret;
6794}
6795
Kalle Valo14e105c2016-04-13 14:13:21 +03006796#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006797
6798static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6799 struct ieee80211_vif *vif,
6800 struct ieee80211_channel *chan,
6801 int duration,
6802 enum ieee80211_roc_type type)
6803{
6804 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006805 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006806 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006807 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006808 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006809
6810 mutex_lock(&ar->conf_mutex);
6811
Anilkumar Kollia6080932017-10-27 11:12:28 +03006812 if (ath10k_mac_tdls_vif_stations_count(hw, vif) > 0) {
6813 ret = -EBUSY;
6814 goto exit;
6815 }
6816
Kalle Valo5e3dd152013-06-12 20:52:10 +03006817 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006818 switch (ar->scan.state) {
6819 case ATH10K_SCAN_IDLE:
6820 reinit_completion(&ar->scan.started);
6821 reinit_completion(&ar->scan.completed);
6822 reinit_completion(&ar->scan.on_channel);
6823 ar->scan.state = ATH10K_SCAN_STARTING;
6824 ar->scan.is_roc = true;
6825 ar->scan.vdev_id = arvif->vdev_id;
6826 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006827 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006828 ret = 0;
6829 break;
6830 case ATH10K_SCAN_STARTING:
6831 case ATH10K_SCAN_RUNNING:
6832 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006833 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006834 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006835 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006836 spin_unlock_bh(&ar->data_lock);
6837
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006838 if (ret)
6839 goto exit;
6840
Michal Kaziorfcf98442015-03-31 11:03:47 +00006841 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006842
Kalle Valo5e3dd152013-06-12 20:52:10 +03006843 memset(&arg, 0, sizeof(arg));
6844 ath10k_wmi_start_scan_init(ar, &arg);
6845 arg.vdev_id = arvif->vdev_id;
6846 arg.scan_id = ATH10K_SCAN_ID;
6847 arg.n_channels = 1;
6848 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006849 arg.dwell_time_active = scan_time_msec;
6850 arg.dwell_time_passive = scan_time_msec;
6851 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006852 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6853 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006854 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006855
6856 ret = ath10k_start_scan(ar, &arg);
6857 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006858 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006859 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006860 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006861 spin_unlock_bh(&ar->data_lock);
6862 goto exit;
6863 }
6864
Kalle Valo14e105c2016-04-13 14:13:21 +03006865 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006866 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006867 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006868
6869 ret = ath10k_scan_stop(ar);
6870 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006871 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006872
Kalle Valo5e3dd152013-06-12 20:52:10 +03006873 ret = -ETIMEDOUT;
6874 goto exit;
6875 }
6876
Michal Kaziorfcf98442015-03-31 11:03:47 +00006877 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6878 msecs_to_jiffies(duration));
6879
Kalle Valo5e3dd152013-06-12 20:52:10 +03006880 ret = 0;
6881exit:
6882 mutex_unlock(&ar->conf_mutex);
6883 return ret;
6884}
6885
6886static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6887{
6888 struct ath10k *ar = hw->priv;
6889
6890 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006891
6892 spin_lock_bh(&ar->data_lock);
6893 ar->scan.roc_notify = false;
6894 spin_unlock_bh(&ar->data_lock);
6895
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006896 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006897
Kalle Valo5e3dd152013-06-12 20:52:10 +03006898 mutex_unlock(&ar->conf_mutex);
6899
Michal Kazior4eb2e162014-10-28 10:23:09 +01006900 cancel_delayed_work_sync(&ar->scan.timeout);
6901
Kalle Valo5e3dd152013-06-12 20:52:10 +03006902 return 0;
6903}
6904
6905/*
6906 * Both RTS and Fragmentation threshold are interface-specific
6907 * in ath10k, but device-specific in mac80211.
6908 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006909
6910static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6911{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006912 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006913 struct ath10k_vif *arvif;
6914 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006915
Michal Kaziorad088bf2013-10-16 15:44:46 +03006916 mutex_lock(&ar->conf_mutex);
6917 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006918 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006919 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006920
Michal Kaziorad088bf2013-10-16 15:44:46 +03006921 ret = ath10k_mac_set_rts(arvif, value);
6922 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006923 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006924 arvif->vdev_id, ret);
6925 break;
6926 }
6927 }
6928 mutex_unlock(&ar->conf_mutex);
6929
6930 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006931}
6932
Michal Kazior92092fe2015-08-03 11:16:43 +02006933static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6934{
6935 /* Even though there's a WMI enum for fragmentation threshold no known
6936 * firmware actually implements it. Moreover it is not possible to rely
6937 * frame fragmentation to mac80211 because firmware clears the "more
6938 * fragments" bit in frame control making it impossible for remote
6939 * devices to reassemble frames.
6940 *
6941 * Hence implement a dummy callback just to say fragmentation isn't
6942 * supported. This effectively prevents mac80211 from doing frame
6943 * fragmentation in software.
6944 */
6945 return -EOPNOTSUPP;
6946}
6947
Wen Gong828853a2018-08-28 19:48:42 +03006948void ath10k_mac_wait_tx_complete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006949{
Michal Kazioraffd3212013-07-16 09:54:35 +02006950 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006951 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006952
6953 /* mac80211 doesn't care if we really xmit queued frames or not
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01006954 * we'll collect those frames either way if we stop/delete vdevs
6955 */
Michal Kazior548db542013-07-05 16:15:15 +03006956
Michal Kazioraffd3212013-07-16 09:54:35 +02006957 if (ar->state == ATH10K_STATE_WEDGED)
Wen Gong828853a2018-08-28 19:48:42 +03006958 return;
Michal Kazioraffd3212013-07-16 09:54:35 +02006959
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006960 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006961 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006962
Michal Kazioredb82362013-07-05 16:15:14 +03006963 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006964 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006965 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006966
Michal Kazior7962b0d2014-10-28 10:34:38 +01006967 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6968 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6969 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006970
6971 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006972 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006973
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006974 if (time_left == 0 || skip)
6975 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6976 skip, ar->state, time_left);
Wen Gong828853a2018-08-28 19:48:42 +03006977}
Michal Kazior548db542013-07-05 16:15:15 +03006978
Wen Gong828853a2018-08-28 19:48:42 +03006979static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6980 u32 queues, bool drop)
6981{
6982 struct ath10k *ar = hw->priv;
Wen Gong9de41622018-10-08 17:02:43 +08006983 struct ath10k_vif *arvif;
6984 u32 bitmap;
Wen Gong828853a2018-08-28 19:48:42 +03006985
Wen Gong9de41622018-10-08 17:02:43 +08006986 if (drop) {
Brian Norrisd987f782018-11-07 16:40:35 -08006987 if (vif && vif->type == NL80211_IFTYPE_STATION) {
Wen Gong9de41622018-10-08 17:02:43 +08006988 bitmap = ~(1 << WMI_MGMT_TID);
6989 list_for_each_entry(arvif, &ar->arvifs, list) {
6990 if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
6991 ath10k_wmi_peer_flush(ar, arvif->vdev_id,
6992 arvif->bssid, bitmap);
6993 }
6994 }
Wen Gong828853a2018-08-28 19:48:42 +03006995 return;
Wen Gong9de41622018-10-08 17:02:43 +08006996 }
Wen Gong828853a2018-08-28 19:48:42 +03006997
6998 mutex_lock(&ar->conf_mutex);
6999 ath10k_mac_wait_tx_complete(ar);
Michal Kazior548db542013-07-05 16:15:15 +03007000 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007001}
7002
7003/* TODO: Implement this function properly
7004 * For now it is needed to reply to Probe Requests in IBSS mode.
7005 * Propably we need this information from FW.
7006 */
7007static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
7008{
7009 return 1;
7010}
7011
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007012static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
7013 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02007014{
7015 struct ath10k *ar = hw->priv;
7016
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007017 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
7018 return;
7019
Michal Kazioraffd3212013-07-16 09:54:35 +02007020 mutex_lock(&ar->conf_mutex);
7021
7022 /* If device failed to restart it will be in a different state, e.g.
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01007023 * ATH10K_STATE_WEDGED
7024 */
Michal Kazioraffd3212013-07-16 09:54:35 +02007025 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007026 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02007027 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01007028 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02007029 }
7030
7031 mutex_unlock(&ar->conf_mutex);
7032}
7033
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05307034static void
7035ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
7036 struct ieee80211_channel *channel)
7037{
7038 int ret;
7039 enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
7040
7041 lockdep_assert_held(&ar->conf_mutex);
7042
7043 if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
7044 (ar->rx_channel != channel))
7045 return;
7046
7047 if (ar->scan.state != ATH10K_SCAN_IDLE) {
7048 ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
7049 return;
7050 }
7051
7052 reinit_completion(&ar->bss_survey_done);
7053
7054 ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
7055 if (ret) {
7056 ath10k_warn(ar, "failed to send pdev bss chan info request\n");
7057 return;
7058 }
7059
7060 ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
7061 if (!ret) {
7062 ath10k_warn(ar, "bss channel survey timed out\n");
7063 return;
7064 }
7065}
7066
Michal Kazior2e1dea42013-07-31 10:32:40 +02007067static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
7068 struct survey_info *survey)
7069{
7070 struct ath10k *ar = hw->priv;
7071 struct ieee80211_supported_band *sband;
7072 struct survey_info *ar_survey = &ar->survey[idx];
7073 int ret = 0;
7074
7075 mutex_lock(&ar->conf_mutex);
7076
Johannes Berg57fbcce2016-04-12 15:56:15 +02007077 sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02007078 if (sband && idx >= sband->n_channels) {
7079 idx -= sband->n_channels;
7080 sband = NULL;
7081 }
7082
7083 if (!sband)
Johannes Berg57fbcce2016-04-12 15:56:15 +02007084 sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02007085
7086 if (!sband || idx >= sband->n_channels) {
7087 ret = -ENOENT;
7088 goto exit;
7089 }
7090
Ashok Raj Nagarajan77eb3d62016-09-02 10:59:53 +05307091 ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05307092
Michal Kazior2e1dea42013-07-31 10:32:40 +02007093 spin_lock_bh(&ar->data_lock);
7094 memcpy(survey, ar_survey, sizeof(*survey));
7095 spin_unlock_bh(&ar->data_lock);
7096
7097 survey->channel = &sband->channels[idx];
7098
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03007099 if (ar->rx_channel == survey->channel)
7100 survey->filled |= SURVEY_INFO_IN_USE;
7101
Michal Kazior2e1dea42013-07-31 10:32:40 +02007102exit:
7103 mutex_unlock(&ar->conf_mutex);
7104 return ret;
7105}
7106
Michal Kazior3ae54222015-03-31 10:49:20 +00007107static bool
7108ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007109 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00007110 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007111{
Michal Kazior3ae54222015-03-31 10:49:20 +00007112 int num_rates = 0;
7113 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007114
Michal Kazior3ae54222015-03-31 10:49:20 +00007115 num_rates += hweight32(mask->control[band].legacy);
7116
7117 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
7118 num_rates += hweight8(mask->control[band].ht_mcs[i]);
7119
7120 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
7121 num_rates += hweight16(mask->control[band].vht_mcs[i]);
7122
7123 return num_rates == 1;
7124}
7125
7126static bool
7127ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007128 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00007129 const struct cfg80211_bitrate_mask *mask,
7130 int *nss)
7131{
7132 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
7133 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
7134 u8 ht_nss_mask = 0;
7135 u8 vht_nss_mask = 0;
7136 int i;
7137
7138 if (mask->control[band].legacy)
7139 return false;
7140
7141 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
7142 if (mask->control[band].ht_mcs[i] == 0)
7143 continue;
7144 else if (mask->control[band].ht_mcs[i] ==
7145 sband->ht_cap.mcs.rx_mask[i])
7146 ht_nss_mask |= BIT(i);
7147 else
7148 return false;
7149 }
7150
7151 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
7152 if (mask->control[band].vht_mcs[i] == 0)
7153 continue;
7154 else if (mask->control[band].vht_mcs[i] ==
7155 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
7156 vht_nss_mask |= BIT(i);
7157 else
7158 return false;
7159 }
7160
7161 if (ht_nss_mask != vht_nss_mask)
7162 return false;
7163
7164 if (ht_nss_mask == 0)
7165 return false;
7166
7167 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
7168 return false;
7169
7170 *nss = fls(ht_nss_mask);
7171
7172 return true;
7173}
7174
7175static int
7176ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007177 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00007178 const struct cfg80211_bitrate_mask *mask,
7179 u8 *rate, u8 *nss)
7180{
Michal Kazior3ae54222015-03-31 10:49:20 +00007181 int rate_idx;
7182 int i;
7183 u16 bitrate;
7184 u8 preamble;
7185 u8 hw_rate;
7186
7187 if (hweight32(mask->control[band].legacy) == 1) {
7188 rate_idx = ffs(mask->control[band].legacy) - 1;
7189
Pradeep Kumar Chitrapucd93b832018-07-25 10:59:39 +03007190 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
7191 rate_idx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
7192
7193 hw_rate = ath10k_wmi_legacy_rates[rate_idx].hw_value;
7194 bitrate = ath10k_wmi_legacy_rates[rate_idx].bitrate;
Michal Kazior3ae54222015-03-31 10:49:20 +00007195
7196 if (ath10k_mac_bitrate_is_cck(bitrate))
7197 preamble = WMI_RATE_PREAMBLE_CCK;
7198 else
7199 preamble = WMI_RATE_PREAMBLE_OFDM;
7200
7201 *nss = 1;
7202 *rate = preamble << 6 |
7203 (*nss - 1) << 4 |
7204 hw_rate << 0;
7205
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007206 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007207 }
7208
Michal Kazior3ae54222015-03-31 10:49:20 +00007209 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
7210 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
7211 *nss = i + 1;
7212 *rate = WMI_RATE_PREAMBLE_HT << 6 |
7213 (*nss - 1) << 4 |
7214 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007215
Michal Kazior3ae54222015-03-31 10:49:20 +00007216 return 0;
7217 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007218 }
7219
Michal Kazior3ae54222015-03-31 10:49:20 +00007220 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
7221 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
7222 *nss = i + 1;
7223 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
7224 (*nss - 1) << 4 |
7225 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007226
Michal Kazior3ae54222015-03-31 10:49:20 +00007227 return 0;
7228 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007229 }
7230
Michal Kazior3ae54222015-03-31 10:49:20 +00007231 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007232}
7233
Michal Kazior3ae54222015-03-31 10:49:20 +00007234static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307235 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007236{
7237 struct ath10k *ar = arvif->ar;
7238 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00007239 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007240
Michal Kazior3ae54222015-03-31 10:49:20 +00007241 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007242
Michal Kazior3ae54222015-03-31 10:49:20 +00007243 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
7244 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007245
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007246 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00007247 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007248 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007249 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00007250 rate, ret);
7251 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007252 }
7253
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007254 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00007255 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007256 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00007257 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
7258 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007259 }
7260
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007261 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00007262 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007263 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00007264 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
7265 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007266 }
7267
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307268 vdev_param = ar->wmi.vdev_param->ldpc;
7269 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
7270 if (ret) {
7271 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
7272 return ret;
7273 }
7274
Michal Kazior3ae54222015-03-31 10:49:20 +00007275 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007276}
7277
Michal Kazior45c9abc2015-04-21 20:42:58 +03007278static bool
7279ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02007280 enum nl80211_band band,
Michal Kazior45c9abc2015-04-21 20:42:58 +03007281 const struct cfg80211_bitrate_mask *mask)
7282{
7283 int i;
7284 u16 vht_mcs;
7285
7286 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
7287 * to express all VHT MCS rate masks. Effectively only the following
7288 * ranges can be used: none, 0-7, 0-8 and 0-9.
7289 */
7290 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
7291 vht_mcs = mask->control[band].vht_mcs[i];
7292
7293 switch (vht_mcs) {
7294 case 0:
7295 case BIT(8) - 1:
7296 case BIT(9) - 1:
7297 case BIT(10) - 1:
7298 break;
7299 default:
7300 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
7301 return false;
7302 }
7303 }
7304
7305 return true;
7306}
7307
7308static void ath10k_mac_set_bitrate_mask_iter(void *data,
7309 struct ieee80211_sta *sta)
7310{
7311 struct ath10k_vif *arvif = data;
7312 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
7313 struct ath10k *ar = arvif->ar;
7314
7315 if (arsta->arvif != arvif)
7316 return;
7317
7318 spin_lock_bh(&ar->data_lock);
7319 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
7320 spin_unlock_bh(&ar->data_lock);
7321
7322 ieee80211_queue_work(ar->hw, &arsta->update_wk);
7323}
7324
Michal Kazior3ae54222015-03-31 10:49:20 +00007325static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
7326 struct ieee80211_vif *vif,
7327 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007328{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007329 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007330 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007331 struct ath10k *ar = arvif->ar;
Johannes Berg57fbcce2016-04-12 15:56:15 +02007332 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007333 const u8 *ht_mcs_mask;
7334 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00007335 u8 rate;
7336 u8 nss;
7337 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307338 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00007339 int single_nss;
7340 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007341
Michal Kazior500ff9f2015-03-31 10:26:21 +00007342 if (ath10k_mac_vif_chan(vif, &def))
7343 return -EPERM;
7344
Michal Kazior500ff9f2015-03-31 10:26:21 +00007345 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007346 ht_mcs_mask = mask->control[band].ht_mcs;
7347 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307348 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007349
Michal Kazior3ae54222015-03-31 10:49:20 +00007350 sgi = mask->control[band].gi;
7351 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007352 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007353
Michal Kazior3ae54222015-03-31 10:49:20 +00007354 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
7355 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
7356 &rate, &nss);
7357 if (ret) {
7358 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
7359 arvif->vdev_id, ret);
7360 return ret;
7361 }
7362 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
7363 &single_nss)) {
7364 rate = WMI_FIXED_RATE_NONE;
7365 nss = single_nss;
7366 } else {
7367 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007368 nss = min(ar->num_rf_chains,
7369 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
7370 ath10k_mac_max_vht_nss(vht_mcs_mask)));
7371
7372 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
7373 return -EINVAL;
7374
7375 mutex_lock(&ar->conf_mutex);
7376
7377 arvif->bitrate_mask = *mask;
7378 ieee80211_iterate_stations_atomic(ar->hw,
7379 ath10k_mac_set_bitrate_mask_iter,
7380 arvif);
7381
7382 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007383 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007384
7385 mutex_lock(&ar->conf_mutex);
7386
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307387 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007388 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00007389 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
7390 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007391 goto exit;
7392 }
7393
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007394exit:
7395 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00007396
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007397 return ret;
7398}
7399
Michal Kazior9797feb2014-02-14 14:49:48 +01007400static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
7401 struct ieee80211_vif *vif,
7402 struct ieee80211_sta *sta,
7403 u32 changed)
7404{
7405 struct ath10k *ar = hw->priv;
7406 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Karthikeyan Periyasamy8b2d93d2018-03-12 17:09:40 +05307407 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7408 struct ath10k_peer *peer;
Michal Kazior9797feb2014-02-14 14:49:48 +01007409 u32 bw, smps;
7410
7411 spin_lock_bh(&ar->data_lock);
7412
Karthikeyan Periyasamy8b2d93d2018-03-12 17:09:40 +05307413 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
7414 if (!peer) {
7415 spin_unlock_bh(&ar->data_lock);
7416 ath10k_warn(ar, "mac sta rc update failed to find peer %pM on vdev %i\n",
7417 sta->addr, arvif->vdev_id);
7418 return;
7419 }
7420
Michal Kazior7aa7a722014-08-25 12:09:38 +02007421 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01007422 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
7423 sta->addr, changed, sta->bandwidth, sta->rx_nss,
7424 sta->smps_mode);
7425
7426 if (changed & IEEE80211_RC_BW_CHANGED) {
7427 bw = WMI_PEER_CHWIDTH_20MHZ;
7428
7429 switch (sta->bandwidth) {
7430 case IEEE80211_STA_RX_BW_20:
7431 bw = WMI_PEER_CHWIDTH_20MHZ;
7432 break;
7433 case IEEE80211_STA_RX_BW_40:
7434 bw = WMI_PEER_CHWIDTH_40MHZ;
7435 break;
7436 case IEEE80211_STA_RX_BW_80:
7437 bw = WMI_PEER_CHWIDTH_80MHZ;
7438 break;
7439 case IEEE80211_STA_RX_BW_160:
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02007440 bw = WMI_PEER_CHWIDTH_160MHZ;
7441 break;
7442 default:
Masanari Iidad939be32015-02-27 23:52:31 +09007443 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02007444 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01007445 bw = WMI_PEER_CHWIDTH_20MHZ;
7446 break;
7447 }
7448
7449 arsta->bw = bw;
7450 }
7451
7452 if (changed & IEEE80211_RC_NSS_CHANGED)
7453 arsta->nss = sta->rx_nss;
7454
7455 if (changed & IEEE80211_RC_SMPS_CHANGED) {
7456 smps = WMI_PEER_SMPS_PS_NONE;
7457
7458 switch (sta->smps_mode) {
7459 case IEEE80211_SMPS_AUTOMATIC:
7460 case IEEE80211_SMPS_OFF:
7461 smps = WMI_PEER_SMPS_PS_NONE;
7462 break;
7463 case IEEE80211_SMPS_STATIC:
7464 smps = WMI_PEER_SMPS_STATIC;
7465 break;
7466 case IEEE80211_SMPS_DYNAMIC:
7467 smps = WMI_PEER_SMPS_DYNAMIC;
7468 break;
7469 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02007470 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02007471 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01007472 smps = WMI_PEER_SMPS_PS_NONE;
7473 break;
7474 }
7475
7476 arsta->smps = smps;
7477 }
7478
Michal Kazior9797feb2014-02-14 14:49:48 +01007479 arsta->changed |= changed;
7480
7481 spin_unlock_bh(&ar->data_lock);
7482
7483 ieee80211_queue_work(hw, &arsta->update_wk);
7484}
7485
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007486static void ath10k_offset_tsf(struct ieee80211_hw *hw,
7487 struct ieee80211_vif *vif, s64 tsf_offset)
Peter Oh9f0b7e72016-04-04 16:19:14 -07007488{
7489 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007490 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007491 u32 offset, vdev_param;
Peter Oh9f0b7e72016-04-04 16:19:14 -07007492 int ret;
7493
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007494 if (tsf_offset < 0) {
7495 vdev_param = ar->wmi.vdev_param->dec_tsf;
7496 offset = -tsf_offset;
7497 } else {
7498 vdev_param = ar->wmi.vdev_param->inc_tsf;
7499 offset = tsf_offset;
7500 }
7501
Peter Oh9f0b7e72016-04-04 16:19:14 -07007502 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007503 vdev_param, offset);
7504
Peter Oh9f0b7e72016-04-04 16:19:14 -07007505 if (ret && ret != -EOPNOTSUPP)
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007506 ath10k_warn(ar, "failed to set tsf offset %d cmd %d: %d\n",
7507 offset, vdev_param, ret);
Peter Oh9f0b7e72016-04-04 16:19:14 -07007508}
7509
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007510static int ath10k_ampdu_action(struct ieee80211_hw *hw,
7511 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02007512 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007513{
Michal Kazior7aa7a722014-08-25 12:09:38 +02007514 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007515 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Sara Sharon50ea05e2015-12-30 16:06:04 +02007516 struct ieee80211_sta *sta = params->sta;
7517 enum ieee80211_ampdu_mlme_action action = params->action;
7518 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007519
Michal Kazior7aa7a722014-08-25 12:09:38 +02007520 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 +02007521 arvif->vdev_id, sta->addr, tid, action);
7522
7523 switch (action) {
7524 case IEEE80211_AMPDU_RX_START:
7525 case IEEE80211_AMPDU_RX_STOP:
7526 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
7527 * creation/removal. Do we need to verify this?
7528 */
7529 return 0;
7530 case IEEE80211_AMPDU_TX_START:
7531 case IEEE80211_AMPDU_TX_STOP_CONT:
7532 case IEEE80211_AMPDU_TX_STOP_FLUSH:
7533 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
7534 case IEEE80211_AMPDU_TX_OPERATIONAL:
7535 /* Firmware offloads Tx aggregation entirely so deny mac80211
7536 * Tx aggregation requests.
7537 */
7538 return -EOPNOTSUPP;
7539 }
7540
7541 return -EINVAL;
7542}
7543
Michal Kazior500ff9f2015-03-31 10:26:21 +00007544static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007545ath10k_mac_update_rx_channel(struct ath10k *ar,
7546 struct ieee80211_chanctx_conf *ctx,
7547 struct ieee80211_vif_chanctx_switch *vifs,
7548 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00007549{
7550 struct cfg80211_chan_def *def = NULL;
7551
7552 /* Both locks are required because ar->rx_channel is modified. This
7553 * allows readers to hold either lock.
7554 */
7555 lockdep_assert_held(&ar->conf_mutex);
7556 lockdep_assert_held(&ar->data_lock);
7557
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007558 WARN_ON(ctx && vifs);
Mohammed Shafi Shajakhanc73f8c02017-03-08 13:52:06 +02007559 WARN_ON(vifs && !n_vifs);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007560
Michal Kazior500ff9f2015-03-31 10:26:21 +00007561 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
7562 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
7563 * ppdu on Rx may reduce performance on low-end systems. It should be
7564 * possible to make tables/hashmaps to speed the lookup up (be vary of
7565 * cpu data cache lines though regarding sizes) but to keep the initial
7566 * implementation simple and less intrusive fallback to the slow lookup
7567 * only for multi-channel cases. Single-channel cases will remain to
7568 * use the old channel derival and thus performance should not be
7569 * affected much.
7570 */
7571 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007572 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00007573 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03007574 ath10k_mac_get_any_chandef_iter,
7575 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007576
7577 if (vifs)
7578 def = &vifs[0].new_ctx->def;
7579
Michal Kazior500ff9f2015-03-31 10:26:21 +00007580 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05307581 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
7582 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
7583 /* During driver restart due to firmware assert, since mac80211
7584 * already has valid channel context for given radio, channel
7585 * context iteration return num_chanctx > 0. So fix rx_channel
7586 * when restart is in progress.
7587 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007588 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007589 } else {
7590 ar->rx_channel = NULL;
7591 }
7592 rcu_read_unlock();
7593}
7594
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007595static void
7596ath10k_mac_update_vif_chan(struct ath10k *ar,
7597 struct ieee80211_vif_chanctx_switch *vifs,
7598 int n_vifs)
7599{
7600 struct ath10k_vif *arvif;
7601 int ret;
7602 int i;
7603
7604 lockdep_assert_held(&ar->conf_mutex);
7605
7606 /* First stop monitor interface. Some FW versions crash if there's a
7607 * lone monitor interface.
7608 */
7609 if (ar->monitor_started)
7610 ath10k_monitor_stop(ar);
7611
7612 for (i = 0; i < n_vifs; i++) {
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007613 arvif = (void *)vifs[i].vif->drv_priv;
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007614
7615 ath10k_dbg(ar, ATH10K_DBG_MAC,
7616 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
7617 arvif->vdev_id,
7618 vifs[i].old_ctx->def.chan->center_freq,
7619 vifs[i].new_ctx->def.chan->center_freq,
7620 vifs[i].old_ctx->def.width,
7621 vifs[i].new_ctx->def.width);
7622
7623 if (WARN_ON(!arvif->is_started))
7624 continue;
7625
7626 if (WARN_ON(!arvif->is_up))
7627 continue;
7628
7629 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7630 if (ret) {
7631 ath10k_warn(ar, "failed to down vdev %d: %d\n",
7632 arvif->vdev_id, ret);
7633 continue;
7634 }
7635 }
7636
7637 /* All relevant vdevs are downed and associated channel resources
7638 * should be available for the channel switch now.
7639 */
7640
7641 spin_lock_bh(&ar->data_lock);
7642 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
7643 spin_unlock_bh(&ar->data_lock);
7644
7645 for (i = 0; i < n_vifs; i++) {
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007646 arvif = (void *)vifs[i].vif->drv_priv;
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007647
7648 if (WARN_ON(!arvif->is_started))
7649 continue;
7650
7651 if (WARN_ON(!arvif->is_up))
7652 continue;
7653
7654 ret = ath10k_mac_setup_bcn_tmpl(arvif);
7655 if (ret)
7656 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
7657 ret);
7658
7659 ret = ath10k_mac_setup_prb_tmpl(arvif);
7660 if (ret)
7661 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
7662 ret);
7663
7664 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7665 if (ret) {
7666 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7667 arvif->vdev_id, ret);
7668 continue;
7669 }
7670
7671 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7672 arvif->bssid);
7673 if (ret) {
7674 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7675 arvif->vdev_id, ret);
7676 continue;
7677 }
7678 }
7679
7680 ath10k_monitor_recalc(ar);
7681}
7682
Michal Kazior500ff9f2015-03-31 10:26:21 +00007683static int
7684ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7685 struct ieee80211_chanctx_conf *ctx)
7686{
7687 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007688
7689 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307690 "mac chanctx add freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007691 ctx->def.chan->center_freq, ctx->def.width, ctx);
7692
7693 mutex_lock(&ar->conf_mutex);
7694
7695 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007696 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007697 spin_unlock_bh(&ar->data_lock);
7698
7699 ath10k_recalc_radar_detection(ar);
7700 ath10k_monitor_recalc(ar);
7701
7702 mutex_unlock(&ar->conf_mutex);
7703
7704 return 0;
7705}
7706
7707static void
7708ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7709 struct ieee80211_chanctx_conf *ctx)
7710{
7711 struct ath10k *ar = hw->priv;
7712
7713 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307714 "mac chanctx remove freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007715 ctx->def.chan->center_freq, ctx->def.width, ctx);
7716
7717 mutex_lock(&ar->conf_mutex);
7718
7719 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007720 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007721 spin_unlock_bh(&ar->data_lock);
7722
7723 ath10k_recalc_radar_detection(ar);
7724 ath10k_monitor_recalc(ar);
7725
7726 mutex_unlock(&ar->conf_mutex);
7727}
7728
Michal Kazior9713e3d2015-09-03 10:44:52 +02007729struct ath10k_mac_change_chanctx_arg {
7730 struct ieee80211_chanctx_conf *ctx;
7731 struct ieee80211_vif_chanctx_switch *vifs;
7732 int n_vifs;
7733 int next_vif;
7734};
7735
7736static void
7737ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
7738 struct ieee80211_vif *vif)
7739{
7740 struct ath10k_mac_change_chanctx_arg *arg = data;
7741
7742 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
7743 return;
7744
7745 arg->n_vifs++;
7746}
7747
7748static void
7749ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
7750 struct ieee80211_vif *vif)
7751{
7752 struct ath10k_mac_change_chanctx_arg *arg = data;
7753 struct ieee80211_chanctx_conf *ctx;
7754
7755 ctx = rcu_access_pointer(vif->chanctx_conf);
7756 if (ctx != arg->ctx)
7757 return;
7758
7759 if (WARN_ON(arg->next_vif == arg->n_vifs))
7760 return;
7761
7762 arg->vifs[arg->next_vif].vif = vif;
7763 arg->vifs[arg->next_vif].old_ctx = ctx;
7764 arg->vifs[arg->next_vif].new_ctx = ctx;
7765 arg->next_vif++;
7766}
7767
Michal Kazior500ff9f2015-03-31 10:26:21 +00007768static void
7769ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7770 struct ieee80211_chanctx_conf *ctx,
7771 u32 changed)
7772{
7773 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007774 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007775
7776 mutex_lock(&ar->conf_mutex);
7777
7778 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307779 "mac chanctx change freq %hu width %d ptr %pK changed %x\n",
Michal Kazior089ab7a2015-06-03 12:16:55 +02007780 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007781
7782 /* This shouldn't really happen because channel switching should use
7783 * switch_vif_chanctx().
7784 */
7785 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7786 goto unlock;
7787
Michal Kazior9713e3d2015-09-03 10:44:52 +02007788 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7789 ieee80211_iterate_active_interfaces_atomic(
7790 hw,
7791 IEEE80211_IFACE_ITER_NORMAL,
7792 ath10k_mac_change_chanctx_cnt_iter,
7793 &arg);
7794 if (arg.n_vifs == 0)
7795 goto radar;
7796
7797 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7798 GFP_KERNEL);
7799 if (!arg.vifs)
7800 goto radar;
7801
7802 ieee80211_iterate_active_interfaces_atomic(
7803 hw,
7804 IEEE80211_IFACE_ITER_NORMAL,
7805 ath10k_mac_change_chanctx_fill_iter,
7806 &arg);
7807 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7808 kfree(arg.vifs);
7809 }
7810
7811radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007812 ath10k_recalc_radar_detection(ar);
7813
7814 /* FIXME: How to configure Rx chains properly? */
7815
7816 /* No other actions are actually necessary. Firmware maintains channel
7817 * definitions per vdev internally and there's no host-side channel
7818 * context abstraction to configure, e.g. channel width.
7819 */
7820
7821unlock:
7822 mutex_unlock(&ar->conf_mutex);
7823}
7824
7825static int
7826ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7827 struct ieee80211_vif *vif,
7828 struct ieee80211_chanctx_conf *ctx)
7829{
7830 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007831 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7832 int ret;
7833
7834 mutex_lock(&ar->conf_mutex);
7835
7836 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307837 "mac chanctx assign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007838 ctx, arvif->vdev_id);
7839
7840 if (WARN_ON(arvif->is_started)) {
7841 mutex_unlock(&ar->conf_mutex);
7842 return -EBUSY;
7843 }
7844
Michal Kazior089ab7a2015-06-03 12:16:55 +02007845 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007846 if (ret) {
7847 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7848 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007849 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007850 goto err;
7851 }
7852
7853 arvif->is_started = true;
7854
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007855 ret = ath10k_mac_vif_setup_ps(arvif);
7856 if (ret) {
7857 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7858 arvif->vdev_id, ret);
7859 goto err_stop;
7860 }
7861
Michal Kazior500ff9f2015-03-31 10:26:21 +00007862 if (vif->type == NL80211_IFTYPE_MONITOR) {
7863 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7864 if (ret) {
7865 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7866 arvif->vdev_id, ret);
7867 goto err_stop;
7868 }
7869
7870 arvif->is_up = true;
7871 }
7872
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02007873 if (ath10k_mac_can_set_cts_prot(arvif)) {
7874 ret = ath10k_mac_set_cts_prot(arvif);
7875 if (ret)
7876 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
7877 arvif->vdev_id, ret);
7878 }
7879
Anilkumar Kollie8123bb2017-12-05 19:01:25 +05307880 if (ath10k_peer_stats_enabled(ar)) {
7881 ar->pktlog_filter |= ATH10K_PKTLOG_PEER_STATS;
7882 ret = ath10k_wmi_pdev_pktlog_enable(ar,
7883 ar->pktlog_filter);
7884 if (ret) {
7885 ath10k_warn(ar, "failed to enable pktlog %d\n", ret);
7886 goto err_stop;
7887 }
7888 }
7889
Michal Kazior500ff9f2015-03-31 10:26:21 +00007890 mutex_unlock(&ar->conf_mutex);
7891 return 0;
7892
7893err_stop:
7894 ath10k_vdev_stop(arvif);
7895 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007896 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007897
7898err:
7899 mutex_unlock(&ar->conf_mutex);
7900 return ret;
7901}
7902
7903static void
7904ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7905 struct ieee80211_vif *vif,
7906 struct ieee80211_chanctx_conf *ctx)
7907{
7908 struct ath10k *ar = hw->priv;
7909 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7910 int ret;
7911
7912 mutex_lock(&ar->conf_mutex);
7913
7914 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307915 "mac chanctx unassign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007916 ctx, arvif->vdev_id);
7917
7918 WARN_ON(!arvif->is_started);
7919
7920 if (vif->type == NL80211_IFTYPE_MONITOR) {
7921 WARN_ON(!arvif->is_up);
7922
7923 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7924 if (ret)
7925 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7926 arvif->vdev_id, ret);
7927
7928 arvif->is_up = false;
7929 }
7930
7931 ret = ath10k_vdev_stop(arvif);
7932 if (ret)
7933 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7934 arvif->vdev_id, ret);
7935
7936 arvif->is_started = false;
7937
7938 mutex_unlock(&ar->conf_mutex);
7939}
7940
7941static int
7942ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7943 struct ieee80211_vif_chanctx_switch *vifs,
7944 int n_vifs,
7945 enum ieee80211_chanctx_switch_mode mode)
7946{
7947 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007948
7949 mutex_lock(&ar->conf_mutex);
7950
7951 ath10k_dbg(ar, ATH10K_DBG_MAC,
7952 "mac chanctx switch n_vifs %d mode %d\n",
7953 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007954 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007955
7956 mutex_unlock(&ar->conf_mutex);
7957 return 0;
7958}
7959
Michal Kazior0a744d92017-01-12 16:14:30 +01007960static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,
7961 struct ieee80211_vif *vif,
7962 struct ieee80211_sta *sta)
7963{
7964 struct ath10k *ar;
7965 struct ath10k_peer *peer;
7966
7967 ar = hw->priv;
7968
7969 list_for_each_entry(peer, &ar->peers, list)
7970 if (peer->sta == sta)
7971 peer->removed = true;
7972}
7973
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05307974static void ath10k_sta_statistics(struct ieee80211_hw *hw,
7975 struct ieee80211_vif *vif,
7976 struct ieee80211_sta *sta,
7977 struct station_info *sinfo)
7978{
7979 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
7980 struct ath10k *ar = arsta->arvif->ar;
7981
7982 if (!ath10k_peer_stats_enabled(ar))
7983 return;
7984
7985 sinfo->rx_duration = arsta->rx_duration;
Omer Efrat22d0d2f2018-06-17 13:07:13 +03007986 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05307987
7988 if (!arsta->txrate.legacy && !arsta->txrate.nss)
7989 return;
7990
7991 if (arsta->txrate.legacy) {
7992 sinfo->txrate.legacy = arsta->txrate.legacy;
7993 } else {
7994 sinfo->txrate.mcs = arsta->txrate.mcs;
7995 sinfo->txrate.nss = arsta->txrate.nss;
7996 sinfo->txrate.bw = arsta->txrate.bw;
7997 }
7998 sinfo->txrate.flags = arsta->txrate.flags;
Omer Efrat22d0d2f2018-06-17 13:07:13 +03007999 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05308000}
8001
Kalle Valo5e3dd152013-06-12 20:52:10 +03008002static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01008003 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02008004 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03008005 .start = ath10k_start,
8006 .stop = ath10k_stop,
8007 .config = ath10k_config,
8008 .add_interface = ath10k_add_interface,
8009 .remove_interface = ath10k_remove_interface,
8010 .configure_filter = ath10k_configure_filter,
8011 .bss_info_changed = ath10k_bss_info_changed,
Benjamin Bergebee76f2016-09-28 15:11:58 +03008012 .set_coverage_class = ath10k_mac_op_set_coverage_class,
Kalle Valo5e3dd152013-06-12 20:52:10 +03008013 .hw_scan = ath10k_hw_scan,
8014 .cancel_hw_scan = ath10k_cancel_hw_scan,
8015 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02008016 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03008017 .sta_state = ath10k_sta_state,
8018 .conf_tx = ath10k_conf_tx,
8019 .remain_on_channel = ath10k_remain_on_channel,
8020 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
8021 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02008022 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03008023 .flush = ath10k_flush,
8024 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7bb2014-05-16 17:15:38 +03008025 .set_antenna = ath10k_set_antenna,
8026 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02008027 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02008028 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00008029 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01008030 .sta_rc_update = ath10k_sta_rc_update,
Pedersen, Thomas973324f2016-09-28 16:56:29 -07008031 .offset_tsf = ath10k_offset_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02008032 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03008033 .get_et_sset_count = ath10k_debug_get_et_sset_count,
8034 .get_et_stats = ath10k_debug_get_et_stats,
8035 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00008036 .add_chanctx = ath10k_mac_op_add_chanctx,
8037 .remove_chanctx = ath10k_mac_op_remove_chanctx,
8038 .change_chanctx = ath10k_mac_op_change_chanctx,
8039 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
8040 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
8041 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Michal Kazior0a744d92017-01-12 16:14:30 +01008042 .sta_pre_rcu_remove = ath10k_mac_op_sta_pre_rcu_remove,
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05308043 .sta_statistics = ath10k_sta_statistics,
Kalle Valo43d2a302014-09-10 18:23:30 +03008044
8045 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
8046
Michal Kazior8cd13ca2013-07-16 09:38:54 +02008047#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02008048 .suspend = ath10k_wow_op_suspend,
8049 .resume = ath10k_wow_op_resume,
Ryan Hsu393b7062017-08-31 15:36:16 +03008050 .set_wakeup = ath10k_wow_op_set_wakeup,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02008051#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02008052#ifdef CONFIG_MAC80211_DEBUGFS
8053 .sta_add_debugfs = ath10k_sta_add_debugfs,
8054#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03008055};
8056
Kalle Valo5e3dd152013-06-12 20:52:10 +03008057#define CHAN2G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02008058 .band = NL80211_BAND_2GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03008059 .hw_value = (_channel), \
8060 .center_freq = (_freq), \
8061 .flags = (_flags), \
8062 .max_antenna_gain = 0, \
8063 .max_power = 30, \
8064}
8065
8066#define CHAN5G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02008067 .band = NL80211_BAND_5GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03008068 .hw_value = (_channel), \
8069 .center_freq = (_freq), \
8070 .flags = (_flags), \
8071 .max_antenna_gain = 0, \
8072 .max_power = 30, \
8073}
8074
8075static const struct ieee80211_channel ath10k_2ghz_channels[] = {
8076 CHAN2G(1, 2412, 0),
8077 CHAN2G(2, 2417, 0),
8078 CHAN2G(3, 2422, 0),
8079 CHAN2G(4, 2427, 0),
8080 CHAN2G(5, 2432, 0),
8081 CHAN2G(6, 2437, 0),
8082 CHAN2G(7, 2442, 0),
8083 CHAN2G(8, 2447, 0),
8084 CHAN2G(9, 2452, 0),
8085 CHAN2G(10, 2457, 0),
8086 CHAN2G(11, 2462, 0),
8087 CHAN2G(12, 2467, 0),
8088 CHAN2G(13, 2472, 0),
8089 CHAN2G(14, 2484, 0),
8090};
8091
8092static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02008093 CHAN5G(36, 5180, 0),
8094 CHAN5G(40, 5200, 0),
8095 CHAN5G(44, 5220, 0),
8096 CHAN5G(48, 5240, 0),
8097 CHAN5G(52, 5260, 0),
8098 CHAN5G(56, 5280, 0),
8099 CHAN5G(60, 5300, 0),
8100 CHAN5G(64, 5320, 0),
8101 CHAN5G(100, 5500, 0),
8102 CHAN5G(104, 5520, 0),
8103 CHAN5G(108, 5540, 0),
8104 CHAN5G(112, 5560, 0),
8105 CHAN5G(116, 5580, 0),
8106 CHAN5G(120, 5600, 0),
8107 CHAN5G(124, 5620, 0),
8108 CHAN5G(128, 5640, 0),
8109 CHAN5G(132, 5660, 0),
8110 CHAN5G(136, 5680, 0),
8111 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07008112 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02008113 CHAN5G(149, 5745, 0),
8114 CHAN5G(153, 5765, 0),
8115 CHAN5G(157, 5785, 0),
8116 CHAN5G(161, 5805, 0),
8117 CHAN5G(165, 5825, 0),
Mohammed Shafi Shajakhan34c30b02016-12-27 20:53:35 +05308118 CHAN5G(169, 5845, 0),
Ben Greear38441fb2018-01-02 16:51:01 -08008119 CHAN5G(173, 5865, 0),
8120 /* If you add more, you may need to change ATH10K_MAX_5G_CHAN */
8121 /* And you will definitely need to change ATH10K_NUM_CHANS in core.h */
Kalle Valo5e3dd152013-06-12 20:52:10 +03008122};
8123
Michal Kaziore7b54192014-08-07 11:03:27 +02008124struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03008125{
8126 struct ieee80211_hw *hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03008127 struct ieee80211_ops *ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008128 struct ath10k *ar;
8129
Michal Kazior4ca18072016-07-18 23:22:18 +03008130 ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);
8131 if (!ops)
Kalle Valo5e3dd152013-06-12 20:52:10 +03008132 return NULL;
8133
Michal Kazior4ca18072016-07-18 23:22:18 +03008134 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);
8135 if (!hw) {
8136 kfree(ops);
8137 return NULL;
8138 }
8139
Kalle Valo5e3dd152013-06-12 20:52:10 +03008140 ar = hw->priv;
8141 ar->hw = hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03008142 ar->ops = ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008143
8144 return ar;
8145}
8146
8147void ath10k_mac_destroy(struct ath10k *ar)
8148{
Michal Kazior4ca18072016-07-18 23:22:18 +03008149 struct ieee80211_ops *ops = ar->ops;
8150
Kalle Valo5e3dd152013-06-12 20:52:10 +03008151 ieee80211_free_hw(ar->hw);
Michal Kazior4ca18072016-07-18 23:22:18 +03008152 kfree(ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008153}
8154
8155static const struct ieee80211_iface_limit ath10k_if_limits[] = {
8156 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308157 .max = 8,
8158 .types = BIT(NL80211_IFTYPE_STATION)
8159 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02008160 },
8161 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308162 .max = 3,
8163 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02008164 },
8165 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308166 .max = 1,
8167 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01008168 },
8169 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308170 .max = 7,
8171 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008172#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308173 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008174#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02008175 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03008176};
8177
Bartosz Markowskif2595092013-12-10 16:20:39 +01008178static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008179 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308180 .max = 8,
8181 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008182#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308183 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008184#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008185 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05308186 {
8187 .max = 1,
8188 .types = BIT(NL80211_IFTYPE_STATION)
8189 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008190};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008191
8192static const struct ieee80211_iface_combination ath10k_if_comb[] = {
8193 {
8194 .limits = ath10k_if_limits,
8195 .n_limits = ARRAY_SIZE(ath10k_if_limits),
8196 .max_interfaces = 8,
8197 .num_different_channels = 1,
8198 .beacon_int_infra_match = true,
8199 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01008200};
8201
8202static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008203 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01008204 .limits = ath10k_10x_if_limits,
8205 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008206 .max_interfaces = 8,
8207 .num_different_channels = 1,
8208 .beacon_int_infra_match = true,
Anilkumar Kolli8ebee732018-03-28 12:19:40 +03008209 .beacon_int_min_gcd = 1,
Bartosz Markowskif2595092013-12-10 16:20:39 +01008210#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008211 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
8212 BIT(NL80211_CHAN_WIDTH_20) |
8213 BIT(NL80211_CHAN_WIDTH_40) |
8214 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02008215#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01008216 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03008217};
8218
Michal Kaziorcf327842015-03-31 10:26:25 +00008219static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
8220 {
8221 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02008222 .types = BIT(NL80211_IFTYPE_STATION),
8223 },
8224 {
8225 .max = 2,
8226 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008227#ifdef CONFIG_MAC80211_MESH
8228 BIT(NL80211_IFTYPE_MESH_POINT) |
8229#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00008230 BIT(NL80211_IFTYPE_P2P_CLIENT) |
8231 BIT(NL80211_IFTYPE_P2P_GO),
8232 },
8233 {
8234 .max = 1,
8235 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
8236 },
8237};
8238
Michal Kaziored25b112015-07-09 13:08:39 +02008239static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
8240 {
8241 .max = 2,
8242 .types = BIT(NL80211_IFTYPE_STATION),
8243 },
8244 {
8245 .max = 2,
8246 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
8247 },
8248 {
8249 .max = 1,
8250 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008251#ifdef CONFIG_MAC80211_MESH
8252 BIT(NL80211_IFTYPE_MESH_POINT) |
8253#endif
Michal Kaziored25b112015-07-09 13:08:39 +02008254 BIT(NL80211_IFTYPE_P2P_GO),
8255 },
8256 {
8257 .max = 1,
8258 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
8259 },
8260};
8261
Michal Kaziorcf327842015-03-31 10:26:25 +00008262static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
8263 {
8264 .max = 1,
8265 .types = BIT(NL80211_IFTYPE_STATION),
8266 },
8267 {
8268 .max = 1,
8269 .types = BIT(NL80211_IFTYPE_ADHOC),
8270 },
8271};
8272
8273/* FIXME: This is not thouroughly tested. These combinations may over- or
8274 * underestimate hw/fw capabilities.
8275 */
8276static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
8277 {
8278 .limits = ath10k_tlv_if_limit,
8279 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02008280 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00008281 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
8282 },
8283 {
8284 .limits = ath10k_tlv_if_limit_ibss,
8285 .num_different_channels = 1,
8286 .max_interfaces = 2,
8287 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
8288 },
8289};
8290
8291static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
8292 {
8293 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02008294 .num_different_channels = 1,
8295 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00008296 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
8297 },
8298 {
Michal Kaziored25b112015-07-09 13:08:39 +02008299 .limits = ath10k_tlv_qcs_if_limit,
8300 .num_different_channels = 2,
8301 .max_interfaces = 4,
8302 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
8303 },
8304 {
Michal Kaziorcf327842015-03-31 10:26:25 +00008305 .limits = ath10k_tlv_if_limit_ibss,
8306 .num_different_channels = 1,
8307 .max_interfaces = 2,
8308 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
8309 },
8310};
8311
Raja Manicf36fef2015-06-22 20:22:25 +05308312static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
8313 {
8314 .max = 1,
8315 .types = BIT(NL80211_IFTYPE_STATION),
8316 },
8317 {
8318 .max = 16,
8319 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008320#ifdef CONFIG_MAC80211_MESH
8321 | BIT(NL80211_IFTYPE_MESH_POINT)
8322#endif
Raja Manicf36fef2015-06-22 20:22:25 +05308323 },
8324};
8325
8326static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
8327 {
8328 .limits = ath10k_10_4_if_limits,
8329 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
8330 .max_interfaces = 16,
8331 .num_different_channels = 1,
8332 .beacon_int_infra_match = true,
Anilkumar Kolli8ebee732018-03-28 12:19:40 +03008333 .beacon_int_min_gcd = 1,
Raja Manicf36fef2015-06-22 20:22:25 +05308334#ifdef CONFIG_ATH10K_DFS_CERTIFIED
8335 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
8336 BIT(NL80211_CHAN_WIDTH_20) |
8337 BIT(NL80211_CHAN_WIDTH_40) |
8338 BIT(NL80211_CHAN_WIDTH_80),
8339#endif
8340 },
8341};
8342
Maharaja Kennadyrajan46005632018-09-18 17:37:26 +05308343static const struct
8344ieee80211_iface_combination ath10k_10_4_bcn_int_if_comb[] = {
8345 {
8346 .limits = ath10k_10_4_if_limits,
8347 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
8348 .max_interfaces = 16,
8349 .num_different_channels = 1,
8350 .beacon_int_infra_match = true,
8351 .beacon_int_min_gcd = 100,
8352#ifdef CONFIG_ATH10K_DFS_CERTIFIED
8353 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
8354 BIT(NL80211_CHAN_WIDTH_20) |
8355 BIT(NL80211_CHAN_WIDTH_40) |
8356 BIT(NL80211_CHAN_WIDTH_80),
8357#endif
8358 },
8359};
8360
Kalle Valo5e3dd152013-06-12 20:52:10 +03008361static void ath10k_get_arvif_iter(void *data, u8 *mac,
8362 struct ieee80211_vif *vif)
8363{
8364 struct ath10k_vif_iter *arvif_iter = data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02008365 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008366
8367 if (arvif->vdev_id == arvif_iter->vdev_id)
8368 arvif_iter->arvif = arvif;
8369}
8370
8371struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
8372{
8373 struct ath10k_vif_iter arvif_iter;
8374 u32 flags;
8375
8376 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
8377 arvif_iter.vdev_id = vdev_id;
8378
8379 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
8380 ieee80211_iterate_active_interfaces_atomic(ar->hw,
8381 flags,
8382 ath10k_get_arvif_iter,
8383 &arvif_iter);
8384 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008385 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008386 return NULL;
8387 }
8388
8389 return arvif_iter.arvif;
8390}
8391
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008392#define WRD_METHOD "WRDD"
8393#define WRDD_WIFI (0x07)
8394
8395static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_object *wrdd)
8396{
8397 union acpi_object *mcc_pkg;
8398 union acpi_object *domain_type;
8399 union acpi_object *mcc_value;
8400 u32 i;
8401
8402 if (wrdd->type != ACPI_TYPE_PACKAGE ||
8403 wrdd->package.count < 2 ||
8404 wrdd->package.elements[0].type != ACPI_TYPE_INTEGER ||
8405 wrdd->package.elements[0].integer.value != 0) {
8406 ath10k_warn(ar, "ignoring malformed/unsupported wrdd structure\n");
8407 return 0;
8408 }
8409
8410 for (i = 1; i < wrdd->package.count; ++i) {
8411 mcc_pkg = &wrdd->package.elements[i];
8412
8413 if (mcc_pkg->type != ACPI_TYPE_PACKAGE)
8414 continue;
8415 if (mcc_pkg->package.count < 2)
8416 continue;
8417 if (mcc_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
8418 mcc_pkg->package.elements[1].type != ACPI_TYPE_INTEGER)
8419 continue;
8420
8421 domain_type = &mcc_pkg->package.elements[0];
8422 if (domain_type->integer.value != WRDD_WIFI)
8423 continue;
8424
8425 mcc_value = &mcc_pkg->package.elements[1];
8426 return mcc_value->integer.value;
8427 }
8428 return 0;
8429}
8430
8431static int ath10k_mac_get_wrdd_regulatory(struct ath10k *ar, u16 *rd)
8432{
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008433 acpi_handle root_handle;
8434 acpi_handle handle;
8435 struct acpi_buffer wrdd = {ACPI_ALLOCATE_BUFFER, NULL};
8436 acpi_status status;
8437 u32 alpha2_code;
8438 char alpha2[3];
8439
Brian Norris79169f12018-11-02 10:17:48 -07008440 root_handle = ACPI_HANDLE(ar->dev);
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008441 if (!root_handle)
8442 return -EOPNOTSUPP;
8443
8444 status = acpi_get_handle(root_handle, (acpi_string)WRD_METHOD, &handle);
8445 if (ACPI_FAILURE(status)) {
8446 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8447 "failed to get wrd method %d\n", status);
8448 return -EIO;
8449 }
8450
8451 status = acpi_evaluate_object(handle, NULL, NULL, &wrdd);
8452 if (ACPI_FAILURE(status)) {
8453 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8454 "failed to call wrdc %d\n", status);
8455 return -EIO;
8456 }
8457
8458 alpha2_code = ath10k_mac_wrdd_get_mcc(ar, wrdd.pointer);
8459 kfree(wrdd.pointer);
8460 if (!alpha2_code)
8461 return -EIO;
8462
8463 alpha2[0] = (alpha2_code >> 8) & 0xff;
8464 alpha2[1] = (alpha2_code >> 0) & 0xff;
8465 alpha2[2] = '\0';
8466
8467 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8468 "regulatory hint from WRDD (alpha2-code): %s\n", alpha2);
8469
8470 *rd = ath_regd_find_country_by_name(alpha2);
8471 if (*rd == 0xffff)
8472 return -EIO;
8473
8474 *rd |= COUNTRY_ERD_FLAG;
8475 return 0;
8476}
8477
8478static int ath10k_mac_init_rd(struct ath10k *ar)
8479{
8480 int ret;
8481 u16 rd;
8482
8483 ret = ath10k_mac_get_wrdd_regulatory(ar, &rd);
8484 if (ret) {
8485 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8486 "fallback to eeprom programmed regulatory settings\n");
8487 rd = ar->hw_eeprom_rd;
8488 }
8489
8490 ar->ath_common.regulatory.current_rd = rd;
8491 return 0;
8492}
8493
Kalle Valo5e3dd152013-06-12 20:52:10 +03008494int ath10k_mac_register(struct ath10k *ar)
8495{
Johannes Berg3cb10942015-01-22 21:38:45 +01008496 static const u32 cipher_suites[] = {
8497 WLAN_CIPHER_SUITE_WEP40,
8498 WLAN_CIPHER_SUITE_WEP104,
8499 WLAN_CIPHER_SUITE_TKIP,
8500 WLAN_CIPHER_SUITE_CCMP,
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07008501
8502 /* Do not add hardware supported ciphers before this line.
8503 * Allow software encryption for all chips. Don't forget to
8504 * update n_cipher_suites below.
8505 */
Johannes Berg3cb10942015-01-22 21:38:45 +01008506 WLAN_CIPHER_SUITE_AES_CMAC,
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07008507 WLAN_CIPHER_SUITE_BIP_CMAC_256,
8508 WLAN_CIPHER_SUITE_BIP_GMAC_128,
8509 WLAN_CIPHER_SUITE_BIP_GMAC_256,
8510
8511 /* Only QCA99x0 and QCA4019 varients support GCMP-128, GCMP-256
8512 * and CCMP-256 in hardware.
8513 */
8514 WLAN_CIPHER_SUITE_GCMP,
8515 WLAN_CIPHER_SUITE_GCMP_256,
8516 WLAN_CIPHER_SUITE_CCMP_256,
Johannes Berg3cb10942015-01-22 21:38:45 +01008517 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03008518 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008519 void *channels;
8520 int ret;
8521
Brian Norris234e4302018-09-07 10:21:57 -07008522 if (!is_valid_ether_addr(ar->mac_addr)) {
8523 ath10k_warn(ar, "invalid MAC address; choosing random\n");
8524 eth_random_addr(ar->mac_addr);
8525 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008526 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
8527
8528 SET_IEEE80211_DEV(ar->hw, ar->dev);
8529
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00008530 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
8531 ARRAY_SIZE(ath10k_5ghz_channels)) !=
8532 ATH10K_NUM_CHANS);
8533
Kalle Valo5e3dd152013-06-12 20:52:10 +03008534 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
8535 channels = kmemdup(ath10k_2ghz_channels,
8536 sizeof(ath10k_2ghz_channels),
8537 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02008538 if (!channels) {
8539 ret = -ENOMEM;
8540 goto err_free;
8541 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008542
Johannes Berg57fbcce2016-04-12 15:56:15 +02008543 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03008544 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
8545 band->channels = channels;
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +03008546
8547 if (ar->hw_params.cck_rate_map_rev2) {
8548 band->n_bitrates = ath10k_g_rates_rev2_size;
8549 band->bitrates = ath10k_g_rates_rev2;
8550 } else {
8551 band->n_bitrates = ath10k_g_rates_size;
8552 band->bitrates = ath10k_g_rates;
8553 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008554
Johannes Berg57fbcce2016-04-12 15:56:15 +02008555 ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008556 }
8557
8558 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
8559 channels = kmemdup(ath10k_5ghz_channels,
8560 sizeof(ath10k_5ghz_channels),
8561 GFP_KERNEL);
8562 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02008563 ret = -ENOMEM;
8564 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008565 }
8566
Johannes Berg57fbcce2016-04-12 15:56:15 +02008567 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03008568 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
8569 band->channels = channels;
8570 band->n_bitrates = ath10k_a_rates_size;
8571 band->bitrates = ath10k_a_rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02008572 ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008573 }
8574
Sven Eckelmann34d56292018-08-24 15:04:59 +03008575 wiphy_read_of_freq_limits(ar->hw->wiphy);
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05308576 ath10k_mac_setup_ht_vht_cap(ar);
8577
Kalle Valo5e3dd152013-06-12 20:52:10 +03008578 ar->hw->wiphy->interface_modes =
8579 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008580 BIT(NL80211_IFTYPE_AP) |
8581 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01008582
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05308583 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
8584 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03008585
Kalle Valoc4cdf752016-04-20 19:45:18 +03008586 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))
Bartosz Markowskid3541812013-12-10 16:20:40 +01008587 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01008588 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01008589 BIT(NL80211_IFTYPE_P2P_CLIENT) |
8590 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008591
Johannes Berg30686bf2015-06-02 21:39:54 +02008592 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
Venkateswara Naralasetty36d9cdb2017-10-04 12:22:57 +03008593
8594 if (!test_bit(ATH10K_FW_FEATURE_NO_PS,
8595 ar->running_fw->fw_file.fw_features)) {
8596 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
8597 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
8598 }
8599
Johannes Berg30686bf2015-06-02 21:39:54 +02008600 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
8601 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
8602 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
8603 ieee80211_hw_set(ar->hw, AP_LINK_PS);
8604 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02008605 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
8606 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
8607 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
8608 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
8609 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
8610 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Sara Sharonf3fe4e92016-10-18 23:12:11 +03008611 ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
Rajkumar Manoharanff32eeb2016-09-06 12:38:41 +05308612 ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008613
David Liuccec9032015-07-24 20:25:32 +03008614 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8615 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
8616
Eliad Peller0d8614b2014-09-10 14:07:36 +03008617 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00008618 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03008619
Kalle Valo5e3dd152013-06-12 20:52:10 +03008620 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03008621 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008622
8623 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02008624 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
8625 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008626 }
8627
8628 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
8629 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
8630
Wen Gongce834e22018-10-04 08:45:31 +03008631 if (test_bit(WMI_SERVICE_NLO, ar->wmi.svc_map)) {
8632 ar->hw->wiphy->max_sched_scan_reqs = 1;
8633 ar->hw->wiphy->max_sched_scan_ssids = WMI_PNO_MAX_SUPP_NETWORKS;
8634 ar->hw->wiphy->max_match_sets = WMI_PNO_MAX_SUPP_NETWORKS;
8635 ar->hw->wiphy->max_sched_scan_ie_len = WMI_PNO_MAX_IE_LENGTH;
8636 ar->hw->wiphy->max_sched_scan_plans = WMI_PNO_MAX_SCHED_SCAN_PLANS;
8637 ar->hw->wiphy->max_sched_scan_plan_interval =
8638 WMI_PNO_MAX_SCHED_SCAN_PLAN_INT;
8639 ar->hw->wiphy->max_sched_scan_plan_iterations =
8640 WMI_PNO_MAX_SCHED_SCAN_PLAN_ITRNS;
8641 }
8642
Kalle Valo5e3dd152013-06-12 20:52:10 +03008643 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01008644 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02008645 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008646
Kalle Valo5e3dd152013-06-12 20:52:10 +03008647 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
8648
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02008649 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
8650 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
8651
8652 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
8653 * that userspace (e.g. wpa_supplicant/hostapd) can generate
8654 * correct Probe Responses. This is more of a hack advert..
8655 */
8656 ar->hw->wiphy->probe_resp_offload |=
8657 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
8658 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
8659 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
8660 }
8661
Manikanta Pubbisettyadd6cd82017-07-28 15:15:42 +03008662 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map) ||
8663 test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, ar->wmi.svc_map)) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03008664 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
Balaji Pothunoori14d65772017-12-21 20:00:42 +05308665 if (test_bit(WMI_SERVICE_TDLS_WIDER_BANDWIDTH, ar->wmi.svc_map))
8666 ieee80211_hw_set(ar->hw, TDLS_WIDER_BW);
Manikanta Pubbisettyadd6cd82017-07-28 15:15:42 +03008667 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03008668
Yingying Tang802ca332018-03-28 12:12:52 +03008669 if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
8670 ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA);
8671
Kalle Valo5e3dd152013-06-12 20:52:10 +03008672 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01008673 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008674 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
8675
8676 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05308677 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
8678 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02008679
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01008680 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
8681
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02008682 ret = ath10k_wow_init(ar);
8683 if (ret) {
8684 ath10k_warn(ar, "failed to init wow: %d\n", ret);
8685 goto err_free;
8686 }
8687
Janusz Dziedzicc7025342015-06-15 14:46:41 +03008688 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
Pradeep Kumar Chitrapube8cce92018-05-23 11:09:09 +03008689 wiphy_ext_feature_set(ar->hw->wiphy,
8690 NL80211_EXT_FEATURE_SET_SCAN_DWELL);
Janusz Dziedzicc7025342015-06-15 14:46:41 +03008691
Balaji Pothunoori6bc17952018-09-10 11:54:30 +05308692 if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map) ||
8693 test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, ar->wmi.svc_map))
Balaji Pothunooric7fd8d22018-09-04 12:52:18 +03008694 wiphy_ext_feature_set(ar->hw->wiphy,
Balaji Pothunoori6bc17952018-09-10 11:54:30 +05308695 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
Balaji Pothunooric7fd8d22018-09-04 12:52:18 +03008696
Kan Yand1ce37b2019-02-11 18:47:52 +02008697 if (ath10k_peer_stats_enabled(ar))
8698 wiphy_ext_feature_set(ar->hw->wiphy,
8699 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
Pradeep Kumar Chitrapu059104b2019-02-11 18:47:54 +02008700
8701 if (test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map))
8702 wiphy_ext_feature_set(ar->hw->wiphy,
8703 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
8704
Kalle Valo5e3dd152013-06-12 20:52:10 +03008705 /*
8706 * on LL hardware queues are managed entirely by the FW
8707 * so we only advertise to mac we can do the queues thing
8708 */
Michal Kazior96d828d2015-03-31 10:26:23 +00008709 ar->hw->queues = IEEE80211_MAX_QUEUES;
8710
8711 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
8712 * something that vdev_ids can't reach so that we don't stop the queue
8713 * accidentally.
8714 */
8715 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008716
Kalle Valobf3c13a2016-04-20 19:45:33 +03008717 switch (ar->running_fw->fw_file.wmi_op_version) {
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008718 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01008719 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
8720 ar->hw->wiphy->n_iface_combinations =
8721 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03008722 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008723 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00008724 case ATH10K_FW_WMI_OP_VERSION_TLV:
8725 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
8726 ar->hw->wiphy->iface_combinations =
8727 ath10k_tlv_qcs_if_comb;
8728 ar->hw->wiphy->n_iface_combinations =
8729 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
8730 } else {
8731 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
8732 ar->hw->wiphy->n_iface_combinations =
8733 ARRAY_SIZE(ath10k_tlv_if_comb);
8734 }
8735 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
8736 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008737 case ATH10K_FW_WMI_OP_VERSION_10_1:
8738 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02008739 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008740 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
8741 ar->hw->wiphy->n_iface_combinations =
8742 ARRAY_SIZE(ath10k_10x_if_comb);
8743 break;
Raja Mani9bd21322015-06-22 20:10:09 +05308744 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05308745 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
8746 ar->hw->wiphy->n_iface_combinations =
8747 ARRAY_SIZE(ath10k_10_4_if_comb);
Maharaja Kennadyrajan46005632018-09-18 17:37:26 +05308748 if (test_bit(WMI_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT,
8749 ar->wmi.svc_map)) {
8750 ar->hw->wiphy->iface_combinations =
8751 ath10k_10_4_bcn_int_if_comb;
8752 ar->hw->wiphy->n_iface_combinations =
8753 ARRAY_SIZE(ath10k_10_4_bcn_int_if_comb);
8754 }
Raja Mani9bd21322015-06-22 20:10:09 +05308755 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008756 case ATH10K_FW_WMI_OP_VERSION_UNSET:
8757 case ATH10K_FW_WMI_OP_VERSION_MAX:
8758 WARN_ON(1);
8759 ret = -EINVAL;
8760 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01008761 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008762
David Liuccec9032015-07-24 20:25:32 +03008763 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8764 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02008765
Masahiro Yamada97f26452016-08-03 13:45:50 -07008766 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008767 /* Init ath dfs pattern detector */
8768 ar->ath_common.debug_mask = ATH_DBG_DFS;
8769 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
8770 NL80211_DFS_UNSET);
8771
8772 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02008773 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008774 }
8775
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008776 ret = ath10k_mac_init_rd(ar);
8777 if (ret) {
8778 ath10k_err(ar, "failed to derive regdom: %d\n", ret);
8779 goto err_dfs_detector_exit;
8780 }
8781
Benjamin Bergebee76f2016-09-28 15:11:58 +03008782 /* Disable set_coverage_class for chipsets that do not support it. */
8783 if (!ar->hw_params.hw_ops->set_coverage_class)
8784 ar->ops->set_coverage_class = NULL;
8785
Kalle Valo5e3dd152013-06-12 20:52:10 +03008786 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
8787 ath10k_reg_notifier);
8788 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008789 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008790 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008791 }
8792
Carl Huang60e1d0f2018-04-19 19:39:40 +03008793 if (test_bit(WMI_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi.svc_map)) {
Carl Huang60e1d0f2018-04-19 19:39:40 +03008794 ar->hw->wiphy->features |=
8795 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
8796 }
8797
Johannes Berg3cb10942015-01-22 21:38:45 +01008798 ar->hw->wiphy->cipher_suites = cipher_suites;
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07008799
8800 /* QCA988x and QCA6174 family chips do not support CCMP-256, GCMP-128
8801 * and GCMP-256 ciphers in hardware. Fetch number of ciphers supported
8802 * from chip specific hw_param table.
8803 */
8804 if (!ar->hw_params.n_cipher_suites ||
8805 ar->hw_params.n_cipher_suites > ARRAY_SIZE(cipher_suites)) {
8806 ath10k_err(ar, "invalid hw_params.n_cipher_suites %d\n",
8807 ar->hw_params.n_cipher_suites);
8808 ar->hw_params.n_cipher_suites = 8;
8809 }
8810 ar->hw->wiphy->n_cipher_suites = ar->hw_params.n_cipher_suites;
Johannes Berg3cb10942015-01-22 21:38:45 +01008811
Andrew Zaborowskiae44b502017-02-10 04:50:23 +01008812 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
8813
Toke Høiland-Jørgensenbb2edb72019-02-11 18:47:49 +02008814 ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
8815
Kalle Valo5e3dd152013-06-12 20:52:10 +03008816 ret = ieee80211_register_hw(ar->hw);
8817 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008818 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008819 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008820 }
8821
Manikanta Pubbisetty4920ce32019-02-11 18:47:56 +02008822 if (test_bit(WMI_SERVICE_PER_PACKET_SW_ENCRYPT, ar->wmi.svc_map)) {
8823 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
8824 ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN);
8825 }
8826
Kalle Valo5e3dd152013-06-12 20:52:10 +03008827 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
8828 ret = regulatory_hint(ar->hw->wiphy,
8829 ar->ath_common.regulatory.alpha2);
8830 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02008831 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008832 }
8833
8834 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02008835
8836err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03008837 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07008838
8839err_dfs_detector_exit:
Masahiro Yamada97f26452016-08-03 13:45:50 -07008840 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Jeff Johnson0e339442015-10-08 09:15:53 -07008841 ar->dfs_detector->exit(ar->dfs_detector);
8842
Michal Kaziord6015b22013-07-22 14:13:30 +02008843err_free:
Johannes Berg57fbcce2016-04-12 15:56:15 +02008844 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8845 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Michal Kaziord6015b22013-07-22 14:13:30 +02008846
Jeff Johnson0e339442015-10-08 09:15:53 -07008847 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008848 return ret;
8849}
8850
8851void ath10k_mac_unregister(struct ath10k *ar)
8852{
8853 ieee80211_unregister_hw(ar->hw);
8854
Masahiro Yamada97f26452016-08-03 13:45:50 -07008855 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008856 ar->dfs_detector->exit(ar->dfs_detector);
8857
Johannes Berg57fbcce2016-04-12 15:56:15 +02008858 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8859 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008860
8861 SET_IEEE80211_DEV(ar->hw, NULL);
8862}