blob: 1cc87cb156209adb33ffbdf2e56f75c61ac5507b [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 Pillai38a13902018-02-27 19:09:07 +02004 * Copyright (c) 2018, 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
21#include <net/mac80211.h>
22#include <linux/etherdevice.h>
Bartosz Markowski209b2a62016-09-28 15:11:58 +030023#include <linux/acpi.h>
Kalle Valo5e3dd152013-06-12 20:52:10 +030024
Michal Kazior8cd13ca2013-07-16 09:38:54 +020025#include "hif.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030026#include "core.h"
27#include "debug.h"
28#include "wmi.h"
29#include "htt.h"
30#include "txrx.h"
Kalle Valo43d2a302014-09-10 18:23:30 +030031#include "testmode.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020032#include "wmi.h"
Michal Kaziorb4aa5392015-03-31 10:26:24 +000033#include "wmi-tlv.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020034#include "wmi-ops.h"
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +020035#include "wow.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030036
Michal Kaziordcc33092015-03-30 09:51:54 +030037/*********/
38/* Rates */
39/*********/
40
Michal Kaziordcc33092015-03-30 09:51:54 +030041static struct ieee80211_rate ath10k_rates[] = {
Michal Kazior5528e032015-03-30 09:51:56 +030042 { .bitrate = 10,
43 .hw_value = ATH10K_HW_RATE_CCK_LP_1M },
44 { .bitrate = 20,
45 .hw_value = ATH10K_HW_RATE_CCK_LP_2M,
46 .hw_value_short = ATH10K_HW_RATE_CCK_SP_2M,
47 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
48 { .bitrate = 55,
49 .hw_value = ATH10K_HW_RATE_CCK_LP_5_5M,
50 .hw_value_short = ATH10K_HW_RATE_CCK_SP_5_5M,
51 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
52 { .bitrate = 110,
53 .hw_value = ATH10K_HW_RATE_CCK_LP_11M,
54 .hw_value_short = ATH10K_HW_RATE_CCK_SP_11M,
55 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
Michal Kazior5653b392015-03-30 09:51:54 +030056
Michal Kazioraf001482015-03-30 09:51:56 +030057 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
58 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
59 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
60 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
61 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
62 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
63 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
64 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
Michal Kaziordcc33092015-03-30 09:51:54 +030065};
66
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +030067static struct ieee80211_rate ath10k_rates_rev2[] = {
68 { .bitrate = 10,
69 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_1M },
70 { .bitrate = 20,
71 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_2M,
72 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_2M,
73 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
74 { .bitrate = 55,
75 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
76 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
77 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
78 { .bitrate = 110,
79 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_11M,
80 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_11M,
81 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
82
83 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
84 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
85 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
86 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
87 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
88 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
89 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
90 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
91};
92
Michal Kazior8d7aa6b2015-03-30 09:51:57 +030093#define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
94
95#define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
96#define ath10k_a_rates_size (ARRAY_SIZE(ath10k_rates) - \
97 ATH10K_MAC_FIRST_OFDM_RATE_IDX)
Michal Kaziordcc33092015-03-30 09:51:54 +030098#define ath10k_g_rates (ath10k_rates + 0)
99#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
100
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +0300101#define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
102#define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
103
Michal Kazior486017c2015-03-30 09:51:54 +0300104static bool ath10k_mac_bitrate_is_cck(int bitrate)
105{
106 switch (bitrate) {
107 case 10:
108 case 20:
109 case 55:
110 case 110:
111 return true;
112 }
113
114 return false;
115}
116
117static u8 ath10k_mac_bitrate_to_rate(int bitrate)
118{
119 return DIV_ROUND_UP(bitrate, 5) |
120 (ath10k_mac_bitrate_is_cck(bitrate) ? BIT(7) : 0);
121}
122
Michal Kazior5528e032015-03-30 09:51:56 +0300123u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
Yanbo Li4b7f3532015-11-12 10:36:10 -0800124 u8 hw_rate, bool cck)
Michal Kazior5528e032015-03-30 09:51:56 +0300125{
126 const struct ieee80211_rate *rate;
127 int i;
128
129 for (i = 0; i < sband->n_bitrates; i++) {
130 rate = &sband->bitrates[i];
131
Yanbo Li4b7f3532015-11-12 10:36:10 -0800132 if (ath10k_mac_bitrate_is_cck(rate->bitrate) != cck)
133 continue;
134
Michal Kazior5528e032015-03-30 09:51:56 +0300135 if (rate->hw_value == hw_rate)
136 return i;
137 else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
138 rate->hw_value_short == hw_rate)
139 return i;
140 }
141
142 return 0;
143}
144
Michal Kazior01cebe12015-03-30 09:51:56 +0300145u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
146 u32 bitrate)
147{
148 int i;
149
150 for (i = 0; i < sband->n_bitrates; i++)
151 if (sband->bitrates[i].bitrate == bitrate)
152 return i;
153
154 return 0;
155}
156
Michal Kazior3ae54222015-03-31 10:49:20 +0000157static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
158{
159 switch ((mcs_map >> (2 * nss)) & 0x3) {
160 case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;
161 case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;
162 case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;
163 }
164 return 0;
165}
166
Michal Kazior45c9abc2015-04-21 20:42:58 +0300167static u32
168ath10k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
169{
170 int nss;
171
172 for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--)
173 if (ht_mcs_mask[nss])
174 return nss + 1;
175
176 return 1;
177}
178
179static u32
180ath10k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
181{
182 int nss;
183
184 for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--)
185 if (vht_mcs_mask[nss])
186 return nss + 1;
187
188 return 1;
189}
Kalle Valo5e3dd152013-06-12 20:52:10 +0300190
Raja Mani7e247a92016-04-12 20:15:53 +0530191int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val)
192{
193 enum wmi_host_platform_type platform_type;
194 int ret;
195
196 if (test_bit(WMI_SERVICE_TX_MODE_DYNAMIC, ar->wmi.svc_map))
197 platform_type = WMI_HOST_PLATFORM_LOW_PERF;
198 else
199 platform_type = WMI_HOST_PLATFORM_HIGH_PERF;
200
201 ret = ath10k_wmi_ext_resource_config(ar, platform_type, val);
202
203 if (ret && ret != -EOPNOTSUPP) {
204 ath10k_warn(ar, "failed to configure ext resource: %d\n", ret);
205 return ret;
206 }
207
208 return 0;
209}
210
Kalle Valo5e3dd152013-06-12 20:52:10 +0300211/**********/
212/* Crypto */
213/**********/
214
215static int ath10k_send_key(struct ath10k_vif *arvif,
216 struct ieee80211_key_conf *key,
217 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100218 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300219{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200220 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300221 struct wmi_vdev_install_key_arg arg = {
222 .vdev_id = arvif->vdev_id,
223 .key_idx = key->keyidx,
224 .key_len = key->keylen,
225 .key_data = key->key,
Michal Kazior370e5672015-02-18 14:02:26 +0100226 .key_flags = flags,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300227 .macaddr = macaddr,
228 };
229
Michal Kazior548db542013-07-05 16:15:15 +0300230 lockdep_assert_held(&arvif->ar->conf_mutex);
231
Kalle Valo5e3dd152013-06-12 20:52:10 +0300232 switch (key->cipher) {
233 case WLAN_CIPHER_SUITE_CCMP:
234 arg.key_cipher = WMI_CIPHER_AES_CCM;
Marek Kwaczynskie4e82e92015-01-24 12:14:53 +0200235 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300236 break;
237 case WLAN_CIPHER_SUITE_TKIP:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300238 arg.key_cipher = WMI_CIPHER_TKIP;
239 arg.key_txmic_len = 8;
240 arg.key_rxmic_len = 8;
241 break;
242 case WLAN_CIPHER_SUITE_WEP40:
243 case WLAN_CIPHER_SUITE_WEP104:
244 arg.key_cipher = WMI_CIPHER_WEP;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300245 break;
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -0700246 case WLAN_CIPHER_SUITE_CCMP_256:
247 arg.key_cipher = WMI_CIPHER_AES_CCM;
248 break;
249 case WLAN_CIPHER_SUITE_GCMP:
250 case WLAN_CIPHER_SUITE_GCMP_256:
251 arg.key_cipher = WMI_CIPHER_AES_GCM;
252 break;
253 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
254 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
255 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
Johannes Berg3cb10942015-01-22 21:38:45 +0100256 case WLAN_CIPHER_SUITE_AES_CMAC:
Bartosz Markowskid7131c02015-03-10 14:32:19 +0100257 WARN_ON(1);
258 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300259 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200260 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300261 return -EOPNOTSUPP;
262 }
263
Kalle Valob9e284e2015-10-05 17:56:35 +0300264 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
David Liuccec9032015-07-24 20:25:32 +0300265 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
David Liuccec9032015-07-24 20:25:32 +0300266
Kalle Valo5e3dd152013-06-12 20:52:10 +0300267 if (cmd == DISABLE_KEY) {
268 arg.key_cipher = WMI_CIPHER_NONE;
269 arg.key_data = NULL;
270 }
271
272 return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
273}
274
275static int ath10k_install_key(struct ath10k_vif *arvif,
276 struct ieee80211_key_conf *key,
277 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100278 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300279{
280 struct ath10k *ar = arvif->ar;
281 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300282 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300283
Michal Kazior548db542013-07-05 16:15:15 +0300284 lockdep_assert_held(&ar->conf_mutex);
285
Wolfram Sang16735d02013-11-14 14:32:02 -0800286 reinit_completion(&ar->install_key_done);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300287
David Liuccec9032015-07-24 20:25:32 +0300288 if (arvif->nohwcrypt)
289 return 1;
290
Michal Kazior370e5672015-02-18 14:02:26 +0100291 ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300292 if (ret)
293 return ret;
294
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300295 time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);
296 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300297 return -ETIMEDOUT;
298
299 return 0;
300}
301
302static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
303 const u8 *addr)
304{
305 struct ath10k *ar = arvif->ar;
306 struct ath10k_peer *peer;
307 int ret;
308 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100309 u32 flags;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300310
311 lockdep_assert_held(&ar->conf_mutex);
312
Michal Kazior8674d902015-08-13 14:10:46 +0200313 if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP &&
Peter Oh7c97b722015-12-03 09:50:55 -0800314 arvif->vif->type != NL80211_IFTYPE_ADHOC &&
315 arvif->vif->type != NL80211_IFTYPE_MESH_POINT))
Michal Kazior8674d902015-08-13 14:10:46 +0200316 return -EINVAL;
317
Kalle Valo5e3dd152013-06-12 20:52:10 +0300318 spin_lock_bh(&ar->data_lock);
319 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
320 spin_unlock_bh(&ar->data_lock);
321
322 if (!peer)
323 return -ENOENT;
324
325 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
326 if (arvif->wep_keys[i] == NULL)
327 continue;
Michal Kazior370e5672015-02-18 14:02:26 +0100328
Michal Kazior8674d902015-08-13 14:10:46 +0200329 switch (arvif->vif->type) {
330 case NL80211_IFTYPE_AP:
331 flags = WMI_KEY_PAIRWISE;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300332
Michal Kazior8674d902015-08-13 14:10:46 +0200333 if (arvif->def_wep_key_idx == i)
334 flags |= WMI_KEY_TX_USAGE;
Michal Kaziorce90b272015-04-10 13:23:21 +0000335
Michal Kazior8674d902015-08-13 14:10:46 +0200336 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
337 SET_KEY, addr, flags);
338 if (ret < 0)
339 return ret;
340 break;
341 case NL80211_IFTYPE_ADHOC:
342 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
343 SET_KEY, addr,
344 WMI_KEY_PAIRWISE);
345 if (ret < 0)
346 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300347
Michal Kazior8674d902015-08-13 14:10:46 +0200348 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
349 SET_KEY, addr, WMI_KEY_GROUP);
350 if (ret < 0)
351 return ret;
352 break;
353 default:
354 WARN_ON(1);
355 return -EINVAL;
356 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300357
Sujith Manoharanae167132014-11-25 11:46:59 +0530358 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300359 peer->keys[i] = arvif->wep_keys[i];
Sujith Manoharanae167132014-11-25 11:46:59 +0530360 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300361 }
362
Michal Kaziorce90b272015-04-10 13:23:21 +0000363 /* In some cases (notably with static WEP IBSS with multiple keys)
364 * multicast Tx becomes broken. Both pairwise and groupwise keys are
365 * installed already. Using WMI_KEY_TX_USAGE in different combinations
366 * didn't seem help. Using def_keyid vdev parameter seems to be
367 * effective so use that.
368 *
369 * FIXME: Revisit. Perhaps this can be done in a less hacky way.
370 */
Michal Kazior8674d902015-08-13 14:10:46 +0200371 if (arvif->vif->type != NL80211_IFTYPE_ADHOC)
372 return 0;
373
Michal Kaziorce90b272015-04-10 13:23:21 +0000374 if (arvif->def_wep_key_idx == -1)
375 return 0;
376
377 ret = ath10k_wmi_vdev_set_param(arvif->ar,
378 arvif->vdev_id,
379 arvif->ar->wmi.vdev_param->def_keyid,
380 arvif->def_wep_key_idx);
381 if (ret) {
382 ath10k_warn(ar, "failed to re-set def wpa key idxon vdev %i: %d\n",
383 arvif->vdev_id, ret);
384 return ret;
385 }
386
Kalle Valo5e3dd152013-06-12 20:52:10 +0300387 return 0;
388}
389
390static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
391 const u8 *addr)
392{
393 struct ath10k *ar = arvif->ar;
394 struct ath10k_peer *peer;
395 int first_errno = 0;
396 int ret;
397 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100398 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300399
400 lockdep_assert_held(&ar->conf_mutex);
401
402 spin_lock_bh(&ar->data_lock);
403 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
404 spin_unlock_bh(&ar->data_lock);
405
406 if (!peer)
407 return -ENOENT;
408
409 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
410 if (peer->keys[i] == NULL)
411 continue;
412
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200413 /* key flags are not required to delete the key */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300414 ret = ath10k_install_key(arvif, peer->keys[i],
Michal Kazior370e5672015-02-18 14:02:26 +0100415 DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300416 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300417 first_errno = ret;
418
David Liuccec9032015-07-24 20:25:32 +0300419 if (ret < 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200420 ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300421 i, ret);
422
Sujith Manoharanae167132014-11-25 11:46:59 +0530423 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300424 peer->keys[i] = NULL;
Sujith Manoharanae167132014-11-25 11:46:59 +0530425 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300426 }
427
428 return first_errno;
429}
430
Sujith Manoharan504f6cd2014-11-25 11:46:58 +0530431bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
432 u8 keyidx)
433{
434 struct ath10k_peer *peer;
435 int i;
436
437 lockdep_assert_held(&ar->data_lock);
438
439 /* We don't know which vdev this peer belongs to,
440 * since WMI doesn't give us that information.
441 *
442 * FIXME: multi-bss needs to be handled.
443 */
444 peer = ath10k_peer_find(ar, 0, addr);
445 if (!peer)
446 return false;
447
448 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
449 if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)
450 return true;
451 }
452
453 return false;
454}
455
Kalle Valo5e3dd152013-06-12 20:52:10 +0300456static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
457 struct ieee80211_key_conf *key)
458{
459 struct ath10k *ar = arvif->ar;
460 struct ath10k_peer *peer;
461 u8 addr[ETH_ALEN];
462 int first_errno = 0;
463 int ret;
464 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100465 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300466
467 lockdep_assert_held(&ar->conf_mutex);
468
469 for (;;) {
470 /* since ath10k_install_key we can't hold data_lock all the
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +0100471 * time, so we try to remove the keys incrementally
472 */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300473 spin_lock_bh(&ar->data_lock);
474 i = 0;
475 list_for_each_entry(peer, &ar->peers, list) {
476 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
477 if (peer->keys[i] == key) {
Kalle Valob25f32c2014-09-14 12:50:49 +0300478 ether_addr_copy(addr, peer->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300479 peer->keys[i] = NULL;
480 break;
481 }
482 }
483
484 if (i < ARRAY_SIZE(peer->keys))
485 break;
486 }
487 spin_unlock_bh(&ar->data_lock);
488
489 if (i == ARRAY_SIZE(peer->keys))
490 break;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200491 /* key flags are not required to delete the key */
Michal Kazior370e5672015-02-18 14:02:26 +0100492 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300493 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300494 first_errno = ret;
495
496 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200497 ath10k_warn(ar, "failed to remove key for %pM: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +0200498 addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300499 }
500
501 return first_errno;
502}
503
Michal Kaziorad325cb2015-02-18 14:02:27 +0100504static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
505 struct ieee80211_key_conf *key)
506{
507 struct ath10k *ar = arvif->ar;
508 struct ath10k_peer *peer;
509 int ret;
510
511 lockdep_assert_held(&ar->conf_mutex);
512
513 list_for_each_entry(peer, &ar->peers, list) {
Kalle Valoc178da52016-04-13 14:13:49 +0300514 if (ether_addr_equal(peer->addr, arvif->vif->addr))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100515 continue;
516
Kalle Valoc178da52016-04-13 14:13:49 +0300517 if (ether_addr_equal(peer->addr, arvif->bssid))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100518 continue;
519
520 if (peer->keys[key->keyidx] == key)
521 continue;
522
523 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
524 arvif->vdev_id, key->keyidx);
525
526 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
527 if (ret) {
528 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
529 arvif->vdev_id, peer->addr, ret);
530 return ret;
531 }
532 }
533
534 return 0;
535}
536
Kalle Valo5e3dd152013-06-12 20:52:10 +0300537/*********************/
538/* General utilities */
539/*********************/
540
541static inline enum wmi_phy_mode
542chan_to_phymode(const struct cfg80211_chan_def *chandef)
543{
544 enum wmi_phy_mode phymode = MODE_UNKNOWN;
545
546 switch (chandef->chan->band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +0200547 case NL80211_BAND_2GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300548 switch (chandef->width) {
549 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800550 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
551 phymode = MODE_11B;
552 else
553 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300554 break;
555 case NL80211_CHAN_WIDTH_20:
556 phymode = MODE_11NG_HT20;
557 break;
558 case NL80211_CHAN_WIDTH_40:
559 phymode = MODE_11NG_HT40;
560 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400561 case NL80211_CHAN_WIDTH_5:
562 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300563 case NL80211_CHAN_WIDTH_80:
564 case NL80211_CHAN_WIDTH_80P80:
565 case NL80211_CHAN_WIDTH_160:
566 phymode = MODE_UNKNOWN;
567 break;
568 }
569 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +0200570 case NL80211_BAND_5GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300571 switch (chandef->width) {
572 case NL80211_CHAN_WIDTH_20_NOHT:
573 phymode = MODE_11A;
574 break;
575 case NL80211_CHAN_WIDTH_20:
576 phymode = MODE_11NA_HT20;
577 break;
578 case NL80211_CHAN_WIDTH_40:
579 phymode = MODE_11NA_HT40;
580 break;
581 case NL80211_CHAN_WIDTH_80:
582 phymode = MODE_11AC_VHT80;
583 break;
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +0200584 case NL80211_CHAN_WIDTH_160:
585 phymode = MODE_11AC_VHT160;
586 break;
587 case NL80211_CHAN_WIDTH_80P80:
588 phymode = MODE_11AC_VHT80_80;
589 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400590 case NL80211_CHAN_WIDTH_5:
591 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300592 phymode = MODE_UNKNOWN;
593 break;
594 }
595 break;
596 default:
597 break;
598 }
599
600 WARN_ON(phymode == MODE_UNKNOWN);
601 return phymode;
602}
603
604static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
605{
606/*
607 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
608 * 0 for no restriction
609 * 1 for 1/4 us
610 * 2 for 1/2 us
611 * 3 for 1 us
612 * 4 for 2 us
613 * 5 for 4 us
614 * 6 for 8 us
615 * 7 for 16 us
616 */
617 switch (mpdudensity) {
618 case 0:
619 return 0;
620 case 1:
621 case 2:
622 case 3:
623 /* Our lower layer calculations limit our precision to
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +0100624 * 1 microsecond
625 */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300626 return 1;
627 case 4:
628 return 2;
629 case 5:
630 return 4;
631 case 6:
632 return 8;
633 case 7:
634 return 16;
635 default:
636 return 0;
637 }
638}
639
Michal Kazior500ff9f2015-03-31 10:26:21 +0000640int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
641 struct cfg80211_chan_def *def)
642{
643 struct ieee80211_chanctx_conf *conf;
644
645 rcu_read_lock();
646 conf = rcu_dereference(vif->chanctx_conf);
647 if (!conf) {
648 rcu_read_unlock();
649 return -ENOENT;
650 }
651
652 *def = conf->def;
653 rcu_read_unlock();
654
655 return 0;
656}
657
658static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,
659 struct ieee80211_chanctx_conf *conf,
660 void *data)
661{
662 int *num = data;
663
664 (*num)++;
665}
666
667static int ath10k_mac_num_chanctxs(struct ath10k *ar)
668{
669 int num = 0;
670
671 ieee80211_iter_chan_contexts_atomic(ar->hw,
672 ath10k_mac_num_chanctxs_iter,
673 &num);
674
675 return num;
676}
677
678static void
679ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
680 struct ieee80211_chanctx_conf *conf,
681 void *data)
682{
683 struct cfg80211_chan_def **def = data;
684
685 *def = &conf->def;
686}
687
Michal Kazior69427262016-03-06 16:14:30 +0200688static int ath10k_peer_create(struct ath10k *ar,
689 struct ieee80211_vif *vif,
690 struct ieee80211_sta *sta,
691 u32 vdev_id,
692 const u8 *addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300693 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300694{
Michal Kaziore04cafb2015-08-05 12:15:24 +0200695 struct ath10k_vif *arvif;
Michal Kazior69427262016-03-06 16:14:30 +0200696 struct ath10k_peer *peer;
Michal Kaziore04cafb2015-08-05 12:15:24 +0200697 int num_peers = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300698 int ret;
699
700 lockdep_assert_held(&ar->conf_mutex);
701
Michal Kaziore04cafb2015-08-05 12:15:24 +0200702 num_peers = ar->num_peers;
703
704 /* Each vdev consumes a peer entry as well */
705 list_for_each_entry(arvif, &ar->arvifs, list)
706 num_peers++;
707
708 if (num_peers >= ar->max_num_peers)
Michal Kaziorcfd10612014-11-25 15:16:05 +0100709 return -ENOBUFS;
710
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300711 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800712 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200713 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200714 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300715 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800716 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300717
718 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800719 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200720 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200721 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300722 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800723 }
Michal Kazior292a7532014-11-25 15:16:04 +0100724
Michal Kazior69427262016-03-06 16:14:30 +0200725 spin_lock_bh(&ar->data_lock);
726
727 peer = ath10k_peer_find(ar, vdev_id, addr);
728 if (!peer) {
Ben Greearfee48cf2016-04-01 14:12:12 -0700729 spin_unlock_bh(&ar->data_lock);
Michal Kazior69427262016-03-06 16:14:30 +0200730 ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n",
731 addr, vdev_id);
732 ath10k_wmi_peer_delete(ar, vdev_id, addr);
Michal Kazior69427262016-03-06 16:14:30 +0200733 return -ENOENT;
734 }
735
736 peer->vif = vif;
737 peer->sta = sta;
738
739 spin_unlock_bh(&ar->data_lock);
740
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100741 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300742
743 return 0;
744}
745
Kalle Valo5a13e762014-01-20 11:01:46 +0200746static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
747{
748 struct ath10k *ar = arvif->ar;
749 u32 param;
750 int ret;
751
752 param = ar->wmi.pdev_param->sta_kickout_th;
753 ret = ath10k_wmi_pdev_set_param(ar, param,
754 ATH10K_KICKOUT_THRESHOLD);
755 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200756 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200757 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200758 return ret;
759 }
760
761 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
762 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
763 ATH10K_KEEPALIVE_MIN_IDLE);
764 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200765 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200766 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200767 return ret;
768 }
769
770 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
771 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
772 ATH10K_KEEPALIVE_MAX_IDLE);
773 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200774 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200775 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200776 return ret;
777 }
778
779 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
780 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
781 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
782 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200783 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200784 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200785 return ret;
786 }
787
788 return 0;
789}
790
Vivek Natarajanacab6402014-11-26 09:06:12 +0200791static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200792{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200793 struct ath10k *ar = arvif->ar;
794 u32 vdev_param;
795
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200796 vdev_param = ar->wmi.vdev_param->rts_threshold;
797 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200798}
799
Kalle Valo5e3dd152013-06-12 20:52:10 +0300800static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
801{
802 int ret;
803
804 lockdep_assert_held(&ar->conf_mutex);
805
806 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
807 if (ret)
808 return ret;
809
810 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
811 if (ret)
812 return ret;
813
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100814 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100815
Kalle Valo5e3dd152013-06-12 20:52:10 +0300816 return 0;
817}
818
819static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
820{
821 struct ath10k_peer *peer, *tmp;
Michal Kazior69427262016-03-06 16:14:30 +0200822 int peer_id;
Ben Greear6d68f792016-06-30 15:23:53 +0300823 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300824
825 lockdep_assert_held(&ar->conf_mutex);
826
827 spin_lock_bh(&ar->data_lock);
828 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
829 if (peer->vdev_id != vdev_id)
830 continue;
831
Michal Kazior7aa7a722014-08-25 12:09:38 +0200832 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300833 peer->addr, vdev_id);
834
Michal Kazior69427262016-03-06 16:14:30 +0200835 for_each_set_bit(peer_id, peer->peer_ids,
836 ATH10K_MAX_NUM_PEER_IDS) {
837 ar->peer_map[peer_id] = NULL;
838 }
839
Ben Greear6d68f792016-06-30 15:23:53 +0300840 /* Double check that peer is properly un-referenced from
841 * the peer_map
842 */
843 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
844 if (ar->peer_map[i] == peer) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +0530845 ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
Ben Greear6d68f792016-06-30 15:23:53 +0300846 peer->addr, peer, i);
847 ar->peer_map[i] = NULL;
848 }
849 }
850
Kalle Valo5e3dd152013-06-12 20:52:10 +0300851 list_del(&peer->list);
852 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100853 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300854 }
855 spin_unlock_bh(&ar->data_lock);
856}
857
Michal Kaziora96d7742013-07-16 09:38:56 +0200858static void ath10k_peer_cleanup_all(struct ath10k *ar)
859{
860 struct ath10k_peer *peer, *tmp;
Ben Greear6d68f792016-06-30 15:23:53 +0300861 int i;
Michal Kaziora96d7742013-07-16 09:38:56 +0200862
863 lockdep_assert_held(&ar->conf_mutex);
864
865 spin_lock_bh(&ar->data_lock);
866 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
867 list_del(&peer->list);
868 kfree(peer);
869 }
Ben Greear6d68f792016-06-30 15:23:53 +0300870
871 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
872 ar->peer_map[i] = NULL;
873
Michal Kaziora96d7742013-07-16 09:38:56 +0200874 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100875
876 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100877 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200878}
879
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300880static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
881 struct ieee80211_sta *sta,
882 enum wmi_tdls_peer_state state)
883{
884 int ret;
885 struct wmi_tdls_peer_update_cmd_arg arg = {};
886 struct wmi_tdls_peer_capab_arg cap = {};
887 struct wmi_channel_arg chan_arg = {};
888
889 lockdep_assert_held(&ar->conf_mutex);
890
891 arg.vdev_id = vdev_id;
892 arg.peer_state = state;
893 ether_addr_copy(arg.addr, sta->addr);
894
895 cap.peer_max_sp = sta->max_sp;
896 cap.peer_uapsd_queues = sta->uapsd_queues;
897
898 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
899 !sta->tdls_initiator)
900 cap.is_peer_responder = 1;
901
902 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
903 if (ret) {
904 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
905 arg.addr, vdev_id, ret);
906 return ret;
907 }
908
909 return 0;
910}
911
Kalle Valo5e3dd152013-06-12 20:52:10 +0300912/************************/
913/* Interface management */
914/************************/
915
Michal Kazior64badcb2014-09-18 11:18:02 +0300916void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
917{
918 struct ath10k *ar = arvif->ar;
919
920 lockdep_assert_held(&ar->data_lock);
921
922 if (!arvif->beacon)
923 return;
924
925 if (!arvif->beacon_buf)
926 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
927 arvif->beacon->len, DMA_TO_DEVICE);
928
Michal Kazioraf213192015-01-29 14:29:52 +0200929 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
930 arvif->beacon_state != ATH10K_BEACON_SENT))
931 return;
932
Michal Kazior64badcb2014-09-18 11:18:02 +0300933 dev_kfree_skb_any(arvif->beacon);
934
935 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200936 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300937}
938
939static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
940{
941 struct ath10k *ar = arvif->ar;
942
943 lockdep_assert_held(&ar->data_lock);
944
945 ath10k_mac_vif_beacon_free(arvif);
946
947 if (arvif->beacon_buf) {
948 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
949 arvif->beacon_buf, arvif->beacon_paddr);
950 arvif->beacon_buf = NULL;
951 }
952}
953
Kalle Valo5e3dd152013-06-12 20:52:10 +0300954static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
955{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300956 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300957
Michal Kazior548db542013-07-05 16:15:15 +0300958 lockdep_assert_held(&ar->conf_mutex);
959
Michal Kazior7962b0d2014-10-28 10:34:38 +0100960 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
961 return -ESHUTDOWN;
962
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300963 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
964 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
965 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300966 return -ETIMEDOUT;
967
968 return 0;
969}
970
Michal Kazior1bbc0972014-04-08 09:45:47 +0300971static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300972{
Michal Kazior500ff9f2015-03-31 10:26:21 +0000973 struct cfg80211_chan_def *chandef = NULL;
Maninder Singh19be9e92015-07-16 09:25:33 +0530974 struct ieee80211_channel *channel = NULL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300975 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300976 int ret = 0;
977
978 lockdep_assert_held(&ar->conf_mutex);
979
Michal Kazior500ff9f2015-03-31 10:26:21 +0000980 ieee80211_iter_chan_contexts_atomic(ar->hw,
981 ath10k_mac_get_any_chandef_iter,
982 &chandef);
983 if (WARN_ON_ONCE(!chandef))
984 return -ENOENT;
985
986 channel = chandef->chan;
987
Kalle Valo5e3dd152013-06-12 20:52:10 +0300988 arg.vdev_id = vdev_id;
989 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +0100990 arg.channel.band_center_freq1 = chandef->center_freq1;
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +0200991 arg.channel.band_center_freq2 = chandef->center_freq2;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300992
993 /* TODO setup this dynamically, what in case we
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +0100994 * don't have any vifs?
995 */
Michal Kaziorc930f742014-01-23 11:38:25 +0100996 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200997 arg.channel.chan_radar =
998 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300999
Michal Kazior89c5c842013-10-23 04:02:13 -07001000 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07001001 arg.channel.max_power = channel->max_power * 2;
1002 arg.channel.max_reg_power = channel->max_reg_power * 2;
1003 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001004
Michal Kazior7962b0d2014-10-28 10:34:38 +01001005 reinit_completion(&ar->vdev_setup_done);
1006
Kalle Valo5e3dd152013-06-12 20:52:10 +03001007 ret = ath10k_wmi_vdev_start(ar, &arg);
1008 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001009 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001010 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001011 return ret;
1012 }
1013
1014 ret = ath10k_vdev_setup_sync(ar);
1015 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001016 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001017 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001018 return ret;
1019 }
1020
1021 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
1022 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001023 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001024 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001025 goto vdev_stop;
1026 }
1027
1028 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001029
Michal Kazior7aa7a722014-08-25 12:09:38 +02001030 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001031 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001032 return 0;
1033
1034vdev_stop:
1035 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1036 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001037 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001038 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001039
1040 return ret;
1041}
1042
Michal Kazior1bbc0972014-04-08 09:45:47 +03001043static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001044{
1045 int ret = 0;
1046
1047 lockdep_assert_held(&ar->conf_mutex);
1048
Marek Puzyniak52fa0192013-09-24 14:06:24 +02001049 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
1050 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001051 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001052 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001053
Michal Kazior7962b0d2014-10-28 10:34:38 +01001054 reinit_completion(&ar->vdev_setup_done);
1055
Kalle Valo5e3dd152013-06-12 20:52:10 +03001056 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1057 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001058 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001059 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001060
1061 ret = ath10k_vdev_setup_sync(ar);
1062 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +02001063 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001064 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001065
Michal Kazior7aa7a722014-08-25 12:09:38 +02001066 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001067 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001068 return ret;
1069}
1070
Michal Kazior1bbc0972014-04-08 09:45:47 +03001071static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001072{
1073 int bit, ret = 0;
1074
1075 lockdep_assert_held(&ar->conf_mutex);
1076
Ben Greeara9aefb32014-08-12 11:02:19 +03001077 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001078 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03001079 return -ENOMEM;
1080 }
1081
Ben Greear16c11172014-09-23 14:17:16 -07001082 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +03001083
Ben Greear16c11172014-09-23 14:17:16 -07001084 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001085
1086 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
1087 WMI_VDEV_TYPE_MONITOR,
1088 0, ar->mac_addr);
1089 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001090 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001091 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +03001092 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001093 }
1094
Ben Greear16c11172014-09-23 14:17:16 -07001095 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +02001096 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001097 ar->monitor_vdev_id);
1098
Kalle Valo5e3dd152013-06-12 20:52:10 +03001099 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001100}
1101
Michal Kazior1bbc0972014-04-08 09:45:47 +03001102static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001103{
1104 int ret = 0;
1105
1106 lockdep_assert_held(&ar->conf_mutex);
1107
Kalle Valo5e3dd152013-06-12 20:52:10 +03001108 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
1109 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001110 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001111 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001112 return ret;
1113 }
1114
Ben Greear16c11172014-09-23 14:17:16 -07001115 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001116
Michal Kazior7aa7a722014-08-25 12:09:38 +02001117 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001118 ar->monitor_vdev_id);
1119 return ret;
1120}
1121
Michal Kazior1bbc0972014-04-08 09:45:47 +03001122static int ath10k_monitor_start(struct ath10k *ar)
1123{
1124 int ret;
1125
1126 lockdep_assert_held(&ar->conf_mutex);
1127
Michal Kazior1bbc0972014-04-08 09:45:47 +03001128 ret = ath10k_monitor_vdev_create(ar);
1129 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001130 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001131 return ret;
1132 }
1133
1134 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
1135 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001136 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001137 ath10k_monitor_vdev_delete(ar);
1138 return ret;
1139 }
1140
1141 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001142 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +03001143
1144 return 0;
1145}
1146
Michal Kazior19337472014-08-28 12:58:16 +02001147static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +03001148{
1149 int ret;
1150
1151 lockdep_assert_held(&ar->conf_mutex);
1152
Michal Kazior1bbc0972014-04-08 09:45:47 +03001153 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001154 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001155 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001156 return ret;
1157 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001158
1159 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001160 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001161 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001162 return ret;
1163 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001164
1165 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001166 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +02001167
1168 return 0;
1169}
1170
Michal Kazior500ff9f2015-03-31 10:26:21 +00001171static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1172{
1173 int num_ctx;
1174
1175 /* At least one chanctx is required to derive a channel to start
1176 * monitor vdev on.
1177 */
1178 num_ctx = ath10k_mac_num_chanctxs(ar);
1179 if (num_ctx == 0)
1180 return false;
1181
1182 /* If there's already an existing special monitor interface then don't
1183 * bother creating another monitor vdev.
1184 */
1185 if (ar->monitor_arvif)
1186 return false;
1187
1188 return ar->monitor ||
Manoharan, Rajkumar705d7aa2016-11-23 16:58:11 +02001189 (!test_bit(ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST,
1190 ar->running_fw->fw_file.fw_features) &&
1191 (ar->filter_flags & FIF_OTHER_BSS)) ||
Michal Kazior500ff9f2015-03-31 10:26:21 +00001192 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1193}
1194
1195static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1196{
1197 int num_ctx;
1198
1199 num_ctx = ath10k_mac_num_chanctxs(ar);
1200
1201 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1202 * shouldn't allow this but make sure to prevent handling the following
1203 * case anyway since multi-channel DFS hasn't been tested at all.
1204 */
1205 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1206 return false;
1207
1208 return true;
1209}
1210
Michal Kazior19337472014-08-28 12:58:16 +02001211static int ath10k_monitor_recalc(struct ath10k *ar)
1212{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001213 bool needed;
1214 bool allowed;
1215 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001216
1217 lockdep_assert_held(&ar->conf_mutex);
1218
Michal Kazior500ff9f2015-03-31 10:26:21 +00001219 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1220 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001221
1222 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001223 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1224 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001225
Michal Kazior500ff9f2015-03-31 10:26:21 +00001226 if (WARN_ON(needed && !allowed)) {
1227 if (ar->monitor_started) {
1228 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1229
1230 ret = ath10k_monitor_stop(ar);
1231 if (ret)
Kalle Valo2a995082015-10-05 17:56:37 +03001232 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",
1233 ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001234 /* not serious */
1235 }
1236
1237 return -EPERM;
1238 }
1239
1240 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001241 return 0;
1242
Michal Kazior500ff9f2015-03-31 10:26:21 +00001243 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001244 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001245 else
1246 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001247}
1248
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02001249static bool ath10k_mac_can_set_cts_prot(struct ath10k_vif *arvif)
1250{
1251 struct ath10k *ar = arvif->ar;
1252
1253 lockdep_assert_held(&ar->conf_mutex);
1254
1255 if (!arvif->is_started) {
1256 ath10k_dbg(ar, ATH10K_DBG_MAC, "defer cts setup, vdev is not ready yet\n");
1257 return false;
1258 }
1259
1260 return true;
1261}
1262
1263static int ath10k_mac_set_cts_prot(struct ath10k_vif *arvif)
1264{
1265 struct ath10k *ar = arvif->ar;
1266 u32 vdev_param;
1267
1268 lockdep_assert_held(&ar->conf_mutex);
1269
1270 vdev_param = ar->wmi.vdev_param->protection_mode;
1271
1272 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_protection %d\n",
1273 arvif->vdev_id, arvif->use_cts_prot);
1274
1275 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1276 arvif->use_cts_prot ? 1 : 0);
1277}
1278
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001279static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1280{
1281 struct ath10k *ar = arvif->ar;
1282 u32 vdev_param, rts_cts = 0;
1283
1284 lockdep_assert_held(&ar->conf_mutex);
1285
1286 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1287
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001288 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001289
1290 if (arvif->num_legacy_stations > 0)
1291 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1292 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001293 else
1294 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1295 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001296
Bartosz Markowski86176902016-12-15 11:23:24 +02001297 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d recalc rts/cts prot %d\n",
1298 arvif->vdev_id, rts_cts);
1299
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001300 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1301 rts_cts);
1302}
1303
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001304static int ath10k_start_cac(struct ath10k *ar)
1305{
1306 int ret;
1307
1308 lockdep_assert_held(&ar->conf_mutex);
1309
1310 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1311
Michal Kazior19337472014-08-28 12:58:16 +02001312 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001313 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001314 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001315 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1316 return ret;
1317 }
1318
Michal Kazior7aa7a722014-08-25 12:09:38 +02001319 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001320 ar->monitor_vdev_id);
1321
1322 return 0;
1323}
1324
1325static int ath10k_stop_cac(struct ath10k *ar)
1326{
1327 lockdep_assert_held(&ar->conf_mutex);
1328
1329 /* CAC is not running - do nothing */
1330 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1331 return 0;
1332
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001333 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001334 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001335
Michal Kazior7aa7a722014-08-25 12:09:38 +02001336 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001337
1338 return 0;
1339}
1340
Michal Kazior500ff9f2015-03-31 10:26:21 +00001341static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1342 struct ieee80211_chanctx_conf *conf,
1343 void *data)
1344{
1345 bool *ret = data;
1346
1347 if (!*ret && conf->radar_enabled)
1348 *ret = true;
1349}
1350
1351static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1352{
1353 bool has_radar = false;
1354
1355 ieee80211_iter_chan_contexts_atomic(ar->hw,
1356 ath10k_mac_has_radar_iter,
1357 &has_radar);
1358
1359 return has_radar;
1360}
1361
Michal Kaziord6500972014-04-08 09:56:09 +03001362static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001363{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001364 int ret;
1365
1366 lockdep_assert_held(&ar->conf_mutex);
1367
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001368 ath10k_stop_cac(ar);
1369
Michal Kazior500ff9f2015-03-31 10:26:21 +00001370 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001371 return;
1372
Michal Kaziord6500972014-04-08 09:56:09 +03001373 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001374 return;
1375
1376 ret = ath10k_start_cac(ar);
1377 if (ret) {
1378 /*
1379 * Not possible to start CAC on current channel so starting
1380 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1381 * by indicating that radar was detected.
1382 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001383 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001384 ieee80211_radar_detected(ar->hw);
1385 }
1386}
1387
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301388static int ath10k_vdev_stop(struct ath10k_vif *arvif)
Michal Kazior72654fa2014-04-08 09:56:09 +03001389{
1390 struct ath10k *ar = arvif->ar;
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301391 int ret;
1392
1393 lockdep_assert_held(&ar->conf_mutex);
1394
1395 reinit_completion(&ar->vdev_setup_done);
1396
1397 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1398 if (ret) {
1399 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1400 arvif->vdev_id, ret);
1401 return ret;
1402 }
1403
1404 ret = ath10k_vdev_setup_sync(ar);
1405 if (ret) {
Colin Ian King23de5792017-06-25 22:29:32 +01001406 ath10k_warn(ar, "failed to synchronize setup for vdev %i: %d\n",
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301407 arvif->vdev_id, ret);
1408 return ret;
1409 }
1410
1411 WARN_ON(ar->num_started_vdevs == 0);
1412
1413 if (ar->num_started_vdevs != 0) {
1414 ar->num_started_vdevs--;
1415 ath10k_recalc_radar_detection(ar);
1416 }
1417
1418 return ret;
1419}
1420
Michal Kazior500ff9f2015-03-31 10:26:21 +00001421static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1422 const struct cfg80211_chan_def *chandef,
1423 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001424{
1425 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001426 struct wmi_vdev_start_request_arg arg = {};
1427 int ret = 0;
1428
1429 lockdep_assert_held(&ar->conf_mutex);
1430
1431 reinit_completion(&ar->vdev_setup_done);
1432
1433 arg.vdev_id = arvif->vdev_id;
1434 arg.dtim_period = arvif->dtim_period;
1435 arg.bcn_intval = arvif->beacon_interval;
1436
1437 arg.channel.freq = chandef->chan->center_freq;
1438 arg.channel.band_center_freq1 = chandef->center_freq1;
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02001439 arg.channel.band_center_freq2 = chandef->center_freq2;
Michal Kazior72654fa2014-04-08 09:56:09 +03001440 arg.channel.mode = chan_to_phymode(chandef);
1441
1442 arg.channel.min_power = 0;
1443 arg.channel.max_power = chandef->chan->max_power * 2;
1444 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1445 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1446
1447 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1448 arg.ssid = arvif->u.ap.ssid;
1449 arg.ssid_len = arvif->u.ap.ssid_len;
1450 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1451
1452 /* For now allow DFS for AP mode */
1453 arg.channel.chan_radar =
1454 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1455 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1456 arg.ssid = arvif->vif->bss_conf.ssid;
1457 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1458 }
1459
Michal Kazior7aa7a722014-08-25 12:09:38 +02001460 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001461 "mac vdev %d start center_freq %d phymode %s\n",
1462 arg.vdev_id, arg.channel.freq,
1463 ath10k_wmi_phymode_str(arg.channel.mode));
1464
Michal Kaziordc55e302014-07-29 12:53:36 +03001465 if (restart)
1466 ret = ath10k_wmi_vdev_restart(ar, &arg);
1467 else
1468 ret = ath10k_wmi_vdev_start(ar, &arg);
1469
Michal Kazior72654fa2014-04-08 09:56:09 +03001470 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001471 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001472 arg.vdev_id, ret);
1473 return ret;
1474 }
1475
1476 ret = ath10k_vdev_setup_sync(ar);
1477 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001478 ath10k_warn(ar,
1479 "failed to synchronize setup for vdev %i restart %d: %d\n",
1480 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001481 return ret;
1482 }
1483
Michal Kaziord6500972014-04-08 09:56:09 +03001484 ar->num_started_vdevs++;
1485 ath10k_recalc_radar_detection(ar);
1486
Michal Kazior72654fa2014-04-08 09:56:09 +03001487 return ret;
1488}
1489
Michal Kazior500ff9f2015-03-31 10:26:21 +00001490static int ath10k_vdev_start(struct ath10k_vif *arvif,
1491 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001492{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001493 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001494}
1495
Michal Kazior500ff9f2015-03-31 10:26:21 +00001496static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1497 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001498{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001499 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kazior72654fa2014-04-08 09:56:09 +03001500}
1501
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001502static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1503 struct sk_buff *bcn)
1504{
1505 struct ath10k *ar = arvif->ar;
1506 struct ieee80211_mgmt *mgmt;
1507 const u8 *p2p_ie;
1508 int ret;
1509
Peter Oh08c27be2016-01-28 13:54:09 -08001510 if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001511 return 0;
1512
1513 mgmt = (void *)bcn->data;
1514 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1515 mgmt->u.beacon.variable,
1516 bcn->len - (mgmt->u.beacon.variable -
1517 bcn->data));
1518 if (!p2p_ie)
1519 return -ENOENT;
1520
1521 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1522 if (ret) {
1523 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1524 arvif->vdev_id, ret);
1525 return ret;
1526 }
1527
1528 return 0;
1529}
1530
1531static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1532 u8 oui_type, size_t ie_offset)
1533{
1534 size_t len;
1535 const u8 *next;
1536 const u8 *end;
1537 u8 *ie;
1538
1539 if (WARN_ON(skb->len < ie_offset))
1540 return -EINVAL;
1541
1542 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1543 skb->data + ie_offset,
1544 skb->len - ie_offset);
1545 if (!ie)
1546 return -ENOENT;
1547
1548 len = ie[1] + 2;
1549 end = skb->data + skb->len;
1550 next = ie + len;
1551
1552 if (WARN_ON(next > end))
1553 return -EINVAL;
1554
1555 memmove(ie, next, end - next);
1556 skb_trim(skb, skb->len - len);
1557
1558 return 0;
1559}
1560
1561static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1562{
1563 struct ath10k *ar = arvif->ar;
1564 struct ieee80211_hw *hw = ar->hw;
1565 struct ieee80211_vif *vif = arvif->vif;
1566 struct ieee80211_mutable_offsets offs = {};
1567 struct sk_buff *bcn;
1568 int ret;
1569
1570 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1571 return 0;
1572
Michal Kazior81a9a172015-03-05 16:02:17 +02001573 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1574 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1575 return 0;
1576
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001577 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1578 if (!bcn) {
1579 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1580 return -EPERM;
1581 }
1582
1583 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1584 if (ret) {
1585 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1586 kfree_skb(bcn);
1587 return ret;
1588 }
1589
1590 /* P2P IE is inserted by firmware automatically (as configured above)
1591 * so remove it from the base beacon template to avoid duplicate P2P
1592 * IEs in beacon frames.
1593 */
1594 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1595 offsetof(struct ieee80211_mgmt,
1596 u.beacon.variable));
1597
1598 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1599 0, NULL, 0);
1600 kfree_skb(bcn);
1601
1602 if (ret) {
1603 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1604 ret);
1605 return ret;
1606 }
1607
1608 return 0;
1609}
1610
1611static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1612{
1613 struct ath10k *ar = arvif->ar;
1614 struct ieee80211_hw *hw = ar->hw;
1615 struct ieee80211_vif *vif = arvif->vif;
1616 struct sk_buff *prb;
1617 int ret;
1618
1619 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1620 return 0;
1621
Michal Kazior81a9a172015-03-05 16:02:17 +02001622 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1623 return 0;
1624
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001625 prb = ieee80211_proberesp_get(hw, vif);
1626 if (!prb) {
1627 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1628 return -EPERM;
1629 }
1630
1631 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1632 kfree_skb(prb);
1633
1634 if (ret) {
1635 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1636 ret);
1637 return ret;
1638 }
1639
1640 return 0;
1641}
1642
Michal Kazior500ff9f2015-03-31 10:26:21 +00001643static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1644{
1645 struct ath10k *ar = arvif->ar;
1646 struct cfg80211_chan_def def;
1647 int ret;
1648
1649 /* When originally vdev is started during assign_vif_chanctx() some
1650 * information is missing, notably SSID. Firmware revisions with beacon
1651 * offloading require the SSID to be provided during vdev (re)start to
1652 * handle hidden SSID properly.
1653 *
1654 * Vdev restart must be done after vdev has been both started and
1655 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1656 * deliver vdev restart response event causing timeouts during vdev
1657 * syncing in ath10k.
1658 *
1659 * Note: The vdev down/up and template reinstallation could be skipped
1660 * since only wmi-tlv firmware are known to have beacon offload and
1661 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1662 * response delivery. It's probably more robust to keep it as is.
1663 */
1664 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1665 return 0;
1666
1667 if (WARN_ON(!arvif->is_started))
1668 return -EINVAL;
1669
1670 if (WARN_ON(!arvif->is_up))
1671 return -EINVAL;
1672
1673 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1674 return -EINVAL;
1675
1676 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1677 if (ret) {
1678 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1679 arvif->vdev_id, ret);
1680 return ret;
1681 }
1682
1683 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1684 * firmware will crash upon vdev up.
1685 */
1686
1687 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1688 if (ret) {
1689 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1690 return ret;
1691 }
1692
1693 ret = ath10k_mac_setup_prb_tmpl(arvif);
1694 if (ret) {
1695 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1696 return ret;
1697 }
1698
1699 ret = ath10k_vdev_restart(arvif, &def);
1700 if (ret) {
1701 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1702 arvif->vdev_id, ret);
1703 return ret;
1704 }
1705
1706 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1707 arvif->bssid);
1708 if (ret) {
1709 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1710 arvif->vdev_id, ret);
1711 return ret;
1712 }
1713
1714 return 0;
1715}
1716
Kalle Valo5e3dd152013-06-12 20:52:10 +03001717static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001718 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001719{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001720 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001721 int ret = 0;
1722
Michal Kazior548db542013-07-05 16:15:15 +03001723 lockdep_assert_held(&arvif->ar->conf_mutex);
1724
Kalle Valo5e3dd152013-06-12 20:52:10 +03001725 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001726 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1727 if (ret)
1728 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1729 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001730
Michal Kaziorc930f742014-01-23 11:38:25 +01001731 arvif->is_up = false;
1732
Michal Kazior748afc42014-01-23 12:48:21 +01001733 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001734 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001735 spin_unlock_bh(&arvif->ar->data_lock);
1736
Kalle Valo5e3dd152013-06-12 20:52:10 +03001737 return;
1738 }
1739
1740 arvif->tx_seq_no = 0x1000;
1741
Michal Kaziorc930f742014-01-23 11:38:25 +01001742 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001743 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001744
1745 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1746 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001747 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001748 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001749 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001750 return;
1751 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001752
Michal Kaziorc930f742014-01-23 11:38:25 +01001753 arvif->is_up = true;
1754
Michal Kazior500ff9f2015-03-31 10:26:21 +00001755 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1756 if (ret) {
1757 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1758 arvif->vdev_id, ret);
1759 return;
1760 }
1761
Michal Kazior7aa7a722014-08-25 12:09:38 +02001762 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001763}
1764
1765static void ath10k_control_ibss(struct ath10k_vif *arvif,
1766 struct ieee80211_bss_conf *info,
1767 const u8 self_peer[ETH_ALEN])
1768{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001769 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001770 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001771 int ret = 0;
1772
Michal Kazior548db542013-07-05 16:15:15 +03001773 lockdep_assert_held(&arvif->ar->conf_mutex);
1774
Kalle Valo5e3dd152013-06-12 20:52:10 +03001775 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001776 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001777 return;
1778
Joe Perches93803b32015-03-02 19:54:49 -08001779 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001780
1781 return;
1782 }
1783
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001784 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1785 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001786 ATH10K_DEFAULT_ATIM);
1787 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001788 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001789 arvif->vdev_id, ret);
1790}
1791
Michal Kazior9f9b5742014-12-12 12:41:36 +01001792static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1793{
1794 struct ath10k *ar = arvif->ar;
1795 u32 param;
1796 u32 value;
1797 int ret;
1798
1799 lockdep_assert_held(&arvif->ar->conf_mutex);
1800
1801 if (arvif->u.sta.uapsd)
1802 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1803 else
1804 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1805
1806 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1807 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1808 if (ret) {
1809 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1810 value, arvif->vdev_id, ret);
1811 return ret;
1812 }
1813
1814 return 0;
1815}
1816
1817static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1818{
1819 struct ath10k *ar = arvif->ar;
1820 u32 param;
1821 u32 value;
1822 int ret;
1823
1824 lockdep_assert_held(&arvif->ar->conf_mutex);
1825
1826 if (arvif->u.sta.uapsd)
1827 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1828 else
1829 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1830
1831 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1832 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1833 param, value);
1834 if (ret) {
1835 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1836 value, arvif->vdev_id, ret);
1837 return ret;
1838 }
1839
1840 return 0;
1841}
1842
Michal Kazior424f2632015-07-09 13:08:35 +02001843static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001844{
1845 struct ath10k_vif *arvif;
1846 int num = 0;
1847
1848 lockdep_assert_held(&ar->conf_mutex);
1849
1850 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001851 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001852 num++;
1853
1854 return num;
1855}
1856
Michal Kaziorad088bf2013-10-16 15:44:46 +03001857static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001858{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001859 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001860 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001861 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001862 enum wmi_sta_powersave_param param;
1863 enum wmi_sta_ps_mode psmode;
1864 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001865 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001866 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001867
Michal Kazior548db542013-07-05 16:15:15 +03001868 lockdep_assert_held(&arvif->ar->conf_mutex);
1869
Michal Kaziorad088bf2013-10-16 15:44:46 +03001870 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1871 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001872
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001873 enable_ps = arvif->ps;
1874
Michal Kazior424f2632015-07-09 13:08:35 +02001875 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001876 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
Kalle Valoc4cdf752016-04-20 19:45:18 +03001877 ar->running_fw->fw_file.fw_features)) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001878 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1879 arvif->vdev_id);
1880 enable_ps = false;
1881 }
1882
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001883 if (!arvif->is_started) {
1884 /* mac80211 can update vif powersave state while disconnected.
1885 * Firmware doesn't behave nicely and consumes more power than
1886 * necessary if PS is disabled on a non-started vdev. Hence
1887 * force-enable PS for non-running vdevs.
1888 */
1889 psmode = WMI_STA_PS_MODE_ENABLED;
1890 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001891 psmode = WMI_STA_PS_MODE_ENABLED;
1892 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1893
Michal Kazior526549a2014-12-12 12:41:37 +01001894 ps_timeout = conf->dynamic_ps_timeout;
1895 if (ps_timeout == 0) {
1896 /* Firmware doesn't like 0 */
1897 ps_timeout = ieee80211_tu_to_usec(
1898 vif->bss_conf.beacon_int) / 1000;
1899 }
1900
Michal Kaziorad088bf2013-10-16 15:44:46 +03001901 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001902 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001903 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001904 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001905 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001906 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001907 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001908 } else {
1909 psmode = WMI_STA_PS_MODE_DISABLED;
1910 }
1911
Michal Kazior7aa7a722014-08-25 12:09:38 +02001912 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001913 arvif->vdev_id, psmode ? "enable" : "disable");
1914
Michal Kaziorad088bf2013-10-16 15:44:46 +03001915 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1916 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001917 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001918 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001919 return ret;
1920 }
1921
1922 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001923}
1924
Michal Kazior46725b152015-01-28 09:57:49 +02001925static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1926{
1927 struct ath10k *ar = arvif->ar;
1928 struct wmi_sta_keepalive_arg arg = {};
1929 int ret;
1930
1931 lockdep_assert_held(&arvif->ar->conf_mutex);
1932
1933 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1934 return 0;
1935
1936 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1937 return 0;
1938
1939 /* Some firmware revisions have a bug and ignore the `enabled` field.
1940 * Instead use the interval to disable the keepalive.
1941 */
1942 arg.vdev_id = arvif->vdev_id;
1943 arg.enabled = 1;
1944 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1945 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1946
1947 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1948 if (ret) {
1949 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1950 arvif->vdev_id, ret);
1951 return ret;
1952 }
1953
1954 return 0;
1955}
1956
Michal Kazior81a9a172015-03-05 16:02:17 +02001957static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1958{
1959 struct ath10k *ar = arvif->ar;
1960 struct ieee80211_vif *vif = arvif->vif;
1961 int ret;
1962
Michal Kazior8513d952015-03-09 14:19:24 +01001963 lockdep_assert_held(&arvif->ar->conf_mutex);
1964
1965 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1966 return;
1967
Michal Kazior81a9a172015-03-05 16:02:17 +02001968 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1969 return;
1970
1971 if (!vif->csa_active)
1972 return;
1973
1974 if (!arvif->is_up)
1975 return;
1976
1977 if (!ieee80211_csa_is_complete(vif)) {
1978 ieee80211_csa_update_counter(vif);
1979
1980 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1981 if (ret)
1982 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1983 ret);
1984
1985 ret = ath10k_mac_setup_prb_tmpl(arvif);
1986 if (ret)
1987 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1988 ret);
1989 } else {
1990 ieee80211_csa_finish(vif);
1991 }
1992}
1993
1994static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1995{
1996 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1997 ap_csa_work);
1998 struct ath10k *ar = arvif->ar;
1999
2000 mutex_lock(&ar->conf_mutex);
2001 ath10k_mac_vif_ap_csa_count_down(arvif);
2002 mutex_unlock(&ar->conf_mutex);
2003}
2004
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002005static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
2006 struct ieee80211_vif *vif)
2007{
2008 struct sk_buff *skb = data;
2009 struct ieee80211_mgmt *mgmt = (void *)skb->data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002010 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002011
2012 if (vif->type != NL80211_IFTYPE_STATION)
2013 return;
2014
2015 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
2016 return;
2017
2018 cancel_delayed_work(&arvif->connection_loss_work);
2019}
2020
2021void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
2022{
2023 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2024 IEEE80211_IFACE_ITER_NORMAL,
2025 ath10k_mac_handle_beacon_iter,
2026 skb);
2027}
2028
2029static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
2030 struct ieee80211_vif *vif)
2031{
2032 u32 *vdev_id = data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002033 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002034 struct ath10k *ar = arvif->ar;
2035 struct ieee80211_hw *hw = ar->hw;
2036
2037 if (arvif->vdev_id != *vdev_id)
2038 return;
2039
2040 if (!arvif->is_up)
2041 return;
2042
2043 ieee80211_beacon_loss(vif);
2044
2045 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
2046 * (done by mac80211) succeeds but beacons do not resume then it
2047 * doesn't make sense to continue operation. Queue connection loss work
2048 * which can be cancelled when beacon is received.
2049 */
2050 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
2051 ATH10K_CONNECTION_LOSS_HZ);
2052}
2053
2054void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
2055{
2056 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2057 IEEE80211_IFACE_ITER_NORMAL,
2058 ath10k_mac_handle_beacon_miss_iter,
2059 &vdev_id);
2060}
2061
2062static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
2063{
2064 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
2065 connection_loss_work.work);
2066 struct ieee80211_vif *vif = arvif->vif;
2067
2068 if (!arvif->is_up)
2069 return;
2070
2071 ieee80211_connection_loss(vif);
2072}
2073
Kalle Valo5e3dd152013-06-12 20:52:10 +03002074/**********************/
2075/* Station management */
2076/**********************/
2077
Michal Kazior590922a2014-10-21 10:10:29 +03002078static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
2079 struct ieee80211_vif *vif)
2080{
2081 /* Some firmware revisions have unstable STA powersave when listen
2082 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
2083 * generate NullFunc frames properly even if buffered frames have been
2084 * indicated in Beacon TIM. Firmware would seldom wake up to pull
2085 * buffered frames. Often pinging the device from AP would simply fail.
2086 *
2087 * As a workaround set it to 1.
2088 */
2089 if (vif->type == NL80211_IFTYPE_STATION)
2090 return 1;
2091
2092 return ar->hw->conf.listen_interval;
2093}
2094
Kalle Valo5e3dd152013-06-12 20:52:10 +03002095static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002096 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002097 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002098 struct wmi_peer_assoc_complete_arg *arg)
2099{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002100 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002101 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03002102
Michal Kazior548db542013-07-05 16:15:15 +03002103 lockdep_assert_held(&ar->conf_mutex);
2104
Michal Kaziorc51880e2015-03-30 09:51:57 +03002105 if (vif->type == NL80211_IFTYPE_STATION)
2106 aid = vif->bss_conf.aid;
2107 else
2108 aid = sta->aid;
2109
Kalle Valob25f32c2014-09-14 12:50:49 +03002110 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002111 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002112 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002113 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03002114 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002115 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03002116 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002117}
2118
2119static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002120 struct ieee80211_vif *vif,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002121 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002122 struct wmi_peer_assoc_complete_arg *arg)
2123{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002124 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002125 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002126 struct cfg80211_bss *bss;
2127 const u8 *rsnie = NULL;
2128 const u8 *wpaie = NULL;
2129
Michal Kazior548db542013-07-05 16:15:15 +03002130 lockdep_assert_held(&ar->conf_mutex);
2131
Michal Kazior500ff9f2015-03-31 10:26:21 +00002132 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2133 return;
2134
2135 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
2136 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002137 if (bss) {
2138 const struct cfg80211_bss_ies *ies;
2139
2140 rcu_read_lock();
2141 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
2142
2143 ies = rcu_dereference(bss->ies);
2144
2145 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03002146 WLAN_OUI_TYPE_MICROSOFT_WPA,
2147 ies->data,
2148 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002149 rcu_read_unlock();
2150 cfg80211_put_bss(ar->hw->wiphy, bss);
2151 }
2152
2153 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2154 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002155 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002156 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002157 }
2158
2159 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002160 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002161 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002162 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002163
2164 if (sta->mfp &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03002165 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT,
2166 ar->running_fw->fw_file.fw_features)) {
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002167 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002168 }
2169}
2170
2171static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002172 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002173 struct ieee80211_sta *sta,
2174 struct wmi_peer_assoc_complete_arg *arg)
2175{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002176 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002177 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002178 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002179 const struct ieee80211_supported_band *sband;
2180 const struct ieee80211_rate *rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002181 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002182 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002183 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002184 int i;
2185
Michal Kazior548db542013-07-05 16:15:15 +03002186 lockdep_assert_held(&ar->conf_mutex);
2187
Michal Kazior500ff9f2015-03-31 10:26:21 +00002188 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2189 return;
2190
Michal Kazior45c9abc2015-04-21 20:42:58 +03002191 band = def.chan->band;
2192 sband = ar->hw->wiphy->bands[band];
2193 ratemask = sta->supp_rates[band];
2194 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002195 rates = sband->bitrates;
2196
2197 rateset->num_rates = 0;
2198
2199 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2200 if (!(ratemask & 1))
2201 continue;
2202
Michal Kazior486017c2015-03-30 09:51:54 +03002203 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2204 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002205 rateset->num_rates++;
2206 }
2207}
2208
Michal Kazior45c9abc2015-04-21 20:42:58 +03002209static bool
2210ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2211{
2212 int nss;
2213
2214 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2215 if (ht_mcs_mask[nss])
2216 return false;
2217
2218 return true;
2219}
2220
2221static bool
2222ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2223{
2224 int nss;
2225
2226 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2227 if (vht_mcs_mask[nss])
2228 return false;
2229
2230 return true;
2231}
2232
Kalle Valo5e3dd152013-06-12 20:52:10 +03002233static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002234 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002235 struct ieee80211_sta *sta,
2236 struct wmi_peer_assoc_complete_arg *arg)
2237{
2238 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002239 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002240 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002241 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002242 const u8 *ht_mcs_mask;
2243 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002244 int i, n;
2245 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002246 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002247
Michal Kazior548db542013-07-05 16:15:15 +03002248 lockdep_assert_held(&ar->conf_mutex);
2249
Michal Kazior45c9abc2015-04-21 20:42:58 +03002250 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2251 return;
2252
Kalle Valo5e3dd152013-06-12 20:52:10 +03002253 if (!ht_cap->ht_supported)
2254 return;
2255
Michal Kazior45c9abc2015-04-21 20:42:58 +03002256 band = def.chan->band;
2257 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2258 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2259
2260 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2261 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2262 return;
2263
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002264 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002265 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2266 ht_cap->ampdu_factor)) - 1;
2267
2268 arg->peer_mpdu_density =
2269 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2270
2271 arg->peer_ht_caps = ht_cap->cap;
2272 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2273
2274 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002275 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002276
2277 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002278 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002279 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2280 }
2281
Michal Kazior45c9abc2015-04-21 20:42:58 +03002282 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2283 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2284 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002285
Michal Kazior45c9abc2015-04-21 20:42:58 +03002286 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2287 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2288 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002289
2290 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2291 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002292 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002293 }
2294
2295 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002296 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2297 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2298 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2299 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002300 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002301 }
2302
Kalle Valo5e3dd152013-06-12 20:52:10 +03002303 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2304 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2305 else if (ht_cap->mcs.rx_mask[1])
2306 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2307
Michal Kazior45c9abc2015-04-21 20:42:58 +03002308 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2309 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2310 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2311 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002312 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002313 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002314
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002315 /*
2316 * This is a workaround for HT-enabled STAs which break the spec
2317 * and have no HT capabilities RX mask (no HT RX MCS map).
2318 *
2319 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2320 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2321 *
2322 * Firmware asserts if such situation occurs.
2323 */
2324 if (n == 0) {
2325 arg->peer_ht_rates.num_rates = 8;
2326 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2327 arg->peer_ht_rates.rates[i] = i;
2328 } else {
2329 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002330 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002331 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002332
Michal Kazior7aa7a722014-08-25 12:09:38 +02002333 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002334 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002335 arg->peer_ht_rates.num_rates,
2336 arg->peer_num_spatial_streams);
2337}
2338
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002339static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2340 struct ath10k_vif *arvif,
2341 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002342{
2343 u32 uapsd = 0;
2344 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002345 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002346
Michal Kazior548db542013-07-05 16:15:15 +03002347 lockdep_assert_held(&ar->conf_mutex);
2348
Kalle Valo5e3dd152013-06-12 20:52:10 +03002349 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002350 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002351 sta->uapsd_queues, sta->max_sp);
2352
Kalle Valo5e3dd152013-06-12 20:52:10 +03002353 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2354 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2355 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2356 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2357 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2358 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2359 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2360 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2361 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2362 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2363 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2364 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2365
Kalle Valo5e3dd152013-06-12 20:52:10 +03002366 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2367 max_sp = sta->max_sp;
2368
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002369 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2370 sta->addr,
2371 WMI_AP_PS_PEER_PARAM_UAPSD,
2372 uapsd);
2373 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002374 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002375 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002376 return ret;
2377 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002378
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002379 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2380 sta->addr,
2381 WMI_AP_PS_PEER_PARAM_MAX_SP,
2382 max_sp);
2383 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002384 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002385 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002386 return ret;
2387 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002388
2389 /* TODO setup this based on STA listen interval and
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01002390 * beacon interval. Currently we don't know
2391 * sta->listen_interval - mac80211 patch required.
2392 * Currently use 10 seconds
2393 */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002394 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002395 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2396 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002397 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002398 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002399 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002400 return ret;
2401 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002402 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002403
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002404 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002405}
2406
Michal Kazior45c9abc2015-04-21 20:42:58 +03002407static u16
2408ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2409 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2410{
2411 int idx_limit;
2412 int nss;
2413 u16 mcs_map;
2414 u16 mcs;
2415
2416 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2417 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2418 vht_mcs_limit[nss];
2419
2420 if (mcs_map)
2421 idx_limit = fls(mcs_map) - 1;
2422 else
2423 idx_limit = -1;
2424
2425 switch (idx_limit) {
2426 case 0: /* fall through */
2427 case 1: /* fall through */
2428 case 2: /* fall through */
2429 case 3: /* fall through */
2430 case 4: /* fall through */
2431 case 5: /* fall through */
2432 case 6: /* fall through */
2433 default:
2434 /* see ath10k_mac_can_set_bitrate_mask() */
2435 WARN_ON(1);
2436 /* fall through */
2437 case -1:
2438 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2439 break;
2440 case 7:
2441 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2442 break;
2443 case 8:
2444 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2445 break;
2446 case 9:
2447 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2448 break;
2449 }
2450
2451 tx_mcs_set &= ~(0x3 << (nss * 2));
2452 tx_mcs_set |= mcs << (nss * 2);
2453 }
2454
2455 return tx_mcs_set;
2456}
2457
Kalle Valo5e3dd152013-06-12 20:52:10 +03002458static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002459 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002460 struct ieee80211_sta *sta,
2461 struct wmi_peer_assoc_complete_arg *arg)
2462{
2463 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002464 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002465 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002466 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002467 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002468 u8 ampdu_factor;
Venkateswara Rao Naralasettyfefcd112017-03-24 13:27:28 +05302469 u8 max_nss, vht_mcs;
2470 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002471
Michal Kazior500ff9f2015-03-31 10:26:21 +00002472 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2473 return;
2474
Kalle Valo5e3dd152013-06-12 20:52:10 +03002475 if (!vht_cap->vht_supported)
2476 return;
2477
Michal Kazior45c9abc2015-04-21 20:42:58 +03002478 band = def.chan->band;
2479 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2480
2481 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2482 return;
2483
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002484 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002485
Johannes Berg57fbcce2016-04-12 15:56:15 +02002486 if (def.chan->band == NL80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002487 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002488
Kalle Valo5e3dd152013-06-12 20:52:10 +03002489 arg->peer_vht_caps = vht_cap->cap;
2490
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002491 ampdu_factor = (vht_cap->cap &
2492 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2493 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2494
2495 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2496 * zero in VHT IE. Using it would result in degraded throughput.
2497 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01002498 * it if VHT max_mpdu is smaller.
2499 */
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002500 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2501 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2502 ampdu_factor)) - 1);
2503
Kalle Valo5e3dd152013-06-12 20:52:10 +03002504 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002505 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002506
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02002507 if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
2508 arg->peer_flags |= ar->wmi.peer_flags->bw160;
2509
Venkateswara Rao Naralasettyfefcd112017-03-24 13:27:28 +05302510 /* Calculate peer NSS capability from VHT capabilities if STA
2511 * supports VHT.
2512 */
2513 for (i = 0, max_nss = 0, vht_mcs = 0; i < NL80211_VHT_NSS_MAX; i++) {
2514 vht_mcs = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) >>
2515 (2 * i) & 3;
2516
2517 if ((vht_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED) &&
2518 vht_mcs_mask[i])
2519 max_nss = i + 1;
2520 }
2521 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002522 arg->peer_vht_rates.rx_max_rate =
2523 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2524 arg->peer_vht_rates.rx_mcs_set =
2525 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2526 arg->peer_vht_rates.tx_max_rate =
2527 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002528 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2529 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002530
Michal Kazior7aa7a722014-08-25 12:09:38 +02002531 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002532 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Ben Greearcc914a52017-06-16 10:37:45 +03002533
2534 if (arg->peer_vht_rates.rx_max_rate &&
2535 (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) {
2536 switch (arg->peer_vht_rates.rx_max_rate) {
2537 case 1560:
2538 /* Must be 2x2 at 160Mhz is all it can do. */
2539 arg->peer_bw_rxnss_override = 2;
2540 break;
2541 case 780:
2542 /* Can only do 1x1 at 160Mhz (Long Guard Interval) */
2543 arg->peer_bw_rxnss_override = 1;
2544 break;
2545 }
2546 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002547}
2548
2549static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002550 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002551 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002552 struct wmi_peer_assoc_complete_arg *arg)
2553{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002554 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior590922a2014-10-21 10:10:29 +03002555
Kalle Valo5e3dd152013-06-12 20:52:10 +03002556 switch (arvif->vdev_type) {
2557 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002558 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002559 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002560
2561 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002562 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002563 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2564 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002565 break;
2566 case WMI_VDEV_TYPE_STA:
Balaji Pothunoori07ffb442017-12-07 16:58:04 +02002567 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002568 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002569 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002570 case WMI_VDEV_TYPE_IBSS:
2571 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002572 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002573 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002574 default:
2575 break;
2576 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002577
2578 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002579 sta->addr, !!(arg->peer_flags &
2580 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002581}
2582
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002583static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002584{
Johannes Berg57fbcce2016-04-12 15:56:15 +02002585 return sta->supp_rates[NL80211_BAND_2GHZ] >>
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002586 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002587}
2588
Kalle Valo06efdbe2017-01-12 13:02:11 +02002589static enum wmi_phy_mode ath10k_mac_get_phymode_vht(struct ath10k *ar,
2590 struct ieee80211_sta *sta)
2591{
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02002592 if (sta->bandwidth == IEEE80211_STA_RX_BW_160) {
2593 switch (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
2594 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
2595 return MODE_11AC_VHT160;
2596 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
2597 return MODE_11AC_VHT80_80;
2598 default:
2599 /* not sure if this is a valid case? */
2600 return MODE_11AC_VHT160;
2601 }
2602 }
2603
Kalle Valo06efdbe2017-01-12 13:02:11 +02002604 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2605 return MODE_11AC_VHT80;
2606
2607 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2608 return MODE_11AC_VHT40;
2609
2610 if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2611 return MODE_11AC_VHT20;
2612
2613 return MODE_UNKNOWN;
2614}
2615
Kalle Valo5e3dd152013-06-12 20:52:10 +03002616static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002617 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002618 struct ieee80211_sta *sta,
2619 struct wmi_peer_assoc_complete_arg *arg)
2620{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002621 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002622 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002623 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002624 const u8 *ht_mcs_mask;
2625 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002626 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2627
Michal Kazior500ff9f2015-03-31 10:26:21 +00002628 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2629 return;
2630
Michal Kazior45c9abc2015-04-21 20:42:58 +03002631 band = def.chan->band;
2632 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2633 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2634
2635 switch (band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02002636 case NL80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002637 if (sta->vht_cap.vht_supported &&
2638 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002639 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2640 phymode = MODE_11AC_VHT40;
2641 else
2642 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002643 } else if (sta->ht_cap.ht_supported &&
2644 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002645 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2646 phymode = MODE_11NG_HT40;
2647 else
2648 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002649 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002650 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002651 } else {
2652 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002653 }
2654
2655 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002656 case NL80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002657 /*
2658 * Check VHT first.
2659 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002660 if (sta->vht_cap.vht_supported &&
2661 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Kalle Valo06efdbe2017-01-12 13:02:11 +02002662 phymode = ath10k_mac_get_phymode_vht(ar, sta);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002663 } else if (sta->ht_cap.ht_supported &&
2664 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2665 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002666 phymode = MODE_11NA_HT40;
2667 else
2668 phymode = MODE_11NA_HT20;
2669 } else {
2670 phymode = MODE_11A;
2671 }
2672
2673 break;
2674 default:
2675 break;
2676 }
2677
Michal Kazior7aa7a722014-08-25 12:09:38 +02002678 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002679 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002680
Kalle Valo5e3dd152013-06-12 20:52:10 +03002681 arg->peer_phymode = phymode;
2682 WARN_ON(phymode == MODE_UNKNOWN);
2683}
2684
Kalle Valob9ada652013-10-16 15:44:46 +03002685static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002686 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002687 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002688 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002689{
Michal Kazior548db542013-07-05 16:15:15 +03002690 lockdep_assert_held(&ar->conf_mutex);
2691
Kalle Valob9ada652013-10-16 15:44:46 +03002692 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002693
Michal Kazior590922a2014-10-21 10:10:29 +03002694 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002695 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002696 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002697 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002698 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002699 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2700 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002701
Kalle Valob9ada652013-10-16 15:44:46 +03002702 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002703}
2704
Michal Kazior90046f52014-02-14 14:45:51 +01002705static const u32 ath10k_smps_map[] = {
2706 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2707 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2708 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2709 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2710};
2711
2712static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2713 const u8 *addr,
2714 const struct ieee80211_sta_ht_cap *ht_cap)
2715{
2716 int smps;
2717
2718 if (!ht_cap->ht_supported)
2719 return 0;
2720
2721 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2722 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2723
2724 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2725 return -EINVAL;
2726
2727 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2728 WMI_PEER_SMPS_STATE,
2729 ath10k_smps_map[smps]);
2730}
2731
Michal Kazior139e1702015-02-15 16:50:42 +02002732static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2733 struct ieee80211_vif *vif,
2734 struct ieee80211_sta_vht_cap vht_cap)
2735{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002736 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior139e1702015-02-15 16:50:42 +02002737 int ret;
2738 u32 param;
2739 u32 value;
2740
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302741 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2742 return 0;
2743
Michal Kazior139e1702015-02-15 16:50:42 +02002744 if (!(ar->vht_cap_info &
2745 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2746 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2747 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2748 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2749 return 0;
2750
2751 param = ar->wmi.vdev_param->txbf;
2752 value = 0;
2753
2754 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2755 return 0;
2756
2757 /* The following logic is correct. If a remote STA advertises support
2758 * for being a beamformer then we should enable us being a beamformee.
2759 */
2760
2761 if (ar->vht_cap_info &
2762 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2763 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2764 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2765 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2766
2767 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2768 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2769 }
2770
2771 if (ar->vht_cap_info &
2772 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2773 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2774 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2775 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2776
2777 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2778 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2779 }
2780
2781 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2782 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2783
2784 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2785 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2786
2787 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2788 if (ret) {
2789 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2790 value, ret);
2791 return ret;
2792 }
2793
2794 return 0;
2795}
2796
Kalle Valo5e3dd152013-06-12 20:52:10 +03002797/* can be called only in mac80211 callbacks due to `key_count` usage */
2798static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2799 struct ieee80211_vif *vif,
2800 struct ieee80211_bss_conf *bss_conf)
2801{
2802 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002803 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior90046f52014-02-14 14:45:51 +01002804 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002805 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002806 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002807 struct ieee80211_sta *ap_sta;
2808 int ret;
2809
Michal Kazior548db542013-07-05 16:15:15 +03002810 lockdep_assert_held(&ar->conf_mutex);
2811
Michal Kazior077efc82014-10-21 10:10:29 +03002812 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2813 arvif->vdev_id, arvif->bssid, arvif->aid);
2814
Kalle Valo5e3dd152013-06-12 20:52:10 +03002815 rcu_read_lock();
2816
2817 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2818 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002819 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002820 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002821 rcu_read_unlock();
2822 return;
2823 }
2824
Michal Kazior90046f52014-02-14 14:45:51 +01002825 /* ap_sta must be accessed only within rcu section which must be left
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01002826 * before calling ath10k_setup_peer_smps() which might sleep.
2827 */
Michal Kazior90046f52014-02-14 14:45:51 +01002828 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002829 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002830
Michal Kazior590922a2014-10-21 10:10:29 +03002831 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002832 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002833 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002834 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002835 rcu_read_unlock();
2836 return;
2837 }
2838
2839 rcu_read_unlock();
2840
Kalle Valob9ada652013-10-16 15:44:46 +03002841 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2842 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002843 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002844 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002845 return;
2846 }
2847
Michal Kazior90046f52014-02-14 14:45:51 +01002848 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2849 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002850 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002851 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002852 return;
2853 }
2854
Michal Kazior139e1702015-02-15 16:50:42 +02002855 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2856 if (ret) {
2857 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2858 arvif->vdev_id, bss_conf->bssid, ret);
2859 return;
2860 }
2861
Michal Kazior7aa7a722014-08-25 12:09:38 +02002862 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002863 "mac vdev %d up (associated) bssid %pM aid %d\n",
2864 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2865
Michal Kazior077efc82014-10-21 10:10:29 +03002866 WARN_ON(arvif->is_up);
2867
Michal Kaziorc930f742014-01-23 11:38:25 +01002868 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002869 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002870
2871 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2872 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002873 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002874 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002875 return;
2876 }
2877
2878 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002879
2880 /* Workaround: Some firmware revisions (tested with qca6174
2881 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2882 * poked with peer param command.
2883 */
2884 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2885 WMI_PEER_DUMMY_VAR, 1);
2886 if (ret) {
2887 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2888 arvif->bssid, arvif->vdev_id, ret);
2889 return;
2890 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002891}
2892
Kalle Valo5e3dd152013-06-12 20:52:10 +03002893static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2894 struct ieee80211_vif *vif)
2895{
2896 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002897 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior139e1702015-02-15 16:50:42 +02002898 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002899 int ret;
2900
Michal Kazior548db542013-07-05 16:15:15 +03002901 lockdep_assert_held(&ar->conf_mutex);
2902
Michal Kazior077efc82014-10-21 10:10:29 +03002903 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2904 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002905
Kalle Valo5e3dd152013-06-12 20:52:10 +03002906 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002907 if (ret)
Ben Greearaa66ba02016-09-26 21:56:25 +03002908 ath10k_warn(ar, "failed to down vdev %i: %d\n",
Michal Kazior077efc82014-10-21 10:10:29 +03002909 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002910
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002911 arvif->def_wep_key_idx = -1;
2912
Michal Kazior139e1702015-02-15 16:50:42 +02002913 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2914 if (ret) {
2915 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2916 arvif->vdev_id, ret);
2917 return;
2918 }
2919
Michal Kaziorc930f742014-01-23 11:38:25 +01002920 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002921
2922 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002923}
2924
Michal Kazior590922a2014-10-21 10:10:29 +03002925static int ath10k_station_assoc(struct ath10k *ar,
2926 struct ieee80211_vif *vif,
2927 struct ieee80211_sta *sta,
2928 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002929{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002930 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valob9ada652013-10-16 15:44:46 +03002931 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002932 int ret = 0;
2933
Michal Kazior548db542013-07-05 16:15:15 +03002934 lockdep_assert_held(&ar->conf_mutex);
2935
Michal Kazior590922a2014-10-21 10:10:29 +03002936 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002937 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002938 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002939 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002940 return ret;
2941 }
2942
2943 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2944 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002945 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002946 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002947 return ret;
2948 }
2949
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002950 /* Re-assoc is run only to update supported rates for given station. It
2951 * doesn't make much sense to reconfigure the peer completely.
2952 */
2953 if (!reassoc) {
2954 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2955 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002956 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002957 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002958 arvif->vdev_id, ret);
2959 return ret;
2960 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002961
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002962 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2963 if (ret) {
2964 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2965 sta->addr, arvif->vdev_id, ret);
2966 return ret;
2967 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002968
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002969 if (!sta->wme) {
2970 arvif->num_legacy_stations++;
2971 ret = ath10k_recalc_rtscts_prot(arvif);
2972 if (ret) {
2973 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2974 arvif->vdev_id, ret);
2975 return ret;
2976 }
2977 }
2978
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002979 /* Plumb cached keys only for static WEP */
2980 if (arvif->def_wep_key_idx != -1) {
2981 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2982 if (ret) {
2983 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2984 arvif->vdev_id, ret);
2985 return ret;
2986 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002987 }
2988 }
2989
Kalle Valo5e3dd152013-06-12 20:52:10 +03002990 return ret;
2991}
2992
Michal Kazior590922a2014-10-21 10:10:29 +03002993static int ath10k_station_disassoc(struct ath10k *ar,
2994 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002995 struct ieee80211_sta *sta)
2996{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02002997 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002998 int ret = 0;
2999
3000 lockdep_assert_held(&ar->conf_mutex);
3001
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02003002 if (!sta->wme) {
3003 arvif->num_legacy_stations--;
3004 ret = ath10k_recalc_rtscts_prot(arvif);
3005 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003006 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02003007 arvif->vdev_id, ret);
3008 return ret;
3009 }
3010 }
3011
Kalle Valo5e3dd152013-06-12 20:52:10 +03003012 ret = ath10k_clear_peer_keys(arvif, sta->addr);
3013 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003014 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003015 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003016 return ret;
3017 }
3018
3019 return ret;
3020}
3021
3022/**************/
3023/* Regulatory */
3024/**************/
3025
3026static int ath10k_update_channel_list(struct ath10k *ar)
3027{
3028 struct ieee80211_hw *hw = ar->hw;
3029 struct ieee80211_supported_band **bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02003030 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003031 struct ieee80211_channel *channel;
3032 struct wmi_scan_chan_list_arg arg = {0};
3033 struct wmi_channel_arg *ch;
3034 bool passive;
3035 int len;
3036 int ret;
3037 int i;
3038
Michal Kazior548db542013-07-05 16:15:15 +03003039 lockdep_assert_held(&ar->conf_mutex);
3040
Kalle Valo5e3dd152013-06-12 20:52:10 +03003041 bands = hw->wiphy->bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02003042 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003043 if (!bands[band])
3044 continue;
3045
3046 for (i = 0; i < bands[band]->n_channels; i++) {
3047 if (bands[band]->channels[i].flags &
3048 IEEE80211_CHAN_DISABLED)
3049 continue;
3050
3051 arg.n_channels++;
3052 }
3053 }
3054
3055 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
3056 arg.channels = kzalloc(len, GFP_KERNEL);
3057 if (!arg.channels)
3058 return -ENOMEM;
3059
3060 ch = arg.channels;
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 channel = &bands[band]->channels[i];
3067
3068 if (channel->flags & IEEE80211_CHAN_DISABLED)
3069 continue;
3070
Eduardo Abinader98029772016-06-30 15:23:55 +03003071 ch->allow_ht = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003072
3073 /* FIXME: when should we really allow VHT? */
3074 ch->allow_vht = true;
3075
3076 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02003077 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003078
3079 ch->ht40plus =
3080 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
3081
Marek Puzyniake8a50f82013-11-20 09:59:47 +02003082 ch->chan_radar =
3083 !!(channel->flags & IEEE80211_CHAN_RADAR);
3084
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02003085 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003086 ch->passive = passive;
3087
3088 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02003089 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07003090 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07003091 ch->max_power = channel->max_power * 2;
3092 ch->max_reg_power = channel->max_reg_power * 2;
3093 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003094 ch->reg_class_id = 0; /* FIXME */
3095
3096 /* FIXME: why use only legacy modes, why not any
3097 * HT/VHT modes? Would that even make any
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01003098 * difference?
3099 */
Johannes Berg57fbcce2016-04-12 15:56:15 +02003100 if (channel->band == NL80211_BAND_2GHZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003101 ch->mode = MODE_11G;
3102 else
3103 ch->mode = MODE_11A;
3104
3105 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
3106 continue;
3107
Michal Kazior7aa7a722014-08-25 12:09:38 +02003108 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03003109 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
3110 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003111 ch->freq, ch->max_power, ch->max_reg_power,
3112 ch->max_antenna_gain, ch->mode);
3113
3114 ch++;
3115 }
3116 }
3117
3118 ret = ath10k_wmi_scan_chan_list(ar, &arg);
3119 kfree(arg.channels);
3120
3121 return ret;
3122}
3123
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003124static enum wmi_dfs_region
3125ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
3126{
3127 switch (dfs_region) {
3128 case NL80211_DFS_UNSET:
3129 return WMI_UNINIT_DFS_DOMAIN;
3130 case NL80211_DFS_FCC:
3131 return WMI_FCC_DFS_DOMAIN;
3132 case NL80211_DFS_ETSI:
3133 return WMI_ETSI_DFS_DOMAIN;
3134 case NL80211_DFS_JP:
3135 return WMI_MKK4_DFS_DOMAIN;
3136 }
3137 return WMI_UNINIT_DFS_DOMAIN;
3138}
3139
Michal Kaziorf7843d72013-07-16 09:38:52 +02003140static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003141{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003142 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003143 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003144 enum wmi_dfs_region wmi_dfs_reg;
3145 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003146
Michal Kaziorf7843d72013-07-16 09:38:52 +02003147 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003148
3149 ret = ath10k_update_channel_list(ar);
3150 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003151 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003152
3153 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003154
Masahiro Yamada97f26452016-08-03 13:45:50 -07003155 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003156 nl_dfs_reg = ar->dfs_detector->region;
3157 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
3158 } else {
3159 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
3160 }
3161
Kalle Valo5e3dd152013-06-12 20:52:10 +03003162 /* Target allows setting up per-band regdomain but ath_common provides
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01003163 * a combined one only
3164 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003165 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02003166 regpair->reg_domain,
3167 regpair->reg_domain, /* 2ghz */
3168 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003169 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003170 regpair->reg_5ghz_ctl,
3171 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003172 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003173 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02003174}
Michal Kazior548db542013-07-05 16:15:15 +03003175
Kalle Valo46bc92b2017-03-16 11:11:02 +02003176static void ath10k_mac_update_channel_list(struct ath10k *ar,
3177 struct ieee80211_supported_band *band)
Tamizh chelvam523f6702017-02-23 18:48:22 +05303178{
3179 int i;
3180
3181 if (ar->low_5ghz_chan && ar->high_5ghz_chan) {
3182 for (i = 0; i < band->n_channels; i++) {
3183 if (band->channels[i].center_freq < ar->low_5ghz_chan ||
3184 band->channels[i].center_freq > ar->high_5ghz_chan)
3185 band->channels[i].flags |=
3186 IEEE80211_CHAN_DISABLED;
3187 }
3188 }
3189}
3190
Michal Kaziorf7843d72013-07-16 09:38:52 +02003191static void ath10k_reg_notifier(struct wiphy *wiphy,
3192 struct regulatory_request *request)
3193{
3194 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
3195 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003196 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003197
3198 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3199
Masahiro Yamada97f26452016-08-03 13:45:50 -07003200 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003201 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003202 request->dfs_region);
3203 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3204 request->dfs_region);
3205 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003206 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003207 request->dfs_region);
3208 }
3209
Michal Kaziorf7843d72013-07-16 09:38:52 +02003210 mutex_lock(&ar->conf_mutex);
3211 if (ar->state == ATH10K_STATE_ON)
3212 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003213 mutex_unlock(&ar->conf_mutex);
Tamizh chelvam523f6702017-02-23 18:48:22 +05303214
3215 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
3216 ath10k_mac_update_channel_list(ar,
Kalle Valo46bc92b2017-03-16 11:11:02 +02003217 ar->hw->wiphy->bands[NL80211_BAND_5GHZ]);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003218}
3219
3220/***************/
3221/* TX handlers */
3222/***************/
3223
Michal Kaziora30c7d02016-03-06 16:14:23 +02003224enum ath10k_mac_tx_path {
3225 ATH10K_MAC_TX_HTT,
3226 ATH10K_MAC_TX_HTT_MGMT,
3227 ATH10K_MAC_TX_WMI_MGMT,
3228 ATH10K_MAC_TX_UNKNOWN,
3229};
3230
Michal Kazior96d828d2015-03-31 10:26:23 +00003231void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3232{
3233 lockdep_assert_held(&ar->htt.tx_lock);
3234
3235 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3236 ar->tx_paused |= BIT(reason);
3237 ieee80211_stop_queues(ar->hw);
3238}
3239
3240static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3241 struct ieee80211_vif *vif)
3242{
3243 struct ath10k *ar = data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003244 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior96d828d2015-03-31 10:26:23 +00003245
3246 if (arvif->tx_paused)
3247 return;
3248
3249 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3250}
3251
3252void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3253{
3254 lockdep_assert_held(&ar->htt.tx_lock);
3255
3256 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3257 ar->tx_paused &= ~BIT(reason);
3258
3259 if (ar->tx_paused)
3260 return;
3261
3262 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3263 IEEE80211_IFACE_ITER_RESUME_ALL,
3264 ath10k_mac_tx_unlock_iter,
3265 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003266
3267 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003268}
3269
3270void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3271{
3272 struct ath10k *ar = arvif->ar;
3273
3274 lockdep_assert_held(&ar->htt.tx_lock);
3275
3276 WARN_ON(reason >= BITS_PER_LONG);
3277 arvif->tx_paused |= BIT(reason);
3278 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3279}
3280
3281void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3282{
3283 struct ath10k *ar = arvif->ar;
3284
3285 lockdep_assert_held(&ar->htt.tx_lock);
3286
3287 WARN_ON(reason >= BITS_PER_LONG);
3288 arvif->tx_paused &= ~BIT(reason);
3289
3290 if (ar->tx_paused)
3291 return;
3292
3293 if (arvif->tx_paused)
3294 return;
3295
3296 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3297}
3298
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003299static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3300 enum wmi_tlv_tx_pause_id pause_id,
3301 enum wmi_tlv_tx_pause_action action)
3302{
3303 struct ath10k *ar = arvif->ar;
3304
3305 lockdep_assert_held(&ar->htt.tx_lock);
3306
Michal Kazioracd0b272015-07-09 13:08:38 +02003307 switch (action) {
3308 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3309 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003310 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003311 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3312 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3313 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003314 default:
Bartosz Markowski209b2a62016-09-28 15:11:58 +03003315 ath10k_dbg(ar, ATH10K_DBG_BOOT,
3316 "received unknown tx pause action %d on vdev %i, ignoring\n",
Michal Kazioracd0b272015-07-09 13:08:38 +02003317 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003318 break;
3319 }
3320}
3321
3322struct ath10k_mac_tx_pause {
3323 u32 vdev_id;
3324 enum wmi_tlv_tx_pause_id pause_id;
3325 enum wmi_tlv_tx_pause_action action;
3326};
3327
3328static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3329 struct ieee80211_vif *vif)
3330{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003331 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003332 struct ath10k_mac_tx_pause *arg = data;
3333
Michal Kazioracd0b272015-07-09 13:08:38 +02003334 if (arvif->vdev_id != arg->vdev_id)
3335 return;
3336
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003337 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3338}
3339
Michal Kazioracd0b272015-07-09 13:08:38 +02003340void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3341 enum wmi_tlv_tx_pause_id pause_id,
3342 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003343{
3344 struct ath10k_mac_tx_pause arg = {
3345 .vdev_id = vdev_id,
3346 .pause_id = pause_id,
3347 .action = action,
3348 };
3349
3350 spin_lock_bh(&ar->htt.tx_lock);
3351 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3352 IEEE80211_IFACE_ITER_RESUME_ALL,
3353 ath10k_mac_handle_tx_pause_iter,
3354 &arg);
3355 spin_unlock_bh(&ar->htt.tx_lock);
3356}
3357
Michal Kaziord740d8f2015-03-30 09:51:51 +03003358static enum ath10k_hw_txrx_mode
Michal Kazior6a2636d2015-11-18 06:59:16 +01003359ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3360 struct ieee80211_vif *vif,
3361 struct ieee80211_sta *sta,
3362 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003363{
3364 const struct ieee80211_hdr *hdr = (void *)skb->data;
3365 __le16 fc = hdr->frame_control;
3366
3367 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3368 return ATH10K_HW_TXRX_RAW;
3369
3370 if (ieee80211_is_mgmt(fc))
3371 return ATH10K_HW_TXRX_MGMT;
3372
3373 /* Workaround:
3374 *
3375 * NullFunc frames are mostly used to ping if a client or AP are still
3376 * reachable and responsive. This implies tx status reports must be
3377 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3378 * come to a conclusion that the other end disappeared and tear down
3379 * BSS connection or it can never disconnect from BSS/client (which is
3380 * the case).
3381 *
3382 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3383 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3384 * which seems to deliver correct tx reports for NullFunc frames. The
3385 * downside of using it is it ignores client powersave state so it can
3386 * end up disconnecting sleeping clients in AP mode. It should fix STA
3387 * mode though because AP don't sleep.
3388 */
3389 if (ar->htt.target_version_major < 3 &&
3390 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03003391 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3392 ar->running_fw->fw_file.fw_features))
Michal Kaziord740d8f2015-03-30 09:51:51 +03003393 return ATH10K_HW_TXRX_MGMT;
3394
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003395 /* Workaround:
3396 *
3397 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3398 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3399 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003400 *
3401 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003402 */
3403 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3404 return ATH10K_HW_TXRX_ETHERNET;
3405
David Liuccec9032015-07-24 20:25:32 +03003406 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3407 return ATH10K_HW_TXRX_RAW;
3408
Michal Kaziord740d8f2015-03-30 09:51:51 +03003409 return ATH10K_HW_TXRX_NATIVE_WIFI;
3410}
3411
David Liuccec9032015-07-24 20:25:32 +03003412static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003413 struct sk_buff *skb)
3414{
3415 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3416 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003417 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3418 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003419
3420 if (!ieee80211_has_protected(hdr->frame_control))
3421 return false;
3422
David Liuccec9032015-07-24 20:25:32 +03003423 if ((info->flags & mask) == mask)
3424 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003425
David Liuccec9032015-07-24 20:25:32 +03003426 if (vif)
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003427 return !((struct ath10k_vif *)vif->drv_priv)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003428
David Liuccec9032015-07-24 20:25:32 +03003429 return true;
3430}
3431
Michal Kazior4b604552014-07-21 21:03:09 +03003432/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3433 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003434 */
Michal Kazior4b604552014-07-21 21:03:09 +03003435static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003436{
3437 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003438 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003439 u8 *qos_ctl;
3440
3441 if (!ieee80211_is_data_qos(hdr->frame_control))
3442 return;
3443
3444 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003445 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3446 skb->data, (void *)qos_ctl - (void *)skb->data);
3447 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003448
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003449 /* Some firmware revisions don't handle sending QoS NullFunc well.
3450 * These frames are mainly used for CQM purposes so it doesn't really
3451 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003452 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003453 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003454 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003455 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003456
3457 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003458}
3459
Michal Kaziord740d8f2015-03-30 09:51:51 +03003460static void ath10k_tx_h_8023(struct sk_buff *skb)
3461{
3462 struct ieee80211_hdr *hdr;
3463 struct rfc1042_hdr *rfc1042;
3464 struct ethhdr *eth;
3465 size_t hdrlen;
3466 u8 da[ETH_ALEN];
3467 u8 sa[ETH_ALEN];
3468 __be16 type;
3469
3470 hdr = (void *)skb->data;
3471 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3472 rfc1042 = (void *)skb->data + hdrlen;
3473
3474 ether_addr_copy(da, ieee80211_get_DA(hdr));
3475 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3476 type = rfc1042->snap_type;
3477
3478 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3479 skb_push(skb, sizeof(*eth));
3480
3481 eth = (void *)skb->data;
3482 ether_addr_copy(eth->h_dest, da);
3483 ether_addr_copy(eth->h_source, sa);
3484 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003485}
3486
Michal Kazior4b604552014-07-21 21:03:09 +03003487static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3488 struct ieee80211_vif *vif,
3489 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003490{
3491 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02003492 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003493
3494 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003495 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003496 return;
3497
3498 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3499 spin_lock_bh(&ar->data_lock);
3500 if (arvif->u.ap.noa_data)
3501 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3502 GFP_ATOMIC))
Johannes Berg59ae1d12017-06-16 14:29:20 +02003503 skb_put_data(skb, arvif->u.ap.noa_data,
3504 arvif->u.ap.noa_len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003505 spin_unlock_bh(&ar->data_lock);
3506 }
3507}
3508
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003509static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3510 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003511 struct ieee80211_txq *txq,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003512 struct sk_buff *skb)
3513{
3514 struct ieee80211_hdr *hdr = (void *)skb->data;
3515 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3516
3517 cb->flags = 0;
3518 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3519 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3520
3521 if (ieee80211_is_mgmt(hdr->frame_control))
3522 cb->flags |= ATH10K_SKB_F_MGMT;
3523
3524 if (ieee80211_is_data_qos(hdr->frame_control))
3525 cb->flags |= ATH10K_SKB_F_QOS;
3526
3527 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003528 cb->txq = txq;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003529}
3530
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303531bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003532{
3533 /* FIXME: Not really sure since when the behaviour changed. At some
3534 * point new firmware stopped requiring creation of peer entries for
3535 * offchannel tx (and actually creating them causes issues with wmi-htc
3536 * tx credit replenishment and reliability). Assuming it's at least 3.4
3537 * because that's when the `freq` was introduced to TX_FRM HTT command.
3538 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303539 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303540 ar->htt.target_version_minor >= 4 &&
Kalle Valo77561f92016-04-20 19:45:47 +03003541 ar->running_fw->fw_file.htt_op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003542}
3543
Michal Kaziord740d8f2015-03-30 09:51:51 +03003544static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003545{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003546 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003547 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003548
Michal Kaziord740d8f2015-03-30 09:51:51 +03003549 spin_lock_bh(&ar->data_lock);
3550
3551 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3552 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3553 ret = -ENOSPC;
3554 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003555 }
3556
Michal Kaziord740d8f2015-03-30 09:51:51 +03003557 __skb_queue_tail(q, skb);
3558 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3559
3560unlock:
3561 spin_unlock_bh(&ar->data_lock);
3562
3563 return ret;
3564}
3565
Michal Kaziora30c7d02016-03-06 16:14:23 +02003566static enum ath10k_mac_tx_path
3567ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3568 struct sk_buff *skb,
3569 enum ath10k_hw_txrx_mode txmode)
3570{
3571 switch (txmode) {
3572 case ATH10K_HW_TXRX_RAW:
3573 case ATH10K_HW_TXRX_NATIVE_WIFI:
3574 case ATH10K_HW_TXRX_ETHERNET:
3575 return ATH10K_MAC_TX_HTT;
3576 case ATH10K_HW_TXRX_MGMT:
3577 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Rakesh Pillai229329f2017-12-11 19:52:52 +05303578 ar->running_fw->fw_file.fw_features) ||
3579 test_bit(WMI_SERVICE_MGMT_TX_WMI,
3580 ar->wmi.svc_map))
Michal Kaziora30c7d02016-03-06 16:14:23 +02003581 return ATH10K_MAC_TX_WMI_MGMT;
3582 else if (ar->htt.target_version_major >= 3)
3583 return ATH10K_MAC_TX_HTT;
3584 else
3585 return ATH10K_MAC_TX_HTT_MGMT;
3586 }
3587
3588 return ATH10K_MAC_TX_UNKNOWN;
3589}
3590
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003591static int ath10k_mac_tx_submit(struct ath10k *ar,
3592 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003593 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003594 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003595{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003596 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003597 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003598
3599 switch (txpath) {
3600 case ATH10K_MAC_TX_HTT:
Govind Singhe62ee5c2017-12-21 14:30:55 +05303601 ret = htt->tx_ops->htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003602 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003603 case ATH10K_MAC_TX_HTT_MGMT:
3604 ret = ath10k_htt_mgmt_tx(htt, skb);
3605 break;
3606 case ATH10K_MAC_TX_WMI_MGMT:
3607 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3608 break;
3609 case ATH10K_MAC_TX_UNKNOWN:
3610 WARN_ON_ONCE(1);
3611 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003612 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003613 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003614
3615 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003616 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3617 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003618 ieee80211_free_txskb(ar->hw, skb);
3619 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003620
3621 return ret;
3622}
3623
3624/* This function consumes the sk_buff regardless of return value as far as
3625 * caller is concerned so no freeing is necessary afterwards.
3626 */
3627static int ath10k_mac_tx(struct ath10k *ar,
3628 struct ieee80211_vif *vif,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003629 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003630 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003631 struct sk_buff *skb)
3632{
3633 struct ieee80211_hw *hw = ar->hw;
3634 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3635 int ret;
3636
3637 /* We should disable CCK RATE due to P2P */
3638 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3639 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3640
3641 switch (txmode) {
3642 case ATH10K_HW_TXRX_MGMT:
3643 case ATH10K_HW_TXRX_NATIVE_WIFI:
3644 ath10k_tx_h_nwifi(hw, skb);
3645 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3646 ath10k_tx_h_seq_no(vif, skb);
3647 break;
3648 case ATH10K_HW_TXRX_ETHERNET:
3649 ath10k_tx_h_8023(skb);
3650 break;
3651 case ATH10K_HW_TXRX_RAW:
3652 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3653 WARN_ON_ONCE(1);
3654 ieee80211_free_txskb(hw, skb);
3655 return -ENOTSUPP;
3656 }
3657 }
3658
3659 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3660 if (!ath10k_mac_tx_frm_has_freq(ar)) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303661 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %pK\n",
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003662 skb);
3663
3664 skb_queue_tail(&ar->offchan_tx_queue, skb);
3665 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3666 return 0;
3667 }
3668 }
3669
Michal Kazior6421969f2016-03-06 16:14:25 +02003670 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003671 if (ret) {
3672 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3673 return ret;
3674 }
3675
3676 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003677}
3678
3679void ath10k_offchan_tx_purge(struct ath10k *ar)
3680{
3681 struct sk_buff *skb;
3682
3683 for (;;) {
3684 skb = skb_dequeue(&ar->offchan_tx_queue);
3685 if (!skb)
3686 break;
3687
3688 ieee80211_free_txskb(ar->hw, skb);
3689 }
3690}
3691
3692void ath10k_offchan_tx_work(struct work_struct *work)
3693{
3694 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3695 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003696 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003697 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003698 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003699 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003700 struct ieee80211_vif *vif;
3701 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003702 struct sk_buff *skb;
3703 const u8 *peer_addr;
3704 int vdev_id;
3705 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003706 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003707 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003708
3709 /* FW requirement: We must create a peer before FW will send out
3710 * an offchannel frame. Otherwise the frame will be stuck and
3711 * never transmitted. We delete the peer upon tx completion.
3712 * It is unlikely that a peer for offchannel tx will already be
3713 * present. However it may be in some rare cases so account for that.
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01003714 * Otherwise we might remove a legitimate peer and break stuff.
3715 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003716
3717 for (;;) {
3718 skb = skb_dequeue(&ar->offchan_tx_queue);
3719 if (!skb)
3720 break;
3721
3722 mutex_lock(&ar->conf_mutex);
3723
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303724 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003725 skb);
3726
3727 hdr = (struct ieee80211_hdr *)skb->data;
3728 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003729
3730 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003731 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003732 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3733 spin_unlock_bh(&ar->data_lock);
3734
3735 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003736 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003737 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003738 peer_addr, vdev_id);
3739
3740 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003741 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3742 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003743 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003744 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003745 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003746 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003747 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003748 }
3749
3750 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003751 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003752 ar->offchan_tx_skb = skb;
3753 spin_unlock_bh(&ar->data_lock);
3754
Michal Kazior8a933962015-11-18 06:59:17 +01003755 /* It's safe to access vif and sta - conf_mutex guarantees that
3756 * sta_state() and remove_interface() are locked exclusively
3757 * out wrt to this offchannel worker.
3758 */
3759 arvif = ath10k_get_arvif(ar, vdev_id);
3760 if (arvif) {
3761 vif = arvif->vif;
3762 sta = ieee80211_find_sta(vif, peer_addr);
3763 } else {
3764 vif = NULL;
3765 sta = NULL;
3766 }
3767
3768 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003769 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003770
Mohammed Shafi Shajakhana7773b5d2016-12-27 19:02:35 +05303771 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003772 if (ret) {
3773 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3774 ret);
3775 /* not serious */
3776 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003777
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003778 time_left =
3779 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3780 if (time_left == 0)
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303781 ath10k_warn(ar, "timed out waiting for offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003782 skb);
3783
Michal Kazioradaeed72015-08-05 12:15:23 +02003784 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003785 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3786 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003787 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003788 peer_addr, vdev_id, ret);
3789 }
3790
3791 mutex_unlock(&ar->conf_mutex);
3792 }
3793}
3794
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003795void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3796{
3797 struct sk_buff *skb;
3798
3799 for (;;) {
3800 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3801 if (!skb)
3802 break;
3803
3804 ieee80211_free_txskb(ar->hw, skb);
3805 }
3806}
3807
3808void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3809{
3810 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3811 struct sk_buff *skb;
Rakesh Pillai38a13902018-02-27 19:09:07 +02003812 dma_addr_t paddr;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003813 int ret;
3814
3815 for (;;) {
3816 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3817 if (!skb)
3818 break;
3819
Rakesh Pillai38a13902018-02-27 19:09:07 +02003820 if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF,
3821 ar->running_fw->fw_file.fw_features)) {
3822 paddr = dma_map_single(ar->dev, skb->data,
3823 skb->len, DMA_TO_DEVICE);
3824 if (!paddr)
3825 continue;
3826 ret = ath10k_wmi_mgmt_tx_send(ar, skb, paddr);
3827 if (ret) {
3828 ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n",
3829 ret);
3830 dma_unmap_single(ar->dev, paddr, skb->len,
3831 DMA_FROM_DEVICE);
3832 ieee80211_free_txskb(ar->hw, skb);
3833 }
3834 } else {
3835 ret = ath10k_wmi_mgmt_tx(ar, skb);
3836 if (ret) {
3837 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
3838 ret);
3839 ieee80211_free_txskb(ar->hw, skb);
3840 }
Michal Kazior5fb5e412013-10-28 07:18:13 +01003841 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003842 }
3843}
3844
Michal Kazior29946872016-03-06 16:14:34 +02003845static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3846{
Bob Copelanda66cd732016-06-29 19:29:25 +03003847 struct ath10k_txq *artxq;
Michal Kazior29946872016-03-06 16:14:34 +02003848
3849 if (!txq)
3850 return;
3851
Bob Copelanda66cd732016-06-29 19:29:25 +03003852 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003853 INIT_LIST_HEAD(&artxq->list);
3854}
3855
3856static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3857{
Bob Copelanda66cd732016-06-29 19:29:25 +03003858 struct ath10k_txq *artxq;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003859 struct ath10k_skb_cb *cb;
3860 struct sk_buff *msdu;
3861 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003862
3863 if (!txq)
3864 return;
3865
Bob Copelanda66cd732016-06-29 19:29:25 +03003866 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003867 spin_lock_bh(&ar->txqs_lock);
3868 if (!list_empty(&artxq->list))
3869 list_del_init(&artxq->list);
3870 spin_unlock_bh(&ar->txqs_lock);
Michal Kaziordd4717b2016-03-06 16:14:39 +02003871
3872 spin_lock_bh(&ar->htt.tx_lock);
3873 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3874 cb = ATH10K_SKB_CB(msdu);
3875 if (cb->txq == txq)
3876 cb->txq = NULL;
3877 }
3878 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003879}
3880
Michal Kazior426e10e2016-03-06 16:14:43 +02003881struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
3882 u16 peer_id,
3883 u8 tid)
3884{
3885 struct ath10k_peer *peer;
3886
3887 lockdep_assert_held(&ar->data_lock);
3888
3889 peer = ar->peer_map[peer_id];
3890 if (!peer)
3891 return NULL;
3892
Michal Kazior0a744d92017-01-12 16:14:30 +01003893 if (peer->removed)
3894 return NULL;
3895
Michal Kazior426e10e2016-03-06 16:14:43 +02003896 if (peer->sta)
3897 return peer->sta->txq[tid];
3898 else if (peer->vif)
3899 return peer->vif->txq;
3900 else
3901 return NULL;
3902}
3903
Michal Kazior29946872016-03-06 16:14:34 +02003904static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3905 struct ieee80211_txq *txq)
3906{
Michal Kazior426e10e2016-03-06 16:14:43 +02003907 struct ath10k *ar = hw->priv;
3908 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3909
3910 /* No need to get locks */
3911
3912 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3913 return true;
3914
3915 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3916 return true;
3917
3918 if (artxq->num_fw_queued < artxq->num_push_allowed)
3919 return true;
3920
3921 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003922}
3923
Michal Kazior426e10e2016-03-06 16:14:43 +02003924int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3925 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02003926{
Michal Kazior29946872016-03-06 16:14:34 +02003927 struct ath10k *ar = hw->priv;
3928 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003929 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003930 struct ieee80211_vif *vif = txq->vif;
3931 struct ieee80211_sta *sta = txq->sta;
3932 enum ath10k_hw_txrx_mode txmode;
3933 enum ath10k_mac_tx_path txpath;
3934 struct sk_buff *skb;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303935 struct ieee80211_hdr *hdr;
Michal Kazior426e10e2016-03-06 16:14:43 +02003936 size_t skb_len;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303937 bool is_mgmt, is_presp;
Michal Kazior29946872016-03-06 16:14:34 +02003938 int ret;
3939
3940 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303941 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003942 spin_unlock_bh(&ar->htt.tx_lock);
3943
3944 if (ret)
3945 return ret;
3946
3947 skb = ieee80211_tx_dequeue(hw, txq);
3948 if (!skb) {
3949 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303950 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003951 spin_unlock_bh(&ar->htt.tx_lock);
3952
3953 return -ENOENT;
3954 }
3955
Michal Kaziordd4717b2016-03-06 16:14:39 +02003956 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Michal Kazior29946872016-03-06 16:14:34 +02003957
Michal Kazior426e10e2016-03-06 16:14:43 +02003958 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02003959 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
3960 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303961 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
3962
3963 if (is_mgmt) {
3964 hdr = (struct ieee80211_hdr *)skb->data;
3965 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
3966
3967 spin_lock_bh(&ar->htt.tx_lock);
3968 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
3969
3970 if (ret) {
3971 ath10k_htt_tx_dec_pending(htt);
3972 spin_unlock_bh(&ar->htt.tx_lock);
3973 return ret;
3974 }
3975 spin_unlock_bh(&ar->htt.tx_lock);
3976 }
Michal Kazior29946872016-03-06 16:14:34 +02003977
Mohammed Shafi Shajakhana7773b5d2016-12-27 19:02:35 +05303978 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
Michal Kazior29946872016-03-06 16:14:34 +02003979 if (unlikely(ret)) {
3980 ath10k_warn(ar, "failed to push frame: %d\n", ret);
3981
3982 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303983 ath10k_htt_tx_dec_pending(htt);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303984 if (is_mgmt)
3985 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003986 spin_unlock_bh(&ar->htt.tx_lock);
3987
3988 return ret;
3989 }
3990
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003991 spin_lock_bh(&ar->htt.tx_lock);
3992 artxq->num_fw_queued++;
3993 spin_unlock_bh(&ar->htt.tx_lock);
3994
Michal Kazior426e10e2016-03-06 16:14:43 +02003995 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003996}
3997
3998void ath10k_mac_tx_push_pending(struct ath10k *ar)
3999{
4000 struct ieee80211_hw *hw = ar->hw;
4001 struct ieee80211_txq *txq;
4002 struct ath10k_txq *artxq;
4003 struct ath10k_txq *last;
4004 int ret;
4005 int max;
4006
Michal Kazior7a0adc82016-05-23 23:12:45 +03004007 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
4008 return;
4009
Michal Kazior29946872016-03-06 16:14:34 +02004010 spin_lock_bh(&ar->txqs_lock);
4011 rcu_read_lock();
4012
4013 last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
4014 while (!list_empty(&ar->txqs)) {
4015 artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
4016 txq = container_of((void *)artxq, struct ieee80211_txq,
4017 drv_priv);
4018
4019 /* Prevent aggressive sta/tid taking over tx queue */
4020 max = 16;
Michal Kazior750eeed2016-03-17 10:51:05 +01004021 ret = 0;
4022 while (ath10k_mac_tx_can_push(hw, txq) && max--) {
Michal Kazior29946872016-03-06 16:14:34 +02004023 ret = ath10k_mac_tx_push_txq(hw, txq);
4024 if (ret < 0)
4025 break;
4026 }
4027
4028 list_del_init(&artxq->list);
Michal Kazior9d71d472016-03-17 10:51:04 +01004029 if (ret != -ENOENT)
4030 list_add_tail(&artxq->list, &ar->txqs);
4031
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004032 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02004033
Michal Kazior9d71d472016-03-17 10:51:04 +01004034 if (artxq == last || (ret < 0 && ret != -ENOENT))
Michal Kazior29946872016-03-06 16:14:34 +02004035 break;
Michal Kazior29946872016-03-06 16:14:34 +02004036 }
4037
4038 rcu_read_unlock();
4039 spin_unlock_bh(&ar->txqs_lock);
4040}
4041
Kalle Valo5e3dd152013-06-12 20:52:10 +03004042/************/
4043/* Scanning */
4044/************/
4045
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004046void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004047{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004048 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004049
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004050 switch (ar->scan.state) {
4051 case ATH10K_SCAN_IDLE:
4052 break;
4053 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01004054 case ATH10K_SCAN_ABORTING:
Avraham Stern7947d3e2016-07-05 15:23:12 +03004055 if (!ar->scan.is_roc) {
4056 struct cfg80211_scan_info info = {
4057 .aborted = (ar->scan.state ==
4058 ATH10K_SCAN_ABORTING),
4059 };
4060
4061 ieee80211_scan_completed(ar->hw, &info);
4062 } else if (ar->scan.roc_notify) {
Michal Kaziord710e752015-07-09 13:08:36 +02004063 ieee80211_remain_on_channel_expired(ar->hw);
Avraham Stern7947d3e2016-07-05 15:23:12 +03004064 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004065 /* fall through */
4066 case ATH10K_SCAN_STARTING:
4067 ar->scan.state = ATH10K_SCAN_IDLE;
4068 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01004069 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004070 ath10k_offchan_tx_purge(ar);
4071 cancel_delayed_work(&ar->scan.timeout);
Daniel Wagner881ed542016-08-18 15:12:06 +02004072 complete(&ar->scan.completed);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004073 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004074 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004075}
Kalle Valo5e3dd152013-06-12 20:52:10 +03004076
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004077void ath10k_scan_finish(struct ath10k *ar)
4078{
4079 spin_lock_bh(&ar->data_lock);
4080 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004081 spin_unlock_bh(&ar->data_lock);
4082}
4083
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004084static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004085{
4086 struct wmi_stop_scan_arg arg = {
4087 .req_id = 1, /* FIXME */
4088 .req_type = WMI_SCAN_STOP_ONE,
4089 .u.scan_id = ATH10K_SCAN_ID,
4090 };
4091 int ret;
4092
4093 lockdep_assert_held(&ar->conf_mutex);
4094
Kalle Valo5e3dd152013-06-12 20:52:10 +03004095 ret = ath10k_wmi_stop_scan(ar, &arg);
4096 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004097 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004098 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004099 }
4100
Kalle Valo14e105c2016-04-13 14:13:21 +03004101 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004102 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004103 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004104 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004105 } else if (ret > 0) {
4106 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004107 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004108
4109out:
4110 /* Scan state should be updated upon scan completion but in case
4111 * firmware fails to deliver the event (for whatever reason) it is
4112 * desired to clean up scan state anyway. Firmware may have just
4113 * dropped the scan completion event delivery due to transport pipe
4114 * being overflown with data and/or it can recover on its own before
4115 * next scan request is submitted.
4116 */
4117 spin_lock_bh(&ar->data_lock);
4118 if (ar->scan.state != ATH10K_SCAN_IDLE)
4119 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004120 spin_unlock_bh(&ar->data_lock);
4121
4122 return ret;
4123}
4124
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004125static void ath10k_scan_abort(struct ath10k *ar)
4126{
4127 int ret;
4128
4129 lockdep_assert_held(&ar->conf_mutex);
4130
4131 spin_lock_bh(&ar->data_lock);
4132
4133 switch (ar->scan.state) {
4134 case ATH10K_SCAN_IDLE:
4135 /* This can happen if timeout worker kicked in and called
4136 * abortion while scan completion was being processed.
4137 */
4138 break;
4139 case ATH10K_SCAN_STARTING:
4140 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02004141 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004142 ath10k_scan_state_str(ar->scan.state),
4143 ar->scan.state);
4144 break;
4145 case ATH10K_SCAN_RUNNING:
4146 ar->scan.state = ATH10K_SCAN_ABORTING;
4147 spin_unlock_bh(&ar->data_lock);
4148
4149 ret = ath10k_scan_stop(ar);
4150 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004151 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004152
4153 spin_lock_bh(&ar->data_lock);
4154 break;
4155 }
4156
4157 spin_unlock_bh(&ar->data_lock);
4158}
4159
4160void ath10k_scan_timeout_work(struct work_struct *work)
4161{
4162 struct ath10k *ar = container_of(work, struct ath10k,
4163 scan.timeout.work);
4164
4165 mutex_lock(&ar->conf_mutex);
4166 ath10k_scan_abort(ar);
4167 mutex_unlock(&ar->conf_mutex);
4168}
4169
Kalle Valo5e3dd152013-06-12 20:52:10 +03004170static int ath10k_start_scan(struct ath10k *ar,
4171 const struct wmi_start_scan_arg *arg)
4172{
4173 int ret;
4174
4175 lockdep_assert_held(&ar->conf_mutex);
4176
4177 ret = ath10k_wmi_start_scan(ar, arg);
4178 if (ret)
4179 return ret;
4180
Kalle Valo14e105c2016-04-13 14:13:21 +03004181 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004182 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004183 ret = ath10k_scan_stop(ar);
4184 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004185 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004186
4187 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004188 }
4189
Ben Greear2f9eec02015-02-15 16:50:38 +02004190 /* If we failed to start the scan, return error code at
4191 * this point. This is probably due to some issue in the
4192 * firmware, but no need to wedge the driver due to that...
4193 */
4194 spin_lock_bh(&ar->data_lock);
4195 if (ar->scan.state == ATH10K_SCAN_IDLE) {
4196 spin_unlock_bh(&ar->data_lock);
4197 return -EINVAL;
4198 }
4199 spin_unlock_bh(&ar->data_lock);
4200
Kalle Valo5e3dd152013-06-12 20:52:10 +03004201 return 0;
4202}
4203
4204/**********************/
4205/* mac80211 callbacks */
4206/**********************/
4207
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004208static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4209 struct ieee80211_tx_control *control,
4210 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004211{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004212 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02004213 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03004214 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4215 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004216 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02004217 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02004218 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01004219 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02004220 enum ath10k_mac_tx_path txpath;
4221 bool is_htt;
4222 bool is_mgmt;
4223 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004224 int ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004225
Michal Kaziordd4717b2016-03-06 16:14:39 +02004226 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004227
Michal Kazior8a933962015-11-18 06:59:17 +01004228 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004229 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
4230 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
4231 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304232 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004233
Michal Kazior6421969f2016-03-06 16:14:25 +02004234 if (is_htt) {
4235 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004236 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4237
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304238 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004239 if (ret) {
4240 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4241 ret);
4242 spin_unlock_bh(&ar->htt.tx_lock);
4243 ieee80211_free_txskb(ar->hw, skb);
4244 return;
4245 }
4246
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304247 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4248 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304249 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4250 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304251 ath10k_htt_tx_dec_pending(htt);
4252 spin_unlock_bh(&ar->htt.tx_lock);
4253 ieee80211_free_txskb(ar->hw, skb);
4254 return;
4255 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004256 spin_unlock_bh(&ar->htt.tx_lock);
4257 }
4258
Mohammed Shafi Shajakhana7773b5d2016-12-27 19:02:35 +05304259 ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004260 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004261 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004262 if (is_htt) {
4263 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304264 ath10k_htt_tx_dec_pending(htt);
4265 if (is_mgmt)
4266 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004267 spin_unlock_bh(&ar->htt.tx_lock);
4268 }
4269 return;
4270 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004271}
4272
Michal Kazior29946872016-03-06 16:14:34 +02004273static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4274 struct ieee80211_txq *txq)
4275{
4276 struct ath10k *ar = hw->priv;
4277 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304278 struct ieee80211_txq *f_txq;
4279 struct ath10k_txq *f_artxq;
4280 int ret = 0;
4281 int max = 16;
Michal Kazior29946872016-03-06 16:14:34 +02004282
Michal Kazior750eeed2016-03-17 10:51:05 +01004283 spin_lock_bh(&ar->txqs_lock);
4284 if (list_empty(&artxq->list))
4285 list_add_tail(&artxq->list, &ar->txqs);
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304286
4287 f_artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
4288 f_txq = container_of((void *)f_artxq, struct ieee80211_txq, drv_priv);
4289 list_del_init(&f_artxq->list);
4290
4291 while (ath10k_mac_tx_can_push(hw, f_txq) && max--) {
4292 ret = ath10k_mac_tx_push_txq(hw, f_txq);
4293 if (ret)
4294 break;
4295 }
4296 if (ret != -ENOENT)
4297 list_add_tail(&f_artxq->list, &ar->txqs);
Michal Kazior750eeed2016-03-17 10:51:05 +01004298 spin_unlock_bh(&ar->txqs_lock);
Michal Kazior29946872016-03-06 16:14:34 +02004299
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304300 ath10k_htt_tx_txq_update(hw, f_txq);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004301 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02004302}
4303
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004304/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004305void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004306{
4307 /* make sure rcu-protected mac80211 tx path itself is drained */
4308 synchronize_net();
4309
4310 ath10k_offchan_tx_purge(ar);
4311 ath10k_mgmt_over_wmi_tx_purge(ar);
4312
4313 cancel_work_sync(&ar->offchan_tx_work);
4314 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4315}
4316
Michal Kazioraffd3212013-07-16 09:54:35 +02004317void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004318{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004319 struct ath10k_vif *arvif;
4320
Michal Kazior818bdd12013-07-16 09:38:57 +02004321 lockdep_assert_held(&ar->conf_mutex);
4322
Michal Kazior19337472014-08-28 12:58:16 +02004323 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4324 ar->filter_flags = 0;
4325 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004326 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004327
4328 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004329 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004330
4331 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004332 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004333
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004334 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004335 ath10k_peer_cleanup_all(ar);
4336 ath10k_core_stop(ar);
4337 ath10k_hif_power_down(ar);
4338
4339 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004340 list_for_each_entry(arvif, &ar->arvifs, list)
4341 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004342 spin_unlock_bh(&ar->data_lock);
4343}
4344
Ben Greear46acf7bb2014-05-16 17:15:38 +03004345static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4346{
4347 struct ath10k *ar = hw->priv;
4348
4349 mutex_lock(&ar->conf_mutex);
4350
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304351 *tx_ant = ar->cfg_tx_chainmask;
4352 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03004353
4354 mutex_unlock(&ar->conf_mutex);
4355
4356 return 0;
4357}
4358
Ben Greear5572a952014-11-24 16:22:10 +02004359static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4360{
4361 /* It is not clear that allowing gaps in chainmask
4362 * is helpful. Probably it will not do what user
4363 * is hoping for, so warn in that case.
4364 */
4365 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4366 return;
4367
4368 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4369 dbg, cm);
4370}
4371
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304372static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4373{
4374 int nsts = ar->vht_cap_info;
4375
4376 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4377 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4378
4379 /* If firmware does not deliver to host number of space-time
4380 * streams supported, assume it support up to 4 BF STS and return
4381 * the value for VHT CAP: nsts-1)
4382 */
4383 if (nsts == 0)
4384 return 3;
4385
4386 return nsts;
4387}
4388
4389static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4390{
4391 int sound_dim = ar->vht_cap_info;
4392
4393 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4394 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4395
4396 /* If the sounding dimension is not advertised by the firmware,
4397 * let's use a default value of 1
4398 */
4399 if (sound_dim == 0)
4400 return 1;
4401
4402 return sound_dim;
4403}
4404
4405static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4406{
4407 struct ieee80211_sta_vht_cap vht_cap = {0};
Ben Greearcc914a52017-06-16 10:37:45 +03004408 struct ath10k_hw_params *hw = &ar->hw_params;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304409 u16 mcs_map;
4410 u32 val;
4411 int i;
4412
4413 vht_cap.vht_supported = 1;
4414 vht_cap.cap = ar->vht_cap_info;
4415
4416 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4417 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4418 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4419 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4420 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4421
4422 vht_cap.cap |= val;
4423 }
4424
4425 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4426 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4427 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4428 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4429 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4430
4431 vht_cap.cap |= val;
4432 }
4433
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02004434 /* Currently the firmware seems to be buggy, don't enable 80+80
4435 * mode until that's resolved.
4436 */
4437 if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) &&
Ben Greeare509e592017-06-16 10:37:44 +03004438 (ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == 0)
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02004439 vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
4440
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304441 mcs_map = 0;
4442 for (i = 0; i < 8; i++) {
4443 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4444 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4445 else
4446 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4447 }
4448
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004449 if (ar->cfg_tx_chainmask <= 1)
4450 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4451
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304452 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4453 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4454
Ben Greearcc914a52017-06-16 10:37:45 +03004455 /* If we are supporting 160Mhz or 80+80, then the NIC may be able to do
4456 * a restricted NSS for 160 or 80+80 vs what it can do for 80Mhz. Give
4457 * user-space a clue if that is the case.
4458 */
4459 if ((vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) &&
4460 (hw->vht160_mcs_rx_highest != 0 ||
4461 hw->vht160_mcs_tx_highest != 0)) {
4462 vht_cap.vht_mcs.rx_highest = cpu_to_le16(hw->vht160_mcs_rx_highest);
4463 vht_cap.vht_mcs.tx_highest = cpu_to_le16(hw->vht160_mcs_tx_highest);
4464 }
4465
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304466 return vht_cap;
4467}
4468
4469static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4470{
4471 int i;
4472 struct ieee80211_sta_ht_cap ht_cap = {0};
4473
4474 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4475 return ht_cap;
4476
4477 ht_cap.ht_supported = 1;
4478 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4479 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4480 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4481 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004482 ht_cap.cap |=
4483 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304484
4485 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4486 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4487
4488 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4489 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4490
4491 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4492 u32 smps;
4493
4494 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4495 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4496
4497 ht_cap.cap |= smps;
4498 }
4499
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004500 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304501 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4502
4503 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4504 u32 stbc;
4505
4506 stbc = ar->ht_cap_info;
4507 stbc &= WMI_HT_CAP_RX_STBC;
4508 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4509 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4510 stbc &= IEEE80211_HT_CAP_RX_STBC;
4511
4512 ht_cap.cap |= stbc;
4513 }
4514
4515 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
4516 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4517
4518 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4519 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4520
4521 /* max AMSDU is implicitly taken from vht_cap_info */
4522 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4523 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4524
4525 for (i = 0; i < ar->num_rf_chains; i++) {
4526 if (ar->cfg_rx_chainmask & BIT(i))
4527 ht_cap.mcs.rx_mask[i] = 0xFF;
4528 }
4529
4530 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4531
4532 return ht_cap;
4533}
4534
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304535static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4536{
4537 struct ieee80211_supported_band *band;
4538 struct ieee80211_sta_vht_cap vht_cap;
4539 struct ieee80211_sta_ht_cap ht_cap;
4540
4541 ht_cap = ath10k_get_ht_cap(ar);
4542 vht_cap = ath10k_create_vht_cap(ar);
4543
4544 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004545 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304546 band->ht_cap = ht_cap;
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304547 }
4548 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004549 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304550 band->ht_cap = ht_cap;
4551 band->vht_cap = vht_cap;
4552 }
4553}
4554
Ben Greear46acf7bb2014-05-16 17:15:38 +03004555static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4556{
4557 int ret;
4558
4559 lockdep_assert_held(&ar->conf_mutex);
4560
Ben Greear5572a952014-11-24 16:22:10 +02004561 ath10k_check_chain_mask(ar, tx_ant, "tx");
4562 ath10k_check_chain_mask(ar, rx_ant, "rx");
4563
Ben Greear46acf7bb2014-05-16 17:15:38 +03004564 ar->cfg_tx_chainmask = tx_ant;
4565 ar->cfg_rx_chainmask = rx_ant;
4566
4567 if ((ar->state != ATH10K_STATE_ON) &&
4568 (ar->state != ATH10K_STATE_RESTARTED))
4569 return 0;
4570
4571 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4572 tx_ant);
4573 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004574 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03004575 ret, tx_ant);
4576 return ret;
4577 }
4578
4579 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4580 rx_ant);
4581 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004582 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03004583 ret, rx_ant);
4584 return ret;
4585 }
4586
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304587 /* Reload HT/VHT capability */
4588 ath10k_mac_setup_ht_vht_cap(ar);
4589
Ben Greear46acf7bb2014-05-16 17:15:38 +03004590 return 0;
4591}
4592
4593static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4594{
4595 struct ath10k *ar = hw->priv;
4596 int ret;
4597
4598 mutex_lock(&ar->conf_mutex);
4599 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4600 mutex_unlock(&ar->conf_mutex);
4601 return ret;
4602}
4603
Kalle Valo5e3dd152013-06-12 20:52:10 +03004604static int ath10k_start(struct ieee80211_hw *hw)
4605{
4606 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304607 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004608 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004609
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004610 /*
4611 * This makes sense only when restarting hw. It is harmless to call
Mohammed Shafi Shajakhan6dfdbfc2016-04-26 14:41:36 +03004612 * unconditionally. This is necessary to make sure no HTT/WMI tx
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004613 * commands will be submitted while restarting.
4614 */
4615 ath10k_drain_tx(ar);
4616
Michal Kazior548db542013-07-05 16:15:15 +03004617 mutex_lock(&ar->conf_mutex);
4618
Michal Kaziorc5058f52014-05-26 12:46:03 +03004619 switch (ar->state) {
4620 case ATH10K_STATE_OFF:
4621 ar->state = ATH10K_STATE_ON;
4622 break;
4623 case ATH10K_STATE_RESTARTING:
Michal Kaziorc5058f52014-05-26 12:46:03 +03004624 ar->state = ATH10K_STATE_RESTARTED;
4625 break;
4626 case ATH10K_STATE_ON:
4627 case ATH10K_STATE_RESTARTED:
4628 case ATH10K_STATE_WEDGED:
4629 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004630 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004631 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004632 case ATH10K_STATE_UTF:
4633 ret = -EBUSY;
4634 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004635 }
4636
4637 ret = ath10k_hif_power_up(ar);
4638 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004639 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004640 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004641 }
4642
Kalle Valo7ebf7212016-04-20 19:44:51 +03004643 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
4644 &ar->normal_mode_fw);
Michal Kazior818bdd12013-07-16 09:38:57 +02004645 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004646 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004647 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004648 }
4649
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304650 param = ar->wmi.pdev_param->pmf_qos;
4651 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004652 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004653 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004654 goto err_core_stop;
4655 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004656
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304657 param = ar->wmi.pdev_param->dynamic_bw;
4658 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004659 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004660 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004661 goto err_core_stop;
4662 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004663
Michal Kaziorcf327842015-03-31 10:26:25 +00004664 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4665 ret = ath10k_wmi_adaptive_qcs(ar, true);
4666 if (ret) {
4667 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4668 ret);
4669 goto err_core_stop;
4670 }
4671 }
4672
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004673 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304674 param = ar->wmi.pdev_param->burst_enable;
4675 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004676 if (ret) {
4677 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4678 goto err_core_stop;
4679 }
4680 }
4681
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304682 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7bb2014-05-16 17:15:38 +03004683
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004684 /*
4685 * By default FW set ARP frames ac to voice (6). In that case ARP
4686 * exchange is not working properly for UAPSD enabled AP. ARP requests
4687 * which arrives with access category 0 are processed by network stack
4688 * and send back with access category 0, but FW changes access category
4689 * to 6. Set ARP frames access category to best effort (0) solves
4690 * this problem.
4691 */
4692
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304693 param = ar->wmi.pdev_param->arp_ac_override;
4694 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004695 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004696 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004697 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004698 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004699 }
4700
Maharaja62f77f02015-10-21 11:49:18 +03004701 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
Kalle Valoc4cdf752016-04-20 19:45:18 +03004702 ar->running_fw->fw_file.fw_features)) {
Maharaja62f77f02015-10-21 11:49:18 +03004703 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4704 WMI_CCA_DETECT_LEVEL_AUTO,
4705 WMI_CCA_DETECT_MARGIN_AUTO);
4706 if (ret) {
4707 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4708 ret);
4709 goto err_core_stop;
4710 }
4711 }
4712
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304713 param = ar->wmi.pdev_param->ani_enable;
4714 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304715 if (ret) {
4716 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4717 ret);
4718 goto err_core_stop;
4719 }
4720
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304721 ar->ani_enabled = true;
4722
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304723 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304724 param = ar->wmi.pdev_param->peer_stats_update_period;
4725 ret = ath10k_wmi_pdev_set_param(ar, param,
4726 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4727 if (ret) {
4728 ath10k_warn(ar,
4729 "failed to set peer stats period : %d\n",
4730 ret);
4731 goto err_core_stop;
4732 }
4733 }
4734
Rajkumar Manoharan39136242016-05-27 20:15:59 +05304735 param = ar->wmi.pdev_param->enable_btcoex;
4736 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
4737 test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
4738 ar->running_fw->fw_file.fw_features)) {
4739 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4740 if (ret) {
4741 ath10k_warn(ar,
4742 "failed to set btcoex param: %d\n", ret);
4743 goto err_core_stop;
4744 }
4745 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
4746 }
4747
Michal Kaziord6500972014-04-08 09:56:09 +03004748 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004749 ath10k_regd_update(ar);
4750
Simon Wunderlich855aed12014-08-02 09:12:54 +03004751 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304752 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004753
Michal Kaziorae254432014-05-26 12:46:02 +03004754 mutex_unlock(&ar->conf_mutex);
4755 return 0;
4756
4757err_core_stop:
4758 ath10k_core_stop(ar);
4759
4760err_power_down:
4761 ath10k_hif_power_down(ar);
4762
4763err_off:
4764 ar->state = ATH10K_STATE_OFF;
4765
4766err:
Michal Kazior548db542013-07-05 16:15:15 +03004767 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004768 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004769}
4770
4771static void ath10k_stop(struct ieee80211_hw *hw)
4772{
4773 struct ath10k *ar = hw->priv;
4774
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004775 ath10k_drain_tx(ar);
4776
Michal Kazior548db542013-07-05 16:15:15 +03004777 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004778 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004779 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004780 ar->state = ATH10K_STATE_OFF;
4781 }
Michal Kazior548db542013-07-05 16:15:15 +03004782 mutex_unlock(&ar->conf_mutex);
4783
Mohammed Shafi Shajakhand94475c2017-03-31 17:28:41 +05304784 cancel_work_sync(&ar->set_coverage_class_work);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004785 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004786 cancel_work_sync(&ar->restart_work);
4787}
4788
Michal Kaziorad088bf2013-10-16 15:44:46 +03004789static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004790{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004791 struct ath10k_vif *arvif;
4792 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004793
4794 lockdep_assert_held(&ar->conf_mutex);
4795
Michal Kaziorad088bf2013-10-16 15:44:46 +03004796 list_for_each_entry(arvif, &ar->arvifs, list) {
4797 ret = ath10k_mac_vif_setup_ps(arvif);
4798 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004799 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004800 break;
4801 }
4802 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004803
Michal Kaziorad088bf2013-10-16 15:44:46 +03004804 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004805}
4806
Michal Kazior7d9d5582014-10-21 10:40:15 +03004807static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4808{
4809 int ret;
4810 u32 param;
4811
4812 lockdep_assert_held(&ar->conf_mutex);
4813
4814 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4815
4816 param = ar->wmi.pdev_param->txpower_limit2g;
4817 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4818 if (ret) {
4819 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4820 txpower, ret);
4821 return ret;
4822 }
4823
4824 param = ar->wmi.pdev_param->txpower_limit5g;
4825 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4826 if (ret) {
4827 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4828 txpower, ret);
4829 return ret;
4830 }
4831
4832 return 0;
4833}
4834
4835static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4836{
4837 struct ath10k_vif *arvif;
4838 int ret, txpower = -1;
4839
4840 lockdep_assert_held(&ar->conf_mutex);
4841
4842 list_for_each_entry(arvif, &ar->arvifs, list) {
Ryan Hsu88407be2016-12-13 14:55:19 -08004843 if (arvif->txpower <= 0)
4844 continue;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004845
4846 if (txpower == -1)
4847 txpower = arvif->txpower;
4848 else
4849 txpower = min(txpower, arvif->txpower);
4850 }
4851
Ryan Hsu88407be2016-12-13 14:55:19 -08004852 if (txpower == -1)
4853 return 0;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004854
4855 ret = ath10k_mac_txpower_setup(ar, txpower);
4856 if (ret) {
4857 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4858 txpower, ret);
4859 return ret;
4860 }
4861
4862 return 0;
4863}
4864
Kalle Valo5e3dd152013-06-12 20:52:10 +03004865static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4866{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004867 struct ath10k *ar = hw->priv;
4868 struct ieee80211_conf *conf = &hw->conf;
4869 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004870
4871 mutex_lock(&ar->conf_mutex);
4872
Michal Kazioraffd3212013-07-16 09:54:35 +02004873 if (changed & IEEE80211_CONF_CHANGE_PS)
4874 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004875
4876 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004877 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4878 ret = ath10k_monitor_recalc(ar);
4879 if (ret)
4880 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004881 }
4882
4883 mutex_unlock(&ar->conf_mutex);
4884 return ret;
4885}
4886
Ben Greear5572a952014-11-24 16:22:10 +02004887static u32 get_nss_from_chainmask(u16 chain_mask)
4888{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05304889 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02004890 return 4;
4891 else if ((chain_mask & 0x7) == 0x7)
4892 return 3;
4893 else if ((chain_mask & 0x3) == 0x3)
4894 return 2;
4895 return 1;
4896}
4897
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304898static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4899{
4900 u32 value = 0;
4901 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004902 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004903 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304904
4905 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4906 return 0;
4907
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004908 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304909 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4910 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004911 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304912
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004913 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304914 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4915 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004916 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304917
4918 if (!value)
4919 return 0;
4920
4921 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4922 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4923
4924 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4925 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4926 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4927
4928 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4929 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4930
4931 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4932 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4933 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4934
4935 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4936 ar->wmi.vdev_param->txbf, value);
4937}
4938
Kalle Valo5e3dd152013-06-12 20:52:10 +03004939/*
4940 * TODO:
4941 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4942 * because we will send mgmt frames without CCK. This requirement
4943 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4944 * in the TX packet.
4945 */
4946static int ath10k_add_interface(struct ieee80211_hw *hw,
4947 struct ieee80211_vif *vif)
4948{
4949 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02004950 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004951 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004952 enum wmi_sta_powersave_param param;
4953 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004954 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004955 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004956 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004957 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004958
Johannes Berg848955c2014-11-11 12:48:42 +01004959 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4960
Kalle Valo5e3dd152013-06-12 20:52:10 +03004961 mutex_lock(&ar->conf_mutex);
4962
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004963 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02004964 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004965
Kalle Valo5e3dd152013-06-12 20:52:10 +03004966 arvif->ar = ar;
4967 arvif->vif = vif;
4968
Ben Greeare63b33f2013-10-22 14:54:14 -07004969 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004970 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004971 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4972 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004973
Michal Kazior45c9abc2015-04-21 20:42:58 +03004974 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4975 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4976 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4977 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4978 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4979 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4980 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004981
Michal Kaziore04cafb2015-08-05 12:15:24 +02004982 if (ar->num_peers >= ar->max_num_peers) {
4983 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004984 ret = -ENOBUFS;
4985 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004986 }
4987
Ben Greeara9aefb32014-08-12 11:02:19 +03004988 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004989 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004990 ret = -EBUSY;
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004991 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004992 }
Ben Greear16c11172014-09-23 14:17:16 -07004993 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004994
Ben Greear16c11172014-09-23 14:17:16 -07004995 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4996 bit, ar->free_vdev_map);
4997
4998 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004999 arvif->vdev_subtype =
5000 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005001
Kalle Valo5e3dd152013-06-12 20:52:10 +03005002 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01005003 case NL80211_IFTYPE_P2P_DEVICE:
5004 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08005005 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5006 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01005007 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005008 case NL80211_IFTYPE_UNSPECIFIED:
5009 case NL80211_IFTYPE_STATION:
5010 arvif->vdev_type = WMI_VDEV_TYPE_STA;
5011 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08005012 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5013 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005014 break;
5015 case NL80211_IFTYPE_ADHOC:
5016 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
5017 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005018 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08005019 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08005020 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5021 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08005022 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005023 ret = -EINVAL;
5024 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
5025 goto err;
5026 }
5027 arvif->vdev_type = WMI_VDEV_TYPE_AP;
5028 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005029 case NL80211_IFTYPE_AP:
5030 arvif->vdev_type = WMI_VDEV_TYPE_AP;
5031
5032 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08005033 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
5034 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005035 break;
5036 case NL80211_IFTYPE_MONITOR:
5037 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
5038 break;
5039 default:
5040 WARN_ON(1);
5041 break;
5042 }
5043
Michal Kazior96d828d2015-03-31 10:26:23 +00005044 /* Using vdev_id as queue number will make it very easy to do per-vif
5045 * tx queue locking. This shouldn't wrap due to interface combinations
5046 * but do a modulo for correctness sake and prevent using offchannel tx
5047 * queues for regular vif tx.
5048 */
5049 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
5050 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
5051 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
5052
Michal Kazior64badcb2014-09-18 11:18:02 +03005053 /* Some firmware revisions don't wait for beacon tx completion before
5054 * sending another SWBA event. This could lead to hardware using old
5055 * (freed) beacon data in some cases, e.g. tx credit starvation
5056 * combined with missed TBTT. This is very very rare.
5057 *
5058 * On non-IOMMU-enabled hosts this could be a possible security issue
5059 * because hw could beacon some random data on the air. On
5060 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
5061 * device would crash.
5062 *
5063 * Since there are no beacon tx completions (implicit nor explicit)
5064 * propagated to host the only workaround for this is to allocate a
5065 * DMA-coherent buffer for a lifetime of a vif and use it for all
5066 * beacon tx commands. Worst case for this approach is some beacons may
5067 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
5068 */
5069 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005070 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03005071 vif->type == NL80211_IFTYPE_AP) {
5072 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
5073 IEEE80211_MAX_FRAME_LEN,
5074 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05305075 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03005076 if (!arvif->beacon_buf) {
5077 ret = -ENOMEM;
5078 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
5079 ret);
5080 goto err;
5081 }
5082 }
David Liuccec9032015-07-24 20:25:32 +03005083 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
5084 arvif->nohwcrypt = true;
5085
5086 if (arvif->nohwcrypt &&
5087 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
5088 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
5089 goto err;
5090 }
Michal Kazior64badcb2014-09-18 11:18:02 +03005091
5092 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
5093 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
5094 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03005095
5096 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
5097 arvif->vdev_subtype, vif->addr);
5098 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005099 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005100 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005101 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005102 }
5103
Ben Greear16c11172014-09-23 14:17:16 -07005104 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305105 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005106 list_add(&arvif->list, &ar->arvifs);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305107 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005108
Michal Kazior46725b152015-01-28 09:57:49 +02005109 /* It makes no sense to have firmware do keepalives. mac80211 already
5110 * takes care of this with idle connection polling.
5111 */
5112 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005113 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02005114 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005115 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005116 goto err_vdev_delete;
5117 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005118
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005119 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005120
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005121 vdev_param = ar->wmi.vdev_param->tx_encap_type;
5122 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005123 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02005124 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005125 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005126 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005127 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005128 goto err_vdev_delete;
5129 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005130
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05305131 /* Configuring number of spatial stream for monitor interface is causing
5132 * target assert in qca9888 and qca6174.
5133 */
5134 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02005135 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
5136
5137 vdev_param = ar->wmi.vdev_param->nss;
5138 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5139 nss);
5140 if (ret) {
5141 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
5142 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
5143 ret);
5144 goto err_vdev_delete;
5145 }
5146 }
5147
Michal Kaziore57e0572015-03-24 13:14:03 +00005148 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5149 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02005150 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
5151 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005152 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00005153 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005154 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005155 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005156 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005157
5158 spin_lock_bh(&ar->data_lock);
5159
5160 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
5161 if (!peer) {
5162 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5163 vif->addr, arvif->vdev_id);
5164 spin_unlock_bh(&ar->data_lock);
5165 ret = -ENOENT;
5166 goto err_peer_delete;
5167 }
5168
5169 arvif->peer_id = find_first_bit(peer->peer_ids,
5170 ATH10K_MAX_NUM_PEER_IDS);
5171
5172 spin_unlock_bh(&ar->data_lock);
5173 } else {
5174 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00005175 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01005176
Michal Kaziore57e0572015-03-24 13:14:03 +00005177 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02005178 ret = ath10k_mac_set_kickout(arvif);
5179 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005180 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005181 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02005182 goto err_peer_delete;
5183 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005184 }
5185
5186 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
5187 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
5188 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5189 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5190 param, value);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005191 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005192 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005193 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005194 goto err_peer_delete;
5195 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005196
Michal Kazior9f9b5742014-12-12 12:41:36 +01005197 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005198 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005199 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005200 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005201 goto err_peer_delete;
5202 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005203
Michal Kazior9f9b5742014-12-12 12:41:36 +01005204 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005205 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005206 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005207 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005208 goto err_peer_delete;
5209 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005210 }
5211
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305212 ret = ath10k_mac_set_txbf_conf(arvif);
5213 if (ret) {
5214 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
5215 arvif->vdev_id, ret);
5216 goto err_peer_delete;
5217 }
5218
Michal Kazior424121c2013-07-22 14:13:31 +02005219 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005220 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005221 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03005222 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005223 goto err_peer_delete;
5224 }
Michal Kazior679c54a2013-07-05 16:15:04 +03005225
Michal Kazior7d9d5582014-10-21 10:40:15 +03005226 arvif->txpower = vif->bss_conf.txpower;
5227 ret = ath10k_mac_txpower_recalc(ar);
5228 if (ret) {
5229 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5230 goto err_peer_delete;
5231 }
5232
Michal Kazior500ff9f2015-03-31 10:26:21 +00005233 if (vif->type == NL80211_IFTYPE_MONITOR) {
5234 ar->monitor_arvif = arvif;
5235 ret = ath10k_monitor_recalc(ar);
5236 if (ret) {
5237 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5238 goto err_peer_delete;
5239 }
5240 }
5241
Michal Kazior6d2d51e2015-08-07 09:08:21 +02005242 spin_lock_bh(&ar->htt.tx_lock);
5243 if (!ar->tx_paused)
5244 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
5245 spin_unlock_bh(&ar->htt.tx_lock);
5246
Kalle Valo5e3dd152013-06-12 20:52:10 +03005247 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005248 return 0;
5249
5250err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00005251 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5252 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005253 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
5254
5255err_vdev_delete:
5256 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07005257 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305258 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005259 list_del(&arvif->list);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305260 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005261
5262err:
Michal Kazior64badcb2014-09-18 11:18:02 +03005263 if (arvif->beacon_buf) {
5264 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
5265 arvif->beacon_buf, arvif->beacon_paddr);
5266 arvif->beacon_buf = NULL;
5267 }
5268
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005269 mutex_unlock(&ar->conf_mutex);
5270
Kalle Valo5e3dd152013-06-12 20:52:10 +03005271 return ret;
5272}
5273
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005274static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
5275{
5276 int i;
5277
5278 for (i = 0; i < BITS_PER_LONG; i++)
5279 ath10k_mac_vif_tx_unlock(arvif, i);
5280}
5281
Kalle Valo5e3dd152013-06-12 20:52:10 +03005282static void ath10k_remove_interface(struct ieee80211_hw *hw,
5283 struct ieee80211_vif *vif)
5284{
5285 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005286 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior69427262016-03-06 16:14:30 +02005287 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005288 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005289 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005290
Michal Kazior81a9a172015-03-05 16:02:17 +02005291 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005292 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005293
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305294 mutex_lock(&ar->conf_mutex);
5295
Michal Kaziored543882013-09-13 14:16:56 +02005296 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03005297 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02005298 spin_unlock_bh(&ar->data_lock);
5299
Simon Wunderlich855aed12014-08-02 09:12:54 +03005300 ret = ath10k_spectral_vif_stop(arvif);
5301 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005302 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005303 arvif->vdev_id, ret);
5304
Ben Greear16c11172014-09-23 14:17:16 -07005305 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305306 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005307 list_del(&arvif->list);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305308 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005309
Michal Kaziore57e0572015-03-24 13:14:03 +00005310 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5311 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005312 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5313 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005314 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005315 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005316 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005317
5318 kfree(arvif->u.ap.noa_data);
5319 }
5320
Michal Kazior7aa7a722014-08-25 12:09:38 +02005321 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005322 arvif->vdev_id);
5323
Kalle Valo5e3dd152013-06-12 20:52:10 +03005324 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5325 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005326 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005327 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005328
Michal Kazior2c512052015-02-15 16:50:40 +02005329 /* Some firmware revisions don't notify host about self-peer removal
5330 * until after associated vdev is deleted.
5331 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005332 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5333 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005334 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5335 vif->addr);
5336 if (ret)
5337 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5338 arvif->vdev_id, ret);
5339
5340 spin_lock_bh(&ar->data_lock);
5341 ar->num_peers--;
5342 spin_unlock_bh(&ar->data_lock);
5343 }
5344
Michal Kazior69427262016-03-06 16:14:30 +02005345 spin_lock_bh(&ar->data_lock);
5346 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5347 peer = ar->peer_map[i];
5348 if (!peer)
5349 continue;
5350
5351 if (peer->vif == vif) {
5352 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5353 vif->addr, arvif->vdev_id);
5354 peer->vif = NULL;
5355 }
5356 }
5357 spin_unlock_bh(&ar->data_lock);
5358
Kalle Valo5e3dd152013-06-12 20:52:10 +03005359 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005360 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005361
Michal Kazior500ff9f2015-03-31 10:26:21 +00005362 if (vif->type == NL80211_IFTYPE_MONITOR) {
5363 ar->monitor_arvif = NULL;
5364 ret = ath10k_monitor_recalc(ar);
5365 if (ret)
5366 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5367 }
5368
Ryan Hsud679fa12016-12-22 14:31:46 -08005369 ret = ath10k_mac_txpower_recalc(ar);
5370 if (ret)
5371 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5372
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005373 spin_lock_bh(&ar->htt.tx_lock);
5374 ath10k_mac_vif_tx_unlock_all(arvif);
5375 spin_unlock_bh(&ar->htt.tx_lock);
5376
Michal Kazior29946872016-03-06 16:14:34 +02005377 ath10k_mac_txq_unref(ar, vif->txq);
5378
Kalle Valo5e3dd152013-06-12 20:52:10 +03005379 mutex_unlock(&ar->conf_mutex);
5380}
5381
5382/*
5383 * FIXME: Has to be verified.
5384 */
5385#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005386 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005387 FIF_CONTROL | \
5388 FIF_PSPOLL | \
5389 FIF_OTHER_BSS | \
5390 FIF_BCN_PRBRESP_PROMISC | \
5391 FIF_PROBE_REQ | \
5392 FIF_FCSFAIL)
5393
5394static void ath10k_configure_filter(struct ieee80211_hw *hw,
5395 unsigned int changed_flags,
5396 unsigned int *total_flags,
5397 u64 multicast)
5398{
5399 struct ath10k *ar = hw->priv;
5400 int ret;
5401
5402 mutex_lock(&ar->conf_mutex);
5403
5404 changed_flags &= SUPPORTED_FILTERS;
5405 *total_flags &= SUPPORTED_FILTERS;
5406 ar->filter_flags = *total_flags;
5407
Michal Kazior19337472014-08-28 12:58:16 +02005408 ret = ath10k_monitor_recalc(ar);
5409 if (ret)
Colin Ian King7f03d302016-08-26 19:08:52 +01005410 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005411
5412 mutex_unlock(&ar->conf_mutex);
5413}
5414
5415static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5416 struct ieee80211_vif *vif,
5417 struct ieee80211_bss_conf *info,
5418 u32 changed)
5419{
5420 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005421 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005422 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03005423 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005424
5425 mutex_lock(&ar->conf_mutex);
5426
5427 if (changed & BSS_CHANGED_IBSS)
5428 ath10k_control_ibss(arvif, info, vif->addr);
5429
5430 if (changed & BSS_CHANGED_BEACON_INT) {
5431 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005432 vdev_param = ar->wmi.vdev_param->beacon_interval;
5433 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005434 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005435 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005436 "mac vdev %d beacon_interval %d\n",
5437 arvif->vdev_id, arvif->beacon_interval);
5438
Kalle Valo5e3dd152013-06-12 20:52:10 +03005439 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005440 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005441 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005442 }
5443
5444 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005445 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005446 "vdev %d set beacon tx mode to staggered\n",
5447 arvif->vdev_id);
5448
Bartosz Markowski226a3392013-09-26 17:47:16 +02005449 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5450 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005451 WMI_BEACON_STAGGERED_MODE);
5452 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005453 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005454 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005455
5456 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5457 if (ret)
5458 ath10k_warn(ar, "failed to update beacon template: %d\n",
5459 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005460
5461 if (ieee80211_vif_is_mesh(vif)) {
5462 /* mesh doesn't use SSID but firmware needs it */
5463 strncpy(arvif->u.ap.ssid, "mesh",
5464 sizeof(arvif->u.ap.ssid));
5465 arvif->u.ap.ssid_len = 4;
5466 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005467 }
5468
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005469 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5470 ret = ath10k_mac_setup_prb_tmpl(arvif);
5471 if (ret)
5472 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5473 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005474 }
5475
Michal Kaziorba2479f2015-01-24 12:14:51 +02005476 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005477 arvif->dtim_period = info->dtim_period;
5478
Michal Kazior7aa7a722014-08-25 12:09:38 +02005479 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005480 "mac vdev %d dtim_period %d\n",
5481 arvif->vdev_id, arvif->dtim_period);
5482
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005483 vdev_param = ar->wmi.vdev_param->dtim_period;
5484 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005485 arvif->dtim_period);
5486 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005487 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005488 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005489 }
5490
5491 if (changed & BSS_CHANGED_SSID &&
5492 vif->type == NL80211_IFTYPE_AP) {
5493 arvif->u.ap.ssid_len = info->ssid_len;
5494 if (info->ssid_len)
5495 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5496 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5497 }
5498
Michal Kazior077efc82014-10-21 10:10:29 +03005499 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5500 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005501
5502 if (changed & BSS_CHANGED_BEACON_ENABLED)
5503 ath10k_control_beaconing(arvif, info);
5504
5505 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005506 arvif->use_cts_prot = info->use_cts_prot;
Kalle Valo60c3daa2013-09-08 17:56:07 +03005507
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005508 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005509 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005510 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005511 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005512
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02005513 if (ath10k_mac_can_set_cts_prot(arvif)) {
5514 ret = ath10k_mac_set_cts_prot(arvif);
5515 if (ret)
5516 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
5517 arvif->vdev_id, ret);
5518 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005519 }
5520
5521 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005522 if (info->use_short_slot)
5523 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5524
5525 else
5526 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5527
Michal Kazior7aa7a722014-08-25 12:09:38 +02005528 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005529 arvif->vdev_id, slottime);
5530
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005531 vdev_param = ar->wmi.vdev_param->slot_time;
5532 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005533 slottime);
5534 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005535 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005536 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005537 }
5538
5539 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005540 if (info->use_short_preamble)
5541 preamble = WMI_VDEV_PREAMBLE_SHORT;
5542 else
5543 preamble = WMI_VDEV_PREAMBLE_LONG;
5544
Michal Kazior7aa7a722014-08-25 12:09:38 +02005545 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005546 "mac vdev %d preamble %dn",
5547 arvif->vdev_id, preamble);
5548
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005549 vdev_param = ar->wmi.vdev_param->preamble;
5550 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005551 preamble);
5552 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005553 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005554 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005555 }
5556
5557 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005558 if (info->assoc) {
5559 /* Workaround: Make sure monitor vdev is not running
5560 * when associating to prevent some firmware revisions
5561 * (e.g. 10.1 and 10.2) from crashing.
5562 */
5563 if (ar->monitor_started)
5564 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005565 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005566 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005567 } else {
5568 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005569 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005570 }
5571
Michal Kazior7d9d5582014-10-21 10:40:15 +03005572 if (changed & BSS_CHANGED_TXPOWER) {
5573 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5574 arvif->vdev_id, info->txpower);
5575
5576 arvif->txpower = info->txpower;
5577 ret = ath10k_mac_txpower_recalc(ar);
5578 if (ret)
5579 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5580 }
5581
Michal Kaziorbf14e652014-12-12 12:41:38 +01005582 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005583 arvif->ps = vif->bss_conf.ps;
5584
5585 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005586 if (ret)
5587 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5588 arvif->vdev_id, ret);
5589 }
5590
Kalle Valo5e3dd152013-06-12 20:52:10 +03005591 mutex_unlock(&ar->conf_mutex);
5592}
5593
Benjamin Bergebee76f2016-09-28 15:11:58 +03005594static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, s16 value)
5595{
5596 struct ath10k *ar = hw->priv;
5597
5598 /* This function should never be called if setting the coverage class
5599 * is not supported on this hardware.
5600 */
5601 if (!ar->hw_params.hw_ops->set_coverage_class) {
5602 WARN_ON_ONCE(1);
5603 return;
5604 }
5605 ar->hw_params.hw_ops->set_coverage_class(ar, value);
5606}
5607
Anilkumar Kollidd0f9cd2017-10-27 11:12:27 +03005608struct ath10k_mac_tdls_iter_data {
5609 u32 num_tdls_stations;
5610 struct ieee80211_vif *curr_vif;
5611};
5612
5613static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5614 struct ieee80211_sta *sta)
5615{
5616 struct ath10k_mac_tdls_iter_data *iter_data = data;
5617 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5618 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5619
5620 if (sta->tdls && sta_vif == iter_data->curr_vif)
5621 iter_data->num_tdls_stations++;
5622}
5623
5624static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5625 struct ieee80211_vif *vif)
5626{
5627 struct ath10k_mac_tdls_iter_data data = {};
5628
5629 data.curr_vif = vif;
5630
5631 ieee80211_iterate_stations_atomic(hw,
5632 ath10k_mac_tdls_vif_stations_count_iter,
5633 &data);
5634 return data.num_tdls_stations;
5635}
5636
5637static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5638 struct ieee80211_vif *vif)
5639{
5640 struct ath10k_vif *arvif = (void *)vif->drv_priv;
5641 int *num_tdls_vifs = data;
5642
5643 if (vif->type != NL80211_IFTYPE_STATION)
5644 return;
5645
5646 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5647 (*num_tdls_vifs)++;
5648}
5649
5650static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5651{
5652 int num_tdls_vifs = 0;
5653
5654 ieee80211_iterate_active_interfaces_atomic(hw,
5655 IEEE80211_IFACE_ITER_NORMAL,
5656 ath10k_mac_tdls_vifs_count_iter,
5657 &num_tdls_vifs);
5658 return num_tdls_vifs;
5659}
5660
Kalle Valo5e3dd152013-06-12 20:52:10 +03005661static int ath10k_hw_scan(struct ieee80211_hw *hw,
5662 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005663 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005664{
5665 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005666 struct ath10k_vif *arvif = (void *)vif->drv_priv;
David Spinadelc56ef672014-02-05 15:21:13 +02005667 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005668 struct wmi_start_scan_arg arg;
5669 int ret = 0;
5670 int i;
5671
5672 mutex_lock(&ar->conf_mutex);
5673
Anilkumar Kollia6080932017-10-27 11:12:28 +03005674 if (ath10k_mac_tdls_vif_stations_count(hw, vif) > 0) {
5675 ret = -EBUSY;
5676 goto exit;
5677 }
5678
Kalle Valo5e3dd152013-06-12 20:52:10 +03005679 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005680 switch (ar->scan.state) {
5681 case ATH10K_SCAN_IDLE:
5682 reinit_completion(&ar->scan.started);
5683 reinit_completion(&ar->scan.completed);
5684 ar->scan.state = ATH10K_SCAN_STARTING;
5685 ar->scan.is_roc = false;
5686 ar->scan.vdev_id = arvif->vdev_id;
5687 ret = 0;
5688 break;
5689 case ATH10K_SCAN_STARTING:
5690 case ATH10K_SCAN_RUNNING:
5691 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005692 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005693 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005694 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005695 spin_unlock_bh(&ar->data_lock);
5696
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005697 if (ret)
5698 goto exit;
5699
Kalle Valo5e3dd152013-06-12 20:52:10 +03005700 memset(&arg, 0, sizeof(arg));
5701 ath10k_wmi_start_scan_init(ar, &arg);
5702 arg.vdev_id = arvif->vdev_id;
5703 arg.scan_id = ATH10K_SCAN_ID;
5704
Kalle Valo5e3dd152013-06-12 20:52:10 +03005705 if (req->ie_len) {
5706 arg.ie_len = req->ie_len;
5707 memcpy(arg.ie, req->ie, arg.ie_len);
5708 }
5709
5710 if (req->n_ssids) {
5711 arg.n_ssids = req->n_ssids;
5712 for (i = 0; i < arg.n_ssids; i++) {
5713 arg.ssids[i].len = req->ssids[i].ssid_len;
5714 arg.ssids[i].ssid = req->ssids[i].ssid;
5715 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005716 } else {
5717 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005718 }
5719
5720 if (req->n_channels) {
5721 arg.n_channels = req->n_channels;
5722 for (i = 0; i < arg.n_channels; i++)
5723 arg.channels[i] = req->channels[i]->center_freq;
5724 }
5725
5726 ret = ath10k_start_scan(ar, &arg);
5727 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005728 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005729 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005730 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005731 spin_unlock_bh(&ar->data_lock);
5732 }
5733
Michal Kazior634349b2015-09-03 10:43:45 +02005734 /* Add a 200ms margin to account for event/command processing */
5735 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5736 msecs_to_jiffies(arg.max_scan_time +
5737 200));
5738
Kalle Valo5e3dd152013-06-12 20:52:10 +03005739exit:
5740 mutex_unlock(&ar->conf_mutex);
5741 return ret;
5742}
5743
5744static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5745 struct ieee80211_vif *vif)
5746{
5747 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005748
5749 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005750 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005751 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01005752
5753 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005754}
5755
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005756static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
5757 struct ath10k_vif *arvif,
5758 enum set_key_cmd cmd,
5759 struct ieee80211_key_conf *key)
5760{
5761 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
5762 int ret;
5763
5764 /* 10.1 firmware branch requires default key index to be set to group
5765 * key index after installing it. Otherwise FW/HW Txes corrupted
5766 * frames with multi-vif APs. This is not required for main firmware
5767 * branch (e.g. 636).
5768 *
Michal Kazior8461baf2015-04-10 13:23:22 +00005769 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
5770 *
5771 * FIXME: It remains unknown if this is required for multi-vif STA
5772 * interfaces on 10.1.
5773 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005774
Michal Kazior8461baf2015-04-10 13:23:22 +00005775 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
5776 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005777 return;
5778
5779 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
5780 return;
5781
5782 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
5783 return;
5784
5785 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5786 return;
5787
5788 if (cmd != SET_KEY)
5789 return;
5790
5791 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5792 key->keyidx);
5793 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005794 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005795 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005796}
5797
Kalle Valo5e3dd152013-06-12 20:52:10 +03005798static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5799 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5800 struct ieee80211_key_conf *key)
5801{
5802 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005803 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005804 struct ath10k_peer *peer;
5805 const u8 *peer_addr;
5806 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5807 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5808 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005809 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005810 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005811 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005812
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005813 /* this one needs to be done in software */
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07005814 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
5815 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
5816 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 ||
5817 key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005818 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005819
David Liuccec9032015-07-24 20:25:32 +03005820 if (arvif->nohwcrypt)
5821 return 1;
5822
Kalle Valo5e3dd152013-06-12 20:52:10 +03005823 if (key->keyidx > WMI_MAX_KEY_INDEX)
5824 return -ENOSPC;
5825
5826 mutex_lock(&ar->conf_mutex);
5827
5828 if (sta)
5829 peer_addr = sta->addr;
5830 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5831 peer_addr = vif->bss_conf.bssid;
5832 else
5833 peer_addr = vif->addr;
5834
5835 key->hw_key_idx = key->keyidx;
5836
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005837 if (is_wep) {
5838 if (cmd == SET_KEY)
5839 arvif->wep_keys[key->keyidx] = key;
5840 else
5841 arvif->wep_keys[key->keyidx] = NULL;
5842 }
5843
Kalle Valo5e3dd152013-06-12 20:52:10 +03005844 /* the peer should not disappear in mid-way (unless FW goes awry) since
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01005845 * we already hold conf_mutex. we just make sure its there now.
5846 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03005847 spin_lock_bh(&ar->data_lock);
5848 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5849 spin_unlock_bh(&ar->data_lock);
5850
5851 if (!peer) {
5852 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005853 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005854 peer_addr);
5855 ret = -EOPNOTSUPP;
5856 goto exit;
5857 } else {
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01005858 /* if the peer doesn't exist there is no key to disable anymore */
Kalle Valo5e3dd152013-06-12 20:52:10 +03005859 goto exit;
5860 }
5861 }
5862
Michal Kazior7cc45732015-03-09 14:24:17 +01005863 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5864 flags |= WMI_KEY_PAIRWISE;
5865 else
5866 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005867
Kalle Valo5e3dd152013-06-12 20:52:10 +03005868 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005869 if (cmd == DISABLE_KEY)
5870 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005871
Michal Kaziorad325cb2015-02-18 14:02:27 +01005872 /* When WEP keys are uploaded it's possible that there are
5873 * stations associated already (e.g. when merging) without any
5874 * keys. Static WEP needs an explicit per-peer key upload.
5875 */
5876 if (vif->type == NL80211_IFTYPE_ADHOC &&
5877 cmd == SET_KEY)
5878 ath10k_mac_vif_update_wep_key(arvif, key);
5879
Michal Kazior370e5672015-02-18 14:02:26 +01005880 /* 802.1x never sets the def_wep_key_idx so each set_key()
5881 * call changes default tx key.
5882 *
5883 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5884 * after first set_key().
5885 */
5886 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5887 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005888 }
5889
Michal Kazior370e5672015-02-18 14:02:26 +01005890 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005891 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005892 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005893 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005894 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005895 goto exit;
5896 }
5897
Michal Kazior29a10002015-04-10 13:05:58 +00005898 /* mac80211 sets static WEP keys as groupwise while firmware requires
5899 * them to be installed twice as both pairwise and groupwise.
5900 */
5901 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5902 flags2 = flags;
5903 flags2 &= ~WMI_KEY_GROUP;
5904 flags2 |= WMI_KEY_PAIRWISE;
5905
5906 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5907 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005908 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005909 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5910 arvif->vdev_id, peer_addr, ret);
5911 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5912 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005913 if (ret2) {
5914 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005915 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5916 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005917 }
Michal Kazior29a10002015-04-10 13:05:58 +00005918 goto exit;
5919 }
5920 }
5921
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005922 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5923
Kalle Valo5e3dd152013-06-12 20:52:10 +03005924 spin_lock_bh(&ar->data_lock);
5925 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5926 if (peer && cmd == SET_KEY)
5927 peer->keys[key->keyidx] = key;
5928 else if (peer && cmd == DISABLE_KEY)
5929 peer->keys[key->keyidx] = NULL;
5930 else if (peer == NULL)
5931 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005932 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005933 spin_unlock_bh(&ar->data_lock);
5934
5935exit:
5936 mutex_unlock(&ar->conf_mutex);
5937 return ret;
5938}
5939
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005940static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5941 struct ieee80211_vif *vif,
5942 int keyidx)
5943{
5944 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02005945 struct ath10k_vif *arvif = (void *)vif->drv_priv;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005946 int ret;
5947
5948 mutex_lock(&arvif->ar->conf_mutex);
5949
5950 if (arvif->ar->state != ATH10K_STATE_ON)
5951 goto unlock;
5952
5953 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5954 arvif->vdev_id, keyidx);
5955
5956 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5957 arvif->vdev_id,
5958 arvif->ar->wmi.vdev_param->def_keyid,
5959 keyidx);
5960
5961 if (ret) {
5962 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5963 arvif->vdev_id,
5964 ret);
5965 goto unlock;
5966 }
5967
5968 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005969
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005970unlock:
5971 mutex_unlock(&arvif->ar->conf_mutex);
5972}
5973
Michal Kazior9797feb2014-02-14 14:49:48 +01005974static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5975{
5976 struct ath10k *ar;
5977 struct ath10k_vif *arvif;
5978 struct ath10k_sta *arsta;
5979 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005980 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02005981 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005982 const u8 *ht_mcs_mask;
5983 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005984 u32 changed, bw, nss, smps;
5985 int err;
5986
5987 arsta = container_of(wk, struct ath10k_sta, update_wk);
5988 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5989 arvif = arsta->arvif;
5990 ar = arvif->ar;
5991
Michal Kazior45c9abc2015-04-21 20:42:58 +03005992 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5993 return;
5994
5995 band = def.chan->band;
5996 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5997 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5998
Michal Kazior9797feb2014-02-14 14:49:48 +01005999 spin_lock_bh(&ar->data_lock);
6000
6001 changed = arsta->changed;
6002 arsta->changed = 0;
6003
6004 bw = arsta->bw;
6005 nss = arsta->nss;
6006 smps = arsta->smps;
6007
6008 spin_unlock_bh(&ar->data_lock);
6009
6010 mutex_lock(&ar->conf_mutex);
6011
Michal Kazior45c9abc2015-04-21 20:42:58 +03006012 nss = max_t(u32, 1, nss);
6013 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6014 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6015
Michal Kazior9797feb2014-02-14 14:49:48 +01006016 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006017 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006018 sta->addr, bw);
6019
6020 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
6021 WMI_PEER_CHAN_WIDTH, bw);
6022 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006023 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006024 sta->addr, bw, err);
6025 }
6026
6027 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006028 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006029 sta->addr, nss);
6030
6031 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
6032 WMI_PEER_NSS, nss);
6033 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006034 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006035 sta->addr, nss, err);
6036 }
6037
6038 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006039 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006040 sta->addr, smps);
6041
6042 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
6043 WMI_PEER_SMPS_STATE, smps);
6044 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006045 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01006046 sta->addr, smps, err);
6047 }
6048
Karthikeyan Periyasamy55cc11d2018-03-27 11:25:29 +03006049 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
6050 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006051 sta->addr);
6052
Michal Kazior590922a2014-10-21 10:10:29 +03006053 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006054 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006055 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02006056 sta->addr);
6057 }
6058
Michal Kazior9797feb2014-02-14 14:49:48 +01006059 mutex_unlock(&ar->conf_mutex);
6060}
6061
Marek Puzyniak7c354242015-03-30 09:51:52 +03006062static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
6063 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006064{
6065 struct ath10k *ar = arvif->ar;
6066
6067 lockdep_assert_held(&ar->conf_mutex);
6068
Marek Puzyniak7c354242015-03-30 09:51:52 +03006069 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006070 return 0;
6071
6072 if (ar->num_stations >= ar->max_num_stations)
6073 return -ENOBUFS;
6074
6075 ar->num_stations++;
6076
6077 return 0;
6078}
6079
Marek Puzyniak7c354242015-03-30 09:51:52 +03006080static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
6081 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006082{
6083 struct ath10k *ar = arvif->ar;
6084
6085 lockdep_assert_held(&ar->conf_mutex);
6086
Marek Puzyniak7c354242015-03-30 09:51:52 +03006087 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01006088 return;
6089
6090 ar->num_stations--;
6091}
6092
Kalle Valo5e3dd152013-06-12 20:52:10 +03006093static int ath10k_sta_state(struct ieee80211_hw *hw,
6094 struct ieee80211_vif *vif,
6095 struct ieee80211_sta *sta,
6096 enum ieee80211_sta_state old_state,
6097 enum ieee80211_sta_state new_state)
6098{
6099 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006100 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior9797feb2014-02-14 14:49:48 +01006101 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006102 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006103 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02006104 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006105
Michal Kazior76f90022014-02-25 09:29:57 +02006106 if (old_state == IEEE80211_STA_NOTEXIST &&
6107 new_state == IEEE80211_STA_NONE) {
6108 memset(arsta, 0, sizeof(*arsta));
6109 arsta->arvif = arvif;
6110 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02006111
6112 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6113 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02006114 }
6115
Michal Kazior9797feb2014-02-14 14:49:48 +01006116 /* cancel must be done outside the mutex to avoid deadlock */
6117 if ((old_state == IEEE80211_STA_NONE &&
6118 new_state == IEEE80211_STA_NOTEXIST))
6119 cancel_work_sync(&arsta->update_wk);
6120
Kalle Valo5e3dd152013-06-12 20:52:10 +03006121 mutex_lock(&ar->conf_mutex);
6122
6123 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03006124 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006125 /*
6126 * New station addition.
6127 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006128 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
6129 u32 num_tdls_stations;
6130 u32 num_tdls_vifs;
6131
Michal Kaziorcfd10612014-11-25 15:16:05 +01006132 ath10k_dbg(ar, ATH10K_DBG_MAC,
6133 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
6134 arvif->vdev_id, sta->addr,
6135 ar->num_stations + 1, ar->max_num_stations,
6136 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006137
Ryan Hsu9a993cc2017-05-31 14:21:28 +03006138 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
6139 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
6140
6141 if (sta->tdls) {
6142 if (num_tdls_stations >= ar->max_num_tdls_vdevs) {
6143 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
6144 arvif->vdev_id,
6145 ar->max_num_tdls_vdevs);
6146 ret = -ELNRNG;
6147 goto exit;
6148 }
6149 peer_type = WMI_PEER_TYPE_TDLS;
6150 }
6151
Marek Puzyniak7c354242015-03-30 09:51:52 +03006152 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01006153 if (ret) {
6154 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
6155 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006156 goto exit;
6157 }
6158
Michal Kazior69427262016-03-06 16:14:30 +02006159 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
6160 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01006161 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006162 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 -08006163 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03006164 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01006165 goto exit;
6166 }
Michal Kazior077efc82014-10-21 10:10:29 +03006167
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006168 spin_lock_bh(&ar->data_lock);
6169
6170 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
6171 if (!peer) {
6172 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
6173 vif->addr, arvif->vdev_id);
6174 spin_unlock_bh(&ar->data_lock);
6175 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6176 ath10k_mac_dec_num_stations(arvif, sta);
6177 ret = -ENOENT;
6178 goto exit;
6179 }
6180
6181 arsta->peer_id = find_first_bit(peer->peer_ids,
6182 ATH10K_MAX_NUM_PEER_IDS);
6183
6184 spin_unlock_bh(&ar->data_lock);
6185
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006186 if (!sta->tdls)
6187 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03006188
Ryan Hsu9a993cc2017-05-31 14:21:28 +03006189 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6190 WMI_TDLS_ENABLE_ACTIVE);
6191 if (ret) {
6192 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6193 arvif->vdev_id, ret);
6194 ath10k_peer_delete(ar, arvif->vdev_id,
6195 sta->addr);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006196 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006197 goto exit;
6198 }
6199
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006200 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6201 WMI_TDLS_PEER_STATE_PEERING);
6202 if (ret) {
6203 ath10k_warn(ar,
6204 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
6205 sta->addr, arvif->vdev_id, ret);
6206 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6207 ath10k_mac_dec_num_stations(arvif, sta);
6208
6209 if (num_tdls_stations != 0)
6210 goto exit;
6211 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6212 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03006213 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006214 } else if ((old_state == IEEE80211_STA_NONE &&
6215 new_state == IEEE80211_STA_NOTEXIST)) {
6216 /*
6217 * Existing station deletion.
6218 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006219 ath10k_dbg(ar, ATH10K_DBG_MAC,
Ben Greear30404202016-08-18 18:26:35 -07006220 "mac vdev %d peer delete %pM sta %pK (sta gone)\n",
6221 arvif->vdev_id, sta->addr, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006222
Manikanta Pubbisetty424ea0d2017-11-06 13:39:31 +05306223 if (sta->tdls) {
6224 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id,
6225 sta,
6226 WMI_TDLS_PEER_STATE_TEARDOWN);
6227 if (ret)
6228 ath10k_warn(ar, "failed to update tdls peer state for %pM state %d: %i\n",
6229 sta->addr,
6230 WMI_TDLS_PEER_STATE_TEARDOWN, ret);
6231 }
6232
Kalle Valo5e3dd152013-06-12 20:52:10 +03006233 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6234 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006235 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006236 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006237
Marek Puzyniak7c354242015-03-30 09:51:52 +03006238 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006239
Michal Kazior69427262016-03-06 16:14:30 +02006240 spin_lock_bh(&ar->data_lock);
6241 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
6242 peer = ar->peer_map[i];
6243 if (!peer)
6244 continue;
6245
6246 if (peer->sta == sta) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05306247 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 +03006248 sta->addr, peer, i, arvif->vdev_id);
Michal Kazior69427262016-03-06 16:14:30 +02006249 peer->sta = NULL;
Ben Greeard0eeafa2016-06-30 15:23:59 +03006250
6251 /* Clean up the peer object as well since we
6252 * must have failed to do this above.
6253 */
6254 list_del(&peer->list);
6255 ar->peer_map[i] = NULL;
6256 kfree(peer);
6257 ar->num_peers--;
Michal Kazior69427262016-03-06 16:14:30 +02006258 }
6259 }
6260 spin_unlock_bh(&ar->data_lock);
6261
Michal Kazior29946872016-03-06 16:14:34 +02006262 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6263 ath10k_mac_txq_unref(ar, sta->txq[i]);
6264
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006265 if (!sta->tdls)
6266 goto exit;
6267
6268 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
6269 goto exit;
6270
6271 /* This was the last tdls peer in current vif */
6272 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6273 WMI_TDLS_DISABLE);
6274 if (ret) {
6275 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6276 arvif->vdev_id, ret);
6277 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006278 } else if (old_state == IEEE80211_STA_AUTH &&
6279 new_state == IEEE80211_STA_ASSOC &&
6280 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006281 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03006282 vif->type == NL80211_IFTYPE_ADHOC)) {
6283 /*
6284 * New association.
6285 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006286 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006287 sta->addr);
6288
Michal Kazior590922a2014-10-21 10:10:29 +03006289 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006290 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006291 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006292 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006293 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006294 new_state == IEEE80211_STA_AUTHORIZED &&
6295 sta->tdls) {
6296 /*
6297 * Tdls station authorized.
6298 */
6299 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
6300 sta->addr);
6301
6302 ret = ath10k_station_assoc(ar, vif, sta, false);
6303 if (ret) {
6304 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
6305 sta->addr, arvif->vdev_id, ret);
6306 goto exit;
6307 }
6308
6309 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6310 WMI_TDLS_PEER_STATE_CONNECTED);
6311 if (ret)
6312 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
6313 sta->addr, arvif->vdev_id, ret);
6314 } else if (old_state == IEEE80211_STA_ASSOC &&
6315 new_state == IEEE80211_STA_AUTH &&
6316 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006317 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006318 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006319 /*
6320 * Disassociation.
6321 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006322 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006323 sta->addr);
6324
Michal Kazior590922a2014-10-21 10:10:29 +03006325 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006326 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006327 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006328 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006329 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006330exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006331 mutex_unlock(&ar->conf_mutex);
6332 return ret;
6333}
6334
6335static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006336 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006337{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006338 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006339 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6340 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006341 u32 value = 0;
6342 int ret = 0;
6343
Michal Kazior548db542013-07-05 16:15:15 +03006344 lockdep_assert_held(&ar->conf_mutex);
6345
Kalle Valo5e3dd152013-06-12 20:52:10 +03006346 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6347 return 0;
6348
6349 switch (ac) {
6350 case IEEE80211_AC_VO:
6351 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6352 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006353 prio = 7;
6354 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006355 break;
6356 case IEEE80211_AC_VI:
6357 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6358 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006359 prio = 5;
6360 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006361 break;
6362 case IEEE80211_AC_BE:
6363 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6364 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006365 prio = 2;
6366 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006367 break;
6368 case IEEE80211_AC_BK:
6369 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6370 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006371 prio = 0;
6372 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006373 break;
6374 }
6375
6376 if (enable)
6377 arvif->u.sta.uapsd |= value;
6378 else
6379 arvif->u.sta.uapsd &= ~value;
6380
6381 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6382 WMI_STA_PS_PARAM_UAPSD,
6383 arvif->u.sta.uapsd);
6384 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006385 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006386 goto exit;
6387 }
6388
6389 if (arvif->u.sta.uapsd)
6390 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6391 else
6392 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6393
6394 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6395 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6396 value);
6397 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006398 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006399
Michal Kazior9f9b5742014-12-12 12:41:36 +01006400 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6401 if (ret) {
6402 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6403 arvif->vdev_id, ret);
6404 return ret;
6405 }
6406
6407 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6408 if (ret) {
6409 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6410 arvif->vdev_id, ret);
6411 return ret;
6412 }
6413
Michal Kaziorb0e56152015-01-24 12:14:52 +02006414 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6415 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6416 /* Only userspace can make an educated decision when to send
6417 * trigger frame. The following effectively disables u-UAPSD
6418 * autotrigger in firmware (which is enabled by default
6419 * provided the autotrigger service is available).
6420 */
6421
6422 arg.wmm_ac = acc;
6423 arg.user_priority = prio;
6424 arg.service_interval = 0;
6425 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6426 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6427
6428 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6429 arvif->bssid, &arg, 1);
6430 if (ret) {
6431 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6432 ret);
6433 return ret;
6434 }
6435 }
6436
Kalle Valo5e3dd152013-06-12 20:52:10 +03006437exit:
6438 return ret;
6439}
6440
6441static int ath10k_conf_tx(struct ieee80211_hw *hw,
6442 struct ieee80211_vif *vif, u16 ac,
6443 const struct ieee80211_tx_queue_params *params)
6444{
6445 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006446 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006447 struct wmi_wmm_params_arg *p = NULL;
6448 int ret;
6449
6450 mutex_lock(&ar->conf_mutex);
6451
6452 switch (ac) {
6453 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006454 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006455 break;
6456 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006457 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006458 break;
6459 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006460 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006461 break;
6462 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006463 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006464 break;
6465 }
6466
6467 if (WARN_ON(!p)) {
6468 ret = -EINVAL;
6469 goto exit;
6470 }
6471
6472 p->cwmin = params->cw_min;
6473 p->cwmax = params->cw_max;
6474 p->aifs = params->aifs;
6475
6476 /*
6477 * The channel time duration programmed in the HW is in absolute
6478 * microseconds, while mac80211 gives the txop in units of
6479 * 32 microseconds.
6480 */
6481 p->txop = params->txop * 32;
6482
Michal Kazior7fc979a2015-01-28 09:57:28 +02006483 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6484 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6485 &arvif->wmm_params);
6486 if (ret) {
6487 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6488 arvif->vdev_id, ret);
6489 goto exit;
6490 }
6491 } else {
6492 /* This won't work well with multi-interface cases but it's
6493 * better than nothing.
6494 */
6495 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6496 if (ret) {
6497 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6498 goto exit;
6499 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006500 }
6501
6502 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6503 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006504 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006505
6506exit:
6507 mutex_unlock(&ar->conf_mutex);
6508 return ret;
6509}
6510
Kalle Valo14e105c2016-04-13 14:13:21 +03006511#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006512
6513static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6514 struct ieee80211_vif *vif,
6515 struct ieee80211_channel *chan,
6516 int duration,
6517 enum ieee80211_roc_type type)
6518{
6519 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02006520 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006521 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006522 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006523 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006524
6525 mutex_lock(&ar->conf_mutex);
6526
Anilkumar Kollia6080932017-10-27 11:12:28 +03006527 if (ath10k_mac_tdls_vif_stations_count(hw, vif) > 0) {
6528 ret = -EBUSY;
6529 goto exit;
6530 }
6531
Kalle Valo5e3dd152013-06-12 20:52:10 +03006532 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006533 switch (ar->scan.state) {
6534 case ATH10K_SCAN_IDLE:
6535 reinit_completion(&ar->scan.started);
6536 reinit_completion(&ar->scan.completed);
6537 reinit_completion(&ar->scan.on_channel);
6538 ar->scan.state = ATH10K_SCAN_STARTING;
6539 ar->scan.is_roc = true;
6540 ar->scan.vdev_id = arvif->vdev_id;
6541 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006542 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006543 ret = 0;
6544 break;
6545 case ATH10K_SCAN_STARTING:
6546 case ATH10K_SCAN_RUNNING:
6547 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006548 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006549 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006550 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006551 spin_unlock_bh(&ar->data_lock);
6552
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006553 if (ret)
6554 goto exit;
6555
Michal Kaziorfcf98442015-03-31 11:03:47 +00006556 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006557
Kalle Valo5e3dd152013-06-12 20:52:10 +03006558 memset(&arg, 0, sizeof(arg));
6559 ath10k_wmi_start_scan_init(ar, &arg);
6560 arg.vdev_id = arvif->vdev_id;
6561 arg.scan_id = ATH10K_SCAN_ID;
6562 arg.n_channels = 1;
6563 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006564 arg.dwell_time_active = scan_time_msec;
6565 arg.dwell_time_passive = scan_time_msec;
6566 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006567 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6568 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006569 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006570
6571 ret = ath10k_start_scan(ar, &arg);
6572 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006573 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006574 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006575 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006576 spin_unlock_bh(&ar->data_lock);
6577 goto exit;
6578 }
6579
Kalle Valo14e105c2016-04-13 14:13:21 +03006580 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006581 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006582 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006583
6584 ret = ath10k_scan_stop(ar);
6585 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006586 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006587
Kalle Valo5e3dd152013-06-12 20:52:10 +03006588 ret = -ETIMEDOUT;
6589 goto exit;
6590 }
6591
Michal Kaziorfcf98442015-03-31 11:03:47 +00006592 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6593 msecs_to_jiffies(duration));
6594
Kalle Valo5e3dd152013-06-12 20:52:10 +03006595 ret = 0;
6596exit:
6597 mutex_unlock(&ar->conf_mutex);
6598 return ret;
6599}
6600
6601static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6602{
6603 struct ath10k *ar = hw->priv;
6604
6605 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006606
6607 spin_lock_bh(&ar->data_lock);
6608 ar->scan.roc_notify = false;
6609 spin_unlock_bh(&ar->data_lock);
6610
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006611 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006612
Kalle Valo5e3dd152013-06-12 20:52:10 +03006613 mutex_unlock(&ar->conf_mutex);
6614
Michal Kazior4eb2e162014-10-28 10:23:09 +01006615 cancel_delayed_work_sync(&ar->scan.timeout);
6616
Kalle Valo5e3dd152013-06-12 20:52:10 +03006617 return 0;
6618}
6619
6620/*
6621 * Both RTS and Fragmentation threshold are interface-specific
6622 * in ath10k, but device-specific in mac80211.
6623 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006624
6625static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6626{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006627 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006628 struct ath10k_vif *arvif;
6629 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006630
Michal Kaziorad088bf2013-10-16 15:44:46 +03006631 mutex_lock(&ar->conf_mutex);
6632 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006633 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006634 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006635
Michal Kaziorad088bf2013-10-16 15:44:46 +03006636 ret = ath10k_mac_set_rts(arvif, value);
6637 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006638 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006639 arvif->vdev_id, ret);
6640 break;
6641 }
6642 }
6643 mutex_unlock(&ar->conf_mutex);
6644
6645 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006646}
6647
Michal Kazior92092fe2015-08-03 11:16:43 +02006648static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6649{
6650 /* Even though there's a WMI enum for fragmentation threshold no known
6651 * firmware actually implements it. Moreover it is not possible to rely
6652 * frame fragmentation to mac80211 because firmware clears the "more
6653 * fragments" bit in frame control making it impossible for remote
6654 * devices to reassemble frames.
6655 *
6656 * Hence implement a dummy callback just to say fragmentation isn't
6657 * supported. This effectively prevents mac80211 from doing frame
6658 * fragmentation in software.
6659 */
6660 return -EOPNOTSUPP;
6661}
6662
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02006663static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6664 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006665{
6666 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02006667 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006668 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006669
6670 /* mac80211 doesn't care if we really xmit queued frames or not
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01006671 * we'll collect those frames either way if we stop/delete vdevs
6672 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006673 if (drop)
6674 return;
6675
Michal Kazior548db542013-07-05 16:15:15 +03006676 mutex_lock(&ar->conf_mutex);
6677
Michal Kazioraffd3212013-07-16 09:54:35 +02006678 if (ar->state == ATH10K_STATE_WEDGED)
6679 goto skip;
6680
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006681 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006682 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006683
Michal Kazioredb82362013-07-05 16:15:14 +03006684 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006685 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006686 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006687
Michal Kazior7962b0d2014-10-28 10:34:38 +01006688 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6689 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6690 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006691
6692 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006693 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006694
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006695 if (time_left == 0 || skip)
6696 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6697 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03006698
Michal Kazioraffd3212013-07-16 09:54:35 +02006699skip:
Michal Kazior548db542013-07-05 16:15:15 +03006700 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006701}
6702
6703/* TODO: Implement this function properly
6704 * For now it is needed to reply to Probe Requests in IBSS mode.
6705 * Propably we need this information from FW.
6706 */
6707static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
6708{
6709 return 1;
6710}
6711
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006712static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
6713 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02006714{
6715 struct ath10k *ar = hw->priv;
6716
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006717 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
6718 return;
6719
Michal Kazioraffd3212013-07-16 09:54:35 +02006720 mutex_lock(&ar->conf_mutex);
6721
6722 /* If device failed to restart it will be in a different state, e.g.
Marcin Rokickid6dfe25c2017-02-20 14:39:57 +01006723 * ATH10K_STATE_WEDGED
6724 */
Michal Kazioraffd3212013-07-16 09:54:35 +02006725 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006726 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02006727 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01006728 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02006729 }
6730
6731 mutex_unlock(&ar->conf_mutex);
6732}
6733
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306734static void
6735ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
6736 struct ieee80211_channel *channel)
6737{
6738 int ret;
6739 enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
6740
6741 lockdep_assert_held(&ar->conf_mutex);
6742
6743 if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
6744 (ar->rx_channel != channel))
6745 return;
6746
6747 if (ar->scan.state != ATH10K_SCAN_IDLE) {
6748 ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
6749 return;
6750 }
6751
6752 reinit_completion(&ar->bss_survey_done);
6753
6754 ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
6755 if (ret) {
6756 ath10k_warn(ar, "failed to send pdev bss chan info request\n");
6757 return;
6758 }
6759
6760 ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
6761 if (!ret) {
6762 ath10k_warn(ar, "bss channel survey timed out\n");
6763 return;
6764 }
6765}
6766
Michal Kazior2e1dea42013-07-31 10:32:40 +02006767static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
6768 struct survey_info *survey)
6769{
6770 struct ath10k *ar = hw->priv;
6771 struct ieee80211_supported_band *sband;
6772 struct survey_info *ar_survey = &ar->survey[idx];
6773 int ret = 0;
6774
6775 mutex_lock(&ar->conf_mutex);
6776
Johannes Berg57fbcce2016-04-12 15:56:15 +02006777 sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006778 if (sband && idx >= sband->n_channels) {
6779 idx -= sband->n_channels;
6780 sband = NULL;
6781 }
6782
6783 if (!sband)
Johannes Berg57fbcce2016-04-12 15:56:15 +02006784 sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006785
6786 if (!sband || idx >= sband->n_channels) {
6787 ret = -ENOENT;
6788 goto exit;
6789 }
6790
Ashok Raj Nagarajan77eb3d62016-09-02 10:59:53 +05306791 ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306792
Michal Kazior2e1dea42013-07-31 10:32:40 +02006793 spin_lock_bh(&ar->data_lock);
6794 memcpy(survey, ar_survey, sizeof(*survey));
6795 spin_unlock_bh(&ar->data_lock);
6796
6797 survey->channel = &sband->channels[idx];
6798
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03006799 if (ar->rx_channel == survey->channel)
6800 survey->filled |= SURVEY_INFO_IN_USE;
6801
Michal Kazior2e1dea42013-07-31 10:32:40 +02006802exit:
6803 mutex_unlock(&ar->conf_mutex);
6804 return ret;
6805}
6806
Michal Kazior3ae54222015-03-31 10:49:20 +00006807static bool
6808ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006809 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006810 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006811{
Michal Kazior3ae54222015-03-31 10:49:20 +00006812 int num_rates = 0;
6813 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006814
Michal Kazior3ae54222015-03-31 10:49:20 +00006815 num_rates += hweight32(mask->control[band].legacy);
6816
6817 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
6818 num_rates += hweight8(mask->control[band].ht_mcs[i]);
6819
6820 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
6821 num_rates += hweight16(mask->control[band].vht_mcs[i]);
6822
6823 return num_rates == 1;
6824}
6825
6826static bool
6827ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006828 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006829 const struct cfg80211_bitrate_mask *mask,
6830 int *nss)
6831{
6832 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6833 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6834 u8 ht_nss_mask = 0;
6835 u8 vht_nss_mask = 0;
6836 int i;
6837
6838 if (mask->control[band].legacy)
6839 return false;
6840
6841 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6842 if (mask->control[band].ht_mcs[i] == 0)
6843 continue;
6844 else if (mask->control[band].ht_mcs[i] ==
6845 sband->ht_cap.mcs.rx_mask[i])
6846 ht_nss_mask |= BIT(i);
6847 else
6848 return false;
6849 }
6850
6851 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6852 if (mask->control[band].vht_mcs[i] == 0)
6853 continue;
6854 else if (mask->control[band].vht_mcs[i] ==
6855 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6856 vht_nss_mask |= BIT(i);
6857 else
6858 return false;
6859 }
6860
6861 if (ht_nss_mask != vht_nss_mask)
6862 return false;
6863
6864 if (ht_nss_mask == 0)
6865 return false;
6866
6867 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6868 return false;
6869
6870 *nss = fls(ht_nss_mask);
6871
6872 return true;
6873}
6874
6875static int
6876ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006877 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006878 const struct cfg80211_bitrate_mask *mask,
6879 u8 *rate, u8 *nss)
6880{
6881 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6882 int rate_idx;
6883 int i;
6884 u16 bitrate;
6885 u8 preamble;
6886 u8 hw_rate;
6887
6888 if (hweight32(mask->control[band].legacy) == 1) {
6889 rate_idx = ffs(mask->control[band].legacy) - 1;
6890
6891 hw_rate = sband->bitrates[rate_idx].hw_value;
6892 bitrate = sband->bitrates[rate_idx].bitrate;
6893
6894 if (ath10k_mac_bitrate_is_cck(bitrate))
6895 preamble = WMI_RATE_PREAMBLE_CCK;
6896 else
6897 preamble = WMI_RATE_PREAMBLE_OFDM;
6898
6899 *nss = 1;
6900 *rate = preamble << 6 |
6901 (*nss - 1) << 4 |
6902 hw_rate << 0;
6903
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006904 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006905 }
6906
Michal Kazior3ae54222015-03-31 10:49:20 +00006907 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6908 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6909 *nss = i + 1;
6910 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6911 (*nss - 1) << 4 |
6912 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006913
Michal Kazior3ae54222015-03-31 10:49:20 +00006914 return 0;
6915 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006916 }
6917
Michal Kazior3ae54222015-03-31 10:49:20 +00006918 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6919 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6920 *nss = i + 1;
6921 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6922 (*nss - 1) << 4 |
6923 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006924
Michal Kazior3ae54222015-03-31 10:49:20 +00006925 return 0;
6926 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006927 }
6928
Michal Kazior3ae54222015-03-31 10:49:20 +00006929 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006930}
6931
Michal Kazior3ae54222015-03-31 10:49:20 +00006932static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306933 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006934{
6935 struct ath10k *ar = arvif->ar;
6936 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006937 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006938
Michal Kazior3ae54222015-03-31 10:49:20 +00006939 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006940
Michal Kazior3ae54222015-03-31 10:49:20 +00006941 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6942 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006943
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006944 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006945 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006946 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006947 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006948 rate, ret);
6949 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006950 }
6951
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006952 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006953 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006954 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006955 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6956 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006957 }
6958
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006959 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006960 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006961 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006962 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6963 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006964 }
6965
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306966 vdev_param = ar->wmi.vdev_param->ldpc;
6967 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6968 if (ret) {
6969 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6970 return ret;
6971 }
6972
Michal Kazior3ae54222015-03-31 10:49:20 +00006973 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006974}
6975
Michal Kazior45c9abc2015-04-21 20:42:58 +03006976static bool
6977ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006978 enum nl80211_band band,
Michal Kazior45c9abc2015-04-21 20:42:58 +03006979 const struct cfg80211_bitrate_mask *mask)
6980{
6981 int i;
6982 u16 vht_mcs;
6983
6984 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6985 * to express all VHT MCS rate masks. Effectively only the following
6986 * ranges can be used: none, 0-7, 0-8 and 0-9.
6987 */
6988 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6989 vht_mcs = mask->control[band].vht_mcs[i];
6990
6991 switch (vht_mcs) {
6992 case 0:
6993 case BIT(8) - 1:
6994 case BIT(9) - 1:
6995 case BIT(10) - 1:
6996 break;
6997 default:
6998 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6999 return false;
7000 }
7001 }
7002
7003 return true;
7004}
7005
7006static void ath10k_mac_set_bitrate_mask_iter(void *data,
7007 struct ieee80211_sta *sta)
7008{
7009 struct ath10k_vif *arvif = data;
7010 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
7011 struct ath10k *ar = arvif->ar;
7012
7013 if (arsta->arvif != arvif)
7014 return;
7015
7016 spin_lock_bh(&ar->data_lock);
7017 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
7018 spin_unlock_bh(&ar->data_lock);
7019
7020 ieee80211_queue_work(ar->hw, &arsta->update_wk);
7021}
7022
Michal Kazior3ae54222015-03-31 10:49:20 +00007023static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
7024 struct ieee80211_vif *vif,
7025 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007026{
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007027 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007028 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007029 struct ath10k *ar = arvif->ar;
Johannes Berg57fbcce2016-04-12 15:56:15 +02007030 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007031 const u8 *ht_mcs_mask;
7032 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00007033 u8 rate;
7034 u8 nss;
7035 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307036 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00007037 int single_nss;
7038 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007039
Michal Kazior500ff9f2015-03-31 10:26:21 +00007040 if (ath10k_mac_vif_chan(vif, &def))
7041 return -EPERM;
7042
Michal Kazior500ff9f2015-03-31 10:26:21 +00007043 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007044 ht_mcs_mask = mask->control[band].ht_mcs;
7045 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307046 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007047
Michal Kazior3ae54222015-03-31 10:49:20 +00007048 sgi = mask->control[band].gi;
7049 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01007050 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007051
Michal Kazior3ae54222015-03-31 10:49:20 +00007052 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
7053 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
7054 &rate, &nss);
7055 if (ret) {
7056 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
7057 arvif->vdev_id, ret);
7058 return ret;
7059 }
7060 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
7061 &single_nss)) {
7062 rate = WMI_FIXED_RATE_NONE;
7063 nss = single_nss;
7064 } else {
7065 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03007066 nss = min(ar->num_rf_chains,
7067 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
7068 ath10k_mac_max_vht_nss(vht_mcs_mask)));
7069
7070 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
7071 return -EINVAL;
7072
7073 mutex_lock(&ar->conf_mutex);
7074
7075 arvif->bitrate_mask = *mask;
7076 ieee80211_iterate_stations_atomic(ar->hw,
7077 ath10k_mac_set_bitrate_mask_iter,
7078 arvif);
7079
7080 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007081 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007082
7083 mutex_lock(&ar->conf_mutex);
7084
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05307085 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007086 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00007087 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
7088 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007089 goto exit;
7090 }
7091
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007092exit:
7093 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00007094
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01007095 return ret;
7096}
7097
Michal Kazior9797feb2014-02-14 14:49:48 +01007098static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
7099 struct ieee80211_vif *vif,
7100 struct ieee80211_sta *sta,
7101 u32 changed)
7102{
7103 struct ath10k *ar = hw->priv;
7104 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Karthikeyan Periyasamy8b2d93d2018-03-12 17:09:40 +05307105 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7106 struct ath10k_peer *peer;
Michal Kazior9797feb2014-02-14 14:49:48 +01007107 u32 bw, smps;
7108
7109 spin_lock_bh(&ar->data_lock);
7110
Karthikeyan Periyasamy8b2d93d2018-03-12 17:09:40 +05307111 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
7112 if (!peer) {
7113 spin_unlock_bh(&ar->data_lock);
7114 ath10k_warn(ar, "mac sta rc update failed to find peer %pM on vdev %i\n",
7115 sta->addr, arvif->vdev_id);
7116 return;
7117 }
7118
Michal Kazior7aa7a722014-08-25 12:09:38 +02007119 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01007120 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
7121 sta->addr, changed, sta->bandwidth, sta->rx_nss,
7122 sta->smps_mode);
7123
7124 if (changed & IEEE80211_RC_BW_CHANGED) {
7125 bw = WMI_PEER_CHWIDTH_20MHZ;
7126
7127 switch (sta->bandwidth) {
7128 case IEEE80211_STA_RX_BW_20:
7129 bw = WMI_PEER_CHWIDTH_20MHZ;
7130 break;
7131 case IEEE80211_STA_RX_BW_40:
7132 bw = WMI_PEER_CHWIDTH_40MHZ;
7133 break;
7134 case IEEE80211_STA_RX_BW_80:
7135 bw = WMI_PEER_CHWIDTH_80MHZ;
7136 break;
7137 case IEEE80211_STA_RX_BW_160:
Sebastian Gottschallbc1efd72017-01-12 13:02:12 +02007138 bw = WMI_PEER_CHWIDTH_160MHZ;
7139 break;
7140 default:
Masanari Iidad939be32015-02-27 23:52:31 +09007141 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02007142 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01007143 bw = WMI_PEER_CHWIDTH_20MHZ;
7144 break;
7145 }
7146
7147 arsta->bw = bw;
7148 }
7149
7150 if (changed & IEEE80211_RC_NSS_CHANGED)
7151 arsta->nss = sta->rx_nss;
7152
7153 if (changed & IEEE80211_RC_SMPS_CHANGED) {
7154 smps = WMI_PEER_SMPS_PS_NONE;
7155
7156 switch (sta->smps_mode) {
7157 case IEEE80211_SMPS_AUTOMATIC:
7158 case IEEE80211_SMPS_OFF:
7159 smps = WMI_PEER_SMPS_PS_NONE;
7160 break;
7161 case IEEE80211_SMPS_STATIC:
7162 smps = WMI_PEER_SMPS_STATIC;
7163 break;
7164 case IEEE80211_SMPS_DYNAMIC:
7165 smps = WMI_PEER_SMPS_DYNAMIC;
7166 break;
7167 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02007168 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02007169 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01007170 smps = WMI_PEER_SMPS_PS_NONE;
7171 break;
7172 }
7173
7174 arsta->smps = smps;
7175 }
7176
Michal Kazior9797feb2014-02-14 14:49:48 +01007177 arsta->changed |= changed;
7178
7179 spin_unlock_bh(&ar->data_lock);
7180
7181 ieee80211_queue_work(hw, &arsta->update_wk);
7182}
7183
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007184static void ath10k_offset_tsf(struct ieee80211_hw *hw,
7185 struct ieee80211_vif *vif, s64 tsf_offset)
Peter Oh9f0b7e72016-04-04 16:19:14 -07007186{
7187 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007188 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007189 u32 offset, vdev_param;
Peter Oh9f0b7e72016-04-04 16:19:14 -07007190 int ret;
7191
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007192 if (tsf_offset < 0) {
7193 vdev_param = ar->wmi.vdev_param->dec_tsf;
7194 offset = -tsf_offset;
7195 } else {
7196 vdev_param = ar->wmi.vdev_param->inc_tsf;
7197 offset = tsf_offset;
7198 }
7199
Peter Oh9f0b7e72016-04-04 16:19:14 -07007200 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007201 vdev_param, offset);
7202
Peter Oh9f0b7e72016-04-04 16:19:14 -07007203 if (ret && ret != -EOPNOTSUPP)
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007204 ath10k_warn(ar, "failed to set tsf offset %d cmd %d: %d\n",
7205 offset, vdev_param, ret);
Peter Oh9f0b7e72016-04-04 16:19:14 -07007206}
7207
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007208static int ath10k_ampdu_action(struct ieee80211_hw *hw,
7209 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02007210 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007211{
Michal Kazior7aa7a722014-08-25 12:09:38 +02007212 struct ath10k *ar = hw->priv;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007213 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Sara Sharon50ea05e2015-12-30 16:06:04 +02007214 struct ieee80211_sta *sta = params->sta;
7215 enum ieee80211_ampdu_mlme_action action = params->action;
7216 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007217
Michal Kazior7aa7a722014-08-25 12:09:38 +02007218 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 +02007219 arvif->vdev_id, sta->addr, tid, action);
7220
7221 switch (action) {
7222 case IEEE80211_AMPDU_RX_START:
7223 case IEEE80211_AMPDU_RX_STOP:
7224 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
7225 * creation/removal. Do we need to verify this?
7226 */
7227 return 0;
7228 case IEEE80211_AMPDU_TX_START:
7229 case IEEE80211_AMPDU_TX_STOP_CONT:
7230 case IEEE80211_AMPDU_TX_STOP_FLUSH:
7231 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
7232 case IEEE80211_AMPDU_TX_OPERATIONAL:
7233 /* Firmware offloads Tx aggregation entirely so deny mac80211
7234 * Tx aggregation requests.
7235 */
7236 return -EOPNOTSUPP;
7237 }
7238
7239 return -EINVAL;
7240}
7241
Michal Kazior500ff9f2015-03-31 10:26:21 +00007242static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007243ath10k_mac_update_rx_channel(struct ath10k *ar,
7244 struct ieee80211_chanctx_conf *ctx,
7245 struct ieee80211_vif_chanctx_switch *vifs,
7246 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00007247{
7248 struct cfg80211_chan_def *def = NULL;
7249
7250 /* Both locks are required because ar->rx_channel is modified. This
7251 * allows readers to hold either lock.
7252 */
7253 lockdep_assert_held(&ar->conf_mutex);
7254 lockdep_assert_held(&ar->data_lock);
7255
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007256 WARN_ON(ctx && vifs);
Mohammed Shafi Shajakhanc73f8c02017-03-08 13:52:06 +02007257 WARN_ON(vifs && !n_vifs);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007258
Michal Kazior500ff9f2015-03-31 10:26:21 +00007259 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
7260 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
7261 * ppdu on Rx may reduce performance on low-end systems. It should be
7262 * possible to make tables/hashmaps to speed the lookup up (be vary of
7263 * cpu data cache lines though regarding sizes) but to keep the initial
7264 * implementation simple and less intrusive fallback to the slow lookup
7265 * only for multi-channel cases. Single-channel cases will remain to
7266 * use the old channel derival and thus performance should not be
7267 * affected much.
7268 */
7269 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007270 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00007271 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03007272 ath10k_mac_get_any_chandef_iter,
7273 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007274
7275 if (vifs)
7276 def = &vifs[0].new_ctx->def;
7277
Michal Kazior500ff9f2015-03-31 10:26:21 +00007278 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05307279 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
7280 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
7281 /* During driver restart due to firmware assert, since mac80211
7282 * already has valid channel context for given radio, channel
7283 * context iteration return num_chanctx > 0. So fix rx_channel
7284 * when restart is in progress.
7285 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007286 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007287 } else {
7288 ar->rx_channel = NULL;
7289 }
7290 rcu_read_unlock();
7291}
7292
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007293static void
7294ath10k_mac_update_vif_chan(struct ath10k *ar,
7295 struct ieee80211_vif_chanctx_switch *vifs,
7296 int n_vifs)
7297{
7298 struct ath10k_vif *arvif;
7299 int ret;
7300 int i;
7301
7302 lockdep_assert_held(&ar->conf_mutex);
7303
7304 /* First stop monitor interface. Some FW versions crash if there's a
7305 * lone monitor interface.
7306 */
7307 if (ar->monitor_started)
7308 ath10k_monitor_stop(ar);
7309
7310 for (i = 0; i < n_vifs; i++) {
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007311 arvif = (void *)vifs[i].vif->drv_priv;
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007312
7313 ath10k_dbg(ar, ATH10K_DBG_MAC,
7314 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
7315 arvif->vdev_id,
7316 vifs[i].old_ctx->def.chan->center_freq,
7317 vifs[i].new_ctx->def.chan->center_freq,
7318 vifs[i].old_ctx->def.width,
7319 vifs[i].new_ctx->def.width);
7320
7321 if (WARN_ON(!arvif->is_started))
7322 continue;
7323
7324 if (WARN_ON(!arvif->is_up))
7325 continue;
7326
7327 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7328 if (ret) {
7329 ath10k_warn(ar, "failed to down vdev %d: %d\n",
7330 arvif->vdev_id, ret);
7331 continue;
7332 }
7333 }
7334
7335 /* All relevant vdevs are downed and associated channel resources
7336 * should be available for the channel switch now.
7337 */
7338
7339 spin_lock_bh(&ar->data_lock);
7340 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
7341 spin_unlock_bh(&ar->data_lock);
7342
7343 for (i = 0; i < n_vifs; i++) {
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02007344 arvif = (void *)vifs[i].vif->drv_priv;
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007345
7346 if (WARN_ON(!arvif->is_started))
7347 continue;
7348
7349 if (WARN_ON(!arvif->is_up))
7350 continue;
7351
7352 ret = ath10k_mac_setup_bcn_tmpl(arvif);
7353 if (ret)
7354 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
7355 ret);
7356
7357 ret = ath10k_mac_setup_prb_tmpl(arvif);
7358 if (ret)
7359 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
7360 ret);
7361
7362 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7363 if (ret) {
7364 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7365 arvif->vdev_id, ret);
7366 continue;
7367 }
7368
7369 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7370 arvif->bssid);
7371 if (ret) {
7372 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7373 arvif->vdev_id, ret);
7374 continue;
7375 }
7376 }
7377
7378 ath10k_monitor_recalc(ar);
7379}
7380
Michal Kazior500ff9f2015-03-31 10:26:21 +00007381static int
7382ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7383 struct ieee80211_chanctx_conf *ctx)
7384{
7385 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007386
7387 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307388 "mac chanctx add freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007389 ctx->def.chan->center_freq, ctx->def.width, ctx);
7390
7391 mutex_lock(&ar->conf_mutex);
7392
7393 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007394 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007395 spin_unlock_bh(&ar->data_lock);
7396
7397 ath10k_recalc_radar_detection(ar);
7398 ath10k_monitor_recalc(ar);
7399
7400 mutex_unlock(&ar->conf_mutex);
7401
7402 return 0;
7403}
7404
7405static void
7406ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7407 struct ieee80211_chanctx_conf *ctx)
7408{
7409 struct ath10k *ar = hw->priv;
7410
7411 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307412 "mac chanctx remove freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007413 ctx->def.chan->center_freq, ctx->def.width, ctx);
7414
7415 mutex_lock(&ar->conf_mutex);
7416
7417 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007418 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007419 spin_unlock_bh(&ar->data_lock);
7420
7421 ath10k_recalc_radar_detection(ar);
7422 ath10k_monitor_recalc(ar);
7423
7424 mutex_unlock(&ar->conf_mutex);
7425}
7426
Michal Kazior9713e3d2015-09-03 10:44:52 +02007427struct ath10k_mac_change_chanctx_arg {
7428 struct ieee80211_chanctx_conf *ctx;
7429 struct ieee80211_vif_chanctx_switch *vifs;
7430 int n_vifs;
7431 int next_vif;
7432};
7433
7434static void
7435ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
7436 struct ieee80211_vif *vif)
7437{
7438 struct ath10k_mac_change_chanctx_arg *arg = data;
7439
7440 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
7441 return;
7442
7443 arg->n_vifs++;
7444}
7445
7446static void
7447ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
7448 struct ieee80211_vif *vif)
7449{
7450 struct ath10k_mac_change_chanctx_arg *arg = data;
7451 struct ieee80211_chanctx_conf *ctx;
7452
7453 ctx = rcu_access_pointer(vif->chanctx_conf);
7454 if (ctx != arg->ctx)
7455 return;
7456
7457 if (WARN_ON(arg->next_vif == arg->n_vifs))
7458 return;
7459
7460 arg->vifs[arg->next_vif].vif = vif;
7461 arg->vifs[arg->next_vif].old_ctx = ctx;
7462 arg->vifs[arg->next_vif].new_ctx = ctx;
7463 arg->next_vif++;
7464}
7465
Michal Kazior500ff9f2015-03-31 10:26:21 +00007466static void
7467ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7468 struct ieee80211_chanctx_conf *ctx,
7469 u32 changed)
7470{
7471 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007472 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007473
7474 mutex_lock(&ar->conf_mutex);
7475
7476 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307477 "mac chanctx change freq %hu width %d ptr %pK changed %x\n",
Michal Kazior089ab7a2015-06-03 12:16:55 +02007478 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007479
7480 /* This shouldn't really happen because channel switching should use
7481 * switch_vif_chanctx().
7482 */
7483 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7484 goto unlock;
7485
Michal Kazior9713e3d2015-09-03 10:44:52 +02007486 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7487 ieee80211_iterate_active_interfaces_atomic(
7488 hw,
7489 IEEE80211_IFACE_ITER_NORMAL,
7490 ath10k_mac_change_chanctx_cnt_iter,
7491 &arg);
7492 if (arg.n_vifs == 0)
7493 goto radar;
7494
7495 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7496 GFP_KERNEL);
7497 if (!arg.vifs)
7498 goto radar;
7499
7500 ieee80211_iterate_active_interfaces_atomic(
7501 hw,
7502 IEEE80211_IFACE_ITER_NORMAL,
7503 ath10k_mac_change_chanctx_fill_iter,
7504 &arg);
7505 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7506 kfree(arg.vifs);
7507 }
7508
7509radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007510 ath10k_recalc_radar_detection(ar);
7511
7512 /* FIXME: How to configure Rx chains properly? */
7513
7514 /* No other actions are actually necessary. Firmware maintains channel
7515 * definitions per vdev internally and there's no host-side channel
7516 * context abstraction to configure, e.g. channel width.
7517 */
7518
7519unlock:
7520 mutex_unlock(&ar->conf_mutex);
7521}
7522
7523static int
7524ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7525 struct ieee80211_vif *vif,
7526 struct ieee80211_chanctx_conf *ctx)
7527{
7528 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007529 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7530 int ret;
7531
7532 mutex_lock(&ar->conf_mutex);
7533
7534 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307535 "mac chanctx assign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007536 ctx, arvif->vdev_id);
7537
7538 if (WARN_ON(arvif->is_started)) {
7539 mutex_unlock(&ar->conf_mutex);
7540 return -EBUSY;
7541 }
7542
Michal Kazior089ab7a2015-06-03 12:16:55 +02007543 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007544 if (ret) {
7545 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7546 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007547 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007548 goto err;
7549 }
7550
7551 arvif->is_started = true;
7552
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007553 ret = ath10k_mac_vif_setup_ps(arvif);
7554 if (ret) {
7555 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7556 arvif->vdev_id, ret);
7557 goto err_stop;
7558 }
7559
Michal Kazior500ff9f2015-03-31 10:26:21 +00007560 if (vif->type == NL80211_IFTYPE_MONITOR) {
7561 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7562 if (ret) {
7563 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7564 arvif->vdev_id, ret);
7565 goto err_stop;
7566 }
7567
7568 arvif->is_up = true;
7569 }
7570
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02007571 if (ath10k_mac_can_set_cts_prot(arvif)) {
7572 ret = ath10k_mac_set_cts_prot(arvif);
7573 if (ret)
7574 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
7575 arvif->vdev_id, ret);
7576 }
7577
Anilkumar Kollie8123bb2017-12-05 19:01:25 +05307578 if (ath10k_peer_stats_enabled(ar)) {
7579 ar->pktlog_filter |= ATH10K_PKTLOG_PEER_STATS;
7580 ret = ath10k_wmi_pdev_pktlog_enable(ar,
7581 ar->pktlog_filter);
7582 if (ret) {
7583 ath10k_warn(ar, "failed to enable pktlog %d\n", ret);
7584 goto err_stop;
7585 }
7586 }
7587
Michal Kazior500ff9f2015-03-31 10:26:21 +00007588 mutex_unlock(&ar->conf_mutex);
7589 return 0;
7590
7591err_stop:
7592 ath10k_vdev_stop(arvif);
7593 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007594 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007595
7596err:
7597 mutex_unlock(&ar->conf_mutex);
7598 return ret;
7599}
7600
7601static void
7602ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7603 struct ieee80211_vif *vif,
7604 struct ieee80211_chanctx_conf *ctx)
7605{
7606 struct ath10k *ar = hw->priv;
7607 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7608 int ret;
7609
7610 mutex_lock(&ar->conf_mutex);
7611
7612 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307613 "mac chanctx unassign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007614 ctx, arvif->vdev_id);
7615
7616 WARN_ON(!arvif->is_started);
7617
7618 if (vif->type == NL80211_IFTYPE_MONITOR) {
7619 WARN_ON(!arvif->is_up);
7620
7621 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7622 if (ret)
7623 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7624 arvif->vdev_id, ret);
7625
7626 arvif->is_up = false;
7627 }
7628
7629 ret = ath10k_vdev_stop(arvif);
7630 if (ret)
7631 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7632 arvif->vdev_id, ret);
7633
7634 arvif->is_started = false;
7635
7636 mutex_unlock(&ar->conf_mutex);
7637}
7638
7639static int
7640ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7641 struct ieee80211_vif_chanctx_switch *vifs,
7642 int n_vifs,
7643 enum ieee80211_chanctx_switch_mode mode)
7644{
7645 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007646
7647 mutex_lock(&ar->conf_mutex);
7648
7649 ath10k_dbg(ar, ATH10K_DBG_MAC,
7650 "mac chanctx switch n_vifs %d mode %d\n",
7651 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007652 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007653
7654 mutex_unlock(&ar->conf_mutex);
7655 return 0;
7656}
7657
Michal Kazior0a744d92017-01-12 16:14:30 +01007658static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,
7659 struct ieee80211_vif *vif,
7660 struct ieee80211_sta *sta)
7661{
7662 struct ath10k *ar;
7663 struct ath10k_peer *peer;
7664
7665 ar = hw->priv;
7666
7667 list_for_each_entry(peer, &ar->peers, list)
7668 if (peer->sta == sta)
7669 peer->removed = true;
7670}
7671
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05307672static void ath10k_sta_statistics(struct ieee80211_hw *hw,
7673 struct ieee80211_vif *vif,
7674 struct ieee80211_sta *sta,
7675 struct station_info *sinfo)
7676{
7677 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
7678 struct ath10k *ar = arsta->arvif->ar;
7679
7680 if (!ath10k_peer_stats_enabled(ar))
7681 return;
7682
7683 sinfo->rx_duration = arsta->rx_duration;
7684 sinfo->filled |= 1ULL << NL80211_STA_INFO_RX_DURATION;
7685
7686 if (!arsta->txrate.legacy && !arsta->txrate.nss)
7687 return;
7688
7689 if (arsta->txrate.legacy) {
7690 sinfo->txrate.legacy = arsta->txrate.legacy;
7691 } else {
7692 sinfo->txrate.mcs = arsta->txrate.mcs;
7693 sinfo->txrate.nss = arsta->txrate.nss;
7694 sinfo->txrate.bw = arsta->txrate.bw;
7695 }
7696 sinfo->txrate.flags = arsta->txrate.flags;
7697 sinfo->filled |= 1ULL << NL80211_STA_INFO_TX_BITRATE;
7698}
7699
Kalle Valo5e3dd152013-06-12 20:52:10 +03007700static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01007701 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02007702 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007703 .start = ath10k_start,
7704 .stop = ath10k_stop,
7705 .config = ath10k_config,
7706 .add_interface = ath10k_add_interface,
7707 .remove_interface = ath10k_remove_interface,
7708 .configure_filter = ath10k_configure_filter,
7709 .bss_info_changed = ath10k_bss_info_changed,
Benjamin Bergebee76f2016-09-28 15:11:58 +03007710 .set_coverage_class = ath10k_mac_op_set_coverage_class,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007711 .hw_scan = ath10k_hw_scan,
7712 .cancel_hw_scan = ath10k_cancel_hw_scan,
7713 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02007714 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007715 .sta_state = ath10k_sta_state,
7716 .conf_tx = ath10k_conf_tx,
7717 .remain_on_channel = ath10k_remain_on_channel,
7718 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
7719 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02007720 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007721 .flush = ath10k_flush,
7722 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7bb2014-05-16 17:15:38 +03007723 .set_antenna = ath10k_set_antenna,
7724 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007725 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02007726 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00007727 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01007728 .sta_rc_update = ath10k_sta_rc_update,
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007729 .offset_tsf = ath10k_offset_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007730 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03007731 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7732 .get_et_stats = ath10k_debug_get_et_stats,
7733 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00007734 .add_chanctx = ath10k_mac_op_add_chanctx,
7735 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7736 .change_chanctx = ath10k_mac_op_change_chanctx,
7737 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7738 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7739 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Michal Kazior0a744d92017-01-12 16:14:30 +01007740 .sta_pre_rcu_remove = ath10k_mac_op_sta_pre_rcu_remove,
Anilkumar Kolli6a7f8912017-12-05 19:01:23 +05307741 .sta_statistics = ath10k_sta_statistics,
Kalle Valo43d2a302014-09-10 18:23:30 +03007742
7743 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7744
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007745#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007746 .suspend = ath10k_wow_op_suspend,
7747 .resume = ath10k_wow_op_resume,
Ryan Hsu393b7062017-08-31 15:36:16 +03007748 .set_wakeup = ath10k_wow_op_set_wakeup,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007749#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007750#ifdef CONFIG_MAC80211_DEBUGFS
7751 .sta_add_debugfs = ath10k_sta_add_debugfs,
7752#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03007753};
7754
Kalle Valo5e3dd152013-06-12 20:52:10 +03007755#define CHAN2G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007756 .band = NL80211_BAND_2GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007757 .hw_value = (_channel), \
7758 .center_freq = (_freq), \
7759 .flags = (_flags), \
7760 .max_antenna_gain = 0, \
7761 .max_power = 30, \
7762}
7763
7764#define CHAN5G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007765 .band = NL80211_BAND_5GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007766 .hw_value = (_channel), \
7767 .center_freq = (_freq), \
7768 .flags = (_flags), \
7769 .max_antenna_gain = 0, \
7770 .max_power = 30, \
7771}
7772
7773static const struct ieee80211_channel ath10k_2ghz_channels[] = {
7774 CHAN2G(1, 2412, 0),
7775 CHAN2G(2, 2417, 0),
7776 CHAN2G(3, 2422, 0),
7777 CHAN2G(4, 2427, 0),
7778 CHAN2G(5, 2432, 0),
7779 CHAN2G(6, 2437, 0),
7780 CHAN2G(7, 2442, 0),
7781 CHAN2G(8, 2447, 0),
7782 CHAN2G(9, 2452, 0),
7783 CHAN2G(10, 2457, 0),
7784 CHAN2G(11, 2462, 0),
7785 CHAN2G(12, 2467, 0),
7786 CHAN2G(13, 2472, 0),
7787 CHAN2G(14, 2484, 0),
7788};
7789
7790static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02007791 CHAN5G(36, 5180, 0),
7792 CHAN5G(40, 5200, 0),
7793 CHAN5G(44, 5220, 0),
7794 CHAN5G(48, 5240, 0),
7795 CHAN5G(52, 5260, 0),
7796 CHAN5G(56, 5280, 0),
7797 CHAN5G(60, 5300, 0),
7798 CHAN5G(64, 5320, 0),
7799 CHAN5G(100, 5500, 0),
7800 CHAN5G(104, 5520, 0),
7801 CHAN5G(108, 5540, 0),
7802 CHAN5G(112, 5560, 0),
7803 CHAN5G(116, 5580, 0),
7804 CHAN5G(120, 5600, 0),
7805 CHAN5G(124, 5620, 0),
7806 CHAN5G(128, 5640, 0),
7807 CHAN5G(132, 5660, 0),
7808 CHAN5G(136, 5680, 0),
7809 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07007810 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02007811 CHAN5G(149, 5745, 0),
7812 CHAN5G(153, 5765, 0),
7813 CHAN5G(157, 5785, 0),
7814 CHAN5G(161, 5805, 0),
7815 CHAN5G(165, 5825, 0),
Mohammed Shafi Shajakhan34c30b02016-12-27 20:53:35 +05307816 CHAN5G(169, 5845, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03007817};
7818
Michal Kaziore7b54192014-08-07 11:03:27 +02007819struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007820{
7821 struct ieee80211_hw *hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007822 struct ieee80211_ops *ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007823 struct ath10k *ar;
7824
Michal Kazior4ca18072016-07-18 23:22:18 +03007825 ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);
7826 if (!ops)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007827 return NULL;
7828
Michal Kazior4ca18072016-07-18 23:22:18 +03007829 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);
7830 if (!hw) {
7831 kfree(ops);
7832 return NULL;
7833 }
7834
Kalle Valo5e3dd152013-06-12 20:52:10 +03007835 ar = hw->priv;
7836 ar->hw = hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007837 ar->ops = ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007838
7839 return ar;
7840}
7841
7842void ath10k_mac_destroy(struct ath10k *ar)
7843{
Michal Kazior4ca18072016-07-18 23:22:18 +03007844 struct ieee80211_ops *ops = ar->ops;
7845
Kalle Valo5e3dd152013-06-12 20:52:10 +03007846 ieee80211_free_hw(ar->hw);
Michal Kazior4ca18072016-07-18 23:22:18 +03007847 kfree(ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007848}
7849
7850static const struct ieee80211_iface_limit ath10k_if_limits[] = {
7851 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307852 .max = 8,
7853 .types = BIT(NL80211_IFTYPE_STATION)
7854 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02007855 },
7856 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307857 .max = 3,
7858 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02007859 },
7860 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307861 .max = 1,
7862 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01007863 },
7864 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307865 .max = 7,
7866 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007867#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307868 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007869#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02007870 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007871};
7872
Bartosz Markowskif2595092013-12-10 16:20:39 +01007873static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007874 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307875 .max = 8,
7876 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007877#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307878 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007879#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007880 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307881 {
7882 .max = 1,
7883 .types = BIT(NL80211_IFTYPE_STATION)
7884 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007885};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007886
7887static const struct ieee80211_iface_combination ath10k_if_comb[] = {
7888 {
7889 .limits = ath10k_if_limits,
7890 .n_limits = ARRAY_SIZE(ath10k_if_limits),
7891 .max_interfaces = 8,
7892 .num_different_channels = 1,
7893 .beacon_int_infra_match = true,
7894 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01007895};
7896
7897static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007898 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01007899 .limits = ath10k_10x_if_limits,
7900 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007901 .max_interfaces = 8,
7902 .num_different_channels = 1,
7903 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01007904#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007905 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7906 BIT(NL80211_CHAN_WIDTH_20) |
7907 BIT(NL80211_CHAN_WIDTH_40) |
7908 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007909#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01007910 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007911};
7912
Michal Kaziorcf327842015-03-31 10:26:25 +00007913static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
7914 {
7915 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02007916 .types = BIT(NL80211_IFTYPE_STATION),
7917 },
7918 {
7919 .max = 2,
7920 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007921#ifdef CONFIG_MAC80211_MESH
7922 BIT(NL80211_IFTYPE_MESH_POINT) |
7923#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00007924 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7925 BIT(NL80211_IFTYPE_P2P_GO),
7926 },
7927 {
7928 .max = 1,
7929 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7930 },
7931};
7932
Michal Kaziored25b112015-07-09 13:08:39 +02007933static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
7934 {
7935 .max = 2,
7936 .types = BIT(NL80211_IFTYPE_STATION),
7937 },
7938 {
7939 .max = 2,
7940 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
7941 },
7942 {
7943 .max = 1,
7944 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007945#ifdef CONFIG_MAC80211_MESH
7946 BIT(NL80211_IFTYPE_MESH_POINT) |
7947#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007948 BIT(NL80211_IFTYPE_P2P_GO),
7949 },
7950 {
7951 .max = 1,
7952 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7953 },
7954};
7955
Michal Kaziorcf327842015-03-31 10:26:25 +00007956static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7957 {
7958 .max = 1,
7959 .types = BIT(NL80211_IFTYPE_STATION),
7960 },
7961 {
7962 .max = 1,
7963 .types = BIT(NL80211_IFTYPE_ADHOC),
7964 },
7965};
7966
7967/* FIXME: This is not thouroughly tested. These combinations may over- or
7968 * underestimate hw/fw capabilities.
7969 */
7970static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7971 {
7972 .limits = ath10k_tlv_if_limit,
7973 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007974 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007975 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7976 },
7977 {
7978 .limits = ath10k_tlv_if_limit_ibss,
7979 .num_different_channels = 1,
7980 .max_interfaces = 2,
7981 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7982 },
7983};
7984
7985static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7986 {
7987 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007988 .num_different_channels = 1,
7989 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007990 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7991 },
7992 {
Michal Kaziored25b112015-07-09 13:08:39 +02007993 .limits = ath10k_tlv_qcs_if_limit,
7994 .num_different_channels = 2,
7995 .max_interfaces = 4,
7996 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7997 },
7998 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007999 .limits = ath10k_tlv_if_limit_ibss,
8000 .num_different_channels = 1,
8001 .max_interfaces = 2,
8002 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
8003 },
8004};
8005
Raja Manicf36fef2015-06-22 20:22:25 +05308006static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
8007 {
8008 .max = 1,
8009 .types = BIT(NL80211_IFTYPE_STATION),
8010 },
8011 {
8012 .max = 16,
8013 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008014#ifdef CONFIG_MAC80211_MESH
8015 | BIT(NL80211_IFTYPE_MESH_POINT)
8016#endif
Raja Manicf36fef2015-06-22 20:22:25 +05308017 },
8018};
8019
8020static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
8021 {
8022 .limits = ath10k_10_4_if_limits,
8023 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
8024 .max_interfaces = 16,
8025 .num_different_channels = 1,
8026 .beacon_int_infra_match = true,
8027#ifdef CONFIG_ATH10K_DFS_CERTIFIED
8028 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
8029 BIT(NL80211_CHAN_WIDTH_20) |
8030 BIT(NL80211_CHAN_WIDTH_40) |
8031 BIT(NL80211_CHAN_WIDTH_80),
8032#endif
8033 },
8034};
8035
Kalle Valo5e3dd152013-06-12 20:52:10 +03008036static void ath10k_get_arvif_iter(void *data, u8 *mac,
8037 struct ieee80211_vif *vif)
8038{
8039 struct ath10k_vif_iter *arvif_iter = data;
Amadeusz Sławiński56ac13b2017-02-13 12:38:37 +02008040 struct ath10k_vif *arvif = (void *)vif->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008041
8042 if (arvif->vdev_id == arvif_iter->vdev_id)
8043 arvif_iter->arvif = arvif;
8044}
8045
8046struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
8047{
8048 struct ath10k_vif_iter arvif_iter;
8049 u32 flags;
8050
8051 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
8052 arvif_iter.vdev_id = vdev_id;
8053
8054 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
8055 ieee80211_iterate_active_interfaces_atomic(ar->hw,
8056 flags,
8057 ath10k_get_arvif_iter,
8058 &arvif_iter);
8059 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008060 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008061 return NULL;
8062 }
8063
8064 return arvif_iter.arvif;
8065}
8066
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008067#define WRD_METHOD "WRDD"
8068#define WRDD_WIFI (0x07)
8069
8070static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_object *wrdd)
8071{
8072 union acpi_object *mcc_pkg;
8073 union acpi_object *domain_type;
8074 union acpi_object *mcc_value;
8075 u32 i;
8076
8077 if (wrdd->type != ACPI_TYPE_PACKAGE ||
8078 wrdd->package.count < 2 ||
8079 wrdd->package.elements[0].type != ACPI_TYPE_INTEGER ||
8080 wrdd->package.elements[0].integer.value != 0) {
8081 ath10k_warn(ar, "ignoring malformed/unsupported wrdd structure\n");
8082 return 0;
8083 }
8084
8085 for (i = 1; i < wrdd->package.count; ++i) {
8086 mcc_pkg = &wrdd->package.elements[i];
8087
8088 if (mcc_pkg->type != ACPI_TYPE_PACKAGE)
8089 continue;
8090 if (mcc_pkg->package.count < 2)
8091 continue;
8092 if (mcc_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
8093 mcc_pkg->package.elements[1].type != ACPI_TYPE_INTEGER)
8094 continue;
8095
8096 domain_type = &mcc_pkg->package.elements[0];
8097 if (domain_type->integer.value != WRDD_WIFI)
8098 continue;
8099
8100 mcc_value = &mcc_pkg->package.elements[1];
8101 return mcc_value->integer.value;
8102 }
8103 return 0;
8104}
8105
8106static int ath10k_mac_get_wrdd_regulatory(struct ath10k *ar, u16 *rd)
8107{
8108 struct pci_dev __maybe_unused *pdev = to_pci_dev(ar->dev);
8109 acpi_handle root_handle;
8110 acpi_handle handle;
8111 struct acpi_buffer wrdd = {ACPI_ALLOCATE_BUFFER, NULL};
8112 acpi_status status;
8113 u32 alpha2_code;
8114 char alpha2[3];
8115
8116 root_handle = ACPI_HANDLE(&pdev->dev);
8117 if (!root_handle)
8118 return -EOPNOTSUPP;
8119
8120 status = acpi_get_handle(root_handle, (acpi_string)WRD_METHOD, &handle);
8121 if (ACPI_FAILURE(status)) {
8122 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8123 "failed to get wrd method %d\n", status);
8124 return -EIO;
8125 }
8126
8127 status = acpi_evaluate_object(handle, NULL, NULL, &wrdd);
8128 if (ACPI_FAILURE(status)) {
8129 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8130 "failed to call wrdc %d\n", status);
8131 return -EIO;
8132 }
8133
8134 alpha2_code = ath10k_mac_wrdd_get_mcc(ar, wrdd.pointer);
8135 kfree(wrdd.pointer);
8136 if (!alpha2_code)
8137 return -EIO;
8138
8139 alpha2[0] = (alpha2_code >> 8) & 0xff;
8140 alpha2[1] = (alpha2_code >> 0) & 0xff;
8141 alpha2[2] = '\0';
8142
8143 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8144 "regulatory hint from WRDD (alpha2-code): %s\n", alpha2);
8145
8146 *rd = ath_regd_find_country_by_name(alpha2);
8147 if (*rd == 0xffff)
8148 return -EIO;
8149
8150 *rd |= COUNTRY_ERD_FLAG;
8151 return 0;
8152}
8153
8154static int ath10k_mac_init_rd(struct ath10k *ar)
8155{
8156 int ret;
8157 u16 rd;
8158
8159 ret = ath10k_mac_get_wrdd_regulatory(ar, &rd);
8160 if (ret) {
8161 ath10k_dbg(ar, ATH10K_DBG_BOOT,
8162 "fallback to eeprom programmed regulatory settings\n");
8163 rd = ar->hw_eeprom_rd;
8164 }
8165
8166 ar->ath_common.regulatory.current_rd = rd;
8167 return 0;
8168}
8169
Kalle Valo5e3dd152013-06-12 20:52:10 +03008170int ath10k_mac_register(struct ath10k *ar)
8171{
Johannes Berg3cb10942015-01-22 21:38:45 +01008172 static const u32 cipher_suites[] = {
8173 WLAN_CIPHER_SUITE_WEP40,
8174 WLAN_CIPHER_SUITE_WEP104,
8175 WLAN_CIPHER_SUITE_TKIP,
8176 WLAN_CIPHER_SUITE_CCMP,
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07008177
8178 /* Do not add hardware supported ciphers before this line.
8179 * Allow software encryption for all chips. Don't forget to
8180 * update n_cipher_suites below.
8181 */
Johannes Berg3cb10942015-01-22 21:38:45 +01008182 WLAN_CIPHER_SUITE_AES_CMAC,
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07008183 WLAN_CIPHER_SUITE_BIP_CMAC_256,
8184 WLAN_CIPHER_SUITE_BIP_GMAC_128,
8185 WLAN_CIPHER_SUITE_BIP_GMAC_256,
8186
8187 /* Only QCA99x0 and QCA4019 varients support GCMP-128, GCMP-256
8188 * and CCMP-256 in hardware.
8189 */
8190 WLAN_CIPHER_SUITE_GCMP,
8191 WLAN_CIPHER_SUITE_GCMP_256,
8192 WLAN_CIPHER_SUITE_CCMP_256,
Johannes Berg3cb10942015-01-22 21:38:45 +01008193 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03008194 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008195 void *channels;
8196 int ret;
8197
8198 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
8199
8200 SET_IEEE80211_DEV(ar->hw, ar->dev);
8201
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00008202 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
8203 ARRAY_SIZE(ath10k_5ghz_channels)) !=
8204 ATH10K_NUM_CHANS);
8205
Kalle Valo5e3dd152013-06-12 20:52:10 +03008206 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
8207 channels = kmemdup(ath10k_2ghz_channels,
8208 sizeof(ath10k_2ghz_channels),
8209 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02008210 if (!channels) {
8211 ret = -ENOMEM;
8212 goto err_free;
8213 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008214
Johannes Berg57fbcce2016-04-12 15:56:15 +02008215 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03008216 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
8217 band->channels = channels;
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +03008218
8219 if (ar->hw_params.cck_rate_map_rev2) {
8220 band->n_bitrates = ath10k_g_rates_rev2_size;
8221 band->bitrates = ath10k_g_rates_rev2;
8222 } else {
8223 band->n_bitrates = ath10k_g_rates_size;
8224 band->bitrates = ath10k_g_rates;
8225 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008226
Johannes Berg57fbcce2016-04-12 15:56:15 +02008227 ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008228 }
8229
8230 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
8231 channels = kmemdup(ath10k_5ghz_channels,
8232 sizeof(ath10k_5ghz_channels),
8233 GFP_KERNEL);
8234 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02008235 ret = -ENOMEM;
8236 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008237 }
8238
Johannes Berg57fbcce2016-04-12 15:56:15 +02008239 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03008240 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
8241 band->channels = channels;
8242 band->n_bitrates = ath10k_a_rates_size;
8243 band->bitrates = ath10k_a_rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02008244 ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008245 }
8246
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05308247 ath10k_mac_setup_ht_vht_cap(ar);
8248
Kalle Valo5e3dd152013-06-12 20:52:10 +03008249 ar->hw->wiphy->interface_modes =
8250 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008251 BIT(NL80211_IFTYPE_AP) |
8252 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01008253
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05308254 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
8255 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03008256
Kalle Valoc4cdf752016-04-20 19:45:18 +03008257 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))
Bartosz Markowskid3541812013-12-10 16:20:40 +01008258 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01008259 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01008260 BIT(NL80211_IFTYPE_P2P_CLIENT) |
8261 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008262
Johannes Berg30686bf2015-06-02 21:39:54 +02008263 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
Venkateswara Naralasetty36d9cdb2017-10-04 12:22:57 +03008264
8265 if (!test_bit(ATH10K_FW_FEATURE_NO_PS,
8266 ar->running_fw->fw_file.fw_features)) {
8267 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
8268 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
8269 }
8270
Johannes Berg30686bf2015-06-02 21:39:54 +02008271 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
8272 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
8273 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
8274 ieee80211_hw_set(ar->hw, AP_LINK_PS);
8275 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02008276 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
8277 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
8278 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
8279 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
8280 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
8281 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Sara Sharonf3fe4e92016-10-18 23:12:11 +03008282 ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
Rajkumar Manoharanff32eeb2016-09-06 12:38:41 +05308283 ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008284
David Liuccec9032015-07-24 20:25:32 +03008285 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8286 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
8287
Eliad Peller0d8614b2014-09-10 14:07:36 +03008288 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00008289 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03008290
Kalle Valo5e3dd152013-06-12 20:52:10 +03008291 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03008292 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008293
8294 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02008295 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
8296 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008297 }
8298
8299 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
8300 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
8301
8302 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01008303 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02008304 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008305
Kalle Valo5e3dd152013-06-12 20:52:10 +03008306 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
8307
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02008308 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
8309 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
8310
8311 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
8312 * that userspace (e.g. wpa_supplicant/hostapd) can generate
8313 * correct Probe Responses. This is more of a hack advert..
8314 */
8315 ar->hw->wiphy->probe_resp_offload |=
8316 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
8317 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
8318 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
8319 }
8320
Manikanta Pubbisettyadd6cd82017-07-28 15:15:42 +03008321 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map) ||
8322 test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, ar->wmi.svc_map)) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03008323 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
Balaji Pothunoori14d65772017-12-21 20:00:42 +05308324 if (test_bit(WMI_SERVICE_TDLS_WIDER_BANDWIDTH, ar->wmi.svc_map))
8325 ieee80211_hw_set(ar->hw, TDLS_WIDER_BW);
Manikanta Pubbisettyadd6cd82017-07-28 15:15:42 +03008326 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03008327
Kalle Valo5e3dd152013-06-12 20:52:10 +03008328 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01008329 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008330 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
8331
8332 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05308333 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
8334 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02008335
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01008336 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
8337
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02008338 ret = ath10k_wow_init(ar);
8339 if (ret) {
8340 ath10k_warn(ar, "failed to init wow: %d\n", ret);
8341 goto err_free;
8342 }
8343
Janusz Dziedzicc7025342015-06-15 14:46:41 +03008344 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
8345
Kalle Valo5e3dd152013-06-12 20:52:10 +03008346 /*
8347 * on LL hardware queues are managed entirely by the FW
8348 * so we only advertise to mac we can do the queues thing
8349 */
Michal Kazior96d828d2015-03-31 10:26:23 +00008350 ar->hw->queues = IEEE80211_MAX_QUEUES;
8351
8352 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
8353 * something that vdev_ids can't reach so that we don't stop the queue
8354 * accidentally.
8355 */
8356 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008357
Kalle Valobf3c13a2016-04-20 19:45:33 +03008358 switch (ar->running_fw->fw_file.wmi_op_version) {
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008359 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01008360 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
8361 ar->hw->wiphy->n_iface_combinations =
8362 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03008363 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008364 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00008365 case ATH10K_FW_WMI_OP_VERSION_TLV:
8366 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
8367 ar->hw->wiphy->iface_combinations =
8368 ath10k_tlv_qcs_if_comb;
8369 ar->hw->wiphy->n_iface_combinations =
8370 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
8371 } else {
8372 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
8373 ar->hw->wiphy->n_iface_combinations =
8374 ARRAY_SIZE(ath10k_tlv_if_comb);
8375 }
8376 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
8377 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008378 case ATH10K_FW_WMI_OP_VERSION_10_1:
8379 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02008380 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008381 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
8382 ar->hw->wiphy->n_iface_combinations =
8383 ARRAY_SIZE(ath10k_10x_if_comb);
8384 break;
Raja Mani9bd21322015-06-22 20:10:09 +05308385 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05308386 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
8387 ar->hw->wiphy->n_iface_combinations =
8388 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05308389 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008390 case ATH10K_FW_WMI_OP_VERSION_UNSET:
8391 case ATH10K_FW_WMI_OP_VERSION_MAX:
8392 WARN_ON(1);
8393 ret = -EINVAL;
8394 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01008395 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008396
David Liuccec9032015-07-24 20:25:32 +03008397 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8398 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02008399
Masahiro Yamada97f26452016-08-03 13:45:50 -07008400 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008401 /* Init ath dfs pattern detector */
8402 ar->ath_common.debug_mask = ATH_DBG_DFS;
8403 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
8404 NL80211_DFS_UNSET);
8405
8406 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02008407 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008408 }
8409
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008410 ret = ath10k_mac_init_rd(ar);
8411 if (ret) {
8412 ath10k_err(ar, "failed to derive regdom: %d\n", ret);
8413 goto err_dfs_detector_exit;
8414 }
8415
Benjamin Bergebee76f2016-09-28 15:11:58 +03008416 /* Disable set_coverage_class for chipsets that do not support it. */
8417 if (!ar->hw_params.hw_ops->set_coverage_class)
8418 ar->ops->set_coverage_class = NULL;
8419
Kalle Valo5e3dd152013-06-12 20:52:10 +03008420 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
8421 ath10k_reg_notifier);
8422 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008423 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008424 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008425 }
8426
Johannes Berg3cb10942015-01-22 21:38:45 +01008427 ar->hw->wiphy->cipher_suites = cipher_suites;
Rajkumar Manoharan2ea9f122017-09-25 15:29:41 -07008428
8429 /* QCA988x and QCA6174 family chips do not support CCMP-256, GCMP-128
8430 * and GCMP-256 ciphers in hardware. Fetch number of ciphers supported
8431 * from chip specific hw_param table.
8432 */
8433 if (!ar->hw_params.n_cipher_suites ||
8434 ar->hw_params.n_cipher_suites > ARRAY_SIZE(cipher_suites)) {
8435 ath10k_err(ar, "invalid hw_params.n_cipher_suites %d\n",
8436 ar->hw_params.n_cipher_suites);
8437 ar->hw_params.n_cipher_suites = 8;
8438 }
8439 ar->hw->wiphy->n_cipher_suites = ar->hw_params.n_cipher_suites;
Johannes Berg3cb10942015-01-22 21:38:45 +01008440
Andrew Zaborowskiae44b502017-02-10 04:50:23 +01008441 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
8442
Kalle Valo5e3dd152013-06-12 20:52:10 +03008443 ret = ieee80211_register_hw(ar->hw);
8444 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008445 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008446 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008447 }
8448
8449 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
8450 ret = regulatory_hint(ar->hw->wiphy,
8451 ar->ath_common.regulatory.alpha2);
8452 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02008453 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008454 }
8455
8456 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02008457
8458err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03008459 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07008460
8461err_dfs_detector_exit:
Masahiro Yamada97f26452016-08-03 13:45:50 -07008462 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Jeff Johnson0e339442015-10-08 09:15:53 -07008463 ar->dfs_detector->exit(ar->dfs_detector);
8464
Michal Kaziord6015b22013-07-22 14:13:30 +02008465err_free:
Johannes Berg57fbcce2016-04-12 15:56:15 +02008466 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8467 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Michal Kaziord6015b22013-07-22 14:13:30 +02008468
Jeff Johnson0e339442015-10-08 09:15:53 -07008469 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008470 return ret;
8471}
8472
8473void ath10k_mac_unregister(struct ath10k *ar)
8474{
8475 ieee80211_unregister_hw(ar->hw);
8476
Masahiro Yamada97f26452016-08-03 13:45:50 -07008477 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008478 ar->dfs_detector->exit(ar->dfs_detector);
8479
Johannes Berg57fbcce2016-04-12 15:56:15 +02008480 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8481 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008482
8483 SET_IEEE80211_DEV(ar->hw, NULL);
8484}