blob: 8d02d53fdc2caa596b9e84279cda21e8c8afd85c [file] [log] [blame]
Kalle Valo5e3dd152013-06-12 20:52:10 +03001/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include "mac.h"
19
20#include <net/mac80211.h>
21#include <linux/etherdevice.h>
22
Michal Kazior8cd13ca2013-07-16 09:38:54 +020023#include "hif.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030024#include "core.h"
25#include "debug.h"
26#include "wmi.h"
27#include "htt.h"
28#include "txrx.h"
Kalle Valo43d2a302014-09-10 18:23:30 +030029#include "testmode.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020030#include "wmi.h"
Michal Kaziorb4aa5392015-03-31 10:26:24 +000031#include "wmi-tlv.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020032#include "wmi-ops.h"
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +020033#include "wow.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030034
Michal Kaziordcc33092015-03-30 09:51:54 +030035/*********/
36/* Rates */
37/*********/
38
Michal Kaziordcc33092015-03-30 09:51:54 +030039static struct ieee80211_rate ath10k_rates[] = {
Michal Kazior5528e032015-03-30 09:51:56 +030040 { .bitrate = 10,
41 .hw_value = ATH10K_HW_RATE_CCK_LP_1M },
42 { .bitrate = 20,
43 .hw_value = ATH10K_HW_RATE_CCK_LP_2M,
44 .hw_value_short = ATH10K_HW_RATE_CCK_SP_2M,
45 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
46 { .bitrate = 55,
47 .hw_value = ATH10K_HW_RATE_CCK_LP_5_5M,
48 .hw_value_short = ATH10K_HW_RATE_CCK_SP_5_5M,
49 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
50 { .bitrate = 110,
51 .hw_value = ATH10K_HW_RATE_CCK_LP_11M,
52 .hw_value_short = ATH10K_HW_RATE_CCK_SP_11M,
53 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
Michal Kazior5653b392015-03-30 09:51:54 +030054
Michal Kazioraf001482015-03-30 09:51:56 +030055 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
56 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
57 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
58 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
59 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
60 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
61 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
62 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
Michal Kaziordcc33092015-03-30 09:51:54 +030063};
64
Michal Kazior8d7aa6b2015-03-30 09:51:57 +030065#define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
66
67#define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
68#define ath10k_a_rates_size (ARRAY_SIZE(ath10k_rates) - \
69 ATH10K_MAC_FIRST_OFDM_RATE_IDX)
Michal Kaziordcc33092015-03-30 09:51:54 +030070#define ath10k_g_rates (ath10k_rates + 0)
71#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
72
Michal Kazior486017c2015-03-30 09:51:54 +030073static bool ath10k_mac_bitrate_is_cck(int bitrate)
74{
75 switch (bitrate) {
76 case 10:
77 case 20:
78 case 55:
79 case 110:
80 return true;
81 }
82
83 return false;
84}
85
86static u8 ath10k_mac_bitrate_to_rate(int bitrate)
87{
88 return DIV_ROUND_UP(bitrate, 5) |
89 (ath10k_mac_bitrate_is_cck(bitrate) ? BIT(7) : 0);
90}
91
Michal Kazior5528e032015-03-30 09:51:56 +030092u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
Yanbo Li4b7f3532015-11-12 10:36:10 -080093 u8 hw_rate, bool cck)
Michal Kazior5528e032015-03-30 09:51:56 +030094{
95 const struct ieee80211_rate *rate;
96 int i;
97
98 for (i = 0; i < sband->n_bitrates; i++) {
99 rate = &sband->bitrates[i];
100
Yanbo Li4b7f3532015-11-12 10:36:10 -0800101 if (ath10k_mac_bitrate_is_cck(rate->bitrate) != cck)
102 continue;
103
Michal Kazior5528e032015-03-30 09:51:56 +0300104 if (rate->hw_value == hw_rate)
105 return i;
106 else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
107 rate->hw_value_short == hw_rate)
108 return i;
109 }
110
111 return 0;
112}
113
Michal Kazior01cebe12015-03-30 09:51:56 +0300114u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
115 u32 bitrate)
116{
117 int i;
118
119 for (i = 0; i < sband->n_bitrates; i++)
120 if (sband->bitrates[i].bitrate == bitrate)
121 return i;
122
123 return 0;
124}
125
Michal Kazior3ae54222015-03-31 10:49:20 +0000126static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
127{
128 switch ((mcs_map >> (2 * nss)) & 0x3) {
129 case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;
130 case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;
131 case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;
132 }
133 return 0;
134}
135
Michal Kazior45c9abc2015-04-21 20:42:58 +0300136static u32
137ath10k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
138{
139 int nss;
140
141 for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--)
142 if (ht_mcs_mask[nss])
143 return nss + 1;
144
145 return 1;
146}
147
148static u32
149ath10k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
150{
151 int nss;
152
153 for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--)
154 if (vht_mcs_mask[nss])
155 return nss + 1;
156
157 return 1;
158}
Kalle Valo5e3dd152013-06-12 20:52:10 +0300159
160/**********/
161/* Crypto */
162/**********/
163
164static int ath10k_send_key(struct ath10k_vif *arvif,
165 struct ieee80211_key_conf *key,
166 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100167 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300168{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200169 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300170 struct wmi_vdev_install_key_arg arg = {
171 .vdev_id = arvif->vdev_id,
172 .key_idx = key->keyidx,
173 .key_len = key->keylen,
174 .key_data = key->key,
Michal Kazior370e5672015-02-18 14:02:26 +0100175 .key_flags = flags,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300176 .macaddr = macaddr,
177 };
178
Michal Kazior548db542013-07-05 16:15:15 +0300179 lockdep_assert_held(&arvif->ar->conf_mutex);
180
Kalle Valo5e3dd152013-06-12 20:52:10 +0300181 switch (key->cipher) {
182 case WLAN_CIPHER_SUITE_CCMP:
183 arg.key_cipher = WMI_CIPHER_AES_CCM;
Marek Kwaczynskie4e82e92015-01-24 12:14:53 +0200184 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300185 break;
186 case WLAN_CIPHER_SUITE_TKIP:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300187 arg.key_cipher = WMI_CIPHER_TKIP;
188 arg.key_txmic_len = 8;
189 arg.key_rxmic_len = 8;
190 break;
191 case WLAN_CIPHER_SUITE_WEP40:
192 case WLAN_CIPHER_SUITE_WEP104:
193 arg.key_cipher = WMI_CIPHER_WEP;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300194 break;
Johannes Berg3cb10942015-01-22 21:38:45 +0100195 case WLAN_CIPHER_SUITE_AES_CMAC:
Bartosz Markowskid7131c02015-03-10 14:32:19 +0100196 WARN_ON(1);
197 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300198 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200199 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300200 return -EOPNOTSUPP;
201 }
202
Kalle Valob9e284e2015-10-05 17:56:35 +0300203 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
David Liuccec9032015-07-24 20:25:32 +0300204 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
David Liuccec9032015-07-24 20:25:32 +0300205
Kalle Valo5e3dd152013-06-12 20:52:10 +0300206 if (cmd == DISABLE_KEY) {
207 arg.key_cipher = WMI_CIPHER_NONE;
208 arg.key_data = NULL;
209 }
210
211 return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
212}
213
214static int ath10k_install_key(struct ath10k_vif *arvif,
215 struct ieee80211_key_conf *key,
216 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100217 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300218{
219 struct ath10k *ar = arvif->ar;
220 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300221 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300222
Michal Kazior548db542013-07-05 16:15:15 +0300223 lockdep_assert_held(&ar->conf_mutex);
224
Wolfram Sang16735d02013-11-14 14:32:02 -0800225 reinit_completion(&ar->install_key_done);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300226
David Liuccec9032015-07-24 20:25:32 +0300227 if (arvif->nohwcrypt)
228 return 1;
229
Michal Kazior370e5672015-02-18 14:02:26 +0100230 ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300231 if (ret)
232 return ret;
233
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300234 time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);
235 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300236 return -ETIMEDOUT;
237
238 return 0;
239}
240
241static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
242 const u8 *addr)
243{
244 struct ath10k *ar = arvif->ar;
245 struct ath10k_peer *peer;
246 int ret;
247 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100248 u32 flags;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300249
250 lockdep_assert_held(&ar->conf_mutex);
251
Michal Kazior8674d902015-08-13 14:10:46 +0200252 if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP &&
Peter Oh7c97b722015-12-03 09:50:55 -0800253 arvif->vif->type != NL80211_IFTYPE_ADHOC &&
254 arvif->vif->type != NL80211_IFTYPE_MESH_POINT))
Michal Kazior8674d902015-08-13 14:10:46 +0200255 return -EINVAL;
256
Kalle Valo5e3dd152013-06-12 20:52:10 +0300257 spin_lock_bh(&ar->data_lock);
258 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
259 spin_unlock_bh(&ar->data_lock);
260
261 if (!peer)
262 return -ENOENT;
263
264 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
265 if (arvif->wep_keys[i] == NULL)
266 continue;
Michal Kazior370e5672015-02-18 14:02:26 +0100267
Michal Kazior8674d902015-08-13 14:10:46 +0200268 switch (arvif->vif->type) {
269 case NL80211_IFTYPE_AP:
270 flags = WMI_KEY_PAIRWISE;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300271
Michal Kazior8674d902015-08-13 14:10:46 +0200272 if (arvif->def_wep_key_idx == i)
273 flags |= WMI_KEY_TX_USAGE;
Michal Kaziorce90b272015-04-10 13:23:21 +0000274
Michal Kazior8674d902015-08-13 14:10:46 +0200275 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
276 SET_KEY, addr, flags);
277 if (ret < 0)
278 return ret;
279 break;
280 case NL80211_IFTYPE_ADHOC:
281 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
282 SET_KEY, addr,
283 WMI_KEY_PAIRWISE);
284 if (ret < 0)
285 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300286
Michal Kazior8674d902015-08-13 14:10:46 +0200287 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
288 SET_KEY, addr, WMI_KEY_GROUP);
289 if (ret < 0)
290 return ret;
291 break;
292 default:
293 WARN_ON(1);
294 return -EINVAL;
295 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300296
Sujith Manoharanae167132014-11-25 11:46:59 +0530297 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300298 peer->keys[i] = arvif->wep_keys[i];
Sujith Manoharanae167132014-11-25 11:46:59 +0530299 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300300 }
301
Michal Kaziorce90b272015-04-10 13:23:21 +0000302 /* In some cases (notably with static WEP IBSS with multiple keys)
303 * multicast Tx becomes broken. Both pairwise and groupwise keys are
304 * installed already. Using WMI_KEY_TX_USAGE in different combinations
305 * didn't seem help. Using def_keyid vdev parameter seems to be
306 * effective so use that.
307 *
308 * FIXME: Revisit. Perhaps this can be done in a less hacky way.
309 */
Michal Kazior8674d902015-08-13 14:10:46 +0200310 if (arvif->vif->type != NL80211_IFTYPE_ADHOC)
311 return 0;
312
Michal Kaziorce90b272015-04-10 13:23:21 +0000313 if (arvif->def_wep_key_idx == -1)
314 return 0;
315
316 ret = ath10k_wmi_vdev_set_param(arvif->ar,
317 arvif->vdev_id,
318 arvif->ar->wmi.vdev_param->def_keyid,
319 arvif->def_wep_key_idx);
320 if (ret) {
321 ath10k_warn(ar, "failed to re-set def wpa key idxon vdev %i: %d\n",
322 arvif->vdev_id, ret);
323 return ret;
324 }
325
Kalle Valo5e3dd152013-06-12 20:52:10 +0300326 return 0;
327}
328
329static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
330 const u8 *addr)
331{
332 struct ath10k *ar = arvif->ar;
333 struct ath10k_peer *peer;
334 int first_errno = 0;
335 int ret;
336 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100337 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300338
339 lockdep_assert_held(&ar->conf_mutex);
340
341 spin_lock_bh(&ar->data_lock);
342 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
343 spin_unlock_bh(&ar->data_lock);
344
345 if (!peer)
346 return -ENOENT;
347
348 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
349 if (peer->keys[i] == NULL)
350 continue;
351
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200352 /* key flags are not required to delete the key */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300353 ret = ath10k_install_key(arvif, peer->keys[i],
Michal Kazior370e5672015-02-18 14:02:26 +0100354 DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300355 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300356 first_errno = ret;
357
David Liuccec9032015-07-24 20:25:32 +0300358 if (ret < 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200359 ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300360 i, ret);
361
Sujith Manoharanae167132014-11-25 11:46:59 +0530362 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300363 peer->keys[i] = NULL;
Sujith Manoharanae167132014-11-25 11:46:59 +0530364 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300365 }
366
367 return first_errno;
368}
369
Sujith Manoharan504f6cd2014-11-25 11:46:58 +0530370bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
371 u8 keyidx)
372{
373 struct ath10k_peer *peer;
374 int i;
375
376 lockdep_assert_held(&ar->data_lock);
377
378 /* We don't know which vdev this peer belongs to,
379 * since WMI doesn't give us that information.
380 *
381 * FIXME: multi-bss needs to be handled.
382 */
383 peer = ath10k_peer_find(ar, 0, addr);
384 if (!peer)
385 return false;
386
387 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
388 if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)
389 return true;
390 }
391
392 return false;
393}
394
Kalle Valo5e3dd152013-06-12 20:52:10 +0300395static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
396 struct ieee80211_key_conf *key)
397{
398 struct ath10k *ar = arvif->ar;
399 struct ath10k_peer *peer;
400 u8 addr[ETH_ALEN];
401 int first_errno = 0;
402 int ret;
403 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100404 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300405
406 lockdep_assert_held(&ar->conf_mutex);
407
408 for (;;) {
409 /* since ath10k_install_key we can't hold data_lock all the
410 * time, so we try to remove the keys incrementally */
411 spin_lock_bh(&ar->data_lock);
412 i = 0;
413 list_for_each_entry(peer, &ar->peers, list) {
414 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
415 if (peer->keys[i] == key) {
Kalle Valob25f32c2014-09-14 12:50:49 +0300416 ether_addr_copy(addr, peer->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300417 peer->keys[i] = NULL;
418 break;
419 }
420 }
421
422 if (i < ARRAY_SIZE(peer->keys))
423 break;
424 }
425 spin_unlock_bh(&ar->data_lock);
426
427 if (i == ARRAY_SIZE(peer->keys))
428 break;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200429 /* key flags are not required to delete the key */
Michal Kazior370e5672015-02-18 14:02:26 +0100430 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300431 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300432 first_errno = ret;
433
434 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200435 ath10k_warn(ar, "failed to remove key for %pM: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +0200436 addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300437 }
438
439 return first_errno;
440}
441
Michal Kaziorad325cb2015-02-18 14:02:27 +0100442static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
443 struct ieee80211_key_conf *key)
444{
445 struct ath10k *ar = arvif->ar;
446 struct ath10k_peer *peer;
447 int ret;
448
449 lockdep_assert_held(&ar->conf_mutex);
450
451 list_for_each_entry(peer, &ar->peers, list) {
452 if (!memcmp(peer->addr, arvif->vif->addr, ETH_ALEN))
453 continue;
454
455 if (!memcmp(peer->addr, arvif->bssid, ETH_ALEN))
456 continue;
457
458 if (peer->keys[key->keyidx] == key)
459 continue;
460
461 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
462 arvif->vdev_id, key->keyidx);
463
464 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
465 if (ret) {
466 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
467 arvif->vdev_id, peer->addr, ret);
468 return ret;
469 }
470 }
471
472 return 0;
473}
474
Kalle Valo5e3dd152013-06-12 20:52:10 +0300475/*********************/
476/* General utilities */
477/*********************/
478
479static inline enum wmi_phy_mode
480chan_to_phymode(const struct cfg80211_chan_def *chandef)
481{
482 enum wmi_phy_mode phymode = MODE_UNKNOWN;
483
484 switch (chandef->chan->band) {
485 case IEEE80211_BAND_2GHZ:
486 switch (chandef->width) {
487 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800488 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
489 phymode = MODE_11B;
490 else
491 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300492 break;
493 case NL80211_CHAN_WIDTH_20:
494 phymode = MODE_11NG_HT20;
495 break;
496 case NL80211_CHAN_WIDTH_40:
497 phymode = MODE_11NG_HT40;
498 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400499 case NL80211_CHAN_WIDTH_5:
500 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300501 case NL80211_CHAN_WIDTH_80:
502 case NL80211_CHAN_WIDTH_80P80:
503 case NL80211_CHAN_WIDTH_160:
504 phymode = MODE_UNKNOWN;
505 break;
506 }
507 break;
508 case IEEE80211_BAND_5GHZ:
509 switch (chandef->width) {
510 case NL80211_CHAN_WIDTH_20_NOHT:
511 phymode = MODE_11A;
512 break;
513 case NL80211_CHAN_WIDTH_20:
514 phymode = MODE_11NA_HT20;
515 break;
516 case NL80211_CHAN_WIDTH_40:
517 phymode = MODE_11NA_HT40;
518 break;
519 case NL80211_CHAN_WIDTH_80:
520 phymode = MODE_11AC_VHT80;
521 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400522 case NL80211_CHAN_WIDTH_5:
523 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300524 case NL80211_CHAN_WIDTH_80P80:
525 case NL80211_CHAN_WIDTH_160:
526 phymode = MODE_UNKNOWN;
527 break;
528 }
529 break;
530 default:
531 break;
532 }
533
534 WARN_ON(phymode == MODE_UNKNOWN);
535 return phymode;
536}
537
538static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
539{
540/*
541 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
542 * 0 for no restriction
543 * 1 for 1/4 us
544 * 2 for 1/2 us
545 * 3 for 1 us
546 * 4 for 2 us
547 * 5 for 4 us
548 * 6 for 8 us
549 * 7 for 16 us
550 */
551 switch (mpdudensity) {
552 case 0:
553 return 0;
554 case 1:
555 case 2:
556 case 3:
557 /* Our lower layer calculations limit our precision to
558 1 microsecond */
559 return 1;
560 case 4:
561 return 2;
562 case 5:
563 return 4;
564 case 6:
565 return 8;
566 case 7:
567 return 16;
568 default:
569 return 0;
570 }
571}
572
Michal Kazior500ff9f2015-03-31 10:26:21 +0000573int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
574 struct cfg80211_chan_def *def)
575{
576 struct ieee80211_chanctx_conf *conf;
577
578 rcu_read_lock();
579 conf = rcu_dereference(vif->chanctx_conf);
580 if (!conf) {
581 rcu_read_unlock();
582 return -ENOENT;
583 }
584
585 *def = conf->def;
586 rcu_read_unlock();
587
588 return 0;
589}
590
591static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,
592 struct ieee80211_chanctx_conf *conf,
593 void *data)
594{
595 int *num = data;
596
597 (*num)++;
598}
599
600static int ath10k_mac_num_chanctxs(struct ath10k *ar)
601{
602 int num = 0;
603
604 ieee80211_iter_chan_contexts_atomic(ar->hw,
605 ath10k_mac_num_chanctxs_iter,
606 &num);
607
608 return num;
609}
610
611static void
612ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
613 struct ieee80211_chanctx_conf *conf,
614 void *data)
615{
616 struct cfg80211_chan_def **def = data;
617
618 *def = &conf->def;
619}
620
Michal Kazior69427262016-03-06 16:14:30 +0200621static int ath10k_peer_create(struct ath10k *ar,
622 struct ieee80211_vif *vif,
623 struct ieee80211_sta *sta,
624 u32 vdev_id,
625 const u8 *addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300626 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300627{
Michal Kaziore04cafb2015-08-05 12:15:24 +0200628 struct ath10k_vif *arvif;
Michal Kazior69427262016-03-06 16:14:30 +0200629 struct ath10k_peer *peer;
Michal Kaziore04cafb2015-08-05 12:15:24 +0200630 int num_peers = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300631 int ret;
632
633 lockdep_assert_held(&ar->conf_mutex);
634
Michal Kaziore04cafb2015-08-05 12:15:24 +0200635 num_peers = ar->num_peers;
636
637 /* Each vdev consumes a peer entry as well */
638 list_for_each_entry(arvif, &ar->arvifs, list)
639 num_peers++;
640
641 if (num_peers >= ar->max_num_peers)
Michal Kaziorcfd10612014-11-25 15:16:05 +0100642 return -ENOBUFS;
643
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300644 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800645 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200646 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200647 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300648 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800649 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300650
651 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800652 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200653 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200654 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300655 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800656 }
Michal Kazior292a7532014-11-25 15:16:04 +0100657
Michal Kazior69427262016-03-06 16:14:30 +0200658 spin_lock_bh(&ar->data_lock);
659
660 peer = ath10k_peer_find(ar, vdev_id, addr);
661 if (!peer) {
662 ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n",
663 addr, vdev_id);
664 ath10k_wmi_peer_delete(ar, vdev_id, addr);
665 spin_unlock_bh(&ar->data_lock);
666 return -ENOENT;
667 }
668
669 peer->vif = vif;
670 peer->sta = sta;
671
672 spin_unlock_bh(&ar->data_lock);
673
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100674 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300675
676 return 0;
677}
678
Kalle Valo5a13e762014-01-20 11:01:46 +0200679static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
680{
681 struct ath10k *ar = arvif->ar;
682 u32 param;
683 int ret;
684
685 param = ar->wmi.pdev_param->sta_kickout_th;
686 ret = ath10k_wmi_pdev_set_param(ar, param,
687 ATH10K_KICKOUT_THRESHOLD);
688 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200689 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200690 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200691 return ret;
692 }
693
694 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
695 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
696 ATH10K_KEEPALIVE_MIN_IDLE);
697 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200698 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200699 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200700 return ret;
701 }
702
703 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
704 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
705 ATH10K_KEEPALIVE_MAX_IDLE);
706 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200707 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200708 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200709 return ret;
710 }
711
712 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
713 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
714 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
715 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200716 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200717 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200718 return ret;
719 }
720
721 return 0;
722}
723
Vivek Natarajanacab6402014-11-26 09:06:12 +0200724static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200725{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200726 struct ath10k *ar = arvif->ar;
727 u32 vdev_param;
728
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200729 vdev_param = ar->wmi.vdev_param->rts_threshold;
730 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200731}
732
Kalle Valo5e3dd152013-06-12 20:52:10 +0300733static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
734{
735 int ret;
736
737 lockdep_assert_held(&ar->conf_mutex);
738
739 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
740 if (ret)
741 return ret;
742
743 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
744 if (ret)
745 return ret;
746
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100747 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100748
Kalle Valo5e3dd152013-06-12 20:52:10 +0300749 return 0;
750}
751
752static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
753{
754 struct ath10k_peer *peer, *tmp;
Michal Kazior69427262016-03-06 16:14:30 +0200755 int peer_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300756
757 lockdep_assert_held(&ar->conf_mutex);
758
759 spin_lock_bh(&ar->data_lock);
760 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
761 if (peer->vdev_id != vdev_id)
762 continue;
763
Michal Kazior7aa7a722014-08-25 12:09:38 +0200764 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300765 peer->addr, vdev_id);
766
Michal Kazior69427262016-03-06 16:14:30 +0200767 for_each_set_bit(peer_id, peer->peer_ids,
768 ATH10K_MAX_NUM_PEER_IDS) {
769 ar->peer_map[peer_id] = NULL;
770 }
771
Kalle Valo5e3dd152013-06-12 20:52:10 +0300772 list_del(&peer->list);
773 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100774 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300775 }
776 spin_unlock_bh(&ar->data_lock);
777}
778
Michal Kaziora96d7742013-07-16 09:38:56 +0200779static void ath10k_peer_cleanup_all(struct ath10k *ar)
780{
781 struct ath10k_peer *peer, *tmp;
782
783 lockdep_assert_held(&ar->conf_mutex);
784
785 spin_lock_bh(&ar->data_lock);
786 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
787 list_del(&peer->list);
788 kfree(peer);
789 }
790 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100791
792 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100793 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200794}
795
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300796static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
797 struct ieee80211_sta *sta,
798 enum wmi_tdls_peer_state state)
799{
800 int ret;
801 struct wmi_tdls_peer_update_cmd_arg arg = {};
802 struct wmi_tdls_peer_capab_arg cap = {};
803 struct wmi_channel_arg chan_arg = {};
804
805 lockdep_assert_held(&ar->conf_mutex);
806
807 arg.vdev_id = vdev_id;
808 arg.peer_state = state;
809 ether_addr_copy(arg.addr, sta->addr);
810
811 cap.peer_max_sp = sta->max_sp;
812 cap.peer_uapsd_queues = sta->uapsd_queues;
813
814 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
815 !sta->tdls_initiator)
816 cap.is_peer_responder = 1;
817
818 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
819 if (ret) {
820 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
821 arg.addr, vdev_id, ret);
822 return ret;
823 }
824
825 return 0;
826}
827
Kalle Valo5e3dd152013-06-12 20:52:10 +0300828/************************/
829/* Interface management */
830/************************/
831
Michal Kazior64badcb2014-09-18 11:18:02 +0300832void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
833{
834 struct ath10k *ar = arvif->ar;
835
836 lockdep_assert_held(&ar->data_lock);
837
838 if (!arvif->beacon)
839 return;
840
841 if (!arvif->beacon_buf)
842 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
843 arvif->beacon->len, DMA_TO_DEVICE);
844
Michal Kazioraf213192015-01-29 14:29:52 +0200845 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
846 arvif->beacon_state != ATH10K_BEACON_SENT))
847 return;
848
Michal Kazior64badcb2014-09-18 11:18:02 +0300849 dev_kfree_skb_any(arvif->beacon);
850
851 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200852 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300853}
854
855static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
856{
857 struct ath10k *ar = arvif->ar;
858
859 lockdep_assert_held(&ar->data_lock);
860
861 ath10k_mac_vif_beacon_free(arvif);
862
863 if (arvif->beacon_buf) {
864 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
865 arvif->beacon_buf, arvif->beacon_paddr);
866 arvif->beacon_buf = NULL;
867 }
868}
869
Kalle Valo5e3dd152013-06-12 20:52:10 +0300870static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
871{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300872 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300873
Michal Kazior548db542013-07-05 16:15:15 +0300874 lockdep_assert_held(&ar->conf_mutex);
875
Michal Kazior7962b0d2014-10-28 10:34:38 +0100876 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
877 return -ESHUTDOWN;
878
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300879 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
880 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
881 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300882 return -ETIMEDOUT;
883
884 return 0;
885}
886
Michal Kazior1bbc0972014-04-08 09:45:47 +0300887static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300888{
Michal Kazior500ff9f2015-03-31 10:26:21 +0000889 struct cfg80211_chan_def *chandef = NULL;
Maninder Singh19be9e92015-07-16 09:25:33 +0530890 struct ieee80211_channel *channel = NULL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300891 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300892 int ret = 0;
893
894 lockdep_assert_held(&ar->conf_mutex);
895
Michal Kazior500ff9f2015-03-31 10:26:21 +0000896 ieee80211_iter_chan_contexts_atomic(ar->hw,
897 ath10k_mac_get_any_chandef_iter,
898 &chandef);
899 if (WARN_ON_ONCE(!chandef))
900 return -ENOENT;
901
902 channel = chandef->chan;
903
Kalle Valo5e3dd152013-06-12 20:52:10 +0300904 arg.vdev_id = vdev_id;
905 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +0100906 arg.channel.band_center_freq1 = chandef->center_freq1;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300907
908 /* TODO setup this dynamically, what in case we
909 don't have any vifs? */
Michal Kaziorc930f742014-01-23 11:38:25 +0100910 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200911 arg.channel.chan_radar =
912 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300913
Michal Kazior89c5c842013-10-23 04:02:13 -0700914 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -0700915 arg.channel.max_power = channel->max_power * 2;
916 arg.channel.max_reg_power = channel->max_reg_power * 2;
917 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300918
Michal Kazior7962b0d2014-10-28 10:34:38 +0100919 reinit_completion(&ar->vdev_setup_done);
920
Kalle Valo5e3dd152013-06-12 20:52:10 +0300921 ret = ath10k_wmi_vdev_start(ar, &arg);
922 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200923 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200924 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300925 return ret;
926 }
927
928 ret = ath10k_vdev_setup_sync(ar);
929 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +0200930 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200931 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300932 return ret;
933 }
934
935 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
936 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200937 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200938 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300939 goto vdev_stop;
940 }
941
942 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300943
Michal Kazior7aa7a722014-08-25 12:09:38 +0200944 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300945 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300946 return 0;
947
948vdev_stop:
949 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
950 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200951 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200952 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300953
954 return ret;
955}
956
Michal Kazior1bbc0972014-04-08 09:45:47 +0300957static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300958{
959 int ret = 0;
960
961 lockdep_assert_held(&ar->conf_mutex);
962
Marek Puzyniak52fa0192013-09-24 14:06:24 +0200963 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
964 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200965 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200966 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300967
Michal Kazior7962b0d2014-10-28 10:34:38 +0100968 reinit_completion(&ar->vdev_setup_done);
969
Kalle Valo5e3dd152013-06-12 20:52:10 +0300970 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
971 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200972 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200973 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300974
975 ret = ath10k_vdev_setup_sync(ar);
976 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +0200977 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200978 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300979
Michal Kazior7aa7a722014-08-25 12:09:38 +0200980 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300981 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300982 return ret;
983}
984
Michal Kazior1bbc0972014-04-08 09:45:47 +0300985static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300986{
987 int bit, ret = 0;
988
989 lockdep_assert_held(&ar->conf_mutex);
990
Ben Greeara9aefb32014-08-12 11:02:19 +0300991 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200992 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300993 return -ENOMEM;
994 }
995
Ben Greear16c11172014-09-23 14:17:16 -0700996 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +0300997
Ben Greear16c11172014-09-23 14:17:16 -0700998 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300999
1000 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
1001 WMI_VDEV_TYPE_MONITOR,
1002 0, ar->mac_addr);
1003 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001004 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001005 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +03001006 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001007 }
1008
Ben Greear16c11172014-09-23 14:17:16 -07001009 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +02001010 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001011 ar->monitor_vdev_id);
1012
Kalle Valo5e3dd152013-06-12 20:52:10 +03001013 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001014}
1015
Michal Kazior1bbc0972014-04-08 09:45:47 +03001016static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001017{
1018 int ret = 0;
1019
1020 lockdep_assert_held(&ar->conf_mutex);
1021
Kalle Valo5e3dd152013-06-12 20:52:10 +03001022 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
1023 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001024 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001025 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001026 return ret;
1027 }
1028
Ben Greear16c11172014-09-23 14:17:16 -07001029 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001030
Michal Kazior7aa7a722014-08-25 12:09:38 +02001031 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001032 ar->monitor_vdev_id);
1033 return ret;
1034}
1035
Michal Kazior1bbc0972014-04-08 09:45:47 +03001036static int ath10k_monitor_start(struct ath10k *ar)
1037{
1038 int ret;
1039
1040 lockdep_assert_held(&ar->conf_mutex);
1041
Michal Kazior1bbc0972014-04-08 09:45:47 +03001042 ret = ath10k_monitor_vdev_create(ar);
1043 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001044 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001045 return ret;
1046 }
1047
1048 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
1049 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001050 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001051 ath10k_monitor_vdev_delete(ar);
1052 return ret;
1053 }
1054
1055 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001056 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +03001057
1058 return 0;
1059}
1060
Michal Kazior19337472014-08-28 12:58:16 +02001061static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +03001062{
1063 int ret;
1064
1065 lockdep_assert_held(&ar->conf_mutex);
1066
Michal Kazior1bbc0972014-04-08 09:45:47 +03001067 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001068 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001069 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001070 return ret;
1071 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001072
1073 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001074 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001075 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001076 return ret;
1077 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001078
1079 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001080 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +02001081
1082 return 0;
1083}
1084
Michal Kazior500ff9f2015-03-31 10:26:21 +00001085static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1086{
1087 int num_ctx;
1088
1089 /* At least one chanctx is required to derive a channel to start
1090 * monitor vdev on.
1091 */
1092 num_ctx = ath10k_mac_num_chanctxs(ar);
1093 if (num_ctx == 0)
1094 return false;
1095
1096 /* If there's already an existing special monitor interface then don't
1097 * bother creating another monitor vdev.
1098 */
1099 if (ar->monitor_arvif)
1100 return false;
1101
1102 return ar->monitor ||
Bob Copeland0d031c82015-09-09 12:47:34 -04001103 ar->filter_flags & FIF_OTHER_BSS ||
Michal Kazior500ff9f2015-03-31 10:26:21 +00001104 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1105}
1106
1107static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1108{
1109 int num_ctx;
1110
1111 num_ctx = ath10k_mac_num_chanctxs(ar);
1112
1113 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1114 * shouldn't allow this but make sure to prevent handling the following
1115 * case anyway since multi-channel DFS hasn't been tested at all.
1116 */
1117 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1118 return false;
1119
1120 return true;
1121}
1122
Michal Kazior19337472014-08-28 12:58:16 +02001123static int ath10k_monitor_recalc(struct ath10k *ar)
1124{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001125 bool needed;
1126 bool allowed;
1127 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001128
1129 lockdep_assert_held(&ar->conf_mutex);
1130
Michal Kazior500ff9f2015-03-31 10:26:21 +00001131 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1132 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001133
1134 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001135 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1136 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001137
Michal Kazior500ff9f2015-03-31 10:26:21 +00001138 if (WARN_ON(needed && !allowed)) {
1139 if (ar->monitor_started) {
1140 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1141
1142 ret = ath10k_monitor_stop(ar);
1143 if (ret)
Kalle Valo2a995082015-10-05 17:56:37 +03001144 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",
1145 ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001146 /* not serious */
1147 }
1148
1149 return -EPERM;
1150 }
1151
1152 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001153 return 0;
1154
Michal Kazior500ff9f2015-03-31 10:26:21 +00001155 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001156 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001157 else
1158 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001159}
1160
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001161static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1162{
1163 struct ath10k *ar = arvif->ar;
1164 u32 vdev_param, rts_cts = 0;
1165
1166 lockdep_assert_held(&ar->conf_mutex);
1167
1168 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1169
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001170 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001171
1172 if (arvif->num_legacy_stations > 0)
1173 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1174 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001175 else
1176 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1177 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001178
1179 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1180 rts_cts);
1181}
1182
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001183static int ath10k_start_cac(struct ath10k *ar)
1184{
1185 int ret;
1186
1187 lockdep_assert_held(&ar->conf_mutex);
1188
1189 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1190
Michal Kazior19337472014-08-28 12:58:16 +02001191 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001192 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001193 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001194 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1195 return ret;
1196 }
1197
Michal Kazior7aa7a722014-08-25 12:09:38 +02001198 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001199 ar->monitor_vdev_id);
1200
1201 return 0;
1202}
1203
1204static int ath10k_stop_cac(struct ath10k *ar)
1205{
1206 lockdep_assert_held(&ar->conf_mutex);
1207
1208 /* CAC is not running - do nothing */
1209 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1210 return 0;
1211
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001212 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001213 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001214
Michal Kazior7aa7a722014-08-25 12:09:38 +02001215 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001216
1217 return 0;
1218}
1219
Michal Kazior500ff9f2015-03-31 10:26:21 +00001220static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1221 struct ieee80211_chanctx_conf *conf,
1222 void *data)
1223{
1224 bool *ret = data;
1225
1226 if (!*ret && conf->radar_enabled)
1227 *ret = true;
1228}
1229
1230static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1231{
1232 bool has_radar = false;
1233
1234 ieee80211_iter_chan_contexts_atomic(ar->hw,
1235 ath10k_mac_has_radar_iter,
1236 &has_radar);
1237
1238 return has_radar;
1239}
1240
Michal Kaziord6500972014-04-08 09:56:09 +03001241static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001242{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001243 int ret;
1244
1245 lockdep_assert_held(&ar->conf_mutex);
1246
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001247 ath10k_stop_cac(ar);
1248
Michal Kazior500ff9f2015-03-31 10:26:21 +00001249 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001250 return;
1251
Michal Kaziord6500972014-04-08 09:56:09 +03001252 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001253 return;
1254
1255 ret = ath10k_start_cac(ar);
1256 if (ret) {
1257 /*
1258 * Not possible to start CAC on current channel so starting
1259 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1260 * by indicating that radar was detected.
1261 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001262 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001263 ieee80211_radar_detected(ar->hw);
1264 }
1265}
1266
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301267static int ath10k_vdev_stop(struct ath10k_vif *arvif)
Michal Kazior72654fa2014-04-08 09:56:09 +03001268{
1269 struct ath10k *ar = arvif->ar;
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301270 int ret;
1271
1272 lockdep_assert_held(&ar->conf_mutex);
1273
1274 reinit_completion(&ar->vdev_setup_done);
1275
1276 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1277 if (ret) {
1278 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1279 arvif->vdev_id, ret);
1280 return ret;
1281 }
1282
1283 ret = ath10k_vdev_setup_sync(ar);
1284 if (ret) {
1285 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
1286 arvif->vdev_id, ret);
1287 return ret;
1288 }
1289
1290 WARN_ON(ar->num_started_vdevs == 0);
1291
1292 if (ar->num_started_vdevs != 0) {
1293 ar->num_started_vdevs--;
1294 ath10k_recalc_radar_detection(ar);
1295 }
1296
1297 return ret;
1298}
1299
Michal Kazior500ff9f2015-03-31 10:26:21 +00001300static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1301 const struct cfg80211_chan_def *chandef,
1302 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001303{
1304 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001305 struct wmi_vdev_start_request_arg arg = {};
1306 int ret = 0;
1307
1308 lockdep_assert_held(&ar->conf_mutex);
1309
1310 reinit_completion(&ar->vdev_setup_done);
1311
1312 arg.vdev_id = arvif->vdev_id;
1313 arg.dtim_period = arvif->dtim_period;
1314 arg.bcn_intval = arvif->beacon_interval;
1315
1316 arg.channel.freq = chandef->chan->center_freq;
1317 arg.channel.band_center_freq1 = chandef->center_freq1;
1318 arg.channel.mode = chan_to_phymode(chandef);
1319
1320 arg.channel.min_power = 0;
1321 arg.channel.max_power = chandef->chan->max_power * 2;
1322 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1323 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1324
1325 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1326 arg.ssid = arvif->u.ap.ssid;
1327 arg.ssid_len = arvif->u.ap.ssid_len;
1328 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1329
1330 /* For now allow DFS for AP mode */
1331 arg.channel.chan_radar =
1332 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1333 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1334 arg.ssid = arvif->vif->bss_conf.ssid;
1335 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1336 }
1337
Michal Kazior7aa7a722014-08-25 12:09:38 +02001338 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001339 "mac vdev %d start center_freq %d phymode %s\n",
1340 arg.vdev_id, arg.channel.freq,
1341 ath10k_wmi_phymode_str(arg.channel.mode));
1342
Michal Kaziordc55e302014-07-29 12:53:36 +03001343 if (restart)
1344 ret = ath10k_wmi_vdev_restart(ar, &arg);
1345 else
1346 ret = ath10k_wmi_vdev_start(ar, &arg);
1347
Michal Kazior72654fa2014-04-08 09:56:09 +03001348 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001349 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001350 arg.vdev_id, ret);
1351 return ret;
1352 }
1353
1354 ret = ath10k_vdev_setup_sync(ar);
1355 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001356 ath10k_warn(ar,
1357 "failed to synchronize setup for vdev %i restart %d: %d\n",
1358 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001359 return ret;
1360 }
1361
Michal Kaziord6500972014-04-08 09:56:09 +03001362 ar->num_started_vdevs++;
1363 ath10k_recalc_radar_detection(ar);
1364
Michal Kazior72654fa2014-04-08 09:56:09 +03001365 return ret;
1366}
1367
Michal Kazior500ff9f2015-03-31 10:26:21 +00001368static int ath10k_vdev_start(struct ath10k_vif *arvif,
1369 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001370{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001371 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001372}
1373
Michal Kazior500ff9f2015-03-31 10:26:21 +00001374static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1375 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001376{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001377 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kazior72654fa2014-04-08 09:56:09 +03001378}
1379
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001380static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1381 struct sk_buff *bcn)
1382{
1383 struct ath10k *ar = arvif->ar;
1384 struct ieee80211_mgmt *mgmt;
1385 const u8 *p2p_ie;
1386 int ret;
1387
Peter Oh08c27be2016-01-28 13:54:09 -08001388 if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001389 return 0;
1390
1391 mgmt = (void *)bcn->data;
1392 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1393 mgmt->u.beacon.variable,
1394 bcn->len - (mgmt->u.beacon.variable -
1395 bcn->data));
1396 if (!p2p_ie)
1397 return -ENOENT;
1398
1399 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1400 if (ret) {
1401 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1402 arvif->vdev_id, ret);
1403 return ret;
1404 }
1405
1406 return 0;
1407}
1408
1409static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1410 u8 oui_type, size_t ie_offset)
1411{
1412 size_t len;
1413 const u8 *next;
1414 const u8 *end;
1415 u8 *ie;
1416
1417 if (WARN_ON(skb->len < ie_offset))
1418 return -EINVAL;
1419
1420 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1421 skb->data + ie_offset,
1422 skb->len - ie_offset);
1423 if (!ie)
1424 return -ENOENT;
1425
1426 len = ie[1] + 2;
1427 end = skb->data + skb->len;
1428 next = ie + len;
1429
1430 if (WARN_ON(next > end))
1431 return -EINVAL;
1432
1433 memmove(ie, next, end - next);
1434 skb_trim(skb, skb->len - len);
1435
1436 return 0;
1437}
1438
1439static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1440{
1441 struct ath10k *ar = arvif->ar;
1442 struct ieee80211_hw *hw = ar->hw;
1443 struct ieee80211_vif *vif = arvif->vif;
1444 struct ieee80211_mutable_offsets offs = {};
1445 struct sk_buff *bcn;
1446 int ret;
1447
1448 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1449 return 0;
1450
Michal Kazior81a9a172015-03-05 16:02:17 +02001451 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1452 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1453 return 0;
1454
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001455 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1456 if (!bcn) {
1457 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1458 return -EPERM;
1459 }
1460
1461 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1462 if (ret) {
1463 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1464 kfree_skb(bcn);
1465 return ret;
1466 }
1467
1468 /* P2P IE is inserted by firmware automatically (as configured above)
1469 * so remove it from the base beacon template to avoid duplicate P2P
1470 * IEs in beacon frames.
1471 */
1472 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1473 offsetof(struct ieee80211_mgmt,
1474 u.beacon.variable));
1475
1476 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1477 0, NULL, 0);
1478 kfree_skb(bcn);
1479
1480 if (ret) {
1481 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1482 ret);
1483 return ret;
1484 }
1485
1486 return 0;
1487}
1488
1489static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1490{
1491 struct ath10k *ar = arvif->ar;
1492 struct ieee80211_hw *hw = ar->hw;
1493 struct ieee80211_vif *vif = arvif->vif;
1494 struct sk_buff *prb;
1495 int ret;
1496
1497 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1498 return 0;
1499
Michal Kazior81a9a172015-03-05 16:02:17 +02001500 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1501 return 0;
1502
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001503 prb = ieee80211_proberesp_get(hw, vif);
1504 if (!prb) {
1505 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1506 return -EPERM;
1507 }
1508
1509 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1510 kfree_skb(prb);
1511
1512 if (ret) {
1513 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1514 ret);
1515 return ret;
1516 }
1517
1518 return 0;
1519}
1520
Michal Kazior500ff9f2015-03-31 10:26:21 +00001521static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1522{
1523 struct ath10k *ar = arvif->ar;
1524 struct cfg80211_chan_def def;
1525 int ret;
1526
1527 /* When originally vdev is started during assign_vif_chanctx() some
1528 * information is missing, notably SSID. Firmware revisions with beacon
1529 * offloading require the SSID to be provided during vdev (re)start to
1530 * handle hidden SSID properly.
1531 *
1532 * Vdev restart must be done after vdev has been both started and
1533 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1534 * deliver vdev restart response event causing timeouts during vdev
1535 * syncing in ath10k.
1536 *
1537 * Note: The vdev down/up and template reinstallation could be skipped
1538 * since only wmi-tlv firmware are known to have beacon offload and
1539 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1540 * response delivery. It's probably more robust to keep it as is.
1541 */
1542 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1543 return 0;
1544
1545 if (WARN_ON(!arvif->is_started))
1546 return -EINVAL;
1547
1548 if (WARN_ON(!arvif->is_up))
1549 return -EINVAL;
1550
1551 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1552 return -EINVAL;
1553
1554 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1555 if (ret) {
1556 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1557 arvif->vdev_id, ret);
1558 return ret;
1559 }
1560
1561 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1562 * firmware will crash upon vdev up.
1563 */
1564
1565 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1566 if (ret) {
1567 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1568 return ret;
1569 }
1570
1571 ret = ath10k_mac_setup_prb_tmpl(arvif);
1572 if (ret) {
1573 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1574 return ret;
1575 }
1576
1577 ret = ath10k_vdev_restart(arvif, &def);
1578 if (ret) {
1579 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1580 arvif->vdev_id, ret);
1581 return ret;
1582 }
1583
1584 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1585 arvif->bssid);
1586 if (ret) {
1587 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1588 arvif->vdev_id, ret);
1589 return ret;
1590 }
1591
1592 return 0;
1593}
1594
Kalle Valo5e3dd152013-06-12 20:52:10 +03001595static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001596 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001597{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001598 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001599 int ret = 0;
1600
Michal Kazior548db542013-07-05 16:15:15 +03001601 lockdep_assert_held(&arvif->ar->conf_mutex);
1602
Kalle Valo5e3dd152013-06-12 20:52:10 +03001603 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001604 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1605 if (ret)
1606 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1607 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001608
Michal Kaziorc930f742014-01-23 11:38:25 +01001609 arvif->is_up = false;
1610
Michal Kazior748afc42014-01-23 12:48:21 +01001611 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001612 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001613 spin_unlock_bh(&arvif->ar->data_lock);
1614
Kalle Valo5e3dd152013-06-12 20:52:10 +03001615 return;
1616 }
1617
1618 arvif->tx_seq_no = 0x1000;
1619
Michal Kaziorc930f742014-01-23 11:38:25 +01001620 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001621 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001622
1623 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1624 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001625 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001626 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001627 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001628 return;
1629 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001630
Michal Kaziorc930f742014-01-23 11:38:25 +01001631 arvif->is_up = true;
1632
Michal Kazior500ff9f2015-03-31 10:26:21 +00001633 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1634 if (ret) {
1635 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1636 arvif->vdev_id, ret);
1637 return;
1638 }
1639
Michal Kazior7aa7a722014-08-25 12:09:38 +02001640 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001641}
1642
1643static void ath10k_control_ibss(struct ath10k_vif *arvif,
1644 struct ieee80211_bss_conf *info,
1645 const u8 self_peer[ETH_ALEN])
1646{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001647 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001648 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001649 int ret = 0;
1650
Michal Kazior548db542013-07-05 16:15:15 +03001651 lockdep_assert_held(&arvif->ar->conf_mutex);
1652
Kalle Valo5e3dd152013-06-12 20:52:10 +03001653 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001654 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001655 return;
1656
Joe Perches93803b32015-03-02 19:54:49 -08001657 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001658
1659 return;
1660 }
1661
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001662 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1663 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001664 ATH10K_DEFAULT_ATIM);
1665 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001666 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001667 arvif->vdev_id, ret);
1668}
1669
Michal Kazior9f9b5742014-12-12 12:41:36 +01001670static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1671{
1672 struct ath10k *ar = arvif->ar;
1673 u32 param;
1674 u32 value;
1675 int ret;
1676
1677 lockdep_assert_held(&arvif->ar->conf_mutex);
1678
1679 if (arvif->u.sta.uapsd)
1680 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1681 else
1682 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1683
1684 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1685 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1686 if (ret) {
1687 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1688 value, arvif->vdev_id, ret);
1689 return ret;
1690 }
1691
1692 return 0;
1693}
1694
1695static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1696{
1697 struct ath10k *ar = arvif->ar;
1698 u32 param;
1699 u32 value;
1700 int ret;
1701
1702 lockdep_assert_held(&arvif->ar->conf_mutex);
1703
1704 if (arvif->u.sta.uapsd)
1705 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1706 else
1707 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1708
1709 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1710 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1711 param, value);
1712 if (ret) {
1713 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1714 value, arvif->vdev_id, ret);
1715 return ret;
1716 }
1717
1718 return 0;
1719}
1720
Michal Kazior424f2632015-07-09 13:08:35 +02001721static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001722{
1723 struct ath10k_vif *arvif;
1724 int num = 0;
1725
1726 lockdep_assert_held(&ar->conf_mutex);
1727
1728 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001729 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001730 num++;
1731
1732 return num;
1733}
1734
Michal Kaziorad088bf2013-10-16 15:44:46 +03001735static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001736{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001737 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001738 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001739 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001740 enum wmi_sta_powersave_param param;
1741 enum wmi_sta_ps_mode psmode;
1742 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001743 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001744 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001745
Michal Kazior548db542013-07-05 16:15:15 +03001746 lockdep_assert_held(&arvif->ar->conf_mutex);
1747
Michal Kaziorad088bf2013-10-16 15:44:46 +03001748 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1749 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001750
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001751 enable_ps = arvif->ps;
1752
Michal Kazior424f2632015-07-09 13:08:35 +02001753 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001754 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
1755 ar->fw_features)) {
1756 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1757 arvif->vdev_id);
1758 enable_ps = false;
1759 }
1760
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001761 if (!arvif->is_started) {
1762 /* mac80211 can update vif powersave state while disconnected.
1763 * Firmware doesn't behave nicely and consumes more power than
1764 * necessary if PS is disabled on a non-started vdev. Hence
1765 * force-enable PS for non-running vdevs.
1766 */
1767 psmode = WMI_STA_PS_MODE_ENABLED;
1768 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001769 psmode = WMI_STA_PS_MODE_ENABLED;
1770 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1771
Michal Kazior526549a2014-12-12 12:41:37 +01001772 ps_timeout = conf->dynamic_ps_timeout;
1773 if (ps_timeout == 0) {
1774 /* Firmware doesn't like 0 */
1775 ps_timeout = ieee80211_tu_to_usec(
1776 vif->bss_conf.beacon_int) / 1000;
1777 }
1778
Michal Kaziorad088bf2013-10-16 15:44:46 +03001779 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001780 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001781 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001782 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001783 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001784 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001785 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001786 } else {
1787 psmode = WMI_STA_PS_MODE_DISABLED;
1788 }
1789
Michal Kazior7aa7a722014-08-25 12:09:38 +02001790 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001791 arvif->vdev_id, psmode ? "enable" : "disable");
1792
Michal Kaziorad088bf2013-10-16 15:44:46 +03001793 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1794 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001795 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001796 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001797 return ret;
1798 }
1799
1800 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001801}
1802
Michal Kazior46725b152015-01-28 09:57:49 +02001803static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1804{
1805 struct ath10k *ar = arvif->ar;
1806 struct wmi_sta_keepalive_arg arg = {};
1807 int ret;
1808
1809 lockdep_assert_held(&arvif->ar->conf_mutex);
1810
1811 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1812 return 0;
1813
1814 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1815 return 0;
1816
1817 /* Some firmware revisions have a bug and ignore the `enabled` field.
1818 * Instead use the interval to disable the keepalive.
1819 */
1820 arg.vdev_id = arvif->vdev_id;
1821 arg.enabled = 1;
1822 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1823 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1824
1825 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1826 if (ret) {
1827 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1828 arvif->vdev_id, ret);
1829 return ret;
1830 }
1831
1832 return 0;
1833}
1834
Michal Kazior81a9a172015-03-05 16:02:17 +02001835static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1836{
1837 struct ath10k *ar = arvif->ar;
1838 struct ieee80211_vif *vif = arvif->vif;
1839 int ret;
1840
Michal Kazior8513d952015-03-09 14:19:24 +01001841 lockdep_assert_held(&arvif->ar->conf_mutex);
1842
1843 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1844 return;
1845
Michal Kazior81a9a172015-03-05 16:02:17 +02001846 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1847 return;
1848
1849 if (!vif->csa_active)
1850 return;
1851
1852 if (!arvif->is_up)
1853 return;
1854
1855 if (!ieee80211_csa_is_complete(vif)) {
1856 ieee80211_csa_update_counter(vif);
1857
1858 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1859 if (ret)
1860 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1861 ret);
1862
1863 ret = ath10k_mac_setup_prb_tmpl(arvif);
1864 if (ret)
1865 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1866 ret);
1867 } else {
1868 ieee80211_csa_finish(vif);
1869 }
1870}
1871
1872static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1873{
1874 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1875 ap_csa_work);
1876 struct ath10k *ar = arvif->ar;
1877
1878 mutex_lock(&ar->conf_mutex);
1879 ath10k_mac_vif_ap_csa_count_down(arvif);
1880 mutex_unlock(&ar->conf_mutex);
1881}
1882
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001883static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1884 struct ieee80211_vif *vif)
1885{
1886 struct sk_buff *skb = data;
1887 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1888 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1889
1890 if (vif->type != NL80211_IFTYPE_STATION)
1891 return;
1892
1893 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1894 return;
1895
1896 cancel_delayed_work(&arvif->connection_loss_work);
1897}
1898
1899void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
1900{
1901 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1902 IEEE80211_IFACE_ITER_NORMAL,
1903 ath10k_mac_handle_beacon_iter,
1904 skb);
1905}
1906
1907static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
1908 struct ieee80211_vif *vif)
1909{
1910 u32 *vdev_id = data;
1911 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1912 struct ath10k *ar = arvif->ar;
1913 struct ieee80211_hw *hw = ar->hw;
1914
1915 if (arvif->vdev_id != *vdev_id)
1916 return;
1917
1918 if (!arvif->is_up)
1919 return;
1920
1921 ieee80211_beacon_loss(vif);
1922
1923 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
1924 * (done by mac80211) succeeds but beacons do not resume then it
1925 * doesn't make sense to continue operation. Queue connection loss work
1926 * which can be cancelled when beacon is received.
1927 */
1928 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
1929 ATH10K_CONNECTION_LOSS_HZ);
1930}
1931
1932void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
1933{
1934 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1935 IEEE80211_IFACE_ITER_NORMAL,
1936 ath10k_mac_handle_beacon_miss_iter,
1937 &vdev_id);
1938}
1939
1940static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
1941{
1942 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1943 connection_loss_work.work);
1944 struct ieee80211_vif *vif = arvif->vif;
1945
1946 if (!arvif->is_up)
1947 return;
1948
1949 ieee80211_connection_loss(vif);
1950}
1951
Kalle Valo5e3dd152013-06-12 20:52:10 +03001952/**********************/
1953/* Station management */
1954/**********************/
1955
Michal Kazior590922a2014-10-21 10:10:29 +03001956static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
1957 struct ieee80211_vif *vif)
1958{
1959 /* Some firmware revisions have unstable STA powersave when listen
1960 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
1961 * generate NullFunc frames properly even if buffered frames have been
1962 * indicated in Beacon TIM. Firmware would seldom wake up to pull
1963 * buffered frames. Often pinging the device from AP would simply fail.
1964 *
1965 * As a workaround set it to 1.
1966 */
1967 if (vif->type == NL80211_IFTYPE_STATION)
1968 return 1;
1969
1970 return ar->hw->conf.listen_interval;
1971}
1972
Kalle Valo5e3dd152013-06-12 20:52:10 +03001973static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001974 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001975 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001976 struct wmi_peer_assoc_complete_arg *arg)
1977{
Michal Kazior590922a2014-10-21 10:10:29 +03001978 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorc51880e2015-03-30 09:51:57 +03001979 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03001980
Michal Kazior548db542013-07-05 16:15:15 +03001981 lockdep_assert_held(&ar->conf_mutex);
1982
Michal Kaziorc51880e2015-03-30 09:51:57 +03001983 if (vif->type == NL80211_IFTYPE_STATION)
1984 aid = vif->bss_conf.aid;
1985 else
1986 aid = sta->aid;
1987
Kalle Valob25f32c2014-09-14 12:50:49 +03001988 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001989 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03001990 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02001991 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03001992 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001993 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03001994 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001995}
1996
1997static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001998 struct ieee80211_vif *vif,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02001999 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002000 struct wmi_peer_assoc_complete_arg *arg)
2001{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002002 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002003 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002004 struct cfg80211_bss *bss;
2005 const u8 *rsnie = NULL;
2006 const u8 *wpaie = NULL;
2007
Michal Kazior548db542013-07-05 16:15:15 +03002008 lockdep_assert_held(&ar->conf_mutex);
2009
Michal Kazior500ff9f2015-03-31 10:26:21 +00002010 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2011 return;
2012
2013 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
2014 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002015 if (bss) {
2016 const struct cfg80211_bss_ies *ies;
2017
2018 rcu_read_lock();
2019 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
2020
2021 ies = rcu_dereference(bss->ies);
2022
2023 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03002024 WLAN_OUI_TYPE_MICROSOFT_WPA,
2025 ies->data,
2026 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002027 rcu_read_unlock();
2028 cfg80211_put_bss(ar->hw->wiphy, bss);
2029 }
2030
2031 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2032 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002033 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002034 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002035 }
2036
2037 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002038 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002039 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002040 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002041
2042 if (sta->mfp &&
2043 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT, ar->fw_features)) {
2044 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002045 }
2046}
2047
2048static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002049 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002050 struct ieee80211_sta *sta,
2051 struct wmi_peer_assoc_complete_arg *arg)
2052{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002053 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002054 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002055 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002056 const struct ieee80211_supported_band *sband;
2057 const struct ieee80211_rate *rates;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002058 enum ieee80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002059 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002060 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002061 int i;
2062
Michal Kazior548db542013-07-05 16:15:15 +03002063 lockdep_assert_held(&ar->conf_mutex);
2064
Michal Kazior500ff9f2015-03-31 10:26:21 +00002065 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2066 return;
2067
Michal Kazior45c9abc2015-04-21 20:42:58 +03002068 band = def.chan->band;
2069 sband = ar->hw->wiphy->bands[band];
2070 ratemask = sta->supp_rates[band];
2071 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002072 rates = sband->bitrates;
2073
2074 rateset->num_rates = 0;
2075
2076 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2077 if (!(ratemask & 1))
2078 continue;
2079
Michal Kazior486017c2015-03-30 09:51:54 +03002080 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2081 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002082 rateset->num_rates++;
2083 }
2084}
2085
Michal Kazior45c9abc2015-04-21 20:42:58 +03002086static bool
2087ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2088{
2089 int nss;
2090
2091 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2092 if (ht_mcs_mask[nss])
2093 return false;
2094
2095 return true;
2096}
2097
2098static bool
2099ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2100{
2101 int nss;
2102
2103 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2104 if (vht_mcs_mask[nss])
2105 return false;
2106
2107 return true;
2108}
2109
Kalle Valo5e3dd152013-06-12 20:52:10 +03002110static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002111 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002112 struct ieee80211_sta *sta,
2113 struct wmi_peer_assoc_complete_arg *arg)
2114{
2115 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002116 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2117 struct cfg80211_chan_def def;
2118 enum ieee80211_band band;
2119 const u8 *ht_mcs_mask;
2120 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002121 int i, n;
2122 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002123 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002124
Michal Kazior548db542013-07-05 16:15:15 +03002125 lockdep_assert_held(&ar->conf_mutex);
2126
Michal Kazior45c9abc2015-04-21 20:42:58 +03002127 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2128 return;
2129
Kalle Valo5e3dd152013-06-12 20:52:10 +03002130 if (!ht_cap->ht_supported)
2131 return;
2132
Michal Kazior45c9abc2015-04-21 20:42:58 +03002133 band = def.chan->band;
2134 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2135 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2136
2137 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2138 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2139 return;
2140
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002141 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002142 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2143 ht_cap->ampdu_factor)) - 1;
2144
2145 arg->peer_mpdu_density =
2146 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2147
2148 arg->peer_ht_caps = ht_cap->cap;
2149 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2150
2151 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002152 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002153
2154 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002155 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002156 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2157 }
2158
Michal Kazior45c9abc2015-04-21 20:42:58 +03002159 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2160 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2161 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002162
Michal Kazior45c9abc2015-04-21 20:42:58 +03002163 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2164 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2165 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002166
2167 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2168 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002169 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002170 }
2171
2172 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002173 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2174 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2175 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2176 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002177 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002178 }
2179
Kalle Valo5e3dd152013-06-12 20:52:10 +03002180 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2181 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2182 else if (ht_cap->mcs.rx_mask[1])
2183 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2184
Michal Kazior45c9abc2015-04-21 20:42:58 +03002185 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2186 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2187 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2188 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002189 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002190 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002191
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002192 /*
2193 * This is a workaround for HT-enabled STAs which break the spec
2194 * and have no HT capabilities RX mask (no HT RX MCS map).
2195 *
2196 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2197 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2198 *
2199 * Firmware asserts if such situation occurs.
2200 */
2201 if (n == 0) {
2202 arg->peer_ht_rates.num_rates = 8;
2203 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2204 arg->peer_ht_rates.rates[i] = i;
2205 } else {
2206 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002207 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002208 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002209
Michal Kazior7aa7a722014-08-25 12:09:38 +02002210 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002211 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002212 arg->peer_ht_rates.num_rates,
2213 arg->peer_num_spatial_streams);
2214}
2215
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002216static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2217 struct ath10k_vif *arvif,
2218 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002219{
2220 u32 uapsd = 0;
2221 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002222 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002223
Michal Kazior548db542013-07-05 16:15:15 +03002224 lockdep_assert_held(&ar->conf_mutex);
2225
Kalle Valo5e3dd152013-06-12 20:52:10 +03002226 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002227 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002228 sta->uapsd_queues, sta->max_sp);
2229
Kalle Valo5e3dd152013-06-12 20:52:10 +03002230 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2231 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2232 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2233 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2234 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2235 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2236 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2237 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2238 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2239 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2240 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2241 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2242
Kalle Valo5e3dd152013-06-12 20:52:10 +03002243 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2244 max_sp = sta->max_sp;
2245
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002246 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2247 sta->addr,
2248 WMI_AP_PS_PEER_PARAM_UAPSD,
2249 uapsd);
2250 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002251 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002252 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002253 return ret;
2254 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002255
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002256 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2257 sta->addr,
2258 WMI_AP_PS_PEER_PARAM_MAX_SP,
2259 max_sp);
2260 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002261 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002262 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002263 return ret;
2264 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002265
2266 /* TODO setup this based on STA listen interval and
2267 beacon interval. Currently we don't know
2268 sta->listen_interval - mac80211 patch required.
2269 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002270 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002271 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2272 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002273 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002274 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002275 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002276 return ret;
2277 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002278 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002279
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002280 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002281}
2282
Michal Kazior45c9abc2015-04-21 20:42:58 +03002283static u16
2284ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2285 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2286{
2287 int idx_limit;
2288 int nss;
2289 u16 mcs_map;
2290 u16 mcs;
2291
2292 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2293 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2294 vht_mcs_limit[nss];
2295
2296 if (mcs_map)
2297 idx_limit = fls(mcs_map) - 1;
2298 else
2299 idx_limit = -1;
2300
2301 switch (idx_limit) {
2302 case 0: /* fall through */
2303 case 1: /* fall through */
2304 case 2: /* fall through */
2305 case 3: /* fall through */
2306 case 4: /* fall through */
2307 case 5: /* fall through */
2308 case 6: /* fall through */
2309 default:
2310 /* see ath10k_mac_can_set_bitrate_mask() */
2311 WARN_ON(1);
2312 /* fall through */
2313 case -1:
2314 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2315 break;
2316 case 7:
2317 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2318 break;
2319 case 8:
2320 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2321 break;
2322 case 9:
2323 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2324 break;
2325 }
2326
2327 tx_mcs_set &= ~(0x3 << (nss * 2));
2328 tx_mcs_set |= mcs << (nss * 2);
2329 }
2330
2331 return tx_mcs_set;
2332}
2333
Kalle Valo5e3dd152013-06-12 20:52:10 +03002334static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002335 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002336 struct ieee80211_sta *sta,
2337 struct wmi_peer_assoc_complete_arg *arg)
2338{
2339 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002340 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002341 struct cfg80211_chan_def def;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002342 enum ieee80211_band band;
2343 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002344 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002345
Michal Kazior500ff9f2015-03-31 10:26:21 +00002346 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2347 return;
2348
Kalle Valo5e3dd152013-06-12 20:52:10 +03002349 if (!vht_cap->vht_supported)
2350 return;
2351
Michal Kazior45c9abc2015-04-21 20:42:58 +03002352 band = def.chan->band;
2353 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2354
2355 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2356 return;
2357
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002358 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002359
Michal Kazior500ff9f2015-03-31 10:26:21 +00002360 if (def.chan->band == IEEE80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002361 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002362
Kalle Valo5e3dd152013-06-12 20:52:10 +03002363 arg->peer_vht_caps = vht_cap->cap;
2364
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002365 ampdu_factor = (vht_cap->cap &
2366 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2367 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2368
2369 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2370 * zero in VHT IE. Using it would result in degraded throughput.
2371 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2372 * it if VHT max_mpdu is smaller. */
2373 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2374 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2375 ampdu_factor)) - 1);
2376
Kalle Valo5e3dd152013-06-12 20:52:10 +03002377 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002378 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002379
2380 arg->peer_vht_rates.rx_max_rate =
2381 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2382 arg->peer_vht_rates.rx_mcs_set =
2383 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2384 arg->peer_vht_rates.tx_max_rate =
2385 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002386 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2387 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002388
Michal Kazior7aa7a722014-08-25 12:09:38 +02002389 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002390 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002391}
2392
2393static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002394 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002395 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002396 struct wmi_peer_assoc_complete_arg *arg)
2397{
Michal Kazior590922a2014-10-21 10:10:29 +03002398 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2399
Kalle Valo5e3dd152013-06-12 20:52:10 +03002400 switch (arvif->vdev_type) {
2401 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002402 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002403 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002404
2405 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002406 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002407 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2408 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002409 break;
2410 case WMI_VDEV_TYPE_STA:
Michal Kazior590922a2014-10-21 10:10:29 +03002411 if (vif->bss_conf.qos)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002412 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002413 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002414 case WMI_VDEV_TYPE_IBSS:
2415 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002416 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002417 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002418 default:
2419 break;
2420 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002421
2422 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002423 sta->addr, !!(arg->peer_flags &
2424 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002425}
2426
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002427static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002428{
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002429 return sta->supp_rates[IEEE80211_BAND_2GHZ] >>
2430 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002431}
2432
Kalle Valo5e3dd152013-06-12 20:52:10 +03002433static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002434 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002435 struct ieee80211_sta *sta,
2436 struct wmi_peer_assoc_complete_arg *arg)
2437{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002438 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002439 struct cfg80211_chan_def def;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002440 enum ieee80211_band band;
2441 const u8 *ht_mcs_mask;
2442 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002443 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2444
Michal Kazior500ff9f2015-03-31 10:26:21 +00002445 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2446 return;
2447
Michal Kazior45c9abc2015-04-21 20:42:58 +03002448 band = def.chan->band;
2449 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2450 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2451
2452 switch (band) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002453 case IEEE80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002454 if (sta->vht_cap.vht_supported &&
2455 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002456 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2457 phymode = MODE_11AC_VHT40;
2458 else
2459 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002460 } else if (sta->ht_cap.ht_supported &&
2461 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002462 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2463 phymode = MODE_11NG_HT40;
2464 else
2465 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002466 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002467 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002468 } else {
2469 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002470 }
2471
2472 break;
2473 case IEEE80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002474 /*
2475 * Check VHT first.
2476 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002477 if (sta->vht_cap.vht_supported &&
2478 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002479 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2480 phymode = MODE_11AC_VHT80;
2481 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2482 phymode = MODE_11AC_VHT40;
2483 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2484 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002485 } else if (sta->ht_cap.ht_supported &&
2486 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2487 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002488 phymode = MODE_11NA_HT40;
2489 else
2490 phymode = MODE_11NA_HT20;
2491 } else {
2492 phymode = MODE_11A;
2493 }
2494
2495 break;
2496 default:
2497 break;
2498 }
2499
Michal Kazior7aa7a722014-08-25 12:09:38 +02002500 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002501 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002502
Kalle Valo5e3dd152013-06-12 20:52:10 +03002503 arg->peer_phymode = phymode;
2504 WARN_ON(phymode == MODE_UNKNOWN);
2505}
2506
Kalle Valob9ada652013-10-16 15:44:46 +03002507static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002508 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002509 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002510 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002511{
Michal Kazior548db542013-07-05 16:15:15 +03002512 lockdep_assert_held(&ar->conf_mutex);
2513
Kalle Valob9ada652013-10-16 15:44:46 +03002514 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002515
Michal Kazior590922a2014-10-21 10:10:29 +03002516 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002517 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002518 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002519 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002520 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002521 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2522 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002523
Kalle Valob9ada652013-10-16 15:44:46 +03002524 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002525}
2526
Michal Kazior90046f52014-02-14 14:45:51 +01002527static const u32 ath10k_smps_map[] = {
2528 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2529 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2530 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2531 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2532};
2533
2534static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2535 const u8 *addr,
2536 const struct ieee80211_sta_ht_cap *ht_cap)
2537{
2538 int smps;
2539
2540 if (!ht_cap->ht_supported)
2541 return 0;
2542
2543 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2544 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2545
2546 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2547 return -EINVAL;
2548
2549 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2550 WMI_PEER_SMPS_STATE,
2551 ath10k_smps_map[smps]);
2552}
2553
Michal Kazior139e1702015-02-15 16:50:42 +02002554static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2555 struct ieee80211_vif *vif,
2556 struct ieee80211_sta_vht_cap vht_cap)
2557{
2558 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2559 int ret;
2560 u32 param;
2561 u32 value;
2562
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302563 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2564 return 0;
2565
Michal Kazior139e1702015-02-15 16:50:42 +02002566 if (!(ar->vht_cap_info &
2567 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2568 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2569 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2570 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2571 return 0;
2572
2573 param = ar->wmi.vdev_param->txbf;
2574 value = 0;
2575
2576 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2577 return 0;
2578
2579 /* The following logic is correct. If a remote STA advertises support
2580 * for being a beamformer then we should enable us being a beamformee.
2581 */
2582
2583 if (ar->vht_cap_info &
2584 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2585 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2586 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2587 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2588
2589 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2590 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2591 }
2592
2593 if (ar->vht_cap_info &
2594 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2595 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2596 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2597 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2598
2599 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2600 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2601 }
2602
2603 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2604 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2605
2606 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2607 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2608
2609 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2610 if (ret) {
2611 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2612 value, ret);
2613 return ret;
2614 }
2615
2616 return 0;
2617}
2618
Kalle Valo5e3dd152013-06-12 20:52:10 +03002619/* can be called only in mac80211 callbacks due to `key_count` usage */
2620static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2621 struct ieee80211_vif *vif,
2622 struct ieee80211_bss_conf *bss_conf)
2623{
2624 struct ath10k *ar = hw->priv;
2625 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002626 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002627 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002628 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002629 struct ieee80211_sta *ap_sta;
2630 int ret;
2631
Michal Kazior548db542013-07-05 16:15:15 +03002632 lockdep_assert_held(&ar->conf_mutex);
2633
Michal Kazior077efc82014-10-21 10:10:29 +03002634 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2635 arvif->vdev_id, arvif->bssid, arvif->aid);
2636
Kalle Valo5e3dd152013-06-12 20:52:10 +03002637 rcu_read_lock();
2638
2639 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2640 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002641 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002642 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002643 rcu_read_unlock();
2644 return;
2645 }
2646
Michal Kazior90046f52014-02-14 14:45:51 +01002647 /* ap_sta must be accessed only within rcu section which must be left
2648 * before calling ath10k_setup_peer_smps() which might sleep. */
2649 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002650 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002651
Michal Kazior590922a2014-10-21 10:10:29 +03002652 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002653 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002654 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002655 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002656 rcu_read_unlock();
2657 return;
2658 }
2659
2660 rcu_read_unlock();
2661
Kalle Valob9ada652013-10-16 15:44:46 +03002662 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2663 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002664 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002665 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002666 return;
2667 }
2668
Michal Kazior90046f52014-02-14 14:45:51 +01002669 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2670 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002671 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002672 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002673 return;
2674 }
2675
Michal Kazior139e1702015-02-15 16:50:42 +02002676 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2677 if (ret) {
2678 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2679 arvif->vdev_id, bss_conf->bssid, ret);
2680 return;
2681 }
2682
Michal Kazior7aa7a722014-08-25 12:09:38 +02002683 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002684 "mac vdev %d up (associated) bssid %pM aid %d\n",
2685 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2686
Michal Kazior077efc82014-10-21 10:10:29 +03002687 WARN_ON(arvif->is_up);
2688
Michal Kaziorc930f742014-01-23 11:38:25 +01002689 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002690 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002691
2692 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2693 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002694 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002695 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002696 return;
2697 }
2698
2699 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002700
2701 /* Workaround: Some firmware revisions (tested with qca6174
2702 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2703 * poked with peer param command.
2704 */
2705 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2706 WMI_PEER_DUMMY_VAR, 1);
2707 if (ret) {
2708 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2709 arvif->bssid, arvif->vdev_id, ret);
2710 return;
2711 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002712}
2713
Kalle Valo5e3dd152013-06-12 20:52:10 +03002714static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2715 struct ieee80211_vif *vif)
2716{
2717 struct ath10k *ar = hw->priv;
2718 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002719 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002720 int ret;
2721
Michal Kazior548db542013-07-05 16:15:15 +03002722 lockdep_assert_held(&ar->conf_mutex);
2723
Michal Kazior077efc82014-10-21 10:10:29 +03002724 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2725 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002726
Kalle Valo5e3dd152013-06-12 20:52:10 +03002727 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002728 if (ret)
2729 ath10k_warn(ar, "faield to down vdev %i: %d\n",
2730 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002731
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002732 arvif->def_wep_key_idx = -1;
2733
Michal Kazior139e1702015-02-15 16:50:42 +02002734 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2735 if (ret) {
2736 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2737 arvif->vdev_id, ret);
2738 return;
2739 }
2740
Michal Kaziorc930f742014-01-23 11:38:25 +01002741 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002742
2743 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002744}
2745
Michal Kazior590922a2014-10-21 10:10:29 +03002746static int ath10k_station_assoc(struct ath10k *ar,
2747 struct ieee80211_vif *vif,
2748 struct ieee80211_sta *sta,
2749 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002750{
Michal Kazior590922a2014-10-21 10:10:29 +03002751 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002752 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002753 int ret = 0;
2754
Michal Kazior548db542013-07-05 16:15:15 +03002755 lockdep_assert_held(&ar->conf_mutex);
2756
Michal Kazior590922a2014-10-21 10:10:29 +03002757 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002758 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002759 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002760 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002761 return ret;
2762 }
2763
2764 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2765 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002766 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002767 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002768 return ret;
2769 }
2770
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002771 /* Re-assoc is run only to update supported rates for given station. It
2772 * doesn't make much sense to reconfigure the peer completely.
2773 */
2774 if (!reassoc) {
2775 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2776 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002777 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002778 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002779 arvif->vdev_id, ret);
2780 return ret;
2781 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002782
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002783 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2784 if (ret) {
2785 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2786 sta->addr, arvif->vdev_id, ret);
2787 return ret;
2788 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002789
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002790 if (!sta->wme) {
2791 arvif->num_legacy_stations++;
2792 ret = ath10k_recalc_rtscts_prot(arvif);
2793 if (ret) {
2794 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2795 arvif->vdev_id, ret);
2796 return ret;
2797 }
2798 }
2799
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002800 /* Plumb cached keys only for static WEP */
2801 if (arvif->def_wep_key_idx != -1) {
2802 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2803 if (ret) {
2804 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2805 arvif->vdev_id, ret);
2806 return ret;
2807 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002808 }
2809 }
2810
Kalle Valo5e3dd152013-06-12 20:52:10 +03002811 return ret;
2812}
2813
Michal Kazior590922a2014-10-21 10:10:29 +03002814static int ath10k_station_disassoc(struct ath10k *ar,
2815 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002816 struct ieee80211_sta *sta)
2817{
Michal Kazior590922a2014-10-21 10:10:29 +03002818 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002819 int ret = 0;
2820
2821 lockdep_assert_held(&ar->conf_mutex);
2822
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002823 if (!sta->wme) {
2824 arvif->num_legacy_stations--;
2825 ret = ath10k_recalc_rtscts_prot(arvif);
2826 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002827 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002828 arvif->vdev_id, ret);
2829 return ret;
2830 }
2831 }
2832
Kalle Valo5e3dd152013-06-12 20:52:10 +03002833 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2834 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002835 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002836 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002837 return ret;
2838 }
2839
2840 return ret;
2841}
2842
2843/**************/
2844/* Regulatory */
2845/**************/
2846
2847static int ath10k_update_channel_list(struct ath10k *ar)
2848{
2849 struct ieee80211_hw *hw = ar->hw;
2850 struct ieee80211_supported_band **bands;
2851 enum ieee80211_band band;
2852 struct ieee80211_channel *channel;
2853 struct wmi_scan_chan_list_arg arg = {0};
2854 struct wmi_channel_arg *ch;
2855 bool passive;
2856 int len;
2857 int ret;
2858 int i;
2859
Michal Kazior548db542013-07-05 16:15:15 +03002860 lockdep_assert_held(&ar->conf_mutex);
2861
Kalle Valo5e3dd152013-06-12 20:52:10 +03002862 bands = hw->wiphy->bands;
2863 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2864 if (!bands[band])
2865 continue;
2866
2867 for (i = 0; i < bands[band]->n_channels; i++) {
2868 if (bands[band]->channels[i].flags &
2869 IEEE80211_CHAN_DISABLED)
2870 continue;
2871
2872 arg.n_channels++;
2873 }
2874 }
2875
2876 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2877 arg.channels = kzalloc(len, GFP_KERNEL);
2878 if (!arg.channels)
2879 return -ENOMEM;
2880
2881 ch = arg.channels;
2882 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2883 if (!bands[band])
2884 continue;
2885
2886 for (i = 0; i < bands[band]->n_channels; i++) {
2887 channel = &bands[band]->channels[i];
2888
2889 if (channel->flags & IEEE80211_CHAN_DISABLED)
2890 continue;
2891
2892 ch->allow_ht = true;
2893
2894 /* FIXME: when should we really allow VHT? */
2895 ch->allow_vht = true;
2896
2897 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002898 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002899
2900 ch->ht40plus =
2901 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2902
Marek Puzyniake8a50f82013-11-20 09:59:47 +02002903 ch->chan_radar =
2904 !!(channel->flags & IEEE80211_CHAN_RADAR);
2905
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002906 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002907 ch->passive = passive;
2908
2909 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02002910 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07002911 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07002912 ch->max_power = channel->max_power * 2;
2913 ch->max_reg_power = channel->max_reg_power * 2;
2914 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002915 ch->reg_class_id = 0; /* FIXME */
2916
2917 /* FIXME: why use only legacy modes, why not any
2918 * HT/VHT modes? Would that even make any
2919 * difference? */
2920 if (channel->band == IEEE80211_BAND_2GHZ)
2921 ch->mode = MODE_11G;
2922 else
2923 ch->mode = MODE_11A;
2924
2925 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
2926 continue;
2927
Michal Kazior7aa7a722014-08-25 12:09:38 +02002928 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002929 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
2930 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002931 ch->freq, ch->max_power, ch->max_reg_power,
2932 ch->max_antenna_gain, ch->mode);
2933
2934 ch++;
2935 }
2936 }
2937
2938 ret = ath10k_wmi_scan_chan_list(ar, &arg);
2939 kfree(arg.channels);
2940
2941 return ret;
2942}
2943
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002944static enum wmi_dfs_region
2945ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
2946{
2947 switch (dfs_region) {
2948 case NL80211_DFS_UNSET:
2949 return WMI_UNINIT_DFS_DOMAIN;
2950 case NL80211_DFS_FCC:
2951 return WMI_FCC_DFS_DOMAIN;
2952 case NL80211_DFS_ETSI:
2953 return WMI_ETSI_DFS_DOMAIN;
2954 case NL80211_DFS_JP:
2955 return WMI_MKK4_DFS_DOMAIN;
2956 }
2957 return WMI_UNINIT_DFS_DOMAIN;
2958}
2959
Michal Kaziorf7843d72013-07-16 09:38:52 +02002960static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002961{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002962 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002963 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002964 enum wmi_dfs_region wmi_dfs_reg;
2965 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002966
Michal Kaziorf7843d72013-07-16 09:38:52 +02002967 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002968
2969 ret = ath10k_update_channel_list(ar);
2970 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002971 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002972
2973 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002974
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002975 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
2976 nl_dfs_reg = ar->dfs_detector->region;
2977 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
2978 } else {
2979 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
2980 }
2981
Kalle Valo5e3dd152013-06-12 20:52:10 +03002982 /* Target allows setting up per-band regdomain but ath_common provides
2983 * a combined one only */
2984 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02002985 regpair->reg_domain,
2986 regpair->reg_domain, /* 2ghz */
2987 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03002988 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002989 regpair->reg_5ghz_ctl,
2990 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002991 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002992 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02002993}
Michal Kazior548db542013-07-05 16:15:15 +03002994
Michal Kaziorf7843d72013-07-16 09:38:52 +02002995static void ath10k_reg_notifier(struct wiphy *wiphy,
2996 struct regulatory_request *request)
2997{
2998 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2999 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003000 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003001
3002 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3003
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003004 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003005 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003006 request->dfs_region);
3007 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3008 request->dfs_region);
3009 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003010 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003011 request->dfs_region);
3012 }
3013
Michal Kaziorf7843d72013-07-16 09:38:52 +02003014 mutex_lock(&ar->conf_mutex);
3015 if (ar->state == ATH10K_STATE_ON)
3016 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003017 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003018}
3019
3020/***************/
3021/* TX handlers */
3022/***************/
3023
Michal Kaziora30c7d02016-03-06 16:14:23 +02003024enum ath10k_mac_tx_path {
3025 ATH10K_MAC_TX_HTT,
3026 ATH10K_MAC_TX_HTT_MGMT,
3027 ATH10K_MAC_TX_WMI_MGMT,
3028 ATH10K_MAC_TX_UNKNOWN,
3029};
3030
Michal Kazior96d828d2015-03-31 10:26:23 +00003031void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3032{
3033 lockdep_assert_held(&ar->htt.tx_lock);
3034
3035 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3036 ar->tx_paused |= BIT(reason);
3037 ieee80211_stop_queues(ar->hw);
3038}
3039
3040static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3041 struct ieee80211_vif *vif)
3042{
3043 struct ath10k *ar = data;
3044 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3045
3046 if (arvif->tx_paused)
3047 return;
3048
3049 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3050}
3051
3052void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3053{
3054 lockdep_assert_held(&ar->htt.tx_lock);
3055
3056 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3057 ar->tx_paused &= ~BIT(reason);
3058
3059 if (ar->tx_paused)
3060 return;
3061
3062 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3063 IEEE80211_IFACE_ITER_RESUME_ALL,
3064 ath10k_mac_tx_unlock_iter,
3065 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003066
3067 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003068}
3069
3070void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3071{
3072 struct ath10k *ar = arvif->ar;
3073
3074 lockdep_assert_held(&ar->htt.tx_lock);
3075
3076 WARN_ON(reason >= BITS_PER_LONG);
3077 arvif->tx_paused |= BIT(reason);
3078 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3079}
3080
3081void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3082{
3083 struct ath10k *ar = arvif->ar;
3084
3085 lockdep_assert_held(&ar->htt.tx_lock);
3086
3087 WARN_ON(reason >= BITS_PER_LONG);
3088 arvif->tx_paused &= ~BIT(reason);
3089
3090 if (ar->tx_paused)
3091 return;
3092
3093 if (arvif->tx_paused)
3094 return;
3095
3096 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3097}
3098
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003099static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3100 enum wmi_tlv_tx_pause_id pause_id,
3101 enum wmi_tlv_tx_pause_action action)
3102{
3103 struct ath10k *ar = arvif->ar;
3104
3105 lockdep_assert_held(&ar->htt.tx_lock);
3106
Michal Kazioracd0b272015-07-09 13:08:38 +02003107 switch (action) {
3108 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3109 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003110 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003111 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3112 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3113 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003114 default:
Michal Kazioracd0b272015-07-09 13:08:38 +02003115 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
3116 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003117 break;
3118 }
3119}
3120
3121struct ath10k_mac_tx_pause {
3122 u32 vdev_id;
3123 enum wmi_tlv_tx_pause_id pause_id;
3124 enum wmi_tlv_tx_pause_action action;
3125};
3126
3127static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3128 struct ieee80211_vif *vif)
3129{
3130 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3131 struct ath10k_mac_tx_pause *arg = data;
3132
Michal Kazioracd0b272015-07-09 13:08:38 +02003133 if (arvif->vdev_id != arg->vdev_id)
3134 return;
3135
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003136 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3137}
3138
Michal Kazioracd0b272015-07-09 13:08:38 +02003139void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3140 enum wmi_tlv_tx_pause_id pause_id,
3141 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003142{
3143 struct ath10k_mac_tx_pause arg = {
3144 .vdev_id = vdev_id,
3145 .pause_id = pause_id,
3146 .action = action,
3147 };
3148
3149 spin_lock_bh(&ar->htt.tx_lock);
3150 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3151 IEEE80211_IFACE_ITER_RESUME_ALL,
3152 ath10k_mac_handle_tx_pause_iter,
3153 &arg);
3154 spin_unlock_bh(&ar->htt.tx_lock);
3155}
3156
Michal Kaziord740d8f2015-03-30 09:51:51 +03003157static enum ath10k_hw_txrx_mode
Michal Kazior6a2636d2015-11-18 06:59:16 +01003158ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3159 struct ieee80211_vif *vif,
3160 struct ieee80211_sta *sta,
3161 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003162{
3163 const struct ieee80211_hdr *hdr = (void *)skb->data;
3164 __le16 fc = hdr->frame_control;
3165
3166 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3167 return ATH10K_HW_TXRX_RAW;
3168
3169 if (ieee80211_is_mgmt(fc))
3170 return ATH10K_HW_TXRX_MGMT;
3171
3172 /* Workaround:
3173 *
3174 * NullFunc frames are mostly used to ping if a client or AP are still
3175 * reachable and responsive. This implies tx status reports must be
3176 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3177 * come to a conclusion that the other end disappeared and tear down
3178 * BSS connection or it can never disconnect from BSS/client (which is
3179 * the case).
3180 *
3181 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3182 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3183 * which seems to deliver correct tx reports for NullFunc frames. The
3184 * downside of using it is it ignores client powersave state so it can
3185 * end up disconnecting sleeping clients in AP mode. It should fix STA
3186 * mode though because AP don't sleep.
3187 */
3188 if (ar->htt.target_version_major < 3 &&
3189 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
3190 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, ar->fw_features))
3191 return ATH10K_HW_TXRX_MGMT;
3192
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003193 /* Workaround:
3194 *
3195 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3196 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3197 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003198 *
3199 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003200 */
3201 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3202 return ATH10K_HW_TXRX_ETHERNET;
3203
David Liuccec9032015-07-24 20:25:32 +03003204 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3205 return ATH10K_HW_TXRX_RAW;
3206
Michal Kaziord740d8f2015-03-30 09:51:51 +03003207 return ATH10K_HW_TXRX_NATIVE_WIFI;
3208}
3209
David Liuccec9032015-07-24 20:25:32 +03003210static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003211 struct sk_buff *skb)
3212{
3213 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3214 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003215 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3216 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003217
3218 if (!ieee80211_has_protected(hdr->frame_control))
3219 return false;
3220
David Liuccec9032015-07-24 20:25:32 +03003221 if ((info->flags & mask) == mask)
3222 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003223
David Liuccec9032015-07-24 20:25:32 +03003224 if (vif)
3225 return !ath10k_vif_to_arvif(vif)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003226
David Liuccec9032015-07-24 20:25:32 +03003227 return true;
3228}
3229
Michal Kazior4b604552014-07-21 21:03:09 +03003230/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3231 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003232 */
Michal Kazior4b604552014-07-21 21:03:09 +03003233static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003234{
3235 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003236 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003237 u8 *qos_ctl;
3238
3239 if (!ieee80211_is_data_qos(hdr->frame_control))
3240 return;
3241
3242 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003243 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3244 skb->data, (void *)qos_ctl - (void *)skb->data);
3245 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003246
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003247 /* Some firmware revisions don't handle sending QoS NullFunc well.
3248 * These frames are mainly used for CQM purposes so it doesn't really
3249 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003250 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003251 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003252 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003253 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003254
3255 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003256}
3257
Michal Kaziord740d8f2015-03-30 09:51:51 +03003258static void ath10k_tx_h_8023(struct sk_buff *skb)
3259{
3260 struct ieee80211_hdr *hdr;
3261 struct rfc1042_hdr *rfc1042;
3262 struct ethhdr *eth;
3263 size_t hdrlen;
3264 u8 da[ETH_ALEN];
3265 u8 sa[ETH_ALEN];
3266 __be16 type;
3267
3268 hdr = (void *)skb->data;
3269 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3270 rfc1042 = (void *)skb->data + hdrlen;
3271
3272 ether_addr_copy(da, ieee80211_get_DA(hdr));
3273 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3274 type = rfc1042->snap_type;
3275
3276 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3277 skb_push(skb, sizeof(*eth));
3278
3279 eth = (void *)skb->data;
3280 ether_addr_copy(eth->h_dest, da);
3281 ether_addr_copy(eth->h_source, sa);
3282 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003283}
3284
Michal Kazior4b604552014-07-21 21:03:09 +03003285static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3286 struct ieee80211_vif *vif,
3287 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003288{
3289 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003290 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3291
3292 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003293 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003294 return;
3295
3296 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3297 spin_lock_bh(&ar->data_lock);
3298 if (arvif->u.ap.noa_data)
3299 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3300 GFP_ATOMIC))
3301 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3302 arvif->u.ap.noa_data,
3303 arvif->u.ap.noa_len);
3304 spin_unlock_bh(&ar->data_lock);
3305 }
3306}
3307
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003308static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3309 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003310 struct ieee80211_txq *txq,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003311 struct sk_buff *skb)
3312{
3313 struct ieee80211_hdr *hdr = (void *)skb->data;
3314 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3315
3316 cb->flags = 0;
3317 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3318 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3319
3320 if (ieee80211_is_mgmt(hdr->frame_control))
3321 cb->flags |= ATH10K_SKB_F_MGMT;
3322
3323 if (ieee80211_is_data_qos(hdr->frame_control))
3324 cb->flags |= ATH10K_SKB_F_QOS;
3325
3326 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003327 cb->txq = txq;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003328}
3329
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303330bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003331{
3332 /* FIXME: Not really sure since when the behaviour changed. At some
3333 * point new firmware stopped requiring creation of peer entries for
3334 * offchannel tx (and actually creating them causes issues with wmi-htc
3335 * tx credit replenishment and reliability). Assuming it's at least 3.4
3336 * because that's when the `freq` was introduced to TX_FRM HTT command.
3337 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303338 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303339 ar->htt.target_version_minor >= 4 &&
3340 ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003341}
3342
Michal Kaziord740d8f2015-03-30 09:51:51 +03003343static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003344{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003345 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003346 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003347
Michal Kaziord740d8f2015-03-30 09:51:51 +03003348 spin_lock_bh(&ar->data_lock);
3349
3350 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3351 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3352 ret = -ENOSPC;
3353 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003354 }
3355
Michal Kaziord740d8f2015-03-30 09:51:51 +03003356 __skb_queue_tail(q, skb);
3357 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3358
3359unlock:
3360 spin_unlock_bh(&ar->data_lock);
3361
3362 return ret;
3363}
3364
Michal Kaziora30c7d02016-03-06 16:14:23 +02003365static enum ath10k_mac_tx_path
3366ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3367 struct sk_buff *skb,
3368 enum ath10k_hw_txrx_mode txmode)
3369{
3370 switch (txmode) {
3371 case ATH10K_HW_TXRX_RAW:
3372 case ATH10K_HW_TXRX_NATIVE_WIFI:
3373 case ATH10K_HW_TXRX_ETHERNET:
3374 return ATH10K_MAC_TX_HTT;
3375 case ATH10K_HW_TXRX_MGMT:
3376 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3377 ar->fw_features))
3378 return ATH10K_MAC_TX_WMI_MGMT;
3379 else if (ar->htt.target_version_major >= 3)
3380 return ATH10K_MAC_TX_HTT;
3381 else
3382 return ATH10K_MAC_TX_HTT_MGMT;
3383 }
3384
3385 return ATH10K_MAC_TX_UNKNOWN;
3386}
3387
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003388static int ath10k_mac_tx_submit(struct ath10k *ar,
3389 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003390 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003391 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003392{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003393 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003394 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003395
3396 switch (txpath) {
3397 case ATH10K_MAC_TX_HTT:
Michal Kazior8a933962015-11-18 06:59:17 +01003398 ret = ath10k_htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003399 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003400 case ATH10K_MAC_TX_HTT_MGMT:
3401 ret = ath10k_htt_mgmt_tx(htt, skb);
3402 break;
3403 case ATH10K_MAC_TX_WMI_MGMT:
3404 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3405 break;
3406 case ATH10K_MAC_TX_UNKNOWN:
3407 WARN_ON_ONCE(1);
3408 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003409 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003410 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003411
3412 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003413 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3414 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003415 ieee80211_free_txskb(ar->hw, skb);
3416 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003417
3418 return ret;
3419}
3420
3421/* This function consumes the sk_buff regardless of return value as far as
3422 * caller is concerned so no freeing is necessary afterwards.
3423 */
3424static int ath10k_mac_tx(struct ath10k *ar,
3425 struct ieee80211_vif *vif,
3426 struct ieee80211_sta *sta,
3427 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003428 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003429 struct sk_buff *skb)
3430{
3431 struct ieee80211_hw *hw = ar->hw;
3432 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3433 int ret;
3434
3435 /* We should disable CCK RATE due to P2P */
3436 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3437 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3438
3439 switch (txmode) {
3440 case ATH10K_HW_TXRX_MGMT:
3441 case ATH10K_HW_TXRX_NATIVE_WIFI:
3442 ath10k_tx_h_nwifi(hw, skb);
3443 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3444 ath10k_tx_h_seq_no(vif, skb);
3445 break;
3446 case ATH10K_HW_TXRX_ETHERNET:
3447 ath10k_tx_h_8023(skb);
3448 break;
3449 case ATH10K_HW_TXRX_RAW:
3450 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3451 WARN_ON_ONCE(1);
3452 ieee80211_free_txskb(hw, skb);
3453 return -ENOTSUPP;
3454 }
3455 }
3456
3457 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3458 if (!ath10k_mac_tx_frm_has_freq(ar)) {
3459 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
3460 skb);
3461
3462 skb_queue_tail(&ar->offchan_tx_queue, skb);
3463 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3464 return 0;
3465 }
3466 }
3467
Michal Kazior6421969f2016-03-06 16:14:25 +02003468 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003469 if (ret) {
3470 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3471 return ret;
3472 }
3473
3474 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003475}
3476
3477void ath10k_offchan_tx_purge(struct ath10k *ar)
3478{
3479 struct sk_buff *skb;
3480
3481 for (;;) {
3482 skb = skb_dequeue(&ar->offchan_tx_queue);
3483 if (!skb)
3484 break;
3485
3486 ieee80211_free_txskb(ar->hw, skb);
3487 }
3488}
3489
3490void ath10k_offchan_tx_work(struct work_struct *work)
3491{
3492 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3493 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003494 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003495 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003496 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003497 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003498 struct ieee80211_vif *vif;
3499 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003500 struct sk_buff *skb;
3501 const u8 *peer_addr;
3502 int vdev_id;
3503 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003504 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003505 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003506
3507 /* FW requirement: We must create a peer before FW will send out
3508 * an offchannel frame. Otherwise the frame will be stuck and
3509 * never transmitted. We delete the peer upon tx completion.
3510 * It is unlikely that a peer for offchannel tx will already be
3511 * present. However it may be in some rare cases so account for that.
3512 * Otherwise we might remove a legitimate peer and break stuff. */
3513
3514 for (;;) {
3515 skb = skb_dequeue(&ar->offchan_tx_queue);
3516 if (!skb)
3517 break;
3518
3519 mutex_lock(&ar->conf_mutex);
3520
Michal Kazior7aa7a722014-08-25 12:09:38 +02003521 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003522 skb);
3523
3524 hdr = (struct ieee80211_hdr *)skb->data;
3525 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003526
3527 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003528 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003529 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3530 spin_unlock_bh(&ar->data_lock);
3531
3532 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003533 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003534 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003535 peer_addr, vdev_id);
3536
3537 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003538 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3539 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003540 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003541 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003542 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003543 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003544 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003545 }
3546
3547 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003548 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003549 ar->offchan_tx_skb = skb;
3550 spin_unlock_bh(&ar->data_lock);
3551
Michal Kazior8a933962015-11-18 06:59:17 +01003552 /* It's safe to access vif and sta - conf_mutex guarantees that
3553 * sta_state() and remove_interface() are locked exclusively
3554 * out wrt to this offchannel worker.
3555 */
3556 arvif = ath10k_get_arvif(ar, vdev_id);
3557 if (arvif) {
3558 vif = arvif->vif;
3559 sta = ieee80211_find_sta(vif, peer_addr);
3560 } else {
3561 vif = NULL;
3562 sta = NULL;
3563 }
3564
3565 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003566 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003567
Michal Kazior6421969f2016-03-06 16:14:25 +02003568 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003569 if (ret) {
3570 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3571 ret);
3572 /* not serious */
3573 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003574
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003575 time_left =
3576 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3577 if (time_left == 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003578 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003579 skb);
3580
Michal Kazioradaeed72015-08-05 12:15:23 +02003581 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003582 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3583 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003584 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003585 peer_addr, vdev_id, ret);
3586 }
3587
3588 mutex_unlock(&ar->conf_mutex);
3589 }
3590}
3591
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003592void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3593{
3594 struct sk_buff *skb;
3595
3596 for (;;) {
3597 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3598 if (!skb)
3599 break;
3600
3601 ieee80211_free_txskb(ar->hw, skb);
3602 }
3603}
3604
3605void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3606{
3607 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3608 struct sk_buff *skb;
3609 int ret;
3610
3611 for (;;) {
3612 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3613 if (!skb)
3614 break;
3615
3616 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003617 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003618 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003619 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003620 ieee80211_free_txskb(ar->hw, skb);
3621 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003622 }
3623}
3624
Michal Kazior29946872016-03-06 16:14:34 +02003625static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3626{
3627 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3628
3629 if (!txq)
3630 return;
3631
3632 INIT_LIST_HEAD(&artxq->list);
3633}
3634
3635static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3636{
3637 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003638 struct ath10k_skb_cb *cb;
3639 struct sk_buff *msdu;
3640 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003641
3642 if (!txq)
3643 return;
3644
3645 spin_lock_bh(&ar->txqs_lock);
3646 if (!list_empty(&artxq->list))
3647 list_del_init(&artxq->list);
3648 spin_unlock_bh(&ar->txqs_lock);
Michal Kaziordd4717b2016-03-06 16:14:39 +02003649
3650 spin_lock_bh(&ar->htt.tx_lock);
3651 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3652 cb = ATH10K_SKB_CB(msdu);
3653 if (cb->txq == txq)
3654 cb->txq = NULL;
3655 }
3656 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003657}
3658
3659static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3660 struct ieee80211_txq *txq)
3661{
3662 return 1; /* TBD */
3663}
3664
3665static int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3666 struct ieee80211_txq *txq)
3667{
3668 const bool is_mgmt = false;
3669 const bool is_presp = false;
3670 struct ath10k *ar = hw->priv;
3671 struct ath10k_htt *htt = &ar->htt;
3672 struct ieee80211_vif *vif = txq->vif;
3673 struct ieee80211_sta *sta = txq->sta;
3674 enum ath10k_hw_txrx_mode txmode;
3675 enum ath10k_mac_tx_path txpath;
3676 struct sk_buff *skb;
3677 int ret;
3678
3679 spin_lock_bh(&ar->htt.tx_lock);
3680 ret = ath10k_htt_tx_inc_pending(htt, is_mgmt, is_presp);
3681 spin_unlock_bh(&ar->htt.tx_lock);
3682
3683 if (ret)
3684 return ret;
3685
3686 skb = ieee80211_tx_dequeue(hw, txq);
3687 if (!skb) {
3688 spin_lock_bh(&ar->htt.tx_lock);
3689 ath10k_htt_tx_dec_pending(htt, is_mgmt);
3690 spin_unlock_bh(&ar->htt.tx_lock);
3691
3692 return -ENOENT;
3693 }
3694
Michal Kaziordd4717b2016-03-06 16:14:39 +02003695 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Michal Kazior29946872016-03-06 16:14:34 +02003696
3697 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
3698 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
3699
3700 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
3701 if (unlikely(ret)) {
3702 ath10k_warn(ar, "failed to push frame: %d\n", ret);
3703
3704 spin_lock_bh(&ar->htt.tx_lock);
3705 ath10k_htt_tx_dec_pending(htt, is_mgmt);
3706 spin_unlock_bh(&ar->htt.tx_lock);
3707
3708 return ret;
3709 }
3710
3711 return 0;
3712}
3713
3714void ath10k_mac_tx_push_pending(struct ath10k *ar)
3715{
3716 struct ieee80211_hw *hw = ar->hw;
3717 struct ieee80211_txq *txq;
3718 struct ath10k_txq *artxq;
3719 struct ath10k_txq *last;
3720 int ret;
3721 int max;
3722
3723 spin_lock_bh(&ar->txqs_lock);
3724 rcu_read_lock();
3725
3726 last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
3727 while (!list_empty(&ar->txqs)) {
3728 artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
3729 txq = container_of((void *)artxq, struct ieee80211_txq,
3730 drv_priv);
3731
3732 /* Prevent aggressive sta/tid taking over tx queue */
3733 max = 16;
3734 while (max--) {
3735 ret = ath10k_mac_tx_push_txq(hw, txq);
3736 if (ret < 0)
3737 break;
3738 }
3739
3740 list_del_init(&artxq->list);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02003741 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02003742
3743 if (artxq == last || (ret < 0 && ret != -ENOENT)) {
3744 if (ret != -ENOENT)
3745 list_add_tail(&artxq->list, &ar->txqs);
3746 break;
3747 }
3748 }
3749
3750 rcu_read_unlock();
3751 spin_unlock_bh(&ar->txqs_lock);
3752}
3753
Kalle Valo5e3dd152013-06-12 20:52:10 +03003754/************/
3755/* Scanning */
3756/************/
3757
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003758void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003759{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003760 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003761
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003762 switch (ar->scan.state) {
3763 case ATH10K_SCAN_IDLE:
3764 break;
3765 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01003766 case ATH10K_SCAN_ABORTING:
3767 if (!ar->scan.is_roc)
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003768 ieee80211_scan_completed(ar->hw,
3769 (ar->scan.state ==
3770 ATH10K_SCAN_ABORTING));
Michal Kaziord710e752015-07-09 13:08:36 +02003771 else if (ar->scan.roc_notify)
3772 ieee80211_remain_on_channel_expired(ar->hw);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003773 /* fall through */
3774 case ATH10K_SCAN_STARTING:
3775 ar->scan.state = ATH10K_SCAN_IDLE;
3776 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01003777 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003778 ath10k_offchan_tx_purge(ar);
3779 cancel_delayed_work(&ar->scan.timeout);
3780 complete_all(&ar->scan.completed);
3781 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003782 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003783}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003784
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003785void ath10k_scan_finish(struct ath10k *ar)
3786{
3787 spin_lock_bh(&ar->data_lock);
3788 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003789 spin_unlock_bh(&ar->data_lock);
3790}
3791
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003792static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003793{
3794 struct wmi_stop_scan_arg arg = {
3795 .req_id = 1, /* FIXME */
3796 .req_type = WMI_SCAN_STOP_ONE,
3797 .u.scan_id = ATH10K_SCAN_ID,
3798 };
3799 int ret;
3800
3801 lockdep_assert_held(&ar->conf_mutex);
3802
Kalle Valo5e3dd152013-06-12 20:52:10 +03003803 ret = ath10k_wmi_stop_scan(ar, &arg);
3804 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003805 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003806 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003807 }
3808
Kalle Valo5e3dd152013-06-12 20:52:10 +03003809 ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003810 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003811 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003812 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003813 } else if (ret > 0) {
3814 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003815 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003816
3817out:
3818 /* Scan state should be updated upon scan completion but in case
3819 * firmware fails to deliver the event (for whatever reason) it is
3820 * desired to clean up scan state anyway. Firmware may have just
3821 * dropped the scan completion event delivery due to transport pipe
3822 * being overflown with data and/or it can recover on its own before
3823 * next scan request is submitted.
3824 */
3825 spin_lock_bh(&ar->data_lock);
3826 if (ar->scan.state != ATH10K_SCAN_IDLE)
3827 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003828 spin_unlock_bh(&ar->data_lock);
3829
3830 return ret;
3831}
3832
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003833static void ath10k_scan_abort(struct ath10k *ar)
3834{
3835 int ret;
3836
3837 lockdep_assert_held(&ar->conf_mutex);
3838
3839 spin_lock_bh(&ar->data_lock);
3840
3841 switch (ar->scan.state) {
3842 case ATH10K_SCAN_IDLE:
3843 /* This can happen if timeout worker kicked in and called
3844 * abortion while scan completion was being processed.
3845 */
3846 break;
3847 case ATH10K_SCAN_STARTING:
3848 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02003849 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003850 ath10k_scan_state_str(ar->scan.state),
3851 ar->scan.state);
3852 break;
3853 case ATH10K_SCAN_RUNNING:
3854 ar->scan.state = ATH10K_SCAN_ABORTING;
3855 spin_unlock_bh(&ar->data_lock);
3856
3857 ret = ath10k_scan_stop(ar);
3858 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003859 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003860
3861 spin_lock_bh(&ar->data_lock);
3862 break;
3863 }
3864
3865 spin_unlock_bh(&ar->data_lock);
3866}
3867
3868void ath10k_scan_timeout_work(struct work_struct *work)
3869{
3870 struct ath10k *ar = container_of(work, struct ath10k,
3871 scan.timeout.work);
3872
3873 mutex_lock(&ar->conf_mutex);
3874 ath10k_scan_abort(ar);
3875 mutex_unlock(&ar->conf_mutex);
3876}
3877
Kalle Valo5e3dd152013-06-12 20:52:10 +03003878static int ath10k_start_scan(struct ath10k *ar,
3879 const struct wmi_start_scan_arg *arg)
3880{
3881 int ret;
3882
3883 lockdep_assert_held(&ar->conf_mutex);
3884
3885 ret = ath10k_wmi_start_scan(ar, arg);
3886 if (ret)
3887 return ret;
3888
Kalle Valo5e3dd152013-06-12 20:52:10 +03003889 ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ);
3890 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003891 ret = ath10k_scan_stop(ar);
3892 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003893 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003894
3895 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003896 }
3897
Ben Greear2f9eec02015-02-15 16:50:38 +02003898 /* If we failed to start the scan, return error code at
3899 * this point. This is probably due to some issue in the
3900 * firmware, but no need to wedge the driver due to that...
3901 */
3902 spin_lock_bh(&ar->data_lock);
3903 if (ar->scan.state == ATH10K_SCAN_IDLE) {
3904 spin_unlock_bh(&ar->data_lock);
3905 return -EINVAL;
3906 }
3907 spin_unlock_bh(&ar->data_lock);
3908
Kalle Valo5e3dd152013-06-12 20:52:10 +03003909 return 0;
3910}
3911
3912/**********************/
3913/* mac80211 callbacks */
3914/**********************/
3915
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003916static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
3917 struct ieee80211_tx_control *control,
3918 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003919{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003920 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02003921 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03003922 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3923 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003924 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003925 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02003926 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01003927 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003928 enum ath10k_mac_tx_path txpath;
3929 bool is_htt;
3930 bool is_mgmt;
3931 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003932 int ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003933
Michal Kaziordd4717b2016-03-06 16:14:39 +02003934 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003935
Michal Kazior8a933962015-11-18 06:59:17 +01003936 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003937 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
3938 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
3939 txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003940
Michal Kazior6421969f2016-03-06 16:14:25 +02003941 if (is_htt) {
3942 spin_lock_bh(&ar->htt.tx_lock);
3943
3944 is_mgmt = ieee80211_is_mgmt(hdr->frame_control);
3945 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
3946
3947 ret = ath10k_htt_tx_inc_pending(htt, is_mgmt, is_presp);
3948 if (ret) {
3949 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
3950 ret);
3951 spin_unlock_bh(&ar->htt.tx_lock);
3952 ieee80211_free_txskb(ar->hw, skb);
3953 return;
3954 }
3955
3956 spin_unlock_bh(&ar->htt.tx_lock);
3957 }
3958
3959 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
3960 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003961 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02003962 if (is_htt) {
3963 spin_lock_bh(&ar->htt.tx_lock);
3964 ath10k_htt_tx_dec_pending(htt, is_mgmt);
3965 spin_unlock_bh(&ar->htt.tx_lock);
3966 }
3967 return;
3968 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003969}
3970
Michal Kazior29946872016-03-06 16:14:34 +02003971static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
3972 struct ieee80211_txq *txq)
3973{
3974 struct ath10k *ar = hw->priv;
3975 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3976
3977 if (ath10k_mac_tx_can_push(hw, txq)) {
3978 spin_lock_bh(&ar->txqs_lock);
3979 if (list_empty(&artxq->list))
3980 list_add_tail(&artxq->list, &ar->txqs);
3981 spin_unlock_bh(&ar->txqs_lock);
3982
3983 tasklet_schedule(&ar->htt.txrx_compl_task);
3984 }
Michal Kaziorc1a43d92016-03-06 16:14:36 +02003985
3986 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02003987}
3988
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003989/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01003990void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003991{
3992 /* make sure rcu-protected mac80211 tx path itself is drained */
3993 synchronize_net();
3994
3995 ath10k_offchan_tx_purge(ar);
3996 ath10k_mgmt_over_wmi_tx_purge(ar);
3997
3998 cancel_work_sync(&ar->offchan_tx_work);
3999 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4000}
4001
Michal Kazioraffd3212013-07-16 09:54:35 +02004002void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004003{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004004 struct ath10k_vif *arvif;
4005
Michal Kazior818bdd12013-07-16 09:38:57 +02004006 lockdep_assert_held(&ar->conf_mutex);
4007
Michal Kazior19337472014-08-28 12:58:16 +02004008 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4009 ar->filter_flags = 0;
4010 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004011 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004012
4013 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004014 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004015
4016 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004017 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004018
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004019 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004020 ath10k_peer_cleanup_all(ar);
4021 ath10k_core_stop(ar);
4022 ath10k_hif_power_down(ar);
4023
4024 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004025 list_for_each_entry(arvif, &ar->arvifs, list)
4026 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004027 spin_unlock_bh(&ar->data_lock);
4028}
4029
Ben Greear46acf7b2014-05-16 17:15:38 +03004030static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4031{
4032 struct ath10k *ar = hw->priv;
4033
4034 mutex_lock(&ar->conf_mutex);
4035
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304036 *tx_ant = ar->cfg_tx_chainmask;
4037 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03004038
4039 mutex_unlock(&ar->conf_mutex);
4040
4041 return 0;
4042}
4043
Ben Greear5572a952014-11-24 16:22:10 +02004044static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4045{
4046 /* It is not clear that allowing gaps in chainmask
4047 * is helpful. Probably it will not do what user
4048 * is hoping for, so warn in that case.
4049 */
4050 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4051 return;
4052
4053 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4054 dbg, cm);
4055}
4056
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304057static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4058{
4059 int nsts = ar->vht_cap_info;
4060
4061 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4062 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4063
4064 /* If firmware does not deliver to host number of space-time
4065 * streams supported, assume it support up to 4 BF STS and return
4066 * the value for VHT CAP: nsts-1)
4067 */
4068 if (nsts == 0)
4069 return 3;
4070
4071 return nsts;
4072}
4073
4074static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4075{
4076 int sound_dim = ar->vht_cap_info;
4077
4078 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4079 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4080
4081 /* If the sounding dimension is not advertised by the firmware,
4082 * let's use a default value of 1
4083 */
4084 if (sound_dim == 0)
4085 return 1;
4086
4087 return sound_dim;
4088}
4089
4090static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4091{
4092 struct ieee80211_sta_vht_cap vht_cap = {0};
4093 u16 mcs_map;
4094 u32 val;
4095 int i;
4096
4097 vht_cap.vht_supported = 1;
4098 vht_cap.cap = ar->vht_cap_info;
4099
4100 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4101 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4102 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4103 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4104 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4105
4106 vht_cap.cap |= val;
4107 }
4108
4109 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4110 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4111 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4112 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4113 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4114
4115 vht_cap.cap |= val;
4116 }
4117
4118 mcs_map = 0;
4119 for (i = 0; i < 8; i++) {
4120 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4121 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4122 else
4123 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4124 }
4125
4126 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4127 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4128
4129 return vht_cap;
4130}
4131
4132static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4133{
4134 int i;
4135 struct ieee80211_sta_ht_cap ht_cap = {0};
4136
4137 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4138 return ht_cap;
4139
4140 ht_cap.ht_supported = 1;
4141 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4142 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4143 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4144 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004145 ht_cap.cap |=
4146 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304147
4148 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4149 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4150
4151 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4152 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4153
4154 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4155 u32 smps;
4156
4157 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4158 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4159
4160 ht_cap.cap |= smps;
4161 }
4162
4163 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC)
4164 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4165
4166 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4167 u32 stbc;
4168
4169 stbc = ar->ht_cap_info;
4170 stbc &= WMI_HT_CAP_RX_STBC;
4171 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4172 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4173 stbc &= IEEE80211_HT_CAP_RX_STBC;
4174
4175 ht_cap.cap |= stbc;
4176 }
4177
4178 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
4179 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4180
4181 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4182 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4183
4184 /* max AMSDU is implicitly taken from vht_cap_info */
4185 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4186 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4187
4188 for (i = 0; i < ar->num_rf_chains; i++) {
4189 if (ar->cfg_rx_chainmask & BIT(i))
4190 ht_cap.mcs.rx_mask[i] = 0xFF;
4191 }
4192
4193 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4194
4195 return ht_cap;
4196}
4197
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304198static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4199{
4200 struct ieee80211_supported_band *band;
4201 struct ieee80211_sta_vht_cap vht_cap;
4202 struct ieee80211_sta_ht_cap ht_cap;
4203
4204 ht_cap = ath10k_get_ht_cap(ar);
4205 vht_cap = ath10k_create_vht_cap(ar);
4206
4207 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
4208 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
4209 band->ht_cap = ht_cap;
4210
4211 /* Enable the VHT support at 2.4 GHz */
4212 band->vht_cap = vht_cap;
4213 }
4214 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
4215 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
4216 band->ht_cap = ht_cap;
4217 band->vht_cap = vht_cap;
4218 }
4219}
4220
Ben Greear46acf7b2014-05-16 17:15:38 +03004221static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4222{
4223 int ret;
4224
4225 lockdep_assert_held(&ar->conf_mutex);
4226
Ben Greear5572a952014-11-24 16:22:10 +02004227 ath10k_check_chain_mask(ar, tx_ant, "tx");
4228 ath10k_check_chain_mask(ar, rx_ant, "rx");
4229
Ben Greear46acf7b2014-05-16 17:15:38 +03004230 ar->cfg_tx_chainmask = tx_ant;
4231 ar->cfg_rx_chainmask = rx_ant;
4232
4233 if ((ar->state != ATH10K_STATE_ON) &&
4234 (ar->state != ATH10K_STATE_RESTARTED))
4235 return 0;
4236
4237 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4238 tx_ant);
4239 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004240 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004241 ret, tx_ant);
4242 return ret;
4243 }
4244
4245 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4246 rx_ant);
4247 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004248 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004249 ret, rx_ant);
4250 return ret;
4251 }
4252
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304253 /* Reload HT/VHT capability */
4254 ath10k_mac_setup_ht_vht_cap(ar);
4255
Ben Greear46acf7b2014-05-16 17:15:38 +03004256 return 0;
4257}
4258
4259static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4260{
4261 struct ath10k *ar = hw->priv;
4262 int ret;
4263
4264 mutex_lock(&ar->conf_mutex);
4265 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4266 mutex_unlock(&ar->conf_mutex);
4267 return ret;
4268}
4269
Kalle Valo5e3dd152013-06-12 20:52:10 +03004270static int ath10k_start(struct ieee80211_hw *hw)
4271{
4272 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304273 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004274 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004275
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004276 /*
4277 * This makes sense only when restarting hw. It is harmless to call
4278 * uncoditionally. This is necessary to make sure no HTT/WMI tx
4279 * commands will be submitted while restarting.
4280 */
4281 ath10k_drain_tx(ar);
4282
Michal Kazior548db542013-07-05 16:15:15 +03004283 mutex_lock(&ar->conf_mutex);
4284
Michal Kaziorc5058f52014-05-26 12:46:03 +03004285 switch (ar->state) {
4286 case ATH10K_STATE_OFF:
4287 ar->state = ATH10K_STATE_ON;
4288 break;
4289 case ATH10K_STATE_RESTARTING:
4290 ath10k_halt(ar);
4291 ar->state = ATH10K_STATE_RESTARTED;
4292 break;
4293 case ATH10K_STATE_ON:
4294 case ATH10K_STATE_RESTARTED:
4295 case ATH10K_STATE_WEDGED:
4296 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004297 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004298 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004299 case ATH10K_STATE_UTF:
4300 ret = -EBUSY;
4301 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004302 }
4303
4304 ret = ath10k_hif_power_up(ar);
4305 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004306 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004307 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004308 }
4309
Kalle Valo43d2a302014-09-10 18:23:30 +03004310 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02004311 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004312 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004313 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004314 }
4315
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304316 param = ar->wmi.pdev_param->pmf_qos;
4317 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004318 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004319 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004320 goto err_core_stop;
4321 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004322
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304323 param = ar->wmi.pdev_param->dynamic_bw;
4324 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004325 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004326 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004327 goto err_core_stop;
4328 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004329
Michal Kaziorcf327842015-03-31 10:26:25 +00004330 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4331 ret = ath10k_wmi_adaptive_qcs(ar, true);
4332 if (ret) {
4333 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4334 ret);
4335 goto err_core_stop;
4336 }
4337 }
4338
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004339 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304340 param = ar->wmi.pdev_param->burst_enable;
4341 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004342 if (ret) {
4343 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4344 goto err_core_stop;
4345 }
4346 }
4347
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304348 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7b2014-05-16 17:15:38 +03004349
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004350 /*
4351 * By default FW set ARP frames ac to voice (6). In that case ARP
4352 * exchange is not working properly for UAPSD enabled AP. ARP requests
4353 * which arrives with access category 0 are processed by network stack
4354 * and send back with access category 0, but FW changes access category
4355 * to 6. Set ARP frames access category to best effort (0) solves
4356 * this problem.
4357 */
4358
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304359 param = ar->wmi.pdev_param->arp_ac_override;
4360 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004361 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004362 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004363 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004364 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004365 }
4366
Maharaja62f77f02015-10-21 11:49:18 +03004367 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
4368 ar->fw_features)) {
4369 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4370 WMI_CCA_DETECT_LEVEL_AUTO,
4371 WMI_CCA_DETECT_MARGIN_AUTO);
4372 if (ret) {
4373 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4374 ret);
4375 goto err_core_stop;
4376 }
4377 }
4378
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304379 param = ar->wmi.pdev_param->ani_enable;
4380 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304381 if (ret) {
4382 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4383 ret);
4384 goto err_core_stop;
4385 }
4386
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304387 ar->ani_enabled = true;
4388
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304389 if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map)) {
4390 param = ar->wmi.pdev_param->peer_stats_update_period;
4391 ret = ath10k_wmi_pdev_set_param(ar, param,
4392 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4393 if (ret) {
4394 ath10k_warn(ar,
4395 "failed to set peer stats period : %d\n",
4396 ret);
4397 goto err_core_stop;
4398 }
4399 }
4400
Michal Kaziord6500972014-04-08 09:56:09 +03004401 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004402 ath10k_regd_update(ar);
4403
Simon Wunderlich855aed12014-08-02 09:12:54 +03004404 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304405 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004406
Michal Kaziorae254432014-05-26 12:46:02 +03004407 mutex_unlock(&ar->conf_mutex);
4408 return 0;
4409
4410err_core_stop:
4411 ath10k_core_stop(ar);
4412
4413err_power_down:
4414 ath10k_hif_power_down(ar);
4415
4416err_off:
4417 ar->state = ATH10K_STATE_OFF;
4418
4419err:
Michal Kazior548db542013-07-05 16:15:15 +03004420 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004421 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004422}
4423
4424static void ath10k_stop(struct ieee80211_hw *hw)
4425{
4426 struct ath10k *ar = hw->priv;
4427
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004428 ath10k_drain_tx(ar);
4429
Michal Kazior548db542013-07-05 16:15:15 +03004430 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004431 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004432 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004433 ar->state = ATH10K_STATE_OFF;
4434 }
Michal Kazior548db542013-07-05 16:15:15 +03004435 mutex_unlock(&ar->conf_mutex);
4436
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004437 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004438 cancel_work_sync(&ar->restart_work);
4439}
4440
Michal Kaziorad088bf2013-10-16 15:44:46 +03004441static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004442{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004443 struct ath10k_vif *arvif;
4444 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004445
4446 lockdep_assert_held(&ar->conf_mutex);
4447
Michal Kaziorad088bf2013-10-16 15:44:46 +03004448 list_for_each_entry(arvif, &ar->arvifs, list) {
4449 ret = ath10k_mac_vif_setup_ps(arvif);
4450 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004451 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004452 break;
4453 }
4454 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004455
Michal Kaziorad088bf2013-10-16 15:44:46 +03004456 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004457}
4458
Michal Kazior7d9d5582014-10-21 10:40:15 +03004459static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4460{
4461 int ret;
4462 u32 param;
4463
4464 lockdep_assert_held(&ar->conf_mutex);
4465
4466 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4467
4468 param = ar->wmi.pdev_param->txpower_limit2g;
4469 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4470 if (ret) {
4471 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4472 txpower, ret);
4473 return ret;
4474 }
4475
4476 param = ar->wmi.pdev_param->txpower_limit5g;
4477 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4478 if (ret) {
4479 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4480 txpower, ret);
4481 return ret;
4482 }
4483
4484 return 0;
4485}
4486
4487static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4488{
4489 struct ath10k_vif *arvif;
4490 int ret, txpower = -1;
4491
4492 lockdep_assert_held(&ar->conf_mutex);
4493
4494 list_for_each_entry(arvif, &ar->arvifs, list) {
4495 WARN_ON(arvif->txpower < 0);
4496
4497 if (txpower == -1)
4498 txpower = arvif->txpower;
4499 else
4500 txpower = min(txpower, arvif->txpower);
4501 }
4502
4503 if (WARN_ON(txpower == -1))
4504 return -EINVAL;
4505
4506 ret = ath10k_mac_txpower_setup(ar, txpower);
4507 if (ret) {
4508 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4509 txpower, ret);
4510 return ret;
4511 }
4512
4513 return 0;
4514}
4515
Kalle Valo5e3dd152013-06-12 20:52:10 +03004516static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4517{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004518 struct ath10k *ar = hw->priv;
4519 struct ieee80211_conf *conf = &hw->conf;
4520 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004521
4522 mutex_lock(&ar->conf_mutex);
4523
Michal Kazioraffd3212013-07-16 09:54:35 +02004524 if (changed & IEEE80211_CONF_CHANGE_PS)
4525 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004526
4527 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004528 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4529 ret = ath10k_monitor_recalc(ar);
4530 if (ret)
4531 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004532 }
4533
4534 mutex_unlock(&ar->conf_mutex);
4535 return ret;
4536}
4537
Ben Greear5572a952014-11-24 16:22:10 +02004538static u32 get_nss_from_chainmask(u16 chain_mask)
4539{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05304540 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02004541 return 4;
4542 else if ((chain_mask & 0x7) == 0x7)
4543 return 3;
4544 else if ((chain_mask & 0x3) == 0x3)
4545 return 2;
4546 return 1;
4547}
4548
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304549static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4550{
4551 u32 value = 0;
4552 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004553 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004554 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304555
4556 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4557 return 0;
4558
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004559 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304560 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4561 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004562 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304563
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004564 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304565 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4566 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004567 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304568
4569 if (!value)
4570 return 0;
4571
4572 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4573 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4574
4575 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4576 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4577 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4578
4579 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4580 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4581
4582 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4583 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4584 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4585
4586 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4587 ar->wmi.vdev_param->txbf, value);
4588}
4589
Kalle Valo5e3dd152013-06-12 20:52:10 +03004590/*
4591 * TODO:
4592 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4593 * because we will send mgmt frames without CCK. This requirement
4594 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4595 * in the TX packet.
4596 */
4597static int ath10k_add_interface(struct ieee80211_hw *hw,
4598 struct ieee80211_vif *vif)
4599{
4600 struct ath10k *ar = hw->priv;
4601 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004602 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004603 enum wmi_sta_powersave_param param;
4604 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004605 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004606 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004607 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004608 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004609
Johannes Berg848955c2014-11-11 12:48:42 +01004610 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4611
Kalle Valo5e3dd152013-06-12 20:52:10 +03004612 mutex_lock(&ar->conf_mutex);
4613
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004614 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02004615 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004616
Kalle Valo5e3dd152013-06-12 20:52:10 +03004617 arvif->ar = ar;
4618 arvif->vif = vif;
4619
Ben Greeare63b33f2013-10-22 14:54:14 -07004620 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004621 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004622 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4623 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004624
Michal Kazior45c9abc2015-04-21 20:42:58 +03004625 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4626 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4627 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4628 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4629 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4630 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4631 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004632
Michal Kaziore04cafb2015-08-05 12:15:24 +02004633 if (ar->num_peers >= ar->max_num_peers) {
4634 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004635 ret = -ENOBUFS;
4636 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004637 }
4638
Ben Greeara9aefb32014-08-12 11:02:19 +03004639 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004640 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004641 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03004642 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004643 }
Ben Greear16c11172014-09-23 14:17:16 -07004644 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004645
Ben Greear16c11172014-09-23 14:17:16 -07004646 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4647 bit, ar->free_vdev_map);
4648
4649 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004650 arvif->vdev_subtype =
4651 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004652
Kalle Valo5e3dd152013-06-12 20:52:10 +03004653 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004654 case NL80211_IFTYPE_P2P_DEVICE:
4655 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004656 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4657 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01004658 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004659 case NL80211_IFTYPE_UNSPECIFIED:
4660 case NL80211_IFTYPE_STATION:
4661 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4662 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004663 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4664 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004665 break;
4666 case NL80211_IFTYPE_ADHOC:
4667 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4668 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004669 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08004670 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08004671 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4672 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08004673 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004674 ret = -EINVAL;
4675 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
4676 goto err;
4677 }
4678 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4679 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004680 case NL80211_IFTYPE_AP:
4681 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4682
4683 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004684 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4685 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004686 break;
4687 case NL80211_IFTYPE_MONITOR:
4688 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4689 break;
4690 default:
4691 WARN_ON(1);
4692 break;
4693 }
4694
Michal Kazior96d828d2015-03-31 10:26:23 +00004695 /* Using vdev_id as queue number will make it very easy to do per-vif
4696 * tx queue locking. This shouldn't wrap due to interface combinations
4697 * but do a modulo for correctness sake and prevent using offchannel tx
4698 * queues for regular vif tx.
4699 */
4700 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4701 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4702 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4703
Michal Kazior64badcb2014-09-18 11:18:02 +03004704 /* Some firmware revisions don't wait for beacon tx completion before
4705 * sending another SWBA event. This could lead to hardware using old
4706 * (freed) beacon data in some cases, e.g. tx credit starvation
4707 * combined with missed TBTT. This is very very rare.
4708 *
4709 * On non-IOMMU-enabled hosts this could be a possible security issue
4710 * because hw could beacon some random data on the air. On
4711 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4712 * device would crash.
4713 *
4714 * Since there are no beacon tx completions (implicit nor explicit)
4715 * propagated to host the only workaround for this is to allocate a
4716 * DMA-coherent buffer for a lifetime of a vif and use it for all
4717 * beacon tx commands. Worst case for this approach is some beacons may
4718 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4719 */
4720 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004721 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03004722 vif->type == NL80211_IFTYPE_AP) {
4723 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4724 IEEE80211_MAX_FRAME_LEN,
4725 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304726 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004727 if (!arvif->beacon_buf) {
4728 ret = -ENOMEM;
4729 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4730 ret);
4731 goto err;
4732 }
4733 }
David Liuccec9032015-07-24 20:25:32 +03004734 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
4735 arvif->nohwcrypt = true;
4736
4737 if (arvif->nohwcrypt &&
4738 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4739 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
4740 goto err;
4741 }
Michal Kazior64badcb2014-09-18 11:18:02 +03004742
4743 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4744 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4745 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004746
4747 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4748 arvif->vdev_subtype, vif->addr);
4749 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004750 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004751 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004752 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004753 }
4754
Ben Greear16c11172014-09-23 14:17:16 -07004755 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Michal Kazior05791192013-10-16 15:44:45 +03004756 list_add(&arvif->list, &ar->arvifs);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004757
Michal Kazior46725b152015-01-28 09:57:49 +02004758 /* It makes no sense to have firmware do keepalives. mac80211 already
4759 * takes care of this with idle connection polling.
4760 */
4761 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004762 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02004763 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004764 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004765 goto err_vdev_delete;
4766 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004767
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004768 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004769
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004770 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4771 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004772 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004773 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03004774 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004775 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004776 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004777 goto err_vdev_delete;
4778 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004779
Ben Greear5572a952014-11-24 16:22:10 +02004780 if (ar->cfg_tx_chainmask) {
4781 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
4782
4783 vdev_param = ar->wmi.vdev_param->nss;
4784 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4785 nss);
4786 if (ret) {
4787 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
4788 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
4789 ret);
4790 goto err_vdev_delete;
4791 }
4792 }
4793
Michal Kaziore57e0572015-03-24 13:14:03 +00004794 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4795 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02004796 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
4797 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004798 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00004799 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004800 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004801 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004802 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004803
4804 spin_lock_bh(&ar->data_lock);
4805
4806 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
4807 if (!peer) {
4808 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
4809 vif->addr, arvif->vdev_id);
4810 spin_unlock_bh(&ar->data_lock);
4811 ret = -ENOENT;
4812 goto err_peer_delete;
4813 }
4814
4815 arvif->peer_id = find_first_bit(peer->peer_ids,
4816 ATH10K_MAX_NUM_PEER_IDS);
4817
4818 spin_unlock_bh(&ar->data_lock);
4819 } else {
4820 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00004821 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01004822
Michal Kaziore57e0572015-03-24 13:14:03 +00004823 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02004824 ret = ath10k_mac_set_kickout(arvif);
4825 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004826 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004827 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02004828 goto err_peer_delete;
4829 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004830 }
4831
4832 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
4833 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
4834 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
4835 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
4836 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004837 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004838 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004839 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004840 goto err_peer_delete;
4841 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004842
Michal Kazior9f9b5742014-12-12 12:41:36 +01004843 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004844 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004845 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004846 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004847 goto err_peer_delete;
4848 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004849
Michal Kazior9f9b5742014-12-12 12:41:36 +01004850 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004851 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004852 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004853 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004854 goto err_peer_delete;
4855 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004856 }
4857
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304858 ret = ath10k_mac_set_txbf_conf(arvif);
4859 if (ret) {
4860 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
4861 arvif->vdev_id, ret);
4862 goto err_peer_delete;
4863 }
4864
Michal Kazior424121c2013-07-22 14:13:31 +02004865 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004866 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004867 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03004868 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004869 goto err_peer_delete;
4870 }
Michal Kazior679c54a2013-07-05 16:15:04 +03004871
Michal Kazior7d9d5582014-10-21 10:40:15 +03004872 arvif->txpower = vif->bss_conf.txpower;
4873 ret = ath10k_mac_txpower_recalc(ar);
4874 if (ret) {
4875 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4876 goto err_peer_delete;
4877 }
4878
Michal Kazior500ff9f2015-03-31 10:26:21 +00004879 if (vif->type == NL80211_IFTYPE_MONITOR) {
4880 ar->monitor_arvif = arvif;
4881 ret = ath10k_monitor_recalc(ar);
4882 if (ret) {
4883 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
4884 goto err_peer_delete;
4885 }
4886 }
4887
Michal Kazior6d2d51e2015-08-07 09:08:21 +02004888 spin_lock_bh(&ar->htt.tx_lock);
4889 if (!ar->tx_paused)
4890 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
4891 spin_unlock_bh(&ar->htt.tx_lock);
4892
Kalle Valo5e3dd152013-06-12 20:52:10 +03004893 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004894 return 0;
4895
4896err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00004897 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4898 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14a2013-10-16 15:44:45 +03004899 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
4900
4901err_vdev_delete:
4902 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07004903 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004904 list_del(&arvif->list);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004905
4906err:
Michal Kazior64badcb2014-09-18 11:18:02 +03004907 if (arvif->beacon_buf) {
4908 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
4909 arvif->beacon_buf, arvif->beacon_paddr);
4910 arvif->beacon_buf = NULL;
4911 }
4912
Michal Kazior9dad14a2013-10-16 15:44:45 +03004913 mutex_unlock(&ar->conf_mutex);
4914
Kalle Valo5e3dd152013-06-12 20:52:10 +03004915 return ret;
4916}
4917
Michal Kaziorb4aa5392015-03-31 10:26:24 +00004918static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
4919{
4920 int i;
4921
4922 for (i = 0; i < BITS_PER_LONG; i++)
4923 ath10k_mac_vif_tx_unlock(arvif, i);
4924}
4925
Kalle Valo5e3dd152013-06-12 20:52:10 +03004926static void ath10k_remove_interface(struct ieee80211_hw *hw,
4927 struct ieee80211_vif *vif)
4928{
4929 struct ath10k *ar = hw->priv;
4930 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior69427262016-03-06 16:14:30 +02004931 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004932 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02004933 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004934
Michal Kazior81a9a172015-03-05 16:02:17 +02004935 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004936 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02004937
Sujith Manoharan5d011f52014-11-25 11:47:00 +05304938 mutex_lock(&ar->conf_mutex);
4939
Michal Kaziored543882013-09-13 14:16:56 +02004940 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004941 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02004942 spin_unlock_bh(&ar->data_lock);
4943
Simon Wunderlich855aed12014-08-02 09:12:54 +03004944 ret = ath10k_spectral_vif_stop(arvif);
4945 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004946 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03004947 arvif->vdev_id, ret);
4948
Ben Greear16c11172014-09-23 14:17:16 -07004949 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004950 list_del(&arvif->list);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004951
Michal Kaziore57e0572015-03-24 13:14:03 +00004952 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4953 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02004954 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
4955 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004956 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00004957 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004958 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004959
4960 kfree(arvif->u.ap.noa_data);
4961 }
4962
Michal Kazior7aa7a722014-08-25 12:09:38 +02004963 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004964 arvif->vdev_id);
4965
Kalle Valo5e3dd152013-06-12 20:52:10 +03004966 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
4967 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004968 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004969 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004970
Michal Kazior2c512052015-02-15 16:50:40 +02004971 /* Some firmware revisions don't notify host about self-peer removal
4972 * until after associated vdev is deleted.
4973 */
Michal Kaziore57e0572015-03-24 13:14:03 +00004974 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4975 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02004976 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
4977 vif->addr);
4978 if (ret)
4979 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
4980 arvif->vdev_id, ret);
4981
4982 spin_lock_bh(&ar->data_lock);
4983 ar->num_peers--;
4984 spin_unlock_bh(&ar->data_lock);
4985 }
4986
Michal Kazior69427262016-03-06 16:14:30 +02004987 spin_lock_bh(&ar->data_lock);
4988 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
4989 peer = ar->peer_map[i];
4990 if (!peer)
4991 continue;
4992
4993 if (peer->vif == vif) {
4994 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
4995 vif->addr, arvif->vdev_id);
4996 peer->vif = NULL;
4997 }
4998 }
4999 spin_unlock_bh(&ar->data_lock);
5000
Kalle Valo5e3dd152013-06-12 20:52:10 +03005001 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005002 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005003
Michal Kazior500ff9f2015-03-31 10:26:21 +00005004 if (vif->type == NL80211_IFTYPE_MONITOR) {
5005 ar->monitor_arvif = NULL;
5006 ret = ath10k_monitor_recalc(ar);
5007 if (ret)
5008 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5009 }
5010
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005011 spin_lock_bh(&ar->htt.tx_lock);
5012 ath10k_mac_vif_tx_unlock_all(arvif);
5013 spin_unlock_bh(&ar->htt.tx_lock);
5014
Michal Kazior29946872016-03-06 16:14:34 +02005015 ath10k_mac_txq_unref(ar, vif->txq);
5016
Kalle Valo5e3dd152013-06-12 20:52:10 +03005017 mutex_unlock(&ar->conf_mutex);
5018}
5019
5020/*
5021 * FIXME: Has to be verified.
5022 */
5023#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005024 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005025 FIF_CONTROL | \
5026 FIF_PSPOLL | \
5027 FIF_OTHER_BSS | \
5028 FIF_BCN_PRBRESP_PROMISC | \
5029 FIF_PROBE_REQ | \
5030 FIF_FCSFAIL)
5031
5032static void ath10k_configure_filter(struct ieee80211_hw *hw,
5033 unsigned int changed_flags,
5034 unsigned int *total_flags,
5035 u64 multicast)
5036{
5037 struct ath10k *ar = hw->priv;
5038 int ret;
5039
5040 mutex_lock(&ar->conf_mutex);
5041
5042 changed_flags &= SUPPORTED_FILTERS;
5043 *total_flags &= SUPPORTED_FILTERS;
5044 ar->filter_flags = *total_flags;
5045
Michal Kazior19337472014-08-28 12:58:16 +02005046 ret = ath10k_monitor_recalc(ar);
5047 if (ret)
5048 ath10k_warn(ar, "failed to recalc montior: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005049
5050 mutex_unlock(&ar->conf_mutex);
5051}
5052
5053static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5054 struct ieee80211_vif *vif,
5055 struct ieee80211_bss_conf *info,
5056 u32 changed)
5057{
5058 struct ath10k *ar = hw->priv;
5059 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5060 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03005061 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005062
5063 mutex_lock(&ar->conf_mutex);
5064
5065 if (changed & BSS_CHANGED_IBSS)
5066 ath10k_control_ibss(arvif, info, vif->addr);
5067
5068 if (changed & BSS_CHANGED_BEACON_INT) {
5069 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005070 vdev_param = ar->wmi.vdev_param->beacon_interval;
5071 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005072 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005073 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005074 "mac vdev %d beacon_interval %d\n",
5075 arvif->vdev_id, arvif->beacon_interval);
5076
Kalle Valo5e3dd152013-06-12 20:52:10 +03005077 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005078 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005079 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005080 }
5081
5082 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005083 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005084 "vdev %d set beacon tx mode to staggered\n",
5085 arvif->vdev_id);
5086
Bartosz Markowski226a3392013-09-26 17:47:16 +02005087 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5088 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005089 WMI_BEACON_STAGGERED_MODE);
5090 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005091 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005092 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005093
5094 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5095 if (ret)
5096 ath10k_warn(ar, "failed to update beacon template: %d\n",
5097 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005098
5099 if (ieee80211_vif_is_mesh(vif)) {
5100 /* mesh doesn't use SSID but firmware needs it */
5101 strncpy(arvif->u.ap.ssid, "mesh",
5102 sizeof(arvif->u.ap.ssid));
5103 arvif->u.ap.ssid_len = 4;
5104 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005105 }
5106
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005107 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5108 ret = ath10k_mac_setup_prb_tmpl(arvif);
5109 if (ret)
5110 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5111 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005112 }
5113
Michal Kaziorba2479f2015-01-24 12:14:51 +02005114 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005115 arvif->dtim_period = info->dtim_period;
5116
Michal Kazior7aa7a722014-08-25 12:09:38 +02005117 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005118 "mac vdev %d dtim_period %d\n",
5119 arvif->vdev_id, arvif->dtim_period);
5120
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005121 vdev_param = ar->wmi.vdev_param->dtim_period;
5122 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005123 arvif->dtim_period);
5124 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005125 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005126 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005127 }
5128
5129 if (changed & BSS_CHANGED_SSID &&
5130 vif->type == NL80211_IFTYPE_AP) {
5131 arvif->u.ap.ssid_len = info->ssid_len;
5132 if (info->ssid_len)
5133 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5134 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5135 }
5136
Michal Kazior077efc82014-10-21 10:10:29 +03005137 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5138 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005139
5140 if (changed & BSS_CHANGED_BEACON_ENABLED)
5141 ath10k_control_beaconing(arvif, info);
5142
5143 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005144 arvif->use_cts_prot = info->use_cts_prot;
Michal Kazior7aa7a722014-08-25 12:09:38 +02005145 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005146 arvif->vdev_id, info->use_cts_prot);
Kalle Valo60c3daa2013-09-08 17:56:07 +03005147
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005148 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005149 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005150 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005151 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005152
5153 vdev_param = ar->wmi.vdev_param->protection_mode;
5154 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5155 info->use_cts_prot ? 1 : 0);
5156 if (ret)
5157 ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
Kalle Valo617b0f42015-10-05 17:56:35 +03005158 info->use_cts_prot, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005159 }
5160
5161 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005162 if (info->use_short_slot)
5163 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5164
5165 else
5166 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5167
Michal Kazior7aa7a722014-08-25 12:09:38 +02005168 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005169 arvif->vdev_id, slottime);
5170
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005171 vdev_param = ar->wmi.vdev_param->slot_time;
5172 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005173 slottime);
5174 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005175 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005176 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005177 }
5178
5179 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005180 if (info->use_short_preamble)
5181 preamble = WMI_VDEV_PREAMBLE_SHORT;
5182 else
5183 preamble = WMI_VDEV_PREAMBLE_LONG;
5184
Michal Kazior7aa7a722014-08-25 12:09:38 +02005185 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005186 "mac vdev %d preamble %dn",
5187 arvif->vdev_id, preamble);
5188
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005189 vdev_param = ar->wmi.vdev_param->preamble;
5190 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005191 preamble);
5192 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005193 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005194 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005195 }
5196
5197 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005198 if (info->assoc) {
5199 /* Workaround: Make sure monitor vdev is not running
5200 * when associating to prevent some firmware revisions
5201 * (e.g. 10.1 and 10.2) from crashing.
5202 */
5203 if (ar->monitor_started)
5204 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005205 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005206 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005207 } else {
5208 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005209 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005210 }
5211
Michal Kazior7d9d5582014-10-21 10:40:15 +03005212 if (changed & BSS_CHANGED_TXPOWER) {
5213 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5214 arvif->vdev_id, info->txpower);
5215
5216 arvif->txpower = info->txpower;
5217 ret = ath10k_mac_txpower_recalc(ar);
5218 if (ret)
5219 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5220 }
5221
Michal Kaziorbf14e652014-12-12 12:41:38 +01005222 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005223 arvif->ps = vif->bss_conf.ps;
5224
5225 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005226 if (ret)
5227 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5228 arvif->vdev_id, ret);
5229 }
5230
Kalle Valo5e3dd152013-06-12 20:52:10 +03005231 mutex_unlock(&ar->conf_mutex);
5232}
5233
5234static int ath10k_hw_scan(struct ieee80211_hw *hw,
5235 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005236 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005237{
5238 struct ath10k *ar = hw->priv;
5239 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02005240 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005241 struct wmi_start_scan_arg arg;
5242 int ret = 0;
5243 int i;
5244
5245 mutex_lock(&ar->conf_mutex);
5246
5247 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005248 switch (ar->scan.state) {
5249 case ATH10K_SCAN_IDLE:
5250 reinit_completion(&ar->scan.started);
5251 reinit_completion(&ar->scan.completed);
5252 ar->scan.state = ATH10K_SCAN_STARTING;
5253 ar->scan.is_roc = false;
5254 ar->scan.vdev_id = arvif->vdev_id;
5255 ret = 0;
5256 break;
5257 case ATH10K_SCAN_STARTING:
5258 case ATH10K_SCAN_RUNNING:
5259 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005260 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005261 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005262 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005263 spin_unlock_bh(&ar->data_lock);
5264
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005265 if (ret)
5266 goto exit;
5267
Kalle Valo5e3dd152013-06-12 20:52:10 +03005268 memset(&arg, 0, sizeof(arg));
5269 ath10k_wmi_start_scan_init(ar, &arg);
5270 arg.vdev_id = arvif->vdev_id;
5271 arg.scan_id = ATH10K_SCAN_ID;
5272
Kalle Valo5e3dd152013-06-12 20:52:10 +03005273 if (req->ie_len) {
5274 arg.ie_len = req->ie_len;
5275 memcpy(arg.ie, req->ie, arg.ie_len);
5276 }
5277
5278 if (req->n_ssids) {
5279 arg.n_ssids = req->n_ssids;
5280 for (i = 0; i < arg.n_ssids; i++) {
5281 arg.ssids[i].len = req->ssids[i].ssid_len;
5282 arg.ssids[i].ssid = req->ssids[i].ssid;
5283 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005284 } else {
5285 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005286 }
5287
5288 if (req->n_channels) {
5289 arg.n_channels = req->n_channels;
5290 for (i = 0; i < arg.n_channels; i++)
5291 arg.channels[i] = req->channels[i]->center_freq;
5292 }
5293
5294 ret = ath10k_start_scan(ar, &arg);
5295 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005296 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005297 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005298 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005299 spin_unlock_bh(&ar->data_lock);
5300 }
5301
Michal Kazior634349b2015-09-03 10:43:45 +02005302 /* Add a 200ms margin to account for event/command processing */
5303 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5304 msecs_to_jiffies(arg.max_scan_time +
5305 200));
5306
Kalle Valo5e3dd152013-06-12 20:52:10 +03005307exit:
5308 mutex_unlock(&ar->conf_mutex);
5309 return ret;
5310}
5311
5312static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5313 struct ieee80211_vif *vif)
5314{
5315 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005316
5317 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005318 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005319 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01005320
5321 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005322}
5323
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005324static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
5325 struct ath10k_vif *arvif,
5326 enum set_key_cmd cmd,
5327 struct ieee80211_key_conf *key)
5328{
5329 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
5330 int ret;
5331
5332 /* 10.1 firmware branch requires default key index to be set to group
5333 * key index after installing it. Otherwise FW/HW Txes corrupted
5334 * frames with multi-vif APs. This is not required for main firmware
5335 * branch (e.g. 636).
5336 *
Michal Kazior8461baf2015-04-10 13:23:22 +00005337 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
5338 *
5339 * FIXME: It remains unknown if this is required for multi-vif STA
5340 * interfaces on 10.1.
5341 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005342
Michal Kazior8461baf2015-04-10 13:23:22 +00005343 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
5344 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005345 return;
5346
5347 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
5348 return;
5349
5350 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
5351 return;
5352
5353 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5354 return;
5355
5356 if (cmd != SET_KEY)
5357 return;
5358
5359 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5360 key->keyidx);
5361 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005362 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005363 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005364}
5365
Kalle Valo5e3dd152013-06-12 20:52:10 +03005366static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5367 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5368 struct ieee80211_key_conf *key)
5369{
5370 struct ath10k *ar = hw->priv;
5371 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5372 struct ath10k_peer *peer;
5373 const u8 *peer_addr;
5374 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5375 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5376 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005377 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005378 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005379 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005380
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005381 /* this one needs to be done in software */
5382 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
5383 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005384
David Liuccec9032015-07-24 20:25:32 +03005385 if (arvif->nohwcrypt)
5386 return 1;
5387
Kalle Valo5e3dd152013-06-12 20:52:10 +03005388 if (key->keyidx > WMI_MAX_KEY_INDEX)
5389 return -ENOSPC;
5390
5391 mutex_lock(&ar->conf_mutex);
5392
5393 if (sta)
5394 peer_addr = sta->addr;
5395 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5396 peer_addr = vif->bss_conf.bssid;
5397 else
5398 peer_addr = vif->addr;
5399
5400 key->hw_key_idx = key->keyidx;
5401
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005402 if (is_wep) {
5403 if (cmd == SET_KEY)
5404 arvif->wep_keys[key->keyidx] = key;
5405 else
5406 arvif->wep_keys[key->keyidx] = NULL;
5407 }
5408
Kalle Valo5e3dd152013-06-12 20:52:10 +03005409 /* the peer should not disappear in mid-way (unless FW goes awry) since
5410 * we already hold conf_mutex. we just make sure its there now. */
5411 spin_lock_bh(&ar->data_lock);
5412 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5413 spin_unlock_bh(&ar->data_lock);
5414
5415 if (!peer) {
5416 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005417 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005418 peer_addr);
5419 ret = -EOPNOTSUPP;
5420 goto exit;
5421 } else {
5422 /* if the peer doesn't exist there is no key to disable
5423 * anymore */
5424 goto exit;
5425 }
5426 }
5427
Michal Kazior7cc45732015-03-09 14:24:17 +01005428 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5429 flags |= WMI_KEY_PAIRWISE;
5430 else
5431 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005432
Kalle Valo5e3dd152013-06-12 20:52:10 +03005433 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005434 if (cmd == DISABLE_KEY)
5435 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005436
Michal Kaziorad325cb2015-02-18 14:02:27 +01005437 /* When WEP keys are uploaded it's possible that there are
5438 * stations associated already (e.g. when merging) without any
5439 * keys. Static WEP needs an explicit per-peer key upload.
5440 */
5441 if (vif->type == NL80211_IFTYPE_ADHOC &&
5442 cmd == SET_KEY)
5443 ath10k_mac_vif_update_wep_key(arvif, key);
5444
Michal Kazior370e5672015-02-18 14:02:26 +01005445 /* 802.1x never sets the def_wep_key_idx so each set_key()
5446 * call changes default tx key.
5447 *
5448 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5449 * after first set_key().
5450 */
5451 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5452 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005453 }
5454
Michal Kazior370e5672015-02-18 14:02:26 +01005455 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005456 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005457 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005458 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005459 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005460 goto exit;
5461 }
5462
Michal Kazior29a10002015-04-10 13:05:58 +00005463 /* mac80211 sets static WEP keys as groupwise while firmware requires
5464 * them to be installed twice as both pairwise and groupwise.
5465 */
5466 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5467 flags2 = flags;
5468 flags2 &= ~WMI_KEY_GROUP;
5469 flags2 |= WMI_KEY_PAIRWISE;
5470
5471 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5472 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005473 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005474 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5475 arvif->vdev_id, peer_addr, ret);
5476 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5477 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005478 if (ret2) {
5479 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005480 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5481 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005482 }
Michal Kazior29a10002015-04-10 13:05:58 +00005483 goto exit;
5484 }
5485 }
5486
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005487 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5488
Kalle Valo5e3dd152013-06-12 20:52:10 +03005489 spin_lock_bh(&ar->data_lock);
5490 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5491 if (peer && cmd == SET_KEY)
5492 peer->keys[key->keyidx] = key;
5493 else if (peer && cmd == DISABLE_KEY)
5494 peer->keys[key->keyidx] = NULL;
5495 else if (peer == NULL)
5496 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005497 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005498 spin_unlock_bh(&ar->data_lock);
5499
5500exit:
5501 mutex_unlock(&ar->conf_mutex);
5502 return ret;
5503}
5504
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005505static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5506 struct ieee80211_vif *vif,
5507 int keyidx)
5508{
5509 struct ath10k *ar = hw->priv;
5510 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5511 int ret;
5512
5513 mutex_lock(&arvif->ar->conf_mutex);
5514
5515 if (arvif->ar->state != ATH10K_STATE_ON)
5516 goto unlock;
5517
5518 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5519 arvif->vdev_id, keyidx);
5520
5521 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5522 arvif->vdev_id,
5523 arvif->ar->wmi.vdev_param->def_keyid,
5524 keyidx);
5525
5526 if (ret) {
5527 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5528 arvif->vdev_id,
5529 ret);
5530 goto unlock;
5531 }
5532
5533 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005534
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005535unlock:
5536 mutex_unlock(&arvif->ar->conf_mutex);
5537}
5538
Michal Kazior9797feb2014-02-14 14:49:48 +01005539static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5540{
5541 struct ath10k *ar;
5542 struct ath10k_vif *arvif;
5543 struct ath10k_sta *arsta;
5544 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005545 struct cfg80211_chan_def def;
5546 enum ieee80211_band band;
5547 const u8 *ht_mcs_mask;
5548 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005549 u32 changed, bw, nss, smps;
5550 int err;
5551
5552 arsta = container_of(wk, struct ath10k_sta, update_wk);
5553 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5554 arvif = arsta->arvif;
5555 ar = arvif->ar;
5556
Michal Kazior45c9abc2015-04-21 20:42:58 +03005557 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5558 return;
5559
5560 band = def.chan->band;
5561 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5562 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5563
Michal Kazior9797feb2014-02-14 14:49:48 +01005564 spin_lock_bh(&ar->data_lock);
5565
5566 changed = arsta->changed;
5567 arsta->changed = 0;
5568
5569 bw = arsta->bw;
5570 nss = arsta->nss;
5571 smps = arsta->smps;
5572
5573 spin_unlock_bh(&ar->data_lock);
5574
5575 mutex_lock(&ar->conf_mutex);
5576
Michal Kazior45c9abc2015-04-21 20:42:58 +03005577 nss = max_t(u32, 1, nss);
5578 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
5579 ath10k_mac_max_vht_nss(vht_mcs_mask)));
5580
Michal Kazior9797feb2014-02-14 14:49:48 +01005581 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005582 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005583 sta->addr, bw);
5584
5585 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5586 WMI_PEER_CHAN_WIDTH, bw);
5587 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005588 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005589 sta->addr, bw, err);
5590 }
5591
5592 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005593 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005594 sta->addr, nss);
5595
5596 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5597 WMI_PEER_NSS, nss);
5598 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005599 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005600 sta->addr, nss, err);
5601 }
5602
5603 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005604 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005605 sta->addr, smps);
5606
5607 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5608 WMI_PEER_SMPS_STATE, smps);
5609 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005610 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005611 sta->addr, smps, err);
5612 }
5613
Janusz Dziedzic55884c02014-12-17 12:30:02 +02005614 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
5615 changed & IEEE80211_RC_NSS_CHANGED) {
5616 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005617 sta->addr);
5618
Michal Kazior590922a2014-10-21 10:10:29 +03005619 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005620 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005621 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005622 sta->addr);
5623 }
5624
Michal Kazior9797feb2014-02-14 14:49:48 +01005625 mutex_unlock(&ar->conf_mutex);
5626}
5627
Marek Puzyniak7c354242015-03-30 09:51:52 +03005628static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
5629 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005630{
5631 struct ath10k *ar = arvif->ar;
5632
5633 lockdep_assert_held(&ar->conf_mutex);
5634
Marek Puzyniak7c354242015-03-30 09:51:52 +03005635 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005636 return 0;
5637
5638 if (ar->num_stations >= ar->max_num_stations)
5639 return -ENOBUFS;
5640
5641 ar->num_stations++;
5642
5643 return 0;
5644}
5645
Marek Puzyniak7c354242015-03-30 09:51:52 +03005646static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
5647 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005648{
5649 struct ath10k *ar = arvif->ar;
5650
5651 lockdep_assert_held(&ar->conf_mutex);
5652
Marek Puzyniak7c354242015-03-30 09:51:52 +03005653 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005654 return;
5655
5656 ar->num_stations--;
5657}
5658
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005659struct ath10k_mac_tdls_iter_data {
5660 u32 num_tdls_stations;
5661 struct ieee80211_vif *curr_vif;
5662};
5663
5664static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5665 struct ieee80211_sta *sta)
5666{
5667 struct ath10k_mac_tdls_iter_data *iter_data = data;
5668 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5669 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5670
5671 if (sta->tdls && sta_vif == iter_data->curr_vif)
5672 iter_data->num_tdls_stations++;
5673}
5674
5675static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5676 struct ieee80211_vif *vif)
5677{
5678 struct ath10k_mac_tdls_iter_data data = {};
5679
5680 data.curr_vif = vif;
5681
5682 ieee80211_iterate_stations_atomic(hw,
5683 ath10k_mac_tdls_vif_stations_count_iter,
5684 &data);
5685 return data.num_tdls_stations;
5686}
5687
5688static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5689 struct ieee80211_vif *vif)
5690{
5691 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5692 int *num_tdls_vifs = data;
5693
5694 if (vif->type != NL80211_IFTYPE_STATION)
5695 return;
5696
5697 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5698 (*num_tdls_vifs)++;
5699}
5700
5701static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5702{
5703 int num_tdls_vifs = 0;
5704
5705 ieee80211_iterate_active_interfaces_atomic(hw,
5706 IEEE80211_IFACE_ITER_NORMAL,
5707 ath10k_mac_tdls_vifs_count_iter,
5708 &num_tdls_vifs);
5709 return num_tdls_vifs;
5710}
5711
Kalle Valo5e3dd152013-06-12 20:52:10 +03005712static int ath10k_sta_state(struct ieee80211_hw *hw,
5713 struct ieee80211_vif *vif,
5714 struct ieee80211_sta *sta,
5715 enum ieee80211_sta_state old_state,
5716 enum ieee80211_sta_state new_state)
5717{
5718 struct ath10k *ar = hw->priv;
5719 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005720 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005721 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005722 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02005723 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005724
Michal Kazior76f90022014-02-25 09:29:57 +02005725 if (old_state == IEEE80211_STA_NOTEXIST &&
5726 new_state == IEEE80211_STA_NONE) {
5727 memset(arsta, 0, sizeof(*arsta));
5728 arsta->arvif = arvif;
5729 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02005730
5731 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5732 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02005733 }
5734
Michal Kazior9797feb2014-02-14 14:49:48 +01005735 /* cancel must be done outside the mutex to avoid deadlock */
5736 if ((old_state == IEEE80211_STA_NONE &&
5737 new_state == IEEE80211_STA_NOTEXIST))
5738 cancel_work_sync(&arsta->update_wk);
5739
Kalle Valo5e3dd152013-06-12 20:52:10 +03005740 mutex_lock(&ar->conf_mutex);
5741
5742 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005743 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005744 /*
5745 * New station addition.
5746 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005747 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5748 u32 num_tdls_stations;
5749 u32 num_tdls_vifs;
5750
Michal Kaziorcfd10612014-11-25 15:16:05 +01005751 ath10k_dbg(ar, ATH10K_DBG_MAC,
5752 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5753 arvif->vdev_id, sta->addr,
5754 ar->num_stations + 1, ar->max_num_stations,
5755 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005756
Marek Puzyniak7c354242015-03-30 09:51:52 +03005757 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005758 if (ret) {
5759 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5760 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005761 goto exit;
5762 }
5763
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005764 if (sta->tdls)
5765 peer_type = WMI_PEER_TYPE_TDLS;
5766
Michal Kazior69427262016-03-06 16:14:30 +02005767 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
5768 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005769 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005770 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 -08005771 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005772 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005773 goto exit;
5774 }
Michal Kazior077efc82014-10-21 10:10:29 +03005775
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005776 spin_lock_bh(&ar->data_lock);
5777
5778 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
5779 if (!peer) {
5780 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5781 vif->addr, arvif->vdev_id);
5782 spin_unlock_bh(&ar->data_lock);
5783 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5784 ath10k_mac_dec_num_stations(arvif, sta);
5785 ret = -ENOENT;
5786 goto exit;
5787 }
5788
5789 arsta->peer_id = find_first_bit(peer->peer_ids,
5790 ATH10K_MAX_NUM_PEER_IDS);
5791
5792 spin_unlock_bh(&ar->data_lock);
5793
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005794 if (!sta->tdls)
5795 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03005796
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005797 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
5798 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
5799
5800 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
5801 num_tdls_stations == 0) {
5802 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
5803 arvif->vdev_id, ar->max_num_tdls_vdevs);
5804 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5805 ath10k_mac_dec_num_stations(arvif, sta);
5806 ret = -ENOBUFS;
5807 goto exit;
5808 }
5809
5810 if (num_tdls_stations == 0) {
5811 /* This is the first tdls peer in current vif */
5812 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
5813
5814 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5815 state);
Michal Kazior077efc82014-10-21 10:10:29 +03005816 if (ret) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005817 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
Michal Kazior077efc82014-10-21 10:10:29 +03005818 arvif->vdev_id, ret);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005819 ath10k_peer_delete(ar, arvif->vdev_id,
5820 sta->addr);
5821 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03005822 goto exit;
5823 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005824 }
Michal Kazior077efc82014-10-21 10:10:29 +03005825
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005826 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5827 WMI_TDLS_PEER_STATE_PEERING);
5828 if (ret) {
5829 ath10k_warn(ar,
5830 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
5831 sta->addr, arvif->vdev_id, ret);
5832 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5833 ath10k_mac_dec_num_stations(arvif, sta);
5834
5835 if (num_tdls_stations != 0)
5836 goto exit;
5837 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5838 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03005839 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005840 } else if ((old_state == IEEE80211_STA_NONE &&
5841 new_state == IEEE80211_STA_NOTEXIST)) {
5842 /*
5843 * Existing station deletion.
5844 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005845 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005846 "mac vdev %d peer delete %pM (sta gone)\n",
5847 arvif->vdev_id, sta->addr);
Michal Kazior077efc82014-10-21 10:10:29 +03005848
Kalle Valo5e3dd152013-06-12 20:52:10 +03005849 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5850 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005851 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005852 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005853
Marek Puzyniak7c354242015-03-30 09:51:52 +03005854 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005855
Michal Kazior69427262016-03-06 16:14:30 +02005856 spin_lock_bh(&ar->data_lock);
5857 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5858 peer = ar->peer_map[i];
5859 if (!peer)
5860 continue;
5861
5862 if (peer->sta == sta) {
5863 ath10k_warn(ar, "found sta peer %pM entry on vdev %i after it was supposedly removed\n",
5864 sta->addr, arvif->vdev_id);
5865 peer->sta = NULL;
5866 }
5867 }
5868 spin_unlock_bh(&ar->data_lock);
5869
Michal Kazior29946872016-03-06 16:14:34 +02005870 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5871 ath10k_mac_txq_unref(ar, sta->txq[i]);
5872
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005873 if (!sta->tdls)
5874 goto exit;
5875
5876 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
5877 goto exit;
5878
5879 /* This was the last tdls peer in current vif */
5880 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5881 WMI_TDLS_DISABLE);
5882 if (ret) {
5883 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
5884 arvif->vdev_id, ret);
5885 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005886 } else if (old_state == IEEE80211_STA_AUTH &&
5887 new_state == IEEE80211_STA_ASSOC &&
5888 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005889 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03005890 vif->type == NL80211_IFTYPE_ADHOC)) {
5891 /*
5892 * New association.
5893 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005894 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005895 sta->addr);
5896
Michal Kazior590922a2014-10-21 10:10:29 +03005897 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005898 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005899 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005900 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005901 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005902 new_state == IEEE80211_STA_AUTHORIZED &&
5903 sta->tdls) {
5904 /*
5905 * Tdls station authorized.
5906 */
5907 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
5908 sta->addr);
5909
5910 ret = ath10k_station_assoc(ar, vif, sta, false);
5911 if (ret) {
5912 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
5913 sta->addr, arvif->vdev_id, ret);
5914 goto exit;
5915 }
5916
5917 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5918 WMI_TDLS_PEER_STATE_CONNECTED);
5919 if (ret)
5920 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
5921 sta->addr, arvif->vdev_id, ret);
5922 } else if (old_state == IEEE80211_STA_ASSOC &&
5923 new_state == IEEE80211_STA_AUTH &&
5924 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005925 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005926 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005927 /*
5928 * Disassociation.
5929 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005930 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005931 sta->addr);
5932
Michal Kazior590922a2014-10-21 10:10:29 +03005933 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005934 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005935 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005936 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005937 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005938exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005939 mutex_unlock(&ar->conf_mutex);
5940 return ret;
5941}
5942
5943static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03005944 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005945{
5946 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02005947 struct wmi_sta_uapsd_auto_trig_arg arg = {};
5948 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005949 u32 value = 0;
5950 int ret = 0;
5951
Michal Kazior548db542013-07-05 16:15:15 +03005952 lockdep_assert_held(&ar->conf_mutex);
5953
Kalle Valo5e3dd152013-06-12 20:52:10 +03005954 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
5955 return 0;
5956
5957 switch (ac) {
5958 case IEEE80211_AC_VO:
5959 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
5960 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005961 prio = 7;
5962 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005963 break;
5964 case IEEE80211_AC_VI:
5965 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
5966 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005967 prio = 5;
5968 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005969 break;
5970 case IEEE80211_AC_BE:
5971 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
5972 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005973 prio = 2;
5974 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005975 break;
5976 case IEEE80211_AC_BK:
5977 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
5978 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005979 prio = 0;
5980 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005981 break;
5982 }
5983
5984 if (enable)
5985 arvif->u.sta.uapsd |= value;
5986 else
5987 arvif->u.sta.uapsd &= ~value;
5988
5989 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5990 WMI_STA_PS_PARAM_UAPSD,
5991 arvif->u.sta.uapsd);
5992 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005993 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005994 goto exit;
5995 }
5996
5997 if (arvif->u.sta.uapsd)
5998 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
5999 else
6000 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6001
6002 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6003 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6004 value);
6005 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006006 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006007
Michal Kazior9f9b5742014-12-12 12:41:36 +01006008 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6009 if (ret) {
6010 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6011 arvif->vdev_id, ret);
6012 return ret;
6013 }
6014
6015 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6016 if (ret) {
6017 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6018 arvif->vdev_id, ret);
6019 return ret;
6020 }
6021
Michal Kaziorb0e56152015-01-24 12:14:52 +02006022 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6023 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6024 /* Only userspace can make an educated decision when to send
6025 * trigger frame. The following effectively disables u-UAPSD
6026 * autotrigger in firmware (which is enabled by default
6027 * provided the autotrigger service is available).
6028 */
6029
6030 arg.wmm_ac = acc;
6031 arg.user_priority = prio;
6032 arg.service_interval = 0;
6033 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6034 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6035
6036 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6037 arvif->bssid, &arg, 1);
6038 if (ret) {
6039 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6040 ret);
6041 return ret;
6042 }
6043 }
6044
Kalle Valo5e3dd152013-06-12 20:52:10 +03006045exit:
6046 return ret;
6047}
6048
6049static int ath10k_conf_tx(struct ieee80211_hw *hw,
6050 struct ieee80211_vif *vif, u16 ac,
6051 const struct ieee80211_tx_queue_params *params)
6052{
6053 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01006054 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006055 struct wmi_wmm_params_arg *p = NULL;
6056 int ret;
6057
6058 mutex_lock(&ar->conf_mutex);
6059
6060 switch (ac) {
6061 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006062 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006063 break;
6064 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006065 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006066 break;
6067 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006068 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006069 break;
6070 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006071 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006072 break;
6073 }
6074
6075 if (WARN_ON(!p)) {
6076 ret = -EINVAL;
6077 goto exit;
6078 }
6079
6080 p->cwmin = params->cw_min;
6081 p->cwmax = params->cw_max;
6082 p->aifs = params->aifs;
6083
6084 /*
6085 * The channel time duration programmed in the HW is in absolute
6086 * microseconds, while mac80211 gives the txop in units of
6087 * 32 microseconds.
6088 */
6089 p->txop = params->txop * 32;
6090
Michal Kazior7fc979a2015-01-28 09:57:28 +02006091 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6092 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6093 &arvif->wmm_params);
6094 if (ret) {
6095 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6096 arvif->vdev_id, ret);
6097 goto exit;
6098 }
6099 } else {
6100 /* This won't work well with multi-interface cases but it's
6101 * better than nothing.
6102 */
6103 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6104 if (ret) {
6105 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6106 goto exit;
6107 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006108 }
6109
6110 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6111 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006112 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006113
6114exit:
6115 mutex_unlock(&ar->conf_mutex);
6116 return ret;
6117}
6118
6119#define ATH10K_ROC_TIMEOUT_HZ (2*HZ)
6120
6121static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6122 struct ieee80211_vif *vif,
6123 struct ieee80211_channel *chan,
6124 int duration,
6125 enum ieee80211_roc_type type)
6126{
6127 struct ath10k *ar = hw->priv;
6128 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6129 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006130 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006131 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006132
6133 mutex_lock(&ar->conf_mutex);
6134
6135 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006136 switch (ar->scan.state) {
6137 case ATH10K_SCAN_IDLE:
6138 reinit_completion(&ar->scan.started);
6139 reinit_completion(&ar->scan.completed);
6140 reinit_completion(&ar->scan.on_channel);
6141 ar->scan.state = ATH10K_SCAN_STARTING;
6142 ar->scan.is_roc = true;
6143 ar->scan.vdev_id = arvif->vdev_id;
6144 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006145 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006146 ret = 0;
6147 break;
6148 case ATH10K_SCAN_STARTING:
6149 case ATH10K_SCAN_RUNNING:
6150 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006151 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006152 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006153 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006154 spin_unlock_bh(&ar->data_lock);
6155
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006156 if (ret)
6157 goto exit;
6158
Michal Kaziorfcf98442015-03-31 11:03:47 +00006159 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006160
Kalle Valo5e3dd152013-06-12 20:52:10 +03006161 memset(&arg, 0, sizeof(arg));
6162 ath10k_wmi_start_scan_init(ar, &arg);
6163 arg.vdev_id = arvif->vdev_id;
6164 arg.scan_id = ATH10K_SCAN_ID;
6165 arg.n_channels = 1;
6166 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006167 arg.dwell_time_active = scan_time_msec;
6168 arg.dwell_time_passive = scan_time_msec;
6169 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006170 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6171 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006172 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006173
6174 ret = ath10k_start_scan(ar, &arg);
6175 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006176 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006177 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006178 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006179 spin_unlock_bh(&ar->data_lock);
6180 goto exit;
6181 }
6182
6183 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ);
6184 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006185 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006186
6187 ret = ath10k_scan_stop(ar);
6188 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006189 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006190
Kalle Valo5e3dd152013-06-12 20:52:10 +03006191 ret = -ETIMEDOUT;
6192 goto exit;
6193 }
6194
Michal Kaziorfcf98442015-03-31 11:03:47 +00006195 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6196 msecs_to_jiffies(duration));
6197
Kalle Valo5e3dd152013-06-12 20:52:10 +03006198 ret = 0;
6199exit:
6200 mutex_unlock(&ar->conf_mutex);
6201 return ret;
6202}
6203
6204static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6205{
6206 struct ath10k *ar = hw->priv;
6207
6208 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006209
6210 spin_lock_bh(&ar->data_lock);
6211 ar->scan.roc_notify = false;
6212 spin_unlock_bh(&ar->data_lock);
6213
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006214 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006215
Kalle Valo5e3dd152013-06-12 20:52:10 +03006216 mutex_unlock(&ar->conf_mutex);
6217
Michal Kazior4eb2e162014-10-28 10:23:09 +01006218 cancel_delayed_work_sync(&ar->scan.timeout);
6219
Kalle Valo5e3dd152013-06-12 20:52:10 +03006220 return 0;
6221}
6222
6223/*
6224 * Both RTS and Fragmentation threshold are interface-specific
6225 * in ath10k, but device-specific in mac80211.
6226 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006227
6228static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6229{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006230 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006231 struct ath10k_vif *arvif;
6232 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006233
Michal Kaziorad088bf2013-10-16 15:44:46 +03006234 mutex_lock(&ar->conf_mutex);
6235 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006236 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006237 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006238
Michal Kaziorad088bf2013-10-16 15:44:46 +03006239 ret = ath10k_mac_set_rts(arvif, value);
6240 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006241 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006242 arvif->vdev_id, ret);
6243 break;
6244 }
6245 }
6246 mutex_unlock(&ar->conf_mutex);
6247
6248 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006249}
6250
Michal Kazior92092fe2015-08-03 11:16:43 +02006251static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6252{
6253 /* Even though there's a WMI enum for fragmentation threshold no known
6254 * firmware actually implements it. Moreover it is not possible to rely
6255 * frame fragmentation to mac80211 because firmware clears the "more
6256 * fragments" bit in frame control making it impossible for remote
6257 * devices to reassemble frames.
6258 *
6259 * Hence implement a dummy callback just to say fragmentation isn't
6260 * supported. This effectively prevents mac80211 from doing frame
6261 * fragmentation in software.
6262 */
6263 return -EOPNOTSUPP;
6264}
6265
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02006266static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6267 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006268{
6269 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02006270 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006271 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006272
6273 /* mac80211 doesn't care if we really xmit queued frames or not
6274 * we'll collect those frames either way if we stop/delete vdevs */
6275 if (drop)
6276 return;
6277
Michal Kazior548db542013-07-05 16:15:15 +03006278 mutex_lock(&ar->conf_mutex);
6279
Michal Kazioraffd3212013-07-16 09:54:35 +02006280 if (ar->state == ATH10K_STATE_WEDGED)
6281 goto skip;
6282
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006283 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006284 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006285
Michal Kazioredb82362013-07-05 16:15:14 +03006286 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006287 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006288 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006289
Michal Kazior7962b0d2014-10-28 10:34:38 +01006290 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6291 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6292 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006293
6294 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006295 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006296
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006297 if (time_left == 0 || skip)
6298 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6299 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03006300
Michal Kazioraffd3212013-07-16 09:54:35 +02006301skip:
Michal Kazior548db542013-07-05 16:15:15 +03006302 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006303}
6304
6305/* TODO: Implement this function properly
6306 * For now it is needed to reply to Probe Requests in IBSS mode.
6307 * Propably we need this information from FW.
6308 */
6309static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
6310{
6311 return 1;
6312}
6313
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006314static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
6315 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02006316{
6317 struct ath10k *ar = hw->priv;
6318
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006319 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
6320 return;
6321
Michal Kazioraffd3212013-07-16 09:54:35 +02006322 mutex_lock(&ar->conf_mutex);
6323
6324 /* If device failed to restart it will be in a different state, e.g.
6325 * ATH10K_STATE_WEDGED */
6326 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006327 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02006328 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01006329 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02006330 }
6331
6332 mutex_unlock(&ar->conf_mutex);
6333}
6334
Michal Kazior2e1dea42013-07-31 10:32:40 +02006335static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
6336 struct survey_info *survey)
6337{
6338 struct ath10k *ar = hw->priv;
6339 struct ieee80211_supported_band *sband;
6340 struct survey_info *ar_survey = &ar->survey[idx];
6341 int ret = 0;
6342
6343 mutex_lock(&ar->conf_mutex);
6344
6345 sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
6346 if (sband && idx >= sband->n_channels) {
6347 idx -= sband->n_channels;
6348 sband = NULL;
6349 }
6350
6351 if (!sband)
6352 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
6353
6354 if (!sband || idx >= sband->n_channels) {
6355 ret = -ENOENT;
6356 goto exit;
6357 }
6358
6359 spin_lock_bh(&ar->data_lock);
6360 memcpy(survey, ar_survey, sizeof(*survey));
6361 spin_unlock_bh(&ar->data_lock);
6362
6363 survey->channel = &sband->channels[idx];
6364
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03006365 if (ar->rx_channel == survey->channel)
6366 survey->filled |= SURVEY_INFO_IN_USE;
6367
Michal Kazior2e1dea42013-07-31 10:32:40 +02006368exit:
6369 mutex_unlock(&ar->conf_mutex);
6370 return ret;
6371}
6372
Michal Kazior3ae54222015-03-31 10:49:20 +00006373static bool
6374ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
6375 enum ieee80211_band band,
6376 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006377{
Michal Kazior3ae54222015-03-31 10:49:20 +00006378 int num_rates = 0;
6379 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006380
Michal Kazior3ae54222015-03-31 10:49:20 +00006381 num_rates += hweight32(mask->control[band].legacy);
6382
6383 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
6384 num_rates += hweight8(mask->control[band].ht_mcs[i]);
6385
6386 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
6387 num_rates += hweight16(mask->control[band].vht_mcs[i]);
6388
6389 return num_rates == 1;
6390}
6391
6392static bool
6393ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
6394 enum ieee80211_band band,
6395 const struct cfg80211_bitrate_mask *mask,
6396 int *nss)
6397{
6398 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6399 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6400 u8 ht_nss_mask = 0;
6401 u8 vht_nss_mask = 0;
6402 int i;
6403
6404 if (mask->control[band].legacy)
6405 return false;
6406
6407 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6408 if (mask->control[band].ht_mcs[i] == 0)
6409 continue;
6410 else if (mask->control[band].ht_mcs[i] ==
6411 sband->ht_cap.mcs.rx_mask[i])
6412 ht_nss_mask |= BIT(i);
6413 else
6414 return false;
6415 }
6416
6417 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6418 if (mask->control[band].vht_mcs[i] == 0)
6419 continue;
6420 else if (mask->control[band].vht_mcs[i] ==
6421 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6422 vht_nss_mask |= BIT(i);
6423 else
6424 return false;
6425 }
6426
6427 if (ht_nss_mask != vht_nss_mask)
6428 return false;
6429
6430 if (ht_nss_mask == 0)
6431 return false;
6432
6433 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6434 return false;
6435
6436 *nss = fls(ht_nss_mask);
6437
6438 return true;
6439}
6440
6441static int
6442ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
6443 enum ieee80211_band band,
6444 const struct cfg80211_bitrate_mask *mask,
6445 u8 *rate, u8 *nss)
6446{
6447 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6448 int rate_idx;
6449 int i;
6450 u16 bitrate;
6451 u8 preamble;
6452 u8 hw_rate;
6453
6454 if (hweight32(mask->control[band].legacy) == 1) {
6455 rate_idx = ffs(mask->control[band].legacy) - 1;
6456
6457 hw_rate = sband->bitrates[rate_idx].hw_value;
6458 bitrate = sband->bitrates[rate_idx].bitrate;
6459
6460 if (ath10k_mac_bitrate_is_cck(bitrate))
6461 preamble = WMI_RATE_PREAMBLE_CCK;
6462 else
6463 preamble = WMI_RATE_PREAMBLE_OFDM;
6464
6465 *nss = 1;
6466 *rate = preamble << 6 |
6467 (*nss - 1) << 4 |
6468 hw_rate << 0;
6469
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006470 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006471 }
6472
Michal Kazior3ae54222015-03-31 10:49:20 +00006473 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6474 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6475 *nss = i + 1;
6476 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6477 (*nss - 1) << 4 |
6478 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006479
Michal Kazior3ae54222015-03-31 10:49:20 +00006480 return 0;
6481 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006482 }
6483
Michal Kazior3ae54222015-03-31 10:49:20 +00006484 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6485 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6486 *nss = i + 1;
6487 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6488 (*nss - 1) << 4 |
6489 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006490
Michal Kazior3ae54222015-03-31 10:49:20 +00006491 return 0;
6492 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006493 }
6494
Michal Kazior3ae54222015-03-31 10:49:20 +00006495 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006496}
6497
Michal Kazior3ae54222015-03-31 10:49:20 +00006498static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306499 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006500{
6501 struct ath10k *ar = arvif->ar;
6502 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006503 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006504
Michal Kazior3ae54222015-03-31 10:49:20 +00006505 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006506
Michal Kazior3ae54222015-03-31 10:49:20 +00006507 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6508 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006509
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006510 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006511 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006512 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006513 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006514 rate, ret);
6515 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006516 }
6517
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006518 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006519 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006520 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006521 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6522 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006523 }
6524
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006525 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006526 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006527 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006528 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6529 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006530 }
6531
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306532 vdev_param = ar->wmi.vdev_param->ldpc;
6533 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6534 if (ret) {
6535 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6536 return ret;
6537 }
6538
Michal Kazior3ae54222015-03-31 10:49:20 +00006539 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006540}
6541
Michal Kazior45c9abc2015-04-21 20:42:58 +03006542static bool
6543ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
6544 enum ieee80211_band band,
6545 const struct cfg80211_bitrate_mask *mask)
6546{
6547 int i;
6548 u16 vht_mcs;
6549
6550 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6551 * to express all VHT MCS rate masks. Effectively only the following
6552 * ranges can be used: none, 0-7, 0-8 and 0-9.
6553 */
6554 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6555 vht_mcs = mask->control[band].vht_mcs[i];
6556
6557 switch (vht_mcs) {
6558 case 0:
6559 case BIT(8) - 1:
6560 case BIT(9) - 1:
6561 case BIT(10) - 1:
6562 break;
6563 default:
6564 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6565 return false;
6566 }
6567 }
6568
6569 return true;
6570}
6571
6572static void ath10k_mac_set_bitrate_mask_iter(void *data,
6573 struct ieee80211_sta *sta)
6574{
6575 struct ath10k_vif *arvif = data;
6576 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6577 struct ath10k *ar = arvif->ar;
6578
6579 if (arsta->arvif != arvif)
6580 return;
6581
6582 spin_lock_bh(&ar->data_lock);
6583 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
6584 spin_unlock_bh(&ar->data_lock);
6585
6586 ieee80211_queue_work(ar->hw, &arsta->update_wk);
6587}
6588
Michal Kazior3ae54222015-03-31 10:49:20 +00006589static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
6590 struct ieee80211_vif *vif,
6591 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006592{
6593 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006594 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006595 struct ath10k *ar = arvif->ar;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006596 enum ieee80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006597 const u8 *ht_mcs_mask;
6598 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00006599 u8 rate;
6600 u8 nss;
6601 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306602 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00006603 int single_nss;
6604 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006605
Michal Kazior500ff9f2015-03-31 10:26:21 +00006606 if (ath10k_mac_vif_chan(vif, &def))
6607 return -EPERM;
6608
Michal Kazior500ff9f2015-03-31 10:26:21 +00006609 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006610 ht_mcs_mask = mask->control[band].ht_mcs;
6611 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306612 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006613
Michal Kazior3ae54222015-03-31 10:49:20 +00006614 sgi = mask->control[band].gi;
6615 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006616 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006617
Michal Kazior3ae54222015-03-31 10:49:20 +00006618 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
6619 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
6620 &rate, &nss);
6621 if (ret) {
6622 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
6623 arvif->vdev_id, ret);
6624 return ret;
6625 }
6626 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
6627 &single_nss)) {
6628 rate = WMI_FIXED_RATE_NONE;
6629 nss = single_nss;
6630 } else {
6631 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006632 nss = min(ar->num_rf_chains,
6633 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6634 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6635
6636 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
6637 return -EINVAL;
6638
6639 mutex_lock(&ar->conf_mutex);
6640
6641 arvif->bitrate_mask = *mask;
6642 ieee80211_iterate_stations_atomic(ar->hw,
6643 ath10k_mac_set_bitrate_mask_iter,
6644 arvif);
6645
6646 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006647 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006648
6649 mutex_lock(&ar->conf_mutex);
6650
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306651 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006652 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006653 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
6654 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006655 goto exit;
6656 }
6657
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006658exit:
6659 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00006660
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006661 return ret;
6662}
6663
Michal Kazior9797feb2014-02-14 14:49:48 +01006664static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6665 struct ieee80211_vif *vif,
6666 struct ieee80211_sta *sta,
6667 u32 changed)
6668{
6669 struct ath10k *ar = hw->priv;
6670 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6671 u32 bw, smps;
6672
6673 spin_lock_bh(&ar->data_lock);
6674
Michal Kazior7aa7a722014-08-25 12:09:38 +02006675 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01006676 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
6677 sta->addr, changed, sta->bandwidth, sta->rx_nss,
6678 sta->smps_mode);
6679
6680 if (changed & IEEE80211_RC_BW_CHANGED) {
6681 bw = WMI_PEER_CHWIDTH_20MHZ;
6682
6683 switch (sta->bandwidth) {
6684 case IEEE80211_STA_RX_BW_20:
6685 bw = WMI_PEER_CHWIDTH_20MHZ;
6686 break;
6687 case IEEE80211_STA_RX_BW_40:
6688 bw = WMI_PEER_CHWIDTH_40MHZ;
6689 break;
6690 case IEEE80211_STA_RX_BW_80:
6691 bw = WMI_PEER_CHWIDTH_80MHZ;
6692 break;
6693 case IEEE80211_STA_RX_BW_160:
Masanari Iidad939be32015-02-27 23:52:31 +09006694 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006695 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006696 bw = WMI_PEER_CHWIDTH_20MHZ;
6697 break;
6698 }
6699
6700 arsta->bw = bw;
6701 }
6702
6703 if (changed & IEEE80211_RC_NSS_CHANGED)
6704 arsta->nss = sta->rx_nss;
6705
6706 if (changed & IEEE80211_RC_SMPS_CHANGED) {
6707 smps = WMI_PEER_SMPS_PS_NONE;
6708
6709 switch (sta->smps_mode) {
6710 case IEEE80211_SMPS_AUTOMATIC:
6711 case IEEE80211_SMPS_OFF:
6712 smps = WMI_PEER_SMPS_PS_NONE;
6713 break;
6714 case IEEE80211_SMPS_STATIC:
6715 smps = WMI_PEER_SMPS_STATIC;
6716 break;
6717 case IEEE80211_SMPS_DYNAMIC:
6718 smps = WMI_PEER_SMPS_DYNAMIC;
6719 break;
6720 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02006721 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006722 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006723 smps = WMI_PEER_SMPS_PS_NONE;
6724 break;
6725 }
6726
6727 arsta->smps = smps;
6728 }
6729
Michal Kazior9797feb2014-02-14 14:49:48 +01006730 arsta->changed |= changed;
6731
6732 spin_unlock_bh(&ar->data_lock);
6733
6734 ieee80211_queue_work(hw, &arsta->update_wk);
6735}
6736
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006737static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
6738{
6739 /*
6740 * FIXME: Return 0 for time being. Need to figure out whether FW
6741 * has the API to fetch 64-bit local TSF
6742 */
6743
6744 return 0;
6745}
6746
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006747static int ath10k_ampdu_action(struct ieee80211_hw *hw,
6748 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02006749 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006750{
Michal Kazior7aa7a722014-08-25 12:09:38 +02006751 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006752 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Sara Sharon50ea05e2015-12-30 16:06:04 +02006753 struct ieee80211_sta *sta = params->sta;
6754 enum ieee80211_ampdu_mlme_action action = params->action;
6755 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006756
Michal Kazior7aa7a722014-08-25 12:09:38 +02006757 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 +02006758 arvif->vdev_id, sta->addr, tid, action);
6759
6760 switch (action) {
6761 case IEEE80211_AMPDU_RX_START:
6762 case IEEE80211_AMPDU_RX_STOP:
6763 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
6764 * creation/removal. Do we need to verify this?
6765 */
6766 return 0;
6767 case IEEE80211_AMPDU_TX_START:
6768 case IEEE80211_AMPDU_TX_STOP_CONT:
6769 case IEEE80211_AMPDU_TX_STOP_FLUSH:
6770 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
6771 case IEEE80211_AMPDU_TX_OPERATIONAL:
6772 /* Firmware offloads Tx aggregation entirely so deny mac80211
6773 * Tx aggregation requests.
6774 */
6775 return -EOPNOTSUPP;
6776 }
6777
6778 return -EINVAL;
6779}
6780
Michal Kazior500ff9f2015-03-31 10:26:21 +00006781static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006782ath10k_mac_update_rx_channel(struct ath10k *ar,
6783 struct ieee80211_chanctx_conf *ctx,
6784 struct ieee80211_vif_chanctx_switch *vifs,
6785 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00006786{
6787 struct cfg80211_chan_def *def = NULL;
6788
6789 /* Both locks are required because ar->rx_channel is modified. This
6790 * allows readers to hold either lock.
6791 */
6792 lockdep_assert_held(&ar->conf_mutex);
6793 lockdep_assert_held(&ar->data_lock);
6794
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006795 WARN_ON(ctx && vifs);
6796 WARN_ON(vifs && n_vifs != 1);
6797
Michal Kazior500ff9f2015-03-31 10:26:21 +00006798 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
6799 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
6800 * ppdu on Rx may reduce performance on low-end systems. It should be
6801 * possible to make tables/hashmaps to speed the lookup up (be vary of
6802 * cpu data cache lines though regarding sizes) but to keep the initial
6803 * implementation simple and less intrusive fallback to the slow lookup
6804 * only for multi-channel cases. Single-channel cases will remain to
6805 * use the old channel derival and thus performance should not be
6806 * affected much.
6807 */
6808 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006809 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00006810 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03006811 ath10k_mac_get_any_chandef_iter,
6812 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006813
6814 if (vifs)
6815 def = &vifs[0].new_ctx->def;
6816
Michal Kazior500ff9f2015-03-31 10:26:21 +00006817 ar->rx_channel = def->chan;
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006818 } else if (ctx && ath10k_mac_num_chanctxs(ar) == 0) {
6819 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006820 } else {
6821 ar->rx_channel = NULL;
6822 }
6823 rcu_read_unlock();
6824}
6825
Michal Kazior7be6d1b2015-09-03 10:44:51 +02006826static void
6827ath10k_mac_update_vif_chan(struct ath10k *ar,
6828 struct ieee80211_vif_chanctx_switch *vifs,
6829 int n_vifs)
6830{
6831 struct ath10k_vif *arvif;
6832 int ret;
6833 int i;
6834
6835 lockdep_assert_held(&ar->conf_mutex);
6836
6837 /* First stop monitor interface. Some FW versions crash if there's a
6838 * lone monitor interface.
6839 */
6840 if (ar->monitor_started)
6841 ath10k_monitor_stop(ar);
6842
6843 for (i = 0; i < n_vifs; i++) {
6844 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6845
6846 ath10k_dbg(ar, ATH10K_DBG_MAC,
6847 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
6848 arvif->vdev_id,
6849 vifs[i].old_ctx->def.chan->center_freq,
6850 vifs[i].new_ctx->def.chan->center_freq,
6851 vifs[i].old_ctx->def.width,
6852 vifs[i].new_ctx->def.width);
6853
6854 if (WARN_ON(!arvif->is_started))
6855 continue;
6856
6857 if (WARN_ON(!arvif->is_up))
6858 continue;
6859
6860 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
6861 if (ret) {
6862 ath10k_warn(ar, "failed to down vdev %d: %d\n",
6863 arvif->vdev_id, ret);
6864 continue;
6865 }
6866 }
6867
6868 /* All relevant vdevs are downed and associated channel resources
6869 * should be available for the channel switch now.
6870 */
6871
6872 spin_lock_bh(&ar->data_lock);
6873 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
6874 spin_unlock_bh(&ar->data_lock);
6875
6876 for (i = 0; i < n_vifs; i++) {
6877 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6878
6879 if (WARN_ON(!arvif->is_started))
6880 continue;
6881
6882 if (WARN_ON(!arvif->is_up))
6883 continue;
6884
6885 ret = ath10k_mac_setup_bcn_tmpl(arvif);
6886 if (ret)
6887 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
6888 ret);
6889
6890 ret = ath10k_mac_setup_prb_tmpl(arvif);
6891 if (ret)
6892 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
6893 ret);
6894
6895 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
6896 if (ret) {
6897 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
6898 arvif->vdev_id, ret);
6899 continue;
6900 }
6901
6902 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
6903 arvif->bssid);
6904 if (ret) {
6905 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
6906 arvif->vdev_id, ret);
6907 continue;
6908 }
6909 }
6910
6911 ath10k_monitor_recalc(ar);
6912}
6913
Michal Kazior500ff9f2015-03-31 10:26:21 +00006914static int
6915ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
6916 struct ieee80211_chanctx_conf *ctx)
6917{
6918 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006919
6920 ath10k_dbg(ar, ATH10K_DBG_MAC,
6921 "mac chanctx add freq %hu width %d ptr %p\n",
6922 ctx->def.chan->center_freq, ctx->def.width, ctx);
6923
6924 mutex_lock(&ar->conf_mutex);
6925
6926 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006927 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006928 spin_unlock_bh(&ar->data_lock);
6929
6930 ath10k_recalc_radar_detection(ar);
6931 ath10k_monitor_recalc(ar);
6932
6933 mutex_unlock(&ar->conf_mutex);
6934
6935 return 0;
6936}
6937
6938static void
6939ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
6940 struct ieee80211_chanctx_conf *ctx)
6941{
6942 struct ath10k *ar = hw->priv;
6943
6944 ath10k_dbg(ar, ATH10K_DBG_MAC,
6945 "mac chanctx remove freq %hu width %d ptr %p\n",
6946 ctx->def.chan->center_freq, ctx->def.width, ctx);
6947
6948 mutex_lock(&ar->conf_mutex);
6949
6950 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006951 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006952 spin_unlock_bh(&ar->data_lock);
6953
6954 ath10k_recalc_radar_detection(ar);
6955 ath10k_monitor_recalc(ar);
6956
6957 mutex_unlock(&ar->conf_mutex);
6958}
6959
Michal Kazior9713e3d2015-09-03 10:44:52 +02006960struct ath10k_mac_change_chanctx_arg {
6961 struct ieee80211_chanctx_conf *ctx;
6962 struct ieee80211_vif_chanctx_switch *vifs;
6963 int n_vifs;
6964 int next_vif;
6965};
6966
6967static void
6968ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
6969 struct ieee80211_vif *vif)
6970{
6971 struct ath10k_mac_change_chanctx_arg *arg = data;
6972
6973 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
6974 return;
6975
6976 arg->n_vifs++;
6977}
6978
6979static void
6980ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
6981 struct ieee80211_vif *vif)
6982{
6983 struct ath10k_mac_change_chanctx_arg *arg = data;
6984 struct ieee80211_chanctx_conf *ctx;
6985
6986 ctx = rcu_access_pointer(vif->chanctx_conf);
6987 if (ctx != arg->ctx)
6988 return;
6989
6990 if (WARN_ON(arg->next_vif == arg->n_vifs))
6991 return;
6992
6993 arg->vifs[arg->next_vif].vif = vif;
6994 arg->vifs[arg->next_vif].old_ctx = ctx;
6995 arg->vifs[arg->next_vif].new_ctx = ctx;
6996 arg->next_vif++;
6997}
6998
Michal Kazior500ff9f2015-03-31 10:26:21 +00006999static void
7000ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7001 struct ieee80211_chanctx_conf *ctx,
7002 u32 changed)
7003{
7004 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007005 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007006
7007 mutex_lock(&ar->conf_mutex);
7008
7009 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007010 "mac chanctx change freq %hu width %d ptr %p changed %x\n",
7011 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007012
7013 /* This shouldn't really happen because channel switching should use
7014 * switch_vif_chanctx().
7015 */
7016 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7017 goto unlock;
7018
Michal Kazior9713e3d2015-09-03 10:44:52 +02007019 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7020 ieee80211_iterate_active_interfaces_atomic(
7021 hw,
7022 IEEE80211_IFACE_ITER_NORMAL,
7023 ath10k_mac_change_chanctx_cnt_iter,
7024 &arg);
7025 if (arg.n_vifs == 0)
7026 goto radar;
7027
7028 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7029 GFP_KERNEL);
7030 if (!arg.vifs)
7031 goto radar;
7032
7033 ieee80211_iterate_active_interfaces_atomic(
7034 hw,
7035 IEEE80211_IFACE_ITER_NORMAL,
7036 ath10k_mac_change_chanctx_fill_iter,
7037 &arg);
7038 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7039 kfree(arg.vifs);
7040 }
7041
7042radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007043 ath10k_recalc_radar_detection(ar);
7044
7045 /* FIXME: How to configure Rx chains properly? */
7046
7047 /* No other actions are actually necessary. Firmware maintains channel
7048 * definitions per vdev internally and there's no host-side channel
7049 * context abstraction to configure, e.g. channel width.
7050 */
7051
7052unlock:
7053 mutex_unlock(&ar->conf_mutex);
7054}
7055
7056static int
7057ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7058 struct ieee80211_vif *vif,
7059 struct ieee80211_chanctx_conf *ctx)
7060{
7061 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007062 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7063 int ret;
7064
7065 mutex_lock(&ar->conf_mutex);
7066
7067 ath10k_dbg(ar, ATH10K_DBG_MAC,
7068 "mac chanctx assign ptr %p vdev_id %i\n",
7069 ctx, arvif->vdev_id);
7070
7071 if (WARN_ON(arvif->is_started)) {
7072 mutex_unlock(&ar->conf_mutex);
7073 return -EBUSY;
7074 }
7075
Michal Kazior089ab7a2015-06-03 12:16:55 +02007076 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007077 if (ret) {
7078 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7079 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007080 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007081 goto err;
7082 }
7083
7084 arvif->is_started = true;
7085
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007086 ret = ath10k_mac_vif_setup_ps(arvif);
7087 if (ret) {
7088 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7089 arvif->vdev_id, ret);
7090 goto err_stop;
7091 }
7092
Michal Kazior500ff9f2015-03-31 10:26:21 +00007093 if (vif->type == NL80211_IFTYPE_MONITOR) {
7094 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7095 if (ret) {
7096 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7097 arvif->vdev_id, ret);
7098 goto err_stop;
7099 }
7100
7101 arvif->is_up = true;
7102 }
7103
7104 mutex_unlock(&ar->conf_mutex);
7105 return 0;
7106
7107err_stop:
7108 ath10k_vdev_stop(arvif);
7109 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007110 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007111
7112err:
7113 mutex_unlock(&ar->conf_mutex);
7114 return ret;
7115}
7116
7117static void
7118ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7119 struct ieee80211_vif *vif,
7120 struct ieee80211_chanctx_conf *ctx)
7121{
7122 struct ath10k *ar = hw->priv;
7123 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7124 int ret;
7125
7126 mutex_lock(&ar->conf_mutex);
7127
7128 ath10k_dbg(ar, ATH10K_DBG_MAC,
7129 "mac chanctx unassign ptr %p vdev_id %i\n",
7130 ctx, arvif->vdev_id);
7131
7132 WARN_ON(!arvif->is_started);
7133
7134 if (vif->type == NL80211_IFTYPE_MONITOR) {
7135 WARN_ON(!arvif->is_up);
7136
7137 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7138 if (ret)
7139 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7140 arvif->vdev_id, ret);
7141
7142 arvif->is_up = false;
7143 }
7144
7145 ret = ath10k_vdev_stop(arvif);
7146 if (ret)
7147 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7148 arvif->vdev_id, ret);
7149
7150 arvif->is_started = false;
7151
7152 mutex_unlock(&ar->conf_mutex);
7153}
7154
7155static int
7156ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7157 struct ieee80211_vif_chanctx_switch *vifs,
7158 int n_vifs,
7159 enum ieee80211_chanctx_switch_mode mode)
7160{
7161 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007162
7163 mutex_lock(&ar->conf_mutex);
7164
7165 ath10k_dbg(ar, ATH10K_DBG_MAC,
7166 "mac chanctx switch n_vifs %d mode %d\n",
7167 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007168 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007169
7170 mutex_unlock(&ar->conf_mutex);
7171 return 0;
7172}
7173
Kalle Valo5e3dd152013-06-12 20:52:10 +03007174static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01007175 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02007176 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007177 .start = ath10k_start,
7178 .stop = ath10k_stop,
7179 .config = ath10k_config,
7180 .add_interface = ath10k_add_interface,
7181 .remove_interface = ath10k_remove_interface,
7182 .configure_filter = ath10k_configure_filter,
7183 .bss_info_changed = ath10k_bss_info_changed,
7184 .hw_scan = ath10k_hw_scan,
7185 .cancel_hw_scan = ath10k_cancel_hw_scan,
7186 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02007187 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007188 .sta_state = ath10k_sta_state,
7189 .conf_tx = ath10k_conf_tx,
7190 .remain_on_channel = ath10k_remain_on_channel,
7191 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
7192 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02007193 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007194 .flush = ath10k_flush,
7195 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03007196 .set_antenna = ath10k_set_antenna,
7197 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007198 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02007199 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00007200 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01007201 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02007202 .get_tsf = ath10k_get_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007203 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03007204 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7205 .get_et_stats = ath10k_debug_get_et_stats,
7206 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00007207 .add_chanctx = ath10k_mac_op_add_chanctx,
7208 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7209 .change_chanctx = ath10k_mac_op_change_chanctx,
7210 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7211 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7212 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Kalle Valo43d2a302014-09-10 18:23:30 +03007213
7214 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7215
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007216#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007217 .suspend = ath10k_wow_op_suspend,
7218 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007219#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007220#ifdef CONFIG_MAC80211_DEBUGFS
7221 .sta_add_debugfs = ath10k_sta_add_debugfs,
7222#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03007223};
7224
Kalle Valo5e3dd152013-06-12 20:52:10 +03007225#define CHAN2G(_channel, _freq, _flags) { \
7226 .band = IEEE80211_BAND_2GHZ, \
7227 .hw_value = (_channel), \
7228 .center_freq = (_freq), \
7229 .flags = (_flags), \
7230 .max_antenna_gain = 0, \
7231 .max_power = 30, \
7232}
7233
7234#define CHAN5G(_channel, _freq, _flags) { \
7235 .band = IEEE80211_BAND_5GHZ, \
7236 .hw_value = (_channel), \
7237 .center_freq = (_freq), \
7238 .flags = (_flags), \
7239 .max_antenna_gain = 0, \
7240 .max_power = 30, \
7241}
7242
7243static const struct ieee80211_channel ath10k_2ghz_channels[] = {
7244 CHAN2G(1, 2412, 0),
7245 CHAN2G(2, 2417, 0),
7246 CHAN2G(3, 2422, 0),
7247 CHAN2G(4, 2427, 0),
7248 CHAN2G(5, 2432, 0),
7249 CHAN2G(6, 2437, 0),
7250 CHAN2G(7, 2442, 0),
7251 CHAN2G(8, 2447, 0),
7252 CHAN2G(9, 2452, 0),
7253 CHAN2G(10, 2457, 0),
7254 CHAN2G(11, 2462, 0),
7255 CHAN2G(12, 2467, 0),
7256 CHAN2G(13, 2472, 0),
7257 CHAN2G(14, 2484, 0),
7258};
7259
7260static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02007261 CHAN5G(36, 5180, 0),
7262 CHAN5G(40, 5200, 0),
7263 CHAN5G(44, 5220, 0),
7264 CHAN5G(48, 5240, 0),
7265 CHAN5G(52, 5260, 0),
7266 CHAN5G(56, 5280, 0),
7267 CHAN5G(60, 5300, 0),
7268 CHAN5G(64, 5320, 0),
7269 CHAN5G(100, 5500, 0),
7270 CHAN5G(104, 5520, 0),
7271 CHAN5G(108, 5540, 0),
7272 CHAN5G(112, 5560, 0),
7273 CHAN5G(116, 5580, 0),
7274 CHAN5G(120, 5600, 0),
7275 CHAN5G(124, 5620, 0),
7276 CHAN5G(128, 5640, 0),
7277 CHAN5G(132, 5660, 0),
7278 CHAN5G(136, 5680, 0),
7279 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07007280 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02007281 CHAN5G(149, 5745, 0),
7282 CHAN5G(153, 5765, 0),
7283 CHAN5G(157, 5785, 0),
7284 CHAN5G(161, 5805, 0),
7285 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03007286};
7287
Michal Kaziore7b54192014-08-07 11:03:27 +02007288struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007289{
7290 struct ieee80211_hw *hw;
7291 struct ath10k *ar;
7292
Michal Kaziore7b54192014-08-07 11:03:27 +02007293 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007294 if (!hw)
7295 return NULL;
7296
7297 ar = hw->priv;
7298 ar->hw = hw;
7299
7300 return ar;
7301}
7302
7303void ath10k_mac_destroy(struct ath10k *ar)
7304{
7305 ieee80211_free_hw(ar->hw);
7306}
7307
7308static const struct ieee80211_iface_limit ath10k_if_limits[] = {
7309 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307310 .max = 8,
7311 .types = BIT(NL80211_IFTYPE_STATION)
7312 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02007313 },
7314 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307315 .max = 3,
7316 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02007317 },
7318 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307319 .max = 1,
7320 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01007321 },
7322 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307323 .max = 7,
7324 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007325#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307326 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007327#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02007328 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007329};
7330
Bartosz Markowskif2595092013-12-10 16:20:39 +01007331static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007332 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307333 .max = 8,
7334 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007335#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307336 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007337#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007338 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307339 {
7340 .max = 1,
7341 .types = BIT(NL80211_IFTYPE_STATION)
7342 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007343};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007344
7345static const struct ieee80211_iface_combination ath10k_if_comb[] = {
7346 {
7347 .limits = ath10k_if_limits,
7348 .n_limits = ARRAY_SIZE(ath10k_if_limits),
7349 .max_interfaces = 8,
7350 .num_different_channels = 1,
7351 .beacon_int_infra_match = true,
7352 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01007353};
7354
7355static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007356 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01007357 .limits = ath10k_10x_if_limits,
7358 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007359 .max_interfaces = 8,
7360 .num_different_channels = 1,
7361 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01007362#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007363 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7364 BIT(NL80211_CHAN_WIDTH_20) |
7365 BIT(NL80211_CHAN_WIDTH_40) |
7366 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007367#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01007368 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007369};
7370
Michal Kaziorcf327842015-03-31 10:26:25 +00007371static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
7372 {
7373 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02007374 .types = BIT(NL80211_IFTYPE_STATION),
7375 },
7376 {
7377 .max = 2,
7378 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007379#ifdef CONFIG_MAC80211_MESH
7380 BIT(NL80211_IFTYPE_MESH_POINT) |
7381#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00007382 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7383 BIT(NL80211_IFTYPE_P2P_GO),
7384 },
7385 {
7386 .max = 1,
7387 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7388 },
7389};
7390
Michal Kaziored25b112015-07-09 13:08:39 +02007391static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
7392 {
7393 .max = 2,
7394 .types = BIT(NL80211_IFTYPE_STATION),
7395 },
7396 {
7397 .max = 2,
7398 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
7399 },
7400 {
7401 .max = 1,
7402 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007403#ifdef CONFIG_MAC80211_MESH
7404 BIT(NL80211_IFTYPE_MESH_POINT) |
7405#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007406 BIT(NL80211_IFTYPE_P2P_GO),
7407 },
7408 {
7409 .max = 1,
7410 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7411 },
7412};
7413
Michal Kaziorcf327842015-03-31 10:26:25 +00007414static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7415 {
7416 .max = 1,
7417 .types = BIT(NL80211_IFTYPE_STATION),
7418 },
7419 {
7420 .max = 1,
7421 .types = BIT(NL80211_IFTYPE_ADHOC),
7422 },
7423};
7424
7425/* FIXME: This is not thouroughly tested. These combinations may over- or
7426 * underestimate hw/fw capabilities.
7427 */
7428static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7429 {
7430 .limits = ath10k_tlv_if_limit,
7431 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007432 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007433 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7434 },
7435 {
7436 .limits = ath10k_tlv_if_limit_ibss,
7437 .num_different_channels = 1,
7438 .max_interfaces = 2,
7439 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7440 },
7441};
7442
7443static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7444 {
7445 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007446 .num_different_channels = 1,
7447 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007448 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7449 },
7450 {
Michal Kaziored25b112015-07-09 13:08:39 +02007451 .limits = ath10k_tlv_qcs_if_limit,
7452 .num_different_channels = 2,
7453 .max_interfaces = 4,
7454 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7455 },
7456 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007457 .limits = ath10k_tlv_if_limit_ibss,
7458 .num_different_channels = 1,
7459 .max_interfaces = 2,
7460 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7461 },
7462};
7463
Raja Manicf36fef2015-06-22 20:22:25 +05307464static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
7465 {
7466 .max = 1,
7467 .types = BIT(NL80211_IFTYPE_STATION),
7468 },
7469 {
7470 .max = 16,
7471 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007472#ifdef CONFIG_MAC80211_MESH
7473 | BIT(NL80211_IFTYPE_MESH_POINT)
7474#endif
Raja Manicf36fef2015-06-22 20:22:25 +05307475 },
7476};
7477
7478static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
7479 {
7480 .limits = ath10k_10_4_if_limits,
7481 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
7482 .max_interfaces = 16,
7483 .num_different_channels = 1,
7484 .beacon_int_infra_match = true,
7485#ifdef CONFIG_ATH10K_DFS_CERTIFIED
7486 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7487 BIT(NL80211_CHAN_WIDTH_20) |
7488 BIT(NL80211_CHAN_WIDTH_40) |
7489 BIT(NL80211_CHAN_WIDTH_80),
7490#endif
7491 },
7492};
7493
Kalle Valo5e3dd152013-06-12 20:52:10 +03007494static void ath10k_get_arvif_iter(void *data, u8 *mac,
7495 struct ieee80211_vif *vif)
7496{
7497 struct ath10k_vif_iter *arvif_iter = data;
7498 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7499
7500 if (arvif->vdev_id == arvif_iter->vdev_id)
7501 arvif_iter->arvif = arvif;
7502}
7503
7504struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
7505{
7506 struct ath10k_vif_iter arvif_iter;
7507 u32 flags;
7508
7509 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
7510 arvif_iter.vdev_id = vdev_id;
7511
7512 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
7513 ieee80211_iterate_active_interfaces_atomic(ar->hw,
7514 flags,
7515 ath10k_get_arvif_iter,
7516 &arvif_iter);
7517 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007518 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007519 return NULL;
7520 }
7521
7522 return arvif_iter.arvif;
7523}
7524
7525int ath10k_mac_register(struct ath10k *ar)
7526{
Johannes Berg3cb10942015-01-22 21:38:45 +01007527 static const u32 cipher_suites[] = {
7528 WLAN_CIPHER_SUITE_WEP40,
7529 WLAN_CIPHER_SUITE_WEP104,
7530 WLAN_CIPHER_SUITE_TKIP,
7531 WLAN_CIPHER_SUITE_CCMP,
7532 WLAN_CIPHER_SUITE_AES_CMAC,
7533 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03007534 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007535 void *channels;
7536 int ret;
7537
7538 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
7539
7540 SET_IEEE80211_DEV(ar->hw, ar->dev);
7541
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00007542 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
7543 ARRAY_SIZE(ath10k_5ghz_channels)) !=
7544 ATH10K_NUM_CHANS);
7545
Kalle Valo5e3dd152013-06-12 20:52:10 +03007546 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
7547 channels = kmemdup(ath10k_2ghz_channels,
7548 sizeof(ath10k_2ghz_channels),
7549 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02007550 if (!channels) {
7551 ret = -ENOMEM;
7552 goto err_free;
7553 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007554
7555 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
7556 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
7557 band->channels = channels;
7558 band->n_bitrates = ath10k_g_rates_size;
7559 band->bitrates = ath10k_g_rates;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007560
7561 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
7562 }
7563
7564 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
7565 channels = kmemdup(ath10k_5ghz_channels,
7566 sizeof(ath10k_5ghz_channels),
7567 GFP_KERNEL);
7568 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02007569 ret = -ENOMEM;
7570 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007571 }
7572
7573 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
7574 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
7575 band->channels = channels;
7576 band->n_bitrates = ath10k_a_rates_size;
7577 band->bitrates = ath10k_a_rates;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007578 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
7579 }
7580
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05307581 ath10k_mac_setup_ht_vht_cap(ar);
7582
Kalle Valo5e3dd152013-06-12 20:52:10 +03007583 ar->hw->wiphy->interface_modes =
7584 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007585 BIT(NL80211_IFTYPE_AP) |
7586 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01007587
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05307588 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
7589 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03007590
Bartosz Markowskid3541812013-12-10 16:20:40 +01007591 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
7592 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01007593 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01007594 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7595 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007596
Johannes Berg30686bf2015-06-02 21:39:54 +02007597 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
7598 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
7599 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
7600 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
7601 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
7602 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
7603 ieee80211_hw_set(ar->hw, AP_LINK_PS);
7604 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02007605 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
7606 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
7607 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
7608 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
7609 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
7610 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007611
David Liuccec9032015-07-24 20:25:32 +03007612 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7613 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
7614
Eliad Peller0d8614b2014-09-10 14:07:36 +03007615 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00007616 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03007617
Kalle Valo5e3dd152013-06-12 20:52:10 +03007618 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03007619 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007620
7621 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02007622 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
7623 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007624 }
7625
7626 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
7627 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
7628
7629 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01007630 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02007631 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007632
Kalle Valo5e3dd152013-06-12 20:52:10 +03007633 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
7634
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02007635 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
7636 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
7637
7638 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
7639 * that userspace (e.g. wpa_supplicant/hostapd) can generate
7640 * correct Probe Responses. This is more of a hack advert..
7641 */
7642 ar->hw->wiphy->probe_resp_offload |=
7643 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
7644 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
7645 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
7646 }
7647
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03007648 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
7649 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7650
Kalle Valo5e3dd152013-06-12 20:52:10 +03007651 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01007652 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007653 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
7654
7655 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02007656 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
7657
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01007658 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
7659
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007660 ret = ath10k_wow_init(ar);
7661 if (ret) {
7662 ath10k_warn(ar, "failed to init wow: %d\n", ret);
7663 goto err_free;
7664 }
7665
Janusz Dziedzicc7025342015-06-15 14:46:41 +03007666 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
7667
Kalle Valo5e3dd152013-06-12 20:52:10 +03007668 /*
7669 * on LL hardware queues are managed entirely by the FW
7670 * so we only advertise to mac we can do the queues thing
7671 */
Michal Kazior96d828d2015-03-31 10:26:23 +00007672 ar->hw->queues = IEEE80211_MAX_QUEUES;
7673
7674 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
7675 * something that vdev_ids can't reach so that we don't stop the queue
7676 * accidentally.
7677 */
7678 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007679
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007680 switch (ar->wmi.op_version) {
7681 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01007682 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
7683 ar->hw->wiphy->n_iface_combinations =
7684 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03007685 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007686 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00007687 case ATH10K_FW_WMI_OP_VERSION_TLV:
7688 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
7689 ar->hw->wiphy->iface_combinations =
7690 ath10k_tlv_qcs_if_comb;
7691 ar->hw->wiphy->n_iface_combinations =
7692 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
7693 } else {
7694 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
7695 ar->hw->wiphy->n_iface_combinations =
7696 ARRAY_SIZE(ath10k_tlv_if_comb);
7697 }
7698 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
7699 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007700 case ATH10K_FW_WMI_OP_VERSION_10_1:
7701 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02007702 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007703 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
7704 ar->hw->wiphy->n_iface_combinations =
7705 ARRAY_SIZE(ath10k_10x_if_comb);
7706 break;
Raja Mani9bd21322015-06-22 20:10:09 +05307707 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05307708 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
7709 ar->hw->wiphy->n_iface_combinations =
7710 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05307711 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007712 case ATH10K_FW_WMI_OP_VERSION_UNSET:
7713 case ATH10K_FW_WMI_OP_VERSION_MAX:
7714 WARN_ON(1);
7715 ret = -EINVAL;
7716 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01007717 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007718
David Liuccec9032015-07-24 20:25:32 +03007719 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7720 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02007721
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007722 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
7723 /* Init ath dfs pattern detector */
7724 ar->ath_common.debug_mask = ATH_DBG_DFS;
7725 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
7726 NL80211_DFS_UNSET);
7727
7728 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02007729 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007730 }
7731
Kalle Valo5e3dd152013-06-12 20:52:10 +03007732 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
7733 ath10k_reg_notifier);
7734 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007735 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007736 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007737 }
7738
Johannes Berg3cb10942015-01-22 21:38:45 +01007739 ar->hw->wiphy->cipher_suites = cipher_suites;
7740 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
7741
Kalle Valo5e3dd152013-06-12 20:52:10 +03007742 ret = ieee80211_register_hw(ar->hw);
7743 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007744 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007745 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007746 }
7747
7748 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
7749 ret = regulatory_hint(ar->hw->wiphy,
7750 ar->ath_common.regulatory.alpha2);
7751 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02007752 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007753 }
7754
7755 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02007756
7757err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03007758 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07007759
7760err_dfs_detector_exit:
7761 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7762 ar->dfs_detector->exit(ar->dfs_detector);
7763
Michal Kaziord6015b22013-07-22 14:13:30 +02007764err_free:
7765 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
7766 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
7767
Jeff Johnson0e339442015-10-08 09:15:53 -07007768 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007769 return ret;
7770}
7771
7772void ath10k_mac_unregister(struct ath10k *ar)
7773{
7774 ieee80211_unregister_hw(ar->hw);
7775
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007776 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7777 ar->dfs_detector->exit(ar->dfs_detector);
7778
Kalle Valo5e3dd152013-06-12 20:52:10 +03007779 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
7780 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
7781
7782 SET_IEEE80211_DEV(ar->hw, NULL);
7783}