blob: 2ccda0ed91fa59f541b08fc16d9cefff7e0a7946 [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,
93 u8 hw_rate)
94{
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
101 if (rate->hw_value == hw_rate)
102 return i;
103 else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
104 rate->hw_value_short == hw_rate)
105 return i;
106 }
107
108 return 0;
109}
110
Michal Kazior01cebe12015-03-30 09:51:56 +0300111u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
112 u32 bitrate)
113{
114 int i;
115
116 for (i = 0; i < sband->n_bitrates; i++)
117 if (sband->bitrates[i].bitrate == bitrate)
118 return i;
119
120 return 0;
121}
122
Michal Kazior3ae54222015-03-31 10:49:20 +0000123static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
124{
125 switch ((mcs_map >> (2 * nss)) & 0x3) {
126 case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;
127 case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;
128 case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;
129 }
130 return 0;
131}
132
Michal Kazior45c9abc2015-04-21 20:42:58 +0300133static u32
134ath10k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
135{
136 int nss;
137
138 for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--)
139 if (ht_mcs_mask[nss])
140 return nss + 1;
141
142 return 1;
143}
144
145static u32
146ath10k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
147{
148 int nss;
149
150 for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--)
151 if (vht_mcs_mask[nss])
152 return nss + 1;
153
154 return 1;
155}
Kalle Valo5e3dd152013-06-12 20:52:10 +0300156
157/**********/
158/* Crypto */
159/**********/
160
161static int ath10k_send_key(struct ath10k_vif *arvif,
162 struct ieee80211_key_conf *key,
163 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100164 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300165{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200166 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300167 struct wmi_vdev_install_key_arg arg = {
168 .vdev_id = arvif->vdev_id,
169 .key_idx = key->keyidx,
170 .key_len = key->keylen,
171 .key_data = key->key,
Michal Kazior370e5672015-02-18 14:02:26 +0100172 .key_flags = flags,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300173 .macaddr = macaddr,
174 };
175
Michal Kazior548db542013-07-05 16:15:15 +0300176 lockdep_assert_held(&arvif->ar->conf_mutex);
177
Kalle Valo5e3dd152013-06-12 20:52:10 +0300178 switch (key->cipher) {
179 case WLAN_CIPHER_SUITE_CCMP:
180 arg.key_cipher = WMI_CIPHER_AES_CCM;
Marek Kwaczynskie4e82e92015-01-24 12:14:53 +0200181 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300182 break;
183 case WLAN_CIPHER_SUITE_TKIP:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300184 arg.key_cipher = WMI_CIPHER_TKIP;
185 arg.key_txmic_len = 8;
186 arg.key_rxmic_len = 8;
187 break;
188 case WLAN_CIPHER_SUITE_WEP40:
189 case WLAN_CIPHER_SUITE_WEP104:
190 arg.key_cipher = WMI_CIPHER_WEP;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300191 break;
Johannes Berg3cb10942015-01-22 21:38:45 +0100192 case WLAN_CIPHER_SUITE_AES_CMAC:
Bartosz Markowskid7131c02015-03-10 14:32:19 +0100193 WARN_ON(1);
194 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300195 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200196 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300197 return -EOPNOTSUPP;
198 }
199
Kalle Valob9e284e2015-10-05 17:56:35 +0300200 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
David Liuccec9032015-07-24 20:25:32 +0300201 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
David Liuccec9032015-07-24 20:25:32 +0300202
Kalle Valo5e3dd152013-06-12 20:52:10 +0300203 if (cmd == DISABLE_KEY) {
204 arg.key_cipher = WMI_CIPHER_NONE;
205 arg.key_data = NULL;
206 }
207
208 return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
209}
210
211static int ath10k_install_key(struct ath10k_vif *arvif,
212 struct ieee80211_key_conf *key,
213 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100214 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300215{
216 struct ath10k *ar = arvif->ar;
217 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300218 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300219
Michal Kazior548db542013-07-05 16:15:15 +0300220 lockdep_assert_held(&ar->conf_mutex);
221
Wolfram Sang16735d02013-11-14 14:32:02 -0800222 reinit_completion(&ar->install_key_done);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300223
David Liuccec9032015-07-24 20:25:32 +0300224 if (arvif->nohwcrypt)
225 return 1;
226
Michal Kazior370e5672015-02-18 14:02:26 +0100227 ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300228 if (ret)
229 return ret;
230
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300231 time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);
232 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300233 return -ETIMEDOUT;
234
235 return 0;
236}
237
238static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
239 const u8 *addr)
240{
241 struct ath10k *ar = arvif->ar;
242 struct ath10k_peer *peer;
243 int ret;
244 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100245 u32 flags;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300246
247 lockdep_assert_held(&ar->conf_mutex);
248
Michal Kazior8674d902015-08-13 14:10:46 +0200249 if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP &&
250 arvif->vif->type != NL80211_IFTYPE_ADHOC))
251 return -EINVAL;
252
Kalle Valo5e3dd152013-06-12 20:52:10 +0300253 spin_lock_bh(&ar->data_lock);
254 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
255 spin_unlock_bh(&ar->data_lock);
256
257 if (!peer)
258 return -ENOENT;
259
260 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
261 if (arvif->wep_keys[i] == NULL)
262 continue;
Michal Kazior370e5672015-02-18 14:02:26 +0100263
Michal Kazior8674d902015-08-13 14:10:46 +0200264 switch (arvif->vif->type) {
265 case NL80211_IFTYPE_AP:
266 flags = WMI_KEY_PAIRWISE;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300267
Michal Kazior8674d902015-08-13 14:10:46 +0200268 if (arvif->def_wep_key_idx == i)
269 flags |= WMI_KEY_TX_USAGE;
Michal Kaziorce90b272015-04-10 13:23:21 +0000270
Michal Kazior8674d902015-08-13 14:10:46 +0200271 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
272 SET_KEY, addr, flags);
273 if (ret < 0)
274 return ret;
275 break;
276 case NL80211_IFTYPE_ADHOC:
277 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
278 SET_KEY, addr,
279 WMI_KEY_PAIRWISE);
280 if (ret < 0)
281 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300282
Michal Kazior8674d902015-08-13 14:10:46 +0200283 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
284 SET_KEY, addr, WMI_KEY_GROUP);
285 if (ret < 0)
286 return ret;
287 break;
288 default:
289 WARN_ON(1);
290 return -EINVAL;
291 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300292
Sujith Manoharanae167132014-11-25 11:46:59 +0530293 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300294 peer->keys[i] = arvif->wep_keys[i];
Sujith Manoharanae167132014-11-25 11:46:59 +0530295 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300296 }
297
Michal Kaziorce90b272015-04-10 13:23:21 +0000298 /* In some cases (notably with static WEP IBSS with multiple keys)
299 * multicast Tx becomes broken. Both pairwise and groupwise keys are
300 * installed already. Using WMI_KEY_TX_USAGE in different combinations
301 * didn't seem help. Using def_keyid vdev parameter seems to be
302 * effective so use that.
303 *
304 * FIXME: Revisit. Perhaps this can be done in a less hacky way.
305 */
Michal Kazior8674d902015-08-13 14:10:46 +0200306 if (arvif->vif->type != NL80211_IFTYPE_ADHOC)
307 return 0;
308
Michal Kaziorce90b272015-04-10 13:23:21 +0000309 if (arvif->def_wep_key_idx == -1)
310 return 0;
311
312 ret = ath10k_wmi_vdev_set_param(arvif->ar,
313 arvif->vdev_id,
314 arvif->ar->wmi.vdev_param->def_keyid,
315 arvif->def_wep_key_idx);
316 if (ret) {
317 ath10k_warn(ar, "failed to re-set def wpa key idxon vdev %i: %d\n",
318 arvif->vdev_id, ret);
319 return ret;
320 }
321
Kalle Valo5e3dd152013-06-12 20:52:10 +0300322 return 0;
323}
324
325static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
326 const u8 *addr)
327{
328 struct ath10k *ar = arvif->ar;
329 struct ath10k_peer *peer;
330 int first_errno = 0;
331 int ret;
332 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100333 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300334
335 lockdep_assert_held(&ar->conf_mutex);
336
337 spin_lock_bh(&ar->data_lock);
338 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
339 spin_unlock_bh(&ar->data_lock);
340
341 if (!peer)
342 return -ENOENT;
343
344 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
345 if (peer->keys[i] == NULL)
346 continue;
347
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200348 /* key flags are not required to delete the key */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300349 ret = ath10k_install_key(arvif, peer->keys[i],
Michal Kazior370e5672015-02-18 14:02:26 +0100350 DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300351 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300352 first_errno = ret;
353
David Liuccec9032015-07-24 20:25:32 +0300354 if (ret < 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200355 ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300356 i, ret);
357
Sujith Manoharanae167132014-11-25 11:46:59 +0530358 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300359 peer->keys[i] = NULL;
Sujith Manoharanae167132014-11-25 11:46:59 +0530360 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300361 }
362
363 return first_errno;
364}
365
Sujith Manoharan504f6cd2014-11-25 11:46:58 +0530366bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
367 u8 keyidx)
368{
369 struct ath10k_peer *peer;
370 int i;
371
372 lockdep_assert_held(&ar->data_lock);
373
374 /* We don't know which vdev this peer belongs to,
375 * since WMI doesn't give us that information.
376 *
377 * FIXME: multi-bss needs to be handled.
378 */
379 peer = ath10k_peer_find(ar, 0, addr);
380 if (!peer)
381 return false;
382
383 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
384 if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)
385 return true;
386 }
387
388 return false;
389}
390
Kalle Valo5e3dd152013-06-12 20:52:10 +0300391static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
392 struct ieee80211_key_conf *key)
393{
394 struct ath10k *ar = arvif->ar;
395 struct ath10k_peer *peer;
396 u8 addr[ETH_ALEN];
397 int first_errno = 0;
398 int ret;
399 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100400 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300401
402 lockdep_assert_held(&ar->conf_mutex);
403
404 for (;;) {
405 /* since ath10k_install_key we can't hold data_lock all the
406 * time, so we try to remove the keys incrementally */
407 spin_lock_bh(&ar->data_lock);
408 i = 0;
409 list_for_each_entry(peer, &ar->peers, list) {
410 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
411 if (peer->keys[i] == key) {
Kalle Valob25f32c2014-09-14 12:50:49 +0300412 ether_addr_copy(addr, peer->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300413 peer->keys[i] = NULL;
414 break;
415 }
416 }
417
418 if (i < ARRAY_SIZE(peer->keys))
419 break;
420 }
421 spin_unlock_bh(&ar->data_lock);
422
423 if (i == ARRAY_SIZE(peer->keys))
424 break;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200425 /* key flags are not required to delete the key */
Michal Kazior370e5672015-02-18 14:02:26 +0100426 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300427 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300428 first_errno = ret;
429
430 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200431 ath10k_warn(ar, "failed to remove key for %pM: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +0200432 addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300433 }
434
435 return first_errno;
436}
437
Michal Kaziorad325cb2015-02-18 14:02:27 +0100438static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
439 struct ieee80211_key_conf *key)
440{
441 struct ath10k *ar = arvif->ar;
442 struct ath10k_peer *peer;
443 int ret;
444
445 lockdep_assert_held(&ar->conf_mutex);
446
447 list_for_each_entry(peer, &ar->peers, list) {
448 if (!memcmp(peer->addr, arvif->vif->addr, ETH_ALEN))
449 continue;
450
451 if (!memcmp(peer->addr, arvif->bssid, ETH_ALEN))
452 continue;
453
454 if (peer->keys[key->keyidx] == key)
455 continue;
456
457 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
458 arvif->vdev_id, key->keyidx);
459
460 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
461 if (ret) {
462 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
463 arvif->vdev_id, peer->addr, ret);
464 return ret;
465 }
466 }
467
468 return 0;
469}
470
Kalle Valo5e3dd152013-06-12 20:52:10 +0300471/*********************/
472/* General utilities */
473/*********************/
474
475static inline enum wmi_phy_mode
476chan_to_phymode(const struct cfg80211_chan_def *chandef)
477{
478 enum wmi_phy_mode phymode = MODE_UNKNOWN;
479
480 switch (chandef->chan->band) {
481 case IEEE80211_BAND_2GHZ:
482 switch (chandef->width) {
483 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800484 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
485 phymode = MODE_11B;
486 else
487 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300488 break;
489 case NL80211_CHAN_WIDTH_20:
490 phymode = MODE_11NG_HT20;
491 break;
492 case NL80211_CHAN_WIDTH_40:
493 phymode = MODE_11NG_HT40;
494 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400495 case NL80211_CHAN_WIDTH_5:
496 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300497 case NL80211_CHAN_WIDTH_80:
498 case NL80211_CHAN_WIDTH_80P80:
499 case NL80211_CHAN_WIDTH_160:
500 phymode = MODE_UNKNOWN;
501 break;
502 }
503 break;
504 case IEEE80211_BAND_5GHZ:
505 switch (chandef->width) {
506 case NL80211_CHAN_WIDTH_20_NOHT:
507 phymode = MODE_11A;
508 break;
509 case NL80211_CHAN_WIDTH_20:
510 phymode = MODE_11NA_HT20;
511 break;
512 case NL80211_CHAN_WIDTH_40:
513 phymode = MODE_11NA_HT40;
514 break;
515 case NL80211_CHAN_WIDTH_80:
516 phymode = MODE_11AC_VHT80;
517 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400518 case NL80211_CHAN_WIDTH_5:
519 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300520 case NL80211_CHAN_WIDTH_80P80:
521 case NL80211_CHAN_WIDTH_160:
522 phymode = MODE_UNKNOWN;
523 break;
524 }
525 break;
526 default:
527 break;
528 }
529
530 WARN_ON(phymode == MODE_UNKNOWN);
531 return phymode;
532}
533
534static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
535{
536/*
537 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
538 * 0 for no restriction
539 * 1 for 1/4 us
540 * 2 for 1/2 us
541 * 3 for 1 us
542 * 4 for 2 us
543 * 5 for 4 us
544 * 6 for 8 us
545 * 7 for 16 us
546 */
547 switch (mpdudensity) {
548 case 0:
549 return 0;
550 case 1:
551 case 2:
552 case 3:
553 /* Our lower layer calculations limit our precision to
554 1 microsecond */
555 return 1;
556 case 4:
557 return 2;
558 case 5:
559 return 4;
560 case 6:
561 return 8;
562 case 7:
563 return 16;
564 default:
565 return 0;
566 }
567}
568
Michal Kazior500ff9f2015-03-31 10:26:21 +0000569int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
570 struct cfg80211_chan_def *def)
571{
572 struct ieee80211_chanctx_conf *conf;
573
574 rcu_read_lock();
575 conf = rcu_dereference(vif->chanctx_conf);
576 if (!conf) {
577 rcu_read_unlock();
578 return -ENOENT;
579 }
580
581 *def = conf->def;
582 rcu_read_unlock();
583
584 return 0;
585}
586
587static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,
588 struct ieee80211_chanctx_conf *conf,
589 void *data)
590{
591 int *num = data;
592
593 (*num)++;
594}
595
596static int ath10k_mac_num_chanctxs(struct ath10k *ar)
597{
598 int num = 0;
599
600 ieee80211_iter_chan_contexts_atomic(ar->hw,
601 ath10k_mac_num_chanctxs_iter,
602 &num);
603
604 return num;
605}
606
607static void
608ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
609 struct ieee80211_chanctx_conf *conf,
610 void *data)
611{
612 struct cfg80211_chan_def **def = data;
613
614 *def = &conf->def;
615}
616
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300617static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr,
618 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300619{
Michal Kaziore04cafb2015-08-05 12:15:24 +0200620 struct ath10k_vif *arvif;
621 int num_peers = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300622 int ret;
623
624 lockdep_assert_held(&ar->conf_mutex);
625
Michal Kaziore04cafb2015-08-05 12:15:24 +0200626 num_peers = ar->num_peers;
627
628 /* Each vdev consumes a peer entry as well */
629 list_for_each_entry(arvif, &ar->arvifs, list)
630 num_peers++;
631
632 if (num_peers >= ar->max_num_peers)
Michal Kaziorcfd10612014-11-25 15:16:05 +0100633 return -ENOBUFS;
634
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300635 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800636 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200637 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200638 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300639 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800640 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300641
642 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800643 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200644 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200645 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300646 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800647 }
Michal Kazior292a7532014-11-25 15:16:04 +0100648
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100649 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300650
651 return 0;
652}
653
Kalle Valo5a13e762014-01-20 11:01:46 +0200654static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
655{
656 struct ath10k *ar = arvif->ar;
657 u32 param;
658 int ret;
659
660 param = ar->wmi.pdev_param->sta_kickout_th;
661 ret = ath10k_wmi_pdev_set_param(ar, param,
662 ATH10K_KICKOUT_THRESHOLD);
663 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200664 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200665 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200666 return ret;
667 }
668
669 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
670 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
671 ATH10K_KEEPALIVE_MIN_IDLE);
672 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200673 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200674 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200675 return ret;
676 }
677
678 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
679 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
680 ATH10K_KEEPALIVE_MAX_IDLE);
681 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200682 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200683 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200684 return ret;
685 }
686
687 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
688 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
689 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
690 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200691 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200692 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200693 return ret;
694 }
695
696 return 0;
697}
698
Vivek Natarajanacab6402014-11-26 09:06:12 +0200699static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200700{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200701 struct ath10k *ar = arvif->ar;
702 u32 vdev_param;
703
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200704 vdev_param = ar->wmi.vdev_param->rts_threshold;
705 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200706}
707
Kalle Valo5e3dd152013-06-12 20:52:10 +0300708static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
709{
710 int ret;
711
712 lockdep_assert_held(&ar->conf_mutex);
713
714 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
715 if (ret)
716 return ret;
717
718 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
719 if (ret)
720 return ret;
721
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100722 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100723
Kalle Valo5e3dd152013-06-12 20:52:10 +0300724 return 0;
725}
726
727static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
728{
729 struct ath10k_peer *peer, *tmp;
730
731 lockdep_assert_held(&ar->conf_mutex);
732
733 spin_lock_bh(&ar->data_lock);
734 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
735 if (peer->vdev_id != vdev_id)
736 continue;
737
Michal Kazior7aa7a722014-08-25 12:09:38 +0200738 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300739 peer->addr, vdev_id);
740
741 list_del(&peer->list);
742 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100743 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300744 }
745 spin_unlock_bh(&ar->data_lock);
746}
747
Michal Kaziora96d7742013-07-16 09:38:56 +0200748static void ath10k_peer_cleanup_all(struct ath10k *ar)
749{
750 struct ath10k_peer *peer, *tmp;
751
752 lockdep_assert_held(&ar->conf_mutex);
753
754 spin_lock_bh(&ar->data_lock);
755 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
756 list_del(&peer->list);
757 kfree(peer);
758 }
759 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100760
761 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100762 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200763}
764
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300765static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
766 struct ieee80211_sta *sta,
767 enum wmi_tdls_peer_state state)
768{
769 int ret;
770 struct wmi_tdls_peer_update_cmd_arg arg = {};
771 struct wmi_tdls_peer_capab_arg cap = {};
772 struct wmi_channel_arg chan_arg = {};
773
774 lockdep_assert_held(&ar->conf_mutex);
775
776 arg.vdev_id = vdev_id;
777 arg.peer_state = state;
778 ether_addr_copy(arg.addr, sta->addr);
779
780 cap.peer_max_sp = sta->max_sp;
781 cap.peer_uapsd_queues = sta->uapsd_queues;
782
783 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
784 !sta->tdls_initiator)
785 cap.is_peer_responder = 1;
786
787 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
788 if (ret) {
789 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
790 arg.addr, vdev_id, ret);
791 return ret;
792 }
793
794 return 0;
795}
796
Kalle Valo5e3dd152013-06-12 20:52:10 +0300797/************************/
798/* Interface management */
799/************************/
800
Michal Kazior64badcb2014-09-18 11:18:02 +0300801void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
802{
803 struct ath10k *ar = arvif->ar;
804
805 lockdep_assert_held(&ar->data_lock);
806
807 if (!arvif->beacon)
808 return;
809
810 if (!arvif->beacon_buf)
811 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
812 arvif->beacon->len, DMA_TO_DEVICE);
813
Michal Kazioraf213192015-01-29 14:29:52 +0200814 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
815 arvif->beacon_state != ATH10K_BEACON_SENT))
816 return;
817
Michal Kazior64badcb2014-09-18 11:18:02 +0300818 dev_kfree_skb_any(arvif->beacon);
819
820 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200821 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300822}
823
824static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
825{
826 struct ath10k *ar = arvif->ar;
827
828 lockdep_assert_held(&ar->data_lock);
829
830 ath10k_mac_vif_beacon_free(arvif);
831
832 if (arvif->beacon_buf) {
833 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
834 arvif->beacon_buf, arvif->beacon_paddr);
835 arvif->beacon_buf = NULL;
836 }
837}
838
Kalle Valo5e3dd152013-06-12 20:52:10 +0300839static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
840{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300841 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300842
Michal Kazior548db542013-07-05 16:15:15 +0300843 lockdep_assert_held(&ar->conf_mutex);
844
Michal Kazior7962b0d2014-10-28 10:34:38 +0100845 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
846 return -ESHUTDOWN;
847
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300848 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
849 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
850 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300851 return -ETIMEDOUT;
852
853 return 0;
854}
855
Michal Kazior1bbc0972014-04-08 09:45:47 +0300856static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300857{
Michal Kazior500ff9f2015-03-31 10:26:21 +0000858 struct cfg80211_chan_def *chandef = NULL;
Maninder Singh19be9e92015-07-16 09:25:33 +0530859 struct ieee80211_channel *channel = NULL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300860 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300861 int ret = 0;
862
863 lockdep_assert_held(&ar->conf_mutex);
864
Michal Kazior500ff9f2015-03-31 10:26:21 +0000865 ieee80211_iter_chan_contexts_atomic(ar->hw,
866 ath10k_mac_get_any_chandef_iter,
867 &chandef);
868 if (WARN_ON_ONCE(!chandef))
869 return -ENOENT;
870
871 channel = chandef->chan;
872
Kalle Valo5e3dd152013-06-12 20:52:10 +0300873 arg.vdev_id = vdev_id;
874 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +0100875 arg.channel.band_center_freq1 = chandef->center_freq1;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300876
877 /* TODO setup this dynamically, what in case we
878 don't have any vifs? */
Michal Kaziorc930f742014-01-23 11:38:25 +0100879 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200880 arg.channel.chan_radar =
881 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300882
Michal Kazior89c5c842013-10-23 04:02:13 -0700883 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -0700884 arg.channel.max_power = channel->max_power * 2;
885 arg.channel.max_reg_power = channel->max_reg_power * 2;
886 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300887
Michal Kazior7962b0d2014-10-28 10:34:38 +0100888 reinit_completion(&ar->vdev_setup_done);
889
Kalle Valo5e3dd152013-06-12 20:52:10 +0300890 ret = ath10k_wmi_vdev_start(ar, &arg);
891 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200892 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200893 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300894 return ret;
895 }
896
897 ret = ath10k_vdev_setup_sync(ar);
898 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +0200899 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200900 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300901 return ret;
902 }
903
904 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
905 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200906 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200907 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300908 goto vdev_stop;
909 }
910
911 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300912
Michal Kazior7aa7a722014-08-25 12:09:38 +0200913 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300914 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300915 return 0;
916
917vdev_stop:
918 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
919 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200920 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200921 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300922
923 return ret;
924}
925
Michal Kazior1bbc0972014-04-08 09:45:47 +0300926static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300927{
928 int ret = 0;
929
930 lockdep_assert_held(&ar->conf_mutex);
931
Marek Puzyniak52fa0192013-09-24 14:06:24 +0200932 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
933 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200934 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200935 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300936
Michal Kazior7962b0d2014-10-28 10:34:38 +0100937 reinit_completion(&ar->vdev_setup_done);
938
Kalle Valo5e3dd152013-06-12 20:52:10 +0300939 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
940 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200941 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200942 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300943
944 ret = ath10k_vdev_setup_sync(ar);
945 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +0200946 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200947 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300948
Michal Kazior7aa7a722014-08-25 12:09:38 +0200949 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300950 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300951 return ret;
952}
953
Michal Kazior1bbc0972014-04-08 09:45:47 +0300954static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300955{
956 int bit, ret = 0;
957
958 lockdep_assert_held(&ar->conf_mutex);
959
Ben Greeara9aefb32014-08-12 11:02:19 +0300960 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200961 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300962 return -ENOMEM;
963 }
964
Ben Greear16c11172014-09-23 14:17:16 -0700965 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +0300966
Ben Greear16c11172014-09-23 14:17:16 -0700967 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300968
969 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
970 WMI_VDEV_TYPE_MONITOR,
971 0, ar->mac_addr);
972 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200973 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200974 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +0300975 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300976 }
977
Ben Greear16c11172014-09-23 14:17:16 -0700978 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +0200979 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300980 ar->monitor_vdev_id);
981
Kalle Valo5e3dd152013-06-12 20:52:10 +0300982 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300983}
984
Michal Kazior1bbc0972014-04-08 09:45:47 +0300985static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300986{
987 int ret = 0;
988
989 lockdep_assert_held(&ar->conf_mutex);
990
Kalle Valo5e3dd152013-06-12 20:52:10 +0300991 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
992 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200993 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200994 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300995 return ret;
996 }
997
Ben Greear16c11172014-09-23 14:17:16 -0700998 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300999
Michal Kazior7aa7a722014-08-25 12:09:38 +02001000 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001001 ar->monitor_vdev_id);
1002 return ret;
1003}
1004
Michal Kazior1bbc0972014-04-08 09:45:47 +03001005static int ath10k_monitor_start(struct ath10k *ar)
1006{
1007 int ret;
1008
1009 lockdep_assert_held(&ar->conf_mutex);
1010
Michal Kazior1bbc0972014-04-08 09:45:47 +03001011 ret = ath10k_monitor_vdev_create(ar);
1012 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001013 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001014 return ret;
1015 }
1016
1017 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
1018 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001019 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001020 ath10k_monitor_vdev_delete(ar);
1021 return ret;
1022 }
1023
1024 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001025 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +03001026
1027 return 0;
1028}
1029
Michal Kazior19337472014-08-28 12:58:16 +02001030static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +03001031{
1032 int ret;
1033
1034 lockdep_assert_held(&ar->conf_mutex);
1035
Michal Kazior1bbc0972014-04-08 09:45:47 +03001036 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001037 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001038 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001039 return ret;
1040 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001041
1042 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001043 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001044 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001045 return ret;
1046 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001047
1048 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001049 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +02001050
1051 return 0;
1052}
1053
Michal Kazior500ff9f2015-03-31 10:26:21 +00001054static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1055{
1056 int num_ctx;
1057
1058 /* At least one chanctx is required to derive a channel to start
1059 * monitor vdev on.
1060 */
1061 num_ctx = ath10k_mac_num_chanctxs(ar);
1062 if (num_ctx == 0)
1063 return false;
1064
1065 /* If there's already an existing special monitor interface then don't
1066 * bother creating another monitor vdev.
1067 */
1068 if (ar->monitor_arvif)
1069 return false;
1070
1071 return ar->monitor ||
Bob Copeland0d031c82015-09-09 12:47:34 -04001072 ar->filter_flags & FIF_OTHER_BSS ||
Michal Kazior500ff9f2015-03-31 10:26:21 +00001073 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1074}
1075
1076static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1077{
1078 int num_ctx;
1079
1080 num_ctx = ath10k_mac_num_chanctxs(ar);
1081
1082 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1083 * shouldn't allow this but make sure to prevent handling the following
1084 * case anyway since multi-channel DFS hasn't been tested at all.
1085 */
1086 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1087 return false;
1088
1089 return true;
1090}
1091
Michal Kazior19337472014-08-28 12:58:16 +02001092static int ath10k_monitor_recalc(struct ath10k *ar)
1093{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001094 bool needed;
1095 bool allowed;
1096 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001097
1098 lockdep_assert_held(&ar->conf_mutex);
1099
Michal Kazior500ff9f2015-03-31 10:26:21 +00001100 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1101 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001102
1103 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001104 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1105 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001106
Michal Kazior500ff9f2015-03-31 10:26:21 +00001107 if (WARN_ON(needed && !allowed)) {
1108 if (ar->monitor_started) {
1109 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1110
1111 ret = ath10k_monitor_stop(ar);
1112 if (ret)
Kalle Valo2a995082015-10-05 17:56:37 +03001113 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",
1114 ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001115 /* not serious */
1116 }
1117
1118 return -EPERM;
1119 }
1120
1121 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001122 return 0;
1123
Michal Kazior500ff9f2015-03-31 10:26:21 +00001124 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001125 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001126 else
1127 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001128}
1129
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001130static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1131{
1132 struct ath10k *ar = arvif->ar;
1133 u32 vdev_param, rts_cts = 0;
1134
1135 lockdep_assert_held(&ar->conf_mutex);
1136
1137 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1138
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001139 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001140
1141 if (arvif->num_legacy_stations > 0)
1142 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1143 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001144 else
1145 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1146 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001147
1148 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1149 rts_cts);
1150}
1151
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001152static int ath10k_start_cac(struct ath10k *ar)
1153{
1154 int ret;
1155
1156 lockdep_assert_held(&ar->conf_mutex);
1157
1158 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1159
Michal Kazior19337472014-08-28 12:58:16 +02001160 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001161 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001162 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001163 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1164 return ret;
1165 }
1166
Michal Kazior7aa7a722014-08-25 12:09:38 +02001167 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001168 ar->monitor_vdev_id);
1169
1170 return 0;
1171}
1172
1173static int ath10k_stop_cac(struct ath10k *ar)
1174{
1175 lockdep_assert_held(&ar->conf_mutex);
1176
1177 /* CAC is not running - do nothing */
1178 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1179 return 0;
1180
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001181 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001182 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001183
Michal Kazior7aa7a722014-08-25 12:09:38 +02001184 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001185
1186 return 0;
1187}
1188
Michal Kazior500ff9f2015-03-31 10:26:21 +00001189static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1190 struct ieee80211_chanctx_conf *conf,
1191 void *data)
1192{
1193 bool *ret = data;
1194
1195 if (!*ret && conf->radar_enabled)
1196 *ret = true;
1197}
1198
1199static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1200{
1201 bool has_radar = false;
1202
1203 ieee80211_iter_chan_contexts_atomic(ar->hw,
1204 ath10k_mac_has_radar_iter,
1205 &has_radar);
1206
1207 return has_radar;
1208}
1209
Michal Kaziord6500972014-04-08 09:56:09 +03001210static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001211{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001212 int ret;
1213
1214 lockdep_assert_held(&ar->conf_mutex);
1215
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001216 ath10k_stop_cac(ar);
1217
Michal Kazior500ff9f2015-03-31 10:26:21 +00001218 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001219 return;
1220
Michal Kaziord6500972014-04-08 09:56:09 +03001221 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001222 return;
1223
1224 ret = ath10k_start_cac(ar);
1225 if (ret) {
1226 /*
1227 * Not possible to start CAC on current channel so starting
1228 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1229 * by indicating that radar was detected.
1230 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001231 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001232 ieee80211_radar_detected(ar->hw);
1233 }
1234}
1235
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301236static int ath10k_vdev_stop(struct ath10k_vif *arvif)
Michal Kazior72654fa2014-04-08 09:56:09 +03001237{
1238 struct ath10k *ar = arvif->ar;
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301239 int ret;
1240
1241 lockdep_assert_held(&ar->conf_mutex);
1242
1243 reinit_completion(&ar->vdev_setup_done);
1244
1245 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1246 if (ret) {
1247 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1248 arvif->vdev_id, ret);
1249 return ret;
1250 }
1251
1252 ret = ath10k_vdev_setup_sync(ar);
1253 if (ret) {
1254 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
1255 arvif->vdev_id, ret);
1256 return ret;
1257 }
1258
1259 WARN_ON(ar->num_started_vdevs == 0);
1260
1261 if (ar->num_started_vdevs != 0) {
1262 ar->num_started_vdevs--;
1263 ath10k_recalc_radar_detection(ar);
1264 }
1265
1266 return ret;
1267}
1268
Michal Kazior500ff9f2015-03-31 10:26:21 +00001269static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1270 const struct cfg80211_chan_def *chandef,
1271 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001272{
1273 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001274 struct wmi_vdev_start_request_arg arg = {};
1275 int ret = 0;
1276
1277 lockdep_assert_held(&ar->conf_mutex);
1278
1279 reinit_completion(&ar->vdev_setup_done);
1280
1281 arg.vdev_id = arvif->vdev_id;
1282 arg.dtim_period = arvif->dtim_period;
1283 arg.bcn_intval = arvif->beacon_interval;
1284
1285 arg.channel.freq = chandef->chan->center_freq;
1286 arg.channel.band_center_freq1 = chandef->center_freq1;
1287 arg.channel.mode = chan_to_phymode(chandef);
1288
1289 arg.channel.min_power = 0;
1290 arg.channel.max_power = chandef->chan->max_power * 2;
1291 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1292 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1293
1294 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1295 arg.ssid = arvif->u.ap.ssid;
1296 arg.ssid_len = arvif->u.ap.ssid_len;
1297 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1298
1299 /* For now allow DFS for AP mode */
1300 arg.channel.chan_radar =
1301 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1302 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1303 arg.ssid = arvif->vif->bss_conf.ssid;
1304 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1305 }
1306
Michal Kazior7aa7a722014-08-25 12:09:38 +02001307 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001308 "mac vdev %d start center_freq %d phymode %s\n",
1309 arg.vdev_id, arg.channel.freq,
1310 ath10k_wmi_phymode_str(arg.channel.mode));
1311
Michal Kaziordc55e302014-07-29 12:53:36 +03001312 if (restart)
1313 ret = ath10k_wmi_vdev_restart(ar, &arg);
1314 else
1315 ret = ath10k_wmi_vdev_start(ar, &arg);
1316
Michal Kazior72654fa2014-04-08 09:56:09 +03001317 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001318 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001319 arg.vdev_id, ret);
1320 return ret;
1321 }
1322
1323 ret = ath10k_vdev_setup_sync(ar);
1324 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001325 ath10k_warn(ar,
1326 "failed to synchronize setup for vdev %i restart %d: %d\n",
1327 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001328 return ret;
1329 }
1330
Michal Kaziord6500972014-04-08 09:56:09 +03001331 ar->num_started_vdevs++;
1332 ath10k_recalc_radar_detection(ar);
1333
Michal Kazior72654fa2014-04-08 09:56:09 +03001334 return ret;
1335}
1336
Michal Kazior500ff9f2015-03-31 10:26:21 +00001337static int ath10k_vdev_start(struct ath10k_vif *arvif,
1338 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001339{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001340 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001341}
1342
Michal Kazior500ff9f2015-03-31 10:26:21 +00001343static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1344 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001345{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001346 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kazior72654fa2014-04-08 09:56:09 +03001347}
1348
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001349static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1350 struct sk_buff *bcn)
1351{
1352 struct ath10k *ar = arvif->ar;
1353 struct ieee80211_mgmt *mgmt;
1354 const u8 *p2p_ie;
1355 int ret;
1356
1357 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1358 return 0;
1359
1360 if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
1361 return 0;
1362
1363 mgmt = (void *)bcn->data;
1364 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1365 mgmt->u.beacon.variable,
1366 bcn->len - (mgmt->u.beacon.variable -
1367 bcn->data));
1368 if (!p2p_ie)
1369 return -ENOENT;
1370
1371 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1372 if (ret) {
1373 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1374 arvif->vdev_id, ret);
1375 return ret;
1376 }
1377
1378 return 0;
1379}
1380
1381static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1382 u8 oui_type, size_t ie_offset)
1383{
1384 size_t len;
1385 const u8 *next;
1386 const u8 *end;
1387 u8 *ie;
1388
1389 if (WARN_ON(skb->len < ie_offset))
1390 return -EINVAL;
1391
1392 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1393 skb->data + ie_offset,
1394 skb->len - ie_offset);
1395 if (!ie)
1396 return -ENOENT;
1397
1398 len = ie[1] + 2;
1399 end = skb->data + skb->len;
1400 next = ie + len;
1401
1402 if (WARN_ON(next > end))
1403 return -EINVAL;
1404
1405 memmove(ie, next, end - next);
1406 skb_trim(skb, skb->len - len);
1407
1408 return 0;
1409}
1410
1411static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1412{
1413 struct ath10k *ar = arvif->ar;
1414 struct ieee80211_hw *hw = ar->hw;
1415 struct ieee80211_vif *vif = arvif->vif;
1416 struct ieee80211_mutable_offsets offs = {};
1417 struct sk_buff *bcn;
1418 int ret;
1419
1420 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1421 return 0;
1422
Michal Kazior81a9a172015-03-05 16:02:17 +02001423 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1424 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1425 return 0;
1426
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001427 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1428 if (!bcn) {
1429 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1430 return -EPERM;
1431 }
1432
1433 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1434 if (ret) {
1435 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1436 kfree_skb(bcn);
1437 return ret;
1438 }
1439
1440 /* P2P IE is inserted by firmware automatically (as configured above)
1441 * so remove it from the base beacon template to avoid duplicate P2P
1442 * IEs in beacon frames.
1443 */
1444 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1445 offsetof(struct ieee80211_mgmt,
1446 u.beacon.variable));
1447
1448 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1449 0, NULL, 0);
1450 kfree_skb(bcn);
1451
1452 if (ret) {
1453 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1454 ret);
1455 return ret;
1456 }
1457
1458 return 0;
1459}
1460
1461static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1462{
1463 struct ath10k *ar = arvif->ar;
1464 struct ieee80211_hw *hw = ar->hw;
1465 struct ieee80211_vif *vif = arvif->vif;
1466 struct sk_buff *prb;
1467 int ret;
1468
1469 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1470 return 0;
1471
Michal Kazior81a9a172015-03-05 16:02:17 +02001472 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1473 return 0;
1474
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001475 prb = ieee80211_proberesp_get(hw, vif);
1476 if (!prb) {
1477 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1478 return -EPERM;
1479 }
1480
1481 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1482 kfree_skb(prb);
1483
1484 if (ret) {
1485 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1486 ret);
1487 return ret;
1488 }
1489
1490 return 0;
1491}
1492
Michal Kazior500ff9f2015-03-31 10:26:21 +00001493static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1494{
1495 struct ath10k *ar = arvif->ar;
1496 struct cfg80211_chan_def def;
1497 int ret;
1498
1499 /* When originally vdev is started during assign_vif_chanctx() some
1500 * information is missing, notably SSID. Firmware revisions with beacon
1501 * offloading require the SSID to be provided during vdev (re)start to
1502 * handle hidden SSID properly.
1503 *
1504 * Vdev restart must be done after vdev has been both started and
1505 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1506 * deliver vdev restart response event causing timeouts during vdev
1507 * syncing in ath10k.
1508 *
1509 * Note: The vdev down/up and template reinstallation could be skipped
1510 * since only wmi-tlv firmware are known to have beacon offload and
1511 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1512 * response delivery. It's probably more robust to keep it as is.
1513 */
1514 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1515 return 0;
1516
1517 if (WARN_ON(!arvif->is_started))
1518 return -EINVAL;
1519
1520 if (WARN_ON(!arvif->is_up))
1521 return -EINVAL;
1522
1523 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1524 return -EINVAL;
1525
1526 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1527 if (ret) {
1528 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1529 arvif->vdev_id, ret);
1530 return ret;
1531 }
1532
1533 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1534 * firmware will crash upon vdev up.
1535 */
1536
1537 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1538 if (ret) {
1539 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1540 return ret;
1541 }
1542
1543 ret = ath10k_mac_setup_prb_tmpl(arvif);
1544 if (ret) {
1545 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1546 return ret;
1547 }
1548
1549 ret = ath10k_vdev_restart(arvif, &def);
1550 if (ret) {
1551 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1552 arvif->vdev_id, ret);
1553 return ret;
1554 }
1555
1556 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1557 arvif->bssid);
1558 if (ret) {
1559 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1560 arvif->vdev_id, ret);
1561 return ret;
1562 }
1563
1564 return 0;
1565}
1566
Kalle Valo5e3dd152013-06-12 20:52:10 +03001567static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001568 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001569{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001570 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001571 int ret = 0;
1572
Michal Kazior548db542013-07-05 16:15:15 +03001573 lockdep_assert_held(&arvif->ar->conf_mutex);
1574
Kalle Valo5e3dd152013-06-12 20:52:10 +03001575 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001576 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1577 if (ret)
1578 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1579 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001580
Michal Kaziorc930f742014-01-23 11:38:25 +01001581 arvif->is_up = false;
1582
Michal Kazior748afc42014-01-23 12:48:21 +01001583 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001584 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001585 spin_unlock_bh(&arvif->ar->data_lock);
1586
Kalle Valo5e3dd152013-06-12 20:52:10 +03001587 return;
1588 }
1589
1590 arvif->tx_seq_no = 0x1000;
1591
Michal Kaziorc930f742014-01-23 11:38:25 +01001592 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001593 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001594
1595 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1596 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001597 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001598 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001599 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001600 return;
1601 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001602
Michal Kaziorc930f742014-01-23 11:38:25 +01001603 arvif->is_up = true;
1604
Michal Kazior500ff9f2015-03-31 10:26:21 +00001605 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1606 if (ret) {
1607 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1608 arvif->vdev_id, ret);
1609 return;
1610 }
1611
Michal Kazior7aa7a722014-08-25 12:09:38 +02001612 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001613}
1614
1615static void ath10k_control_ibss(struct ath10k_vif *arvif,
1616 struct ieee80211_bss_conf *info,
1617 const u8 self_peer[ETH_ALEN])
1618{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001619 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001620 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001621 int ret = 0;
1622
Michal Kazior548db542013-07-05 16:15:15 +03001623 lockdep_assert_held(&arvif->ar->conf_mutex);
1624
Kalle Valo5e3dd152013-06-12 20:52:10 +03001625 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001626 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001627 return;
1628
Joe Perches93803b32015-03-02 19:54:49 -08001629 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001630
1631 return;
1632 }
1633
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001634 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1635 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001636 ATH10K_DEFAULT_ATIM);
1637 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001638 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001639 arvif->vdev_id, ret);
1640}
1641
Michal Kazior9f9b5742014-12-12 12:41:36 +01001642static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1643{
1644 struct ath10k *ar = arvif->ar;
1645 u32 param;
1646 u32 value;
1647 int ret;
1648
1649 lockdep_assert_held(&arvif->ar->conf_mutex);
1650
1651 if (arvif->u.sta.uapsd)
1652 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1653 else
1654 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1655
1656 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1657 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1658 if (ret) {
1659 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1660 value, arvif->vdev_id, ret);
1661 return ret;
1662 }
1663
1664 return 0;
1665}
1666
1667static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1668{
1669 struct ath10k *ar = arvif->ar;
1670 u32 param;
1671 u32 value;
1672 int ret;
1673
1674 lockdep_assert_held(&arvif->ar->conf_mutex);
1675
1676 if (arvif->u.sta.uapsd)
1677 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1678 else
1679 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1680
1681 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1682 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1683 param, value);
1684 if (ret) {
1685 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1686 value, arvif->vdev_id, ret);
1687 return ret;
1688 }
1689
1690 return 0;
1691}
1692
Michal Kazior424f2632015-07-09 13:08:35 +02001693static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001694{
1695 struct ath10k_vif *arvif;
1696 int num = 0;
1697
1698 lockdep_assert_held(&ar->conf_mutex);
1699
1700 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001701 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001702 num++;
1703
1704 return num;
1705}
1706
Michal Kaziorad088bf2013-10-16 15:44:46 +03001707static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001708{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001709 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001710 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001711 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001712 enum wmi_sta_powersave_param param;
1713 enum wmi_sta_ps_mode psmode;
1714 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001715 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001716 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001717
Michal Kazior548db542013-07-05 16:15:15 +03001718 lockdep_assert_held(&arvif->ar->conf_mutex);
1719
Michal Kaziorad088bf2013-10-16 15:44:46 +03001720 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1721 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001722
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001723 enable_ps = arvif->ps;
1724
Michal Kazior424f2632015-07-09 13:08:35 +02001725 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001726 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
1727 ar->fw_features)) {
1728 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1729 arvif->vdev_id);
1730 enable_ps = false;
1731 }
1732
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001733 if (!arvif->is_started) {
1734 /* mac80211 can update vif powersave state while disconnected.
1735 * Firmware doesn't behave nicely and consumes more power than
1736 * necessary if PS is disabled on a non-started vdev. Hence
1737 * force-enable PS for non-running vdevs.
1738 */
1739 psmode = WMI_STA_PS_MODE_ENABLED;
1740 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001741 psmode = WMI_STA_PS_MODE_ENABLED;
1742 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1743
Michal Kazior526549a2014-12-12 12:41:37 +01001744 ps_timeout = conf->dynamic_ps_timeout;
1745 if (ps_timeout == 0) {
1746 /* Firmware doesn't like 0 */
1747 ps_timeout = ieee80211_tu_to_usec(
1748 vif->bss_conf.beacon_int) / 1000;
1749 }
1750
Michal Kaziorad088bf2013-10-16 15:44:46 +03001751 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001752 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001753 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001754 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001755 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001756 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001757 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001758 } else {
1759 psmode = WMI_STA_PS_MODE_DISABLED;
1760 }
1761
Michal Kazior7aa7a722014-08-25 12:09:38 +02001762 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001763 arvif->vdev_id, psmode ? "enable" : "disable");
1764
Michal Kaziorad088bf2013-10-16 15:44:46 +03001765 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1766 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001767 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001768 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001769 return ret;
1770 }
1771
1772 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001773}
1774
Michal Kazior46725b152015-01-28 09:57:49 +02001775static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1776{
1777 struct ath10k *ar = arvif->ar;
1778 struct wmi_sta_keepalive_arg arg = {};
1779 int ret;
1780
1781 lockdep_assert_held(&arvif->ar->conf_mutex);
1782
1783 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1784 return 0;
1785
1786 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1787 return 0;
1788
1789 /* Some firmware revisions have a bug and ignore the `enabled` field.
1790 * Instead use the interval to disable the keepalive.
1791 */
1792 arg.vdev_id = arvif->vdev_id;
1793 arg.enabled = 1;
1794 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1795 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1796
1797 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1798 if (ret) {
1799 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1800 arvif->vdev_id, ret);
1801 return ret;
1802 }
1803
1804 return 0;
1805}
1806
Michal Kazior81a9a172015-03-05 16:02:17 +02001807static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1808{
1809 struct ath10k *ar = arvif->ar;
1810 struct ieee80211_vif *vif = arvif->vif;
1811 int ret;
1812
Michal Kazior8513d952015-03-09 14:19:24 +01001813 lockdep_assert_held(&arvif->ar->conf_mutex);
1814
1815 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1816 return;
1817
Michal Kazior81a9a172015-03-05 16:02:17 +02001818 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1819 return;
1820
1821 if (!vif->csa_active)
1822 return;
1823
1824 if (!arvif->is_up)
1825 return;
1826
1827 if (!ieee80211_csa_is_complete(vif)) {
1828 ieee80211_csa_update_counter(vif);
1829
1830 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1831 if (ret)
1832 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1833 ret);
1834
1835 ret = ath10k_mac_setup_prb_tmpl(arvif);
1836 if (ret)
1837 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1838 ret);
1839 } else {
1840 ieee80211_csa_finish(vif);
1841 }
1842}
1843
1844static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1845{
1846 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1847 ap_csa_work);
1848 struct ath10k *ar = arvif->ar;
1849
1850 mutex_lock(&ar->conf_mutex);
1851 ath10k_mac_vif_ap_csa_count_down(arvif);
1852 mutex_unlock(&ar->conf_mutex);
1853}
1854
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001855static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1856 struct ieee80211_vif *vif)
1857{
1858 struct sk_buff *skb = data;
1859 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1860 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1861
1862 if (vif->type != NL80211_IFTYPE_STATION)
1863 return;
1864
1865 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1866 return;
1867
1868 cancel_delayed_work(&arvif->connection_loss_work);
1869}
1870
1871void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
1872{
1873 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1874 IEEE80211_IFACE_ITER_NORMAL,
1875 ath10k_mac_handle_beacon_iter,
1876 skb);
1877}
1878
1879static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
1880 struct ieee80211_vif *vif)
1881{
1882 u32 *vdev_id = data;
1883 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1884 struct ath10k *ar = arvif->ar;
1885 struct ieee80211_hw *hw = ar->hw;
1886
1887 if (arvif->vdev_id != *vdev_id)
1888 return;
1889
1890 if (!arvif->is_up)
1891 return;
1892
1893 ieee80211_beacon_loss(vif);
1894
1895 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
1896 * (done by mac80211) succeeds but beacons do not resume then it
1897 * doesn't make sense to continue operation. Queue connection loss work
1898 * which can be cancelled when beacon is received.
1899 */
1900 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
1901 ATH10K_CONNECTION_LOSS_HZ);
1902}
1903
1904void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
1905{
1906 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1907 IEEE80211_IFACE_ITER_NORMAL,
1908 ath10k_mac_handle_beacon_miss_iter,
1909 &vdev_id);
1910}
1911
1912static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
1913{
1914 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1915 connection_loss_work.work);
1916 struct ieee80211_vif *vif = arvif->vif;
1917
1918 if (!arvif->is_up)
1919 return;
1920
1921 ieee80211_connection_loss(vif);
1922}
1923
Kalle Valo5e3dd152013-06-12 20:52:10 +03001924/**********************/
1925/* Station management */
1926/**********************/
1927
Michal Kazior590922a2014-10-21 10:10:29 +03001928static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
1929 struct ieee80211_vif *vif)
1930{
1931 /* Some firmware revisions have unstable STA powersave when listen
1932 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
1933 * generate NullFunc frames properly even if buffered frames have been
1934 * indicated in Beacon TIM. Firmware would seldom wake up to pull
1935 * buffered frames. Often pinging the device from AP would simply fail.
1936 *
1937 * As a workaround set it to 1.
1938 */
1939 if (vif->type == NL80211_IFTYPE_STATION)
1940 return 1;
1941
1942 return ar->hw->conf.listen_interval;
1943}
1944
Kalle Valo5e3dd152013-06-12 20:52:10 +03001945static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001946 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001947 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001948 struct wmi_peer_assoc_complete_arg *arg)
1949{
Michal Kazior590922a2014-10-21 10:10:29 +03001950 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorc51880e2015-03-30 09:51:57 +03001951 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03001952
Michal Kazior548db542013-07-05 16:15:15 +03001953 lockdep_assert_held(&ar->conf_mutex);
1954
Michal Kaziorc51880e2015-03-30 09:51:57 +03001955 if (vif->type == NL80211_IFTYPE_STATION)
1956 aid = vif->bss_conf.aid;
1957 else
1958 aid = sta->aid;
1959
Kalle Valob25f32c2014-09-14 12:50:49 +03001960 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001961 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03001962 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02001963 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03001964 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001965 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03001966 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001967}
1968
1969static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001970 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001971 struct wmi_peer_assoc_complete_arg *arg)
1972{
Kalle Valo5e3dd152013-06-12 20:52:10 +03001973 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00001974 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001975 struct cfg80211_bss *bss;
1976 const u8 *rsnie = NULL;
1977 const u8 *wpaie = NULL;
1978
Michal Kazior548db542013-07-05 16:15:15 +03001979 lockdep_assert_held(&ar->conf_mutex);
1980
Michal Kazior500ff9f2015-03-31 10:26:21 +00001981 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
1982 return;
1983
1984 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
1985 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001986 if (bss) {
1987 const struct cfg80211_bss_ies *ies;
1988
1989 rcu_read_lock();
1990 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
1991
1992 ies = rcu_dereference(bss->ies);
1993
1994 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03001995 WLAN_OUI_TYPE_MICROSOFT_WPA,
1996 ies->data,
1997 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001998 rcu_read_unlock();
1999 cfg80211_put_bss(ar->hw->wiphy, bss);
2000 }
2001
2002 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2003 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002004 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002005 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002006 }
2007
2008 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002009 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002010 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002011 }
2012}
2013
2014static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002015 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002016 struct ieee80211_sta *sta,
2017 struct wmi_peer_assoc_complete_arg *arg)
2018{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002019 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002020 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002021 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002022 const struct ieee80211_supported_band *sband;
2023 const struct ieee80211_rate *rates;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002024 enum ieee80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002025 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002026 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002027 int i;
2028
Michal Kazior548db542013-07-05 16:15:15 +03002029 lockdep_assert_held(&ar->conf_mutex);
2030
Michal Kazior500ff9f2015-03-31 10:26:21 +00002031 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2032 return;
2033
Michal Kazior45c9abc2015-04-21 20:42:58 +03002034 band = def.chan->band;
2035 sband = ar->hw->wiphy->bands[band];
2036 ratemask = sta->supp_rates[band];
2037 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002038 rates = sband->bitrates;
2039
2040 rateset->num_rates = 0;
2041
2042 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2043 if (!(ratemask & 1))
2044 continue;
2045
Michal Kazior486017c2015-03-30 09:51:54 +03002046 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2047 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002048 rateset->num_rates++;
2049 }
2050}
2051
Michal Kazior45c9abc2015-04-21 20:42:58 +03002052static bool
2053ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2054{
2055 int nss;
2056
2057 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2058 if (ht_mcs_mask[nss])
2059 return false;
2060
2061 return true;
2062}
2063
2064static bool
2065ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2066{
2067 int nss;
2068
2069 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2070 if (vht_mcs_mask[nss])
2071 return false;
2072
2073 return true;
2074}
2075
Kalle Valo5e3dd152013-06-12 20:52:10 +03002076static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002077 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002078 struct ieee80211_sta *sta,
2079 struct wmi_peer_assoc_complete_arg *arg)
2080{
2081 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002082 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2083 struct cfg80211_chan_def def;
2084 enum ieee80211_band band;
2085 const u8 *ht_mcs_mask;
2086 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002087 int i, n;
2088 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002089 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002090
Michal Kazior548db542013-07-05 16:15:15 +03002091 lockdep_assert_held(&ar->conf_mutex);
2092
Michal Kazior45c9abc2015-04-21 20:42:58 +03002093 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2094 return;
2095
Kalle Valo5e3dd152013-06-12 20:52:10 +03002096 if (!ht_cap->ht_supported)
2097 return;
2098
Michal Kazior45c9abc2015-04-21 20:42:58 +03002099 band = def.chan->band;
2100 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2101 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2102
2103 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2104 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2105 return;
2106
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002107 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002108 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2109 ht_cap->ampdu_factor)) - 1;
2110
2111 arg->peer_mpdu_density =
2112 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2113
2114 arg->peer_ht_caps = ht_cap->cap;
2115 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2116
2117 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002118 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002119
2120 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002121 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002122 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2123 }
2124
Michal Kazior45c9abc2015-04-21 20:42:58 +03002125 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2126 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2127 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002128
Michal Kazior45c9abc2015-04-21 20:42:58 +03002129 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2130 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2131 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002132
2133 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2134 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002135 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002136 }
2137
2138 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002139 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2140 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2141 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2142 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002143 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002144 }
2145
Kalle Valo5e3dd152013-06-12 20:52:10 +03002146 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2147 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2148 else if (ht_cap->mcs.rx_mask[1])
2149 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2150
Michal Kazior45c9abc2015-04-21 20:42:58 +03002151 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2152 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2153 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2154 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002155 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002156 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002157
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002158 /*
2159 * This is a workaround for HT-enabled STAs which break the spec
2160 * and have no HT capabilities RX mask (no HT RX MCS map).
2161 *
2162 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2163 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2164 *
2165 * Firmware asserts if such situation occurs.
2166 */
2167 if (n == 0) {
2168 arg->peer_ht_rates.num_rates = 8;
2169 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2170 arg->peer_ht_rates.rates[i] = i;
2171 } else {
2172 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002173 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002174 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002175
Michal Kazior7aa7a722014-08-25 12:09:38 +02002176 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002177 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002178 arg->peer_ht_rates.num_rates,
2179 arg->peer_num_spatial_streams);
2180}
2181
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002182static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2183 struct ath10k_vif *arvif,
2184 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002185{
2186 u32 uapsd = 0;
2187 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002188 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002189
Michal Kazior548db542013-07-05 16:15:15 +03002190 lockdep_assert_held(&ar->conf_mutex);
2191
Kalle Valo5e3dd152013-06-12 20:52:10 +03002192 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002193 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002194 sta->uapsd_queues, sta->max_sp);
2195
Kalle Valo5e3dd152013-06-12 20:52:10 +03002196 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2197 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2198 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2199 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2200 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2201 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2202 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2203 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2204 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2205 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2206 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2207 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2208
Kalle Valo5e3dd152013-06-12 20:52:10 +03002209 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2210 max_sp = sta->max_sp;
2211
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002212 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2213 sta->addr,
2214 WMI_AP_PS_PEER_PARAM_UAPSD,
2215 uapsd);
2216 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002217 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002218 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002219 return ret;
2220 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002221
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002222 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2223 sta->addr,
2224 WMI_AP_PS_PEER_PARAM_MAX_SP,
2225 max_sp);
2226 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002227 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002228 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002229 return ret;
2230 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002231
2232 /* TODO setup this based on STA listen interval and
2233 beacon interval. Currently we don't know
2234 sta->listen_interval - mac80211 patch required.
2235 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002236 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002237 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2238 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002239 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002240 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002241 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002242 return ret;
2243 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002244 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002245
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002246 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002247}
2248
Michal Kazior45c9abc2015-04-21 20:42:58 +03002249static u16
2250ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2251 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2252{
2253 int idx_limit;
2254 int nss;
2255 u16 mcs_map;
2256 u16 mcs;
2257
2258 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2259 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2260 vht_mcs_limit[nss];
2261
2262 if (mcs_map)
2263 idx_limit = fls(mcs_map) - 1;
2264 else
2265 idx_limit = -1;
2266
2267 switch (idx_limit) {
2268 case 0: /* fall through */
2269 case 1: /* fall through */
2270 case 2: /* fall through */
2271 case 3: /* fall through */
2272 case 4: /* fall through */
2273 case 5: /* fall through */
2274 case 6: /* fall through */
2275 default:
2276 /* see ath10k_mac_can_set_bitrate_mask() */
2277 WARN_ON(1);
2278 /* fall through */
2279 case -1:
2280 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2281 break;
2282 case 7:
2283 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2284 break;
2285 case 8:
2286 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2287 break;
2288 case 9:
2289 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2290 break;
2291 }
2292
2293 tx_mcs_set &= ~(0x3 << (nss * 2));
2294 tx_mcs_set |= mcs << (nss * 2);
2295 }
2296
2297 return tx_mcs_set;
2298}
2299
Kalle Valo5e3dd152013-06-12 20:52:10 +03002300static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002301 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002302 struct ieee80211_sta *sta,
2303 struct wmi_peer_assoc_complete_arg *arg)
2304{
2305 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002306 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002307 struct cfg80211_chan_def def;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002308 enum ieee80211_band band;
2309 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002310 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002311
Michal Kazior500ff9f2015-03-31 10:26:21 +00002312 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2313 return;
2314
Kalle Valo5e3dd152013-06-12 20:52:10 +03002315 if (!vht_cap->vht_supported)
2316 return;
2317
Michal Kazior45c9abc2015-04-21 20:42:58 +03002318 band = def.chan->band;
2319 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2320
2321 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2322 return;
2323
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002324 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002325
Michal Kazior500ff9f2015-03-31 10:26:21 +00002326 if (def.chan->band == IEEE80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002327 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002328
Kalle Valo5e3dd152013-06-12 20:52:10 +03002329 arg->peer_vht_caps = vht_cap->cap;
2330
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002331 ampdu_factor = (vht_cap->cap &
2332 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2333 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2334
2335 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2336 * zero in VHT IE. Using it would result in degraded throughput.
2337 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2338 * it if VHT max_mpdu is smaller. */
2339 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2340 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2341 ampdu_factor)) - 1);
2342
Kalle Valo5e3dd152013-06-12 20:52:10 +03002343 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002344 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002345
2346 arg->peer_vht_rates.rx_max_rate =
2347 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2348 arg->peer_vht_rates.rx_mcs_set =
2349 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2350 arg->peer_vht_rates.tx_max_rate =
2351 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002352 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2353 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002354
Michal Kazior7aa7a722014-08-25 12:09:38 +02002355 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002356 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002357}
2358
2359static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002360 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002361 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002362 struct wmi_peer_assoc_complete_arg *arg)
2363{
Michal Kazior590922a2014-10-21 10:10:29 +03002364 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2365
Kalle Valo5e3dd152013-06-12 20:52:10 +03002366 switch (arvif->vdev_type) {
2367 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002368 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002369 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002370
2371 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002372 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002373 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2374 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002375 break;
2376 case WMI_VDEV_TYPE_STA:
Michal Kazior590922a2014-10-21 10:10:29 +03002377 if (vif->bss_conf.qos)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002378 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002379 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002380 case WMI_VDEV_TYPE_IBSS:
2381 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002382 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002383 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002384 default:
2385 break;
2386 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002387
2388 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002389 sta->addr, !!(arg->peer_flags &
2390 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002391}
2392
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002393static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002394{
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002395 return sta->supp_rates[IEEE80211_BAND_2GHZ] >>
2396 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002397}
2398
Kalle Valo5e3dd152013-06-12 20:52:10 +03002399static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002400 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002401 struct ieee80211_sta *sta,
2402 struct wmi_peer_assoc_complete_arg *arg)
2403{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002404 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002405 struct cfg80211_chan_def def;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002406 enum ieee80211_band band;
2407 const u8 *ht_mcs_mask;
2408 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002409 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2410
Michal Kazior500ff9f2015-03-31 10:26:21 +00002411 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2412 return;
2413
Michal Kazior45c9abc2015-04-21 20:42:58 +03002414 band = def.chan->band;
2415 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2416 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2417
2418 switch (band) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002419 case IEEE80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002420 if (sta->vht_cap.vht_supported &&
2421 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002422 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2423 phymode = MODE_11AC_VHT40;
2424 else
2425 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002426 } else if (sta->ht_cap.ht_supported &&
2427 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002428 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2429 phymode = MODE_11NG_HT40;
2430 else
2431 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002432 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002433 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002434 } else {
2435 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002436 }
2437
2438 break;
2439 case IEEE80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002440 /*
2441 * Check VHT first.
2442 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002443 if (sta->vht_cap.vht_supported &&
2444 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002445 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2446 phymode = MODE_11AC_VHT80;
2447 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2448 phymode = MODE_11AC_VHT40;
2449 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2450 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002451 } else if (sta->ht_cap.ht_supported &&
2452 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2453 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002454 phymode = MODE_11NA_HT40;
2455 else
2456 phymode = MODE_11NA_HT20;
2457 } else {
2458 phymode = MODE_11A;
2459 }
2460
2461 break;
2462 default:
2463 break;
2464 }
2465
Michal Kazior7aa7a722014-08-25 12:09:38 +02002466 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002467 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002468
Kalle Valo5e3dd152013-06-12 20:52:10 +03002469 arg->peer_phymode = phymode;
2470 WARN_ON(phymode == MODE_UNKNOWN);
2471}
2472
Kalle Valob9ada652013-10-16 15:44:46 +03002473static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002474 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002475 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002476 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002477{
Michal Kazior548db542013-07-05 16:15:15 +03002478 lockdep_assert_held(&ar->conf_mutex);
2479
Kalle Valob9ada652013-10-16 15:44:46 +03002480 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002481
Michal Kazior590922a2014-10-21 10:10:29 +03002482 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
2483 ath10k_peer_assoc_h_crypto(ar, vif, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002484 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002485 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002486 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002487 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2488 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002489
Kalle Valob9ada652013-10-16 15:44:46 +03002490 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002491}
2492
Michal Kazior90046f52014-02-14 14:45:51 +01002493static const u32 ath10k_smps_map[] = {
2494 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2495 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2496 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2497 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2498};
2499
2500static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2501 const u8 *addr,
2502 const struct ieee80211_sta_ht_cap *ht_cap)
2503{
2504 int smps;
2505
2506 if (!ht_cap->ht_supported)
2507 return 0;
2508
2509 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2510 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2511
2512 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2513 return -EINVAL;
2514
2515 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2516 WMI_PEER_SMPS_STATE,
2517 ath10k_smps_map[smps]);
2518}
2519
Michal Kazior139e1702015-02-15 16:50:42 +02002520static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2521 struct ieee80211_vif *vif,
2522 struct ieee80211_sta_vht_cap vht_cap)
2523{
2524 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2525 int ret;
2526 u32 param;
2527 u32 value;
2528
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302529 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2530 return 0;
2531
Michal Kazior139e1702015-02-15 16:50:42 +02002532 if (!(ar->vht_cap_info &
2533 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2534 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2535 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2536 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2537 return 0;
2538
2539 param = ar->wmi.vdev_param->txbf;
2540 value = 0;
2541
2542 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2543 return 0;
2544
2545 /* The following logic is correct. If a remote STA advertises support
2546 * for being a beamformer then we should enable us being a beamformee.
2547 */
2548
2549 if (ar->vht_cap_info &
2550 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2551 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2552 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2553 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2554
2555 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2556 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2557 }
2558
2559 if (ar->vht_cap_info &
2560 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2561 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2562 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2563 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2564
2565 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2566 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2567 }
2568
2569 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2570 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2571
2572 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2573 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2574
2575 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2576 if (ret) {
2577 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2578 value, ret);
2579 return ret;
2580 }
2581
2582 return 0;
2583}
2584
Kalle Valo5e3dd152013-06-12 20:52:10 +03002585/* can be called only in mac80211 callbacks due to `key_count` usage */
2586static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2587 struct ieee80211_vif *vif,
2588 struct ieee80211_bss_conf *bss_conf)
2589{
2590 struct ath10k *ar = hw->priv;
2591 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002592 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002593 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002594 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002595 struct ieee80211_sta *ap_sta;
2596 int ret;
2597
Michal Kazior548db542013-07-05 16:15:15 +03002598 lockdep_assert_held(&ar->conf_mutex);
2599
Michal Kazior077efc82014-10-21 10:10:29 +03002600 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2601 arvif->vdev_id, arvif->bssid, arvif->aid);
2602
Kalle Valo5e3dd152013-06-12 20:52:10 +03002603 rcu_read_lock();
2604
2605 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2606 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002607 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002608 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002609 rcu_read_unlock();
2610 return;
2611 }
2612
Michal Kazior90046f52014-02-14 14:45:51 +01002613 /* ap_sta must be accessed only within rcu section which must be left
2614 * before calling ath10k_setup_peer_smps() which might sleep. */
2615 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002616 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002617
Michal Kazior590922a2014-10-21 10:10:29 +03002618 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002619 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002620 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002621 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002622 rcu_read_unlock();
2623 return;
2624 }
2625
2626 rcu_read_unlock();
2627
Kalle Valob9ada652013-10-16 15:44:46 +03002628 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2629 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002630 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002631 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002632 return;
2633 }
2634
Michal Kazior90046f52014-02-14 14:45:51 +01002635 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2636 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002637 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002638 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002639 return;
2640 }
2641
Michal Kazior139e1702015-02-15 16:50:42 +02002642 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2643 if (ret) {
2644 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2645 arvif->vdev_id, bss_conf->bssid, ret);
2646 return;
2647 }
2648
Michal Kazior7aa7a722014-08-25 12:09:38 +02002649 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002650 "mac vdev %d up (associated) bssid %pM aid %d\n",
2651 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2652
Michal Kazior077efc82014-10-21 10:10:29 +03002653 WARN_ON(arvif->is_up);
2654
Michal Kaziorc930f742014-01-23 11:38:25 +01002655 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002656 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002657
2658 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2659 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002660 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002661 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002662 return;
2663 }
2664
2665 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002666
2667 /* Workaround: Some firmware revisions (tested with qca6174
2668 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2669 * poked with peer param command.
2670 */
2671 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2672 WMI_PEER_DUMMY_VAR, 1);
2673 if (ret) {
2674 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2675 arvif->bssid, arvif->vdev_id, ret);
2676 return;
2677 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002678}
2679
Kalle Valo5e3dd152013-06-12 20:52:10 +03002680static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2681 struct ieee80211_vif *vif)
2682{
2683 struct ath10k *ar = hw->priv;
2684 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002685 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002686 int ret;
2687
Michal Kazior548db542013-07-05 16:15:15 +03002688 lockdep_assert_held(&ar->conf_mutex);
2689
Michal Kazior077efc82014-10-21 10:10:29 +03002690 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2691 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002692
Kalle Valo5e3dd152013-06-12 20:52:10 +03002693 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002694 if (ret)
2695 ath10k_warn(ar, "faield to down vdev %i: %d\n",
2696 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002697
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002698 arvif->def_wep_key_idx = -1;
2699
Michal Kazior139e1702015-02-15 16:50:42 +02002700 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2701 if (ret) {
2702 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2703 arvif->vdev_id, ret);
2704 return;
2705 }
2706
Michal Kaziorc930f742014-01-23 11:38:25 +01002707 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002708
2709 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002710}
2711
Michal Kazior590922a2014-10-21 10:10:29 +03002712static int ath10k_station_assoc(struct ath10k *ar,
2713 struct ieee80211_vif *vif,
2714 struct ieee80211_sta *sta,
2715 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002716{
Michal Kazior590922a2014-10-21 10:10:29 +03002717 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002718 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002719 int ret = 0;
2720
Michal Kazior548db542013-07-05 16:15:15 +03002721 lockdep_assert_held(&ar->conf_mutex);
2722
Michal Kazior590922a2014-10-21 10:10:29 +03002723 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002724 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002725 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002726 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002727 return ret;
2728 }
2729
2730 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2731 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002732 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002733 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002734 return ret;
2735 }
2736
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002737 /* Re-assoc is run only to update supported rates for given station. It
2738 * doesn't make much sense to reconfigure the peer completely.
2739 */
2740 if (!reassoc) {
2741 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2742 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002743 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002744 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002745 arvif->vdev_id, ret);
2746 return ret;
2747 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002748
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002749 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2750 if (ret) {
2751 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2752 sta->addr, arvif->vdev_id, ret);
2753 return ret;
2754 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002755
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002756 if (!sta->wme) {
2757 arvif->num_legacy_stations++;
2758 ret = ath10k_recalc_rtscts_prot(arvif);
2759 if (ret) {
2760 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2761 arvif->vdev_id, ret);
2762 return ret;
2763 }
2764 }
2765
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002766 /* Plumb cached keys only for static WEP */
2767 if (arvif->def_wep_key_idx != -1) {
2768 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2769 if (ret) {
2770 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2771 arvif->vdev_id, ret);
2772 return ret;
2773 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002774 }
2775 }
2776
Kalle Valo5e3dd152013-06-12 20:52:10 +03002777 return ret;
2778}
2779
Michal Kazior590922a2014-10-21 10:10:29 +03002780static int ath10k_station_disassoc(struct ath10k *ar,
2781 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002782 struct ieee80211_sta *sta)
2783{
Michal Kazior590922a2014-10-21 10:10:29 +03002784 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002785 int ret = 0;
2786
2787 lockdep_assert_held(&ar->conf_mutex);
2788
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002789 if (!sta->wme) {
2790 arvif->num_legacy_stations--;
2791 ret = ath10k_recalc_rtscts_prot(arvif);
2792 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002793 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002794 arvif->vdev_id, ret);
2795 return ret;
2796 }
2797 }
2798
Kalle Valo5e3dd152013-06-12 20:52:10 +03002799 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2800 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002801 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002802 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002803 return ret;
2804 }
2805
2806 return ret;
2807}
2808
2809/**************/
2810/* Regulatory */
2811/**************/
2812
2813static int ath10k_update_channel_list(struct ath10k *ar)
2814{
2815 struct ieee80211_hw *hw = ar->hw;
2816 struct ieee80211_supported_band **bands;
2817 enum ieee80211_band band;
2818 struct ieee80211_channel *channel;
2819 struct wmi_scan_chan_list_arg arg = {0};
2820 struct wmi_channel_arg *ch;
2821 bool passive;
2822 int len;
2823 int ret;
2824 int i;
2825
Michal Kazior548db542013-07-05 16:15:15 +03002826 lockdep_assert_held(&ar->conf_mutex);
2827
Kalle Valo5e3dd152013-06-12 20:52:10 +03002828 bands = hw->wiphy->bands;
2829 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2830 if (!bands[band])
2831 continue;
2832
2833 for (i = 0; i < bands[band]->n_channels; i++) {
2834 if (bands[band]->channels[i].flags &
2835 IEEE80211_CHAN_DISABLED)
2836 continue;
2837
2838 arg.n_channels++;
2839 }
2840 }
2841
2842 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2843 arg.channels = kzalloc(len, GFP_KERNEL);
2844 if (!arg.channels)
2845 return -ENOMEM;
2846
2847 ch = arg.channels;
2848 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2849 if (!bands[band])
2850 continue;
2851
2852 for (i = 0; i < bands[band]->n_channels; i++) {
2853 channel = &bands[band]->channels[i];
2854
2855 if (channel->flags & IEEE80211_CHAN_DISABLED)
2856 continue;
2857
2858 ch->allow_ht = true;
2859
2860 /* FIXME: when should we really allow VHT? */
2861 ch->allow_vht = true;
2862
2863 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002864 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002865
2866 ch->ht40plus =
2867 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2868
Marek Puzyniake8a50f82013-11-20 09:59:47 +02002869 ch->chan_radar =
2870 !!(channel->flags & IEEE80211_CHAN_RADAR);
2871
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002872 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002873 ch->passive = passive;
2874
2875 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02002876 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07002877 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07002878 ch->max_power = channel->max_power * 2;
2879 ch->max_reg_power = channel->max_reg_power * 2;
2880 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002881 ch->reg_class_id = 0; /* FIXME */
2882
2883 /* FIXME: why use only legacy modes, why not any
2884 * HT/VHT modes? Would that even make any
2885 * difference? */
2886 if (channel->band == IEEE80211_BAND_2GHZ)
2887 ch->mode = MODE_11G;
2888 else
2889 ch->mode = MODE_11A;
2890
2891 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
2892 continue;
2893
Michal Kazior7aa7a722014-08-25 12:09:38 +02002894 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002895 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
2896 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002897 ch->freq, ch->max_power, ch->max_reg_power,
2898 ch->max_antenna_gain, ch->mode);
2899
2900 ch++;
2901 }
2902 }
2903
2904 ret = ath10k_wmi_scan_chan_list(ar, &arg);
2905 kfree(arg.channels);
2906
2907 return ret;
2908}
2909
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002910static enum wmi_dfs_region
2911ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
2912{
2913 switch (dfs_region) {
2914 case NL80211_DFS_UNSET:
2915 return WMI_UNINIT_DFS_DOMAIN;
2916 case NL80211_DFS_FCC:
2917 return WMI_FCC_DFS_DOMAIN;
2918 case NL80211_DFS_ETSI:
2919 return WMI_ETSI_DFS_DOMAIN;
2920 case NL80211_DFS_JP:
2921 return WMI_MKK4_DFS_DOMAIN;
2922 }
2923 return WMI_UNINIT_DFS_DOMAIN;
2924}
2925
Michal Kaziorf7843d72013-07-16 09:38:52 +02002926static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002927{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002928 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002929 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002930 enum wmi_dfs_region wmi_dfs_reg;
2931 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002932
Michal Kaziorf7843d72013-07-16 09:38:52 +02002933 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002934
2935 ret = ath10k_update_channel_list(ar);
2936 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002937 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002938
2939 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002940
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002941 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
2942 nl_dfs_reg = ar->dfs_detector->region;
2943 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
2944 } else {
2945 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
2946 }
2947
Kalle Valo5e3dd152013-06-12 20:52:10 +03002948 /* Target allows setting up per-band regdomain but ath_common provides
2949 * a combined one only */
2950 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02002951 regpair->reg_domain,
2952 regpair->reg_domain, /* 2ghz */
2953 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03002954 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002955 regpair->reg_5ghz_ctl,
2956 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002957 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002958 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02002959}
Michal Kazior548db542013-07-05 16:15:15 +03002960
Michal Kaziorf7843d72013-07-16 09:38:52 +02002961static void ath10k_reg_notifier(struct wiphy *wiphy,
2962 struct regulatory_request *request)
2963{
2964 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2965 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002966 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002967
2968 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
2969
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002970 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002971 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002972 request->dfs_region);
2973 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
2974 request->dfs_region);
2975 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002976 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002977 request->dfs_region);
2978 }
2979
Michal Kaziorf7843d72013-07-16 09:38:52 +02002980 mutex_lock(&ar->conf_mutex);
2981 if (ar->state == ATH10K_STATE_ON)
2982 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03002983 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002984}
2985
2986/***************/
2987/* TX handlers */
2988/***************/
2989
Michal Kazior96d828d2015-03-31 10:26:23 +00002990void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
2991{
2992 lockdep_assert_held(&ar->htt.tx_lock);
2993
2994 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
2995 ar->tx_paused |= BIT(reason);
2996 ieee80211_stop_queues(ar->hw);
2997}
2998
2999static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3000 struct ieee80211_vif *vif)
3001{
3002 struct ath10k *ar = data;
3003 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3004
3005 if (arvif->tx_paused)
3006 return;
3007
3008 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3009}
3010
3011void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3012{
3013 lockdep_assert_held(&ar->htt.tx_lock);
3014
3015 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3016 ar->tx_paused &= ~BIT(reason);
3017
3018 if (ar->tx_paused)
3019 return;
3020
3021 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3022 IEEE80211_IFACE_ITER_RESUME_ALL,
3023 ath10k_mac_tx_unlock_iter,
3024 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003025
3026 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003027}
3028
3029void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3030{
3031 struct ath10k *ar = arvif->ar;
3032
3033 lockdep_assert_held(&ar->htt.tx_lock);
3034
3035 WARN_ON(reason >= BITS_PER_LONG);
3036 arvif->tx_paused |= BIT(reason);
3037 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3038}
3039
3040void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3041{
3042 struct ath10k *ar = arvif->ar;
3043
3044 lockdep_assert_held(&ar->htt.tx_lock);
3045
3046 WARN_ON(reason >= BITS_PER_LONG);
3047 arvif->tx_paused &= ~BIT(reason);
3048
3049 if (ar->tx_paused)
3050 return;
3051
3052 if (arvif->tx_paused)
3053 return;
3054
3055 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3056}
3057
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003058static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3059 enum wmi_tlv_tx_pause_id pause_id,
3060 enum wmi_tlv_tx_pause_action action)
3061{
3062 struct ath10k *ar = arvif->ar;
3063
3064 lockdep_assert_held(&ar->htt.tx_lock);
3065
Michal Kazioracd0b272015-07-09 13:08:38 +02003066 switch (action) {
3067 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3068 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003069 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003070 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3071 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3072 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003073 default:
Michal Kazioracd0b272015-07-09 13:08:38 +02003074 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
3075 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003076 break;
3077 }
3078}
3079
3080struct ath10k_mac_tx_pause {
3081 u32 vdev_id;
3082 enum wmi_tlv_tx_pause_id pause_id;
3083 enum wmi_tlv_tx_pause_action action;
3084};
3085
3086static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3087 struct ieee80211_vif *vif)
3088{
3089 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3090 struct ath10k_mac_tx_pause *arg = data;
3091
Michal Kazioracd0b272015-07-09 13:08:38 +02003092 if (arvif->vdev_id != arg->vdev_id)
3093 return;
3094
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003095 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3096}
3097
Michal Kazioracd0b272015-07-09 13:08:38 +02003098void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3099 enum wmi_tlv_tx_pause_id pause_id,
3100 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003101{
3102 struct ath10k_mac_tx_pause arg = {
3103 .vdev_id = vdev_id,
3104 .pause_id = pause_id,
3105 .action = action,
3106 };
3107
3108 spin_lock_bh(&ar->htt.tx_lock);
3109 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3110 IEEE80211_IFACE_ITER_RESUME_ALL,
3111 ath10k_mac_handle_tx_pause_iter,
3112 &arg);
3113 spin_unlock_bh(&ar->htt.tx_lock);
3114}
3115
Michal Kazior42c3aa62013-10-02 11:03:38 +02003116static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
3117{
3118 if (ieee80211_is_mgmt(hdr->frame_control))
3119 return HTT_DATA_TX_EXT_TID_MGMT;
3120
3121 if (!ieee80211_is_data_qos(hdr->frame_control))
3122 return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
3123
3124 if (!is_unicast_ether_addr(ieee80211_get_DA(hdr)))
3125 return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
3126
3127 return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
3128}
3129
Michal Kazior2b37c292014-09-02 11:00:22 +03003130static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003131{
Michal Kazior2b37c292014-09-02 11:00:22 +03003132 if (vif)
3133 return ath10k_vif_to_arvif(vif)->vdev_id;
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003134
Michal Kazior1bbc0972014-04-08 09:45:47 +03003135 if (ar->monitor_started)
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003136 return ar->monitor_vdev_id;
3137
Michal Kazior7aa7a722014-08-25 12:09:38 +02003138 ath10k_warn(ar, "failed to resolve vdev id\n");
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003139 return 0;
3140}
3141
Michal Kaziord740d8f2015-03-30 09:51:51 +03003142static enum ath10k_hw_txrx_mode
3143ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003144 struct ieee80211_sta *sta, struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003145{
3146 const struct ieee80211_hdr *hdr = (void *)skb->data;
3147 __le16 fc = hdr->frame_control;
3148
3149 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3150 return ATH10K_HW_TXRX_RAW;
3151
3152 if (ieee80211_is_mgmt(fc))
3153 return ATH10K_HW_TXRX_MGMT;
3154
3155 /* Workaround:
3156 *
3157 * NullFunc frames are mostly used to ping if a client or AP are still
3158 * reachable and responsive. This implies tx status reports must be
3159 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3160 * come to a conclusion that the other end disappeared and tear down
3161 * BSS connection or it can never disconnect from BSS/client (which is
3162 * the case).
3163 *
3164 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3165 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3166 * which seems to deliver correct tx reports for NullFunc frames. The
3167 * downside of using it is it ignores client powersave state so it can
3168 * end up disconnecting sleeping clients in AP mode. It should fix STA
3169 * mode though because AP don't sleep.
3170 */
3171 if (ar->htt.target_version_major < 3 &&
3172 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
3173 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, ar->fw_features))
3174 return ATH10K_HW_TXRX_MGMT;
3175
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003176 /* Workaround:
3177 *
3178 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3179 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3180 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003181 *
3182 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003183 */
3184 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3185 return ATH10K_HW_TXRX_ETHERNET;
3186
David Liuccec9032015-07-24 20:25:32 +03003187 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3188 return ATH10K_HW_TXRX_RAW;
3189
Michal Kaziord740d8f2015-03-30 09:51:51 +03003190 return ATH10K_HW_TXRX_NATIVE_WIFI;
3191}
3192
David Liuccec9032015-07-24 20:25:32 +03003193static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
3194 struct sk_buff *skb) {
3195 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3196 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3197 IEEE80211_TX_CTL_INJECTED;
3198 if ((info->flags & mask) == mask)
3199 return false;
3200 if (vif)
3201 return !ath10k_vif_to_arvif(vif)->nohwcrypt;
3202 return true;
3203}
3204
Michal Kazior4b604552014-07-21 21:03:09 +03003205/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3206 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003207 */
Michal Kazior4b604552014-07-21 21:03:09 +03003208static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003209{
3210 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003211 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003212 u8 *qos_ctl;
3213
3214 if (!ieee80211_is_data_qos(hdr->frame_control))
3215 return;
3216
3217 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003218 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3219 skb->data, (void *)qos_ctl - (void *)skb->data);
3220 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003221
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003222 /* Some firmware revisions don't handle sending QoS NullFunc well.
3223 * These frames are mainly used for CQM purposes so it doesn't really
3224 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003225 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003226 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003227 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003228 cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003229
3230 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003231}
3232
Michal Kaziord740d8f2015-03-30 09:51:51 +03003233static void ath10k_tx_h_8023(struct sk_buff *skb)
3234{
3235 struct ieee80211_hdr *hdr;
3236 struct rfc1042_hdr *rfc1042;
3237 struct ethhdr *eth;
3238 size_t hdrlen;
3239 u8 da[ETH_ALEN];
3240 u8 sa[ETH_ALEN];
3241 __be16 type;
3242
3243 hdr = (void *)skb->data;
3244 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3245 rfc1042 = (void *)skb->data + hdrlen;
3246
3247 ether_addr_copy(da, ieee80211_get_DA(hdr));
3248 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3249 type = rfc1042->snap_type;
3250
3251 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3252 skb_push(skb, sizeof(*eth));
3253
3254 eth = (void *)skb->data;
3255 ether_addr_copy(eth->h_dest, da);
3256 ether_addr_copy(eth->h_source, sa);
3257 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003258}
3259
Michal Kazior4b604552014-07-21 21:03:09 +03003260static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3261 struct ieee80211_vif *vif,
3262 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003263{
3264 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003265 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3266
3267 /* This is case only for P2P_GO */
3268 if (arvif->vdev_type != WMI_VDEV_TYPE_AP ||
3269 arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
3270 return;
3271
3272 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3273 spin_lock_bh(&ar->data_lock);
3274 if (arvif->u.ap.noa_data)
3275 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3276 GFP_ATOMIC))
3277 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3278 arvif->u.ap.noa_data,
3279 arvif->u.ap.noa_len);
3280 spin_unlock_bh(&ar->data_lock);
3281 }
3282}
3283
Michal Kazior8d6d3622014-11-24 14:58:31 +01003284static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
3285{
3286 /* FIXME: Not really sure since when the behaviour changed. At some
3287 * point new firmware stopped requiring creation of peer entries for
3288 * offchannel tx (and actually creating them causes issues with wmi-htc
3289 * tx credit replenishment and reliability). Assuming it's at least 3.4
3290 * because that's when the `freq` was introduced to TX_FRM HTT command.
3291 */
3292 return !(ar->htt.target_version_major >= 3 &&
3293 ar->htt.target_version_minor >= 4);
3294}
3295
Michal Kaziord740d8f2015-03-30 09:51:51 +03003296static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003297{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003298 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003299 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003300
Michal Kaziord740d8f2015-03-30 09:51:51 +03003301 spin_lock_bh(&ar->data_lock);
3302
3303 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3304 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3305 ret = -ENOSPC;
3306 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003307 }
3308
Michal Kaziord740d8f2015-03-30 09:51:51 +03003309 __skb_queue_tail(q, skb);
3310 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3311
3312unlock:
3313 spin_unlock_bh(&ar->data_lock);
3314
3315 return ret;
3316}
3317
3318static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
3319{
3320 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3321 struct ath10k_htt *htt = &ar->htt;
3322 int ret = 0;
3323
3324 switch (cb->txmode) {
3325 case ATH10K_HW_TXRX_RAW:
3326 case ATH10K_HW_TXRX_NATIVE_WIFI:
3327 case ATH10K_HW_TXRX_ETHERNET:
3328 ret = ath10k_htt_tx(htt, skb);
3329 break;
3330 case ATH10K_HW_TXRX_MGMT:
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003331 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Michal Kaziord740d8f2015-03-30 09:51:51 +03003332 ar->fw_features))
3333 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3334 else if (ar->htt.target_version_major >= 3)
3335 ret = ath10k_htt_tx(htt, skb);
3336 else
3337 ret = ath10k_htt_mgmt_tx(htt, skb);
3338 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003339 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003340
3341 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003342 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3343 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003344 ieee80211_free_txskb(ar->hw, skb);
3345 }
3346}
3347
3348void ath10k_offchan_tx_purge(struct ath10k *ar)
3349{
3350 struct sk_buff *skb;
3351
3352 for (;;) {
3353 skb = skb_dequeue(&ar->offchan_tx_queue);
3354 if (!skb)
3355 break;
3356
3357 ieee80211_free_txskb(ar->hw, skb);
3358 }
3359}
3360
3361void ath10k_offchan_tx_work(struct work_struct *work)
3362{
3363 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3364 struct ath10k_peer *peer;
3365 struct ieee80211_hdr *hdr;
3366 struct sk_buff *skb;
3367 const u8 *peer_addr;
3368 int vdev_id;
3369 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003370 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003371 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003372
3373 /* FW requirement: We must create a peer before FW will send out
3374 * an offchannel frame. Otherwise the frame will be stuck and
3375 * never transmitted. We delete the peer upon tx completion.
3376 * It is unlikely that a peer for offchannel tx will already be
3377 * present. However it may be in some rare cases so account for that.
3378 * Otherwise we might remove a legitimate peer and break stuff. */
3379
3380 for (;;) {
3381 skb = skb_dequeue(&ar->offchan_tx_queue);
3382 if (!skb)
3383 break;
3384
3385 mutex_lock(&ar->conf_mutex);
3386
Michal Kazior7aa7a722014-08-25 12:09:38 +02003387 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003388 skb);
3389
3390 hdr = (struct ieee80211_hdr *)skb->data;
3391 peer_addr = ieee80211_get_DA(hdr);
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003392 vdev_id = ATH10K_SKB_CB(skb)->vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003393
3394 spin_lock_bh(&ar->data_lock);
3395 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3396 spin_unlock_bh(&ar->data_lock);
3397
3398 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003399 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003400 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003401 peer_addr, vdev_id);
3402
3403 if (!peer) {
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003404 ret = ath10k_peer_create(ar, vdev_id, peer_addr,
3405 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003406 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003407 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003408 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003409 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003410 }
3411
3412 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003413 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003414 ar->offchan_tx_skb = skb;
3415 spin_unlock_bh(&ar->data_lock);
3416
Michal Kaziord740d8f2015-03-30 09:51:51 +03003417 ath10k_mac_tx(ar, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003418
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003419 time_left =
3420 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3421 if (time_left == 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003422 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003423 skb);
3424
Michal Kazioradaeed72015-08-05 12:15:23 +02003425 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003426 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3427 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003428 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003429 peer_addr, vdev_id, ret);
3430 }
3431
3432 mutex_unlock(&ar->conf_mutex);
3433 }
3434}
3435
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003436void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3437{
3438 struct sk_buff *skb;
3439
3440 for (;;) {
3441 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3442 if (!skb)
3443 break;
3444
3445 ieee80211_free_txskb(ar->hw, skb);
3446 }
3447}
3448
3449void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3450{
3451 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3452 struct sk_buff *skb;
3453 int ret;
3454
3455 for (;;) {
3456 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3457 if (!skb)
3458 break;
3459
3460 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003461 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003462 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003463 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003464 ieee80211_free_txskb(ar->hw, skb);
3465 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003466 }
3467}
3468
Kalle Valo5e3dd152013-06-12 20:52:10 +03003469/************/
3470/* Scanning */
3471/************/
3472
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003473void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003474{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003475 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003476
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003477 switch (ar->scan.state) {
3478 case ATH10K_SCAN_IDLE:
3479 break;
3480 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01003481 case ATH10K_SCAN_ABORTING:
3482 if (!ar->scan.is_roc)
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003483 ieee80211_scan_completed(ar->hw,
3484 (ar->scan.state ==
3485 ATH10K_SCAN_ABORTING));
Michal Kaziord710e752015-07-09 13:08:36 +02003486 else if (ar->scan.roc_notify)
3487 ieee80211_remain_on_channel_expired(ar->hw);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003488 /* fall through */
3489 case ATH10K_SCAN_STARTING:
3490 ar->scan.state = ATH10K_SCAN_IDLE;
3491 ar->scan_channel = NULL;
3492 ath10k_offchan_tx_purge(ar);
3493 cancel_delayed_work(&ar->scan.timeout);
3494 complete_all(&ar->scan.completed);
3495 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003496 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003497}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003498
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003499void ath10k_scan_finish(struct ath10k *ar)
3500{
3501 spin_lock_bh(&ar->data_lock);
3502 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003503 spin_unlock_bh(&ar->data_lock);
3504}
3505
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003506static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003507{
3508 struct wmi_stop_scan_arg arg = {
3509 .req_id = 1, /* FIXME */
3510 .req_type = WMI_SCAN_STOP_ONE,
3511 .u.scan_id = ATH10K_SCAN_ID,
3512 };
3513 int ret;
3514
3515 lockdep_assert_held(&ar->conf_mutex);
3516
Kalle Valo5e3dd152013-06-12 20:52:10 +03003517 ret = ath10k_wmi_stop_scan(ar, &arg);
3518 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003519 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003520 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003521 }
3522
Kalle Valo5e3dd152013-06-12 20:52:10 +03003523 ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003524 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003525 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003526 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003527 } else if (ret > 0) {
3528 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003529 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003530
3531out:
3532 /* Scan state should be updated upon scan completion but in case
3533 * firmware fails to deliver the event (for whatever reason) it is
3534 * desired to clean up scan state anyway. Firmware may have just
3535 * dropped the scan completion event delivery due to transport pipe
3536 * being overflown with data and/or it can recover on its own before
3537 * next scan request is submitted.
3538 */
3539 spin_lock_bh(&ar->data_lock);
3540 if (ar->scan.state != ATH10K_SCAN_IDLE)
3541 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003542 spin_unlock_bh(&ar->data_lock);
3543
3544 return ret;
3545}
3546
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003547static void ath10k_scan_abort(struct ath10k *ar)
3548{
3549 int ret;
3550
3551 lockdep_assert_held(&ar->conf_mutex);
3552
3553 spin_lock_bh(&ar->data_lock);
3554
3555 switch (ar->scan.state) {
3556 case ATH10K_SCAN_IDLE:
3557 /* This can happen if timeout worker kicked in and called
3558 * abortion while scan completion was being processed.
3559 */
3560 break;
3561 case ATH10K_SCAN_STARTING:
3562 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02003563 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003564 ath10k_scan_state_str(ar->scan.state),
3565 ar->scan.state);
3566 break;
3567 case ATH10K_SCAN_RUNNING:
3568 ar->scan.state = ATH10K_SCAN_ABORTING;
3569 spin_unlock_bh(&ar->data_lock);
3570
3571 ret = ath10k_scan_stop(ar);
3572 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003573 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003574
3575 spin_lock_bh(&ar->data_lock);
3576 break;
3577 }
3578
3579 spin_unlock_bh(&ar->data_lock);
3580}
3581
3582void ath10k_scan_timeout_work(struct work_struct *work)
3583{
3584 struct ath10k *ar = container_of(work, struct ath10k,
3585 scan.timeout.work);
3586
3587 mutex_lock(&ar->conf_mutex);
3588 ath10k_scan_abort(ar);
3589 mutex_unlock(&ar->conf_mutex);
3590}
3591
Kalle Valo5e3dd152013-06-12 20:52:10 +03003592static int ath10k_start_scan(struct ath10k *ar,
3593 const struct wmi_start_scan_arg *arg)
3594{
3595 int ret;
3596
3597 lockdep_assert_held(&ar->conf_mutex);
3598
3599 ret = ath10k_wmi_start_scan(ar, arg);
3600 if (ret)
3601 return ret;
3602
Kalle Valo5e3dd152013-06-12 20:52:10 +03003603 ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ);
3604 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003605 ret = ath10k_scan_stop(ar);
3606 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003607 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003608
3609 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003610 }
3611
Ben Greear2f9eec02015-02-15 16:50:38 +02003612 /* If we failed to start the scan, return error code at
3613 * this point. This is probably due to some issue in the
3614 * firmware, but no need to wedge the driver due to that...
3615 */
3616 spin_lock_bh(&ar->data_lock);
3617 if (ar->scan.state == ATH10K_SCAN_IDLE) {
3618 spin_unlock_bh(&ar->data_lock);
3619 return -EINVAL;
3620 }
3621 spin_unlock_bh(&ar->data_lock);
3622
Kalle Valo5e3dd152013-06-12 20:52:10 +03003623 return 0;
3624}
3625
3626/**********************/
3627/* mac80211 callbacks */
3628/**********************/
3629
3630static void ath10k_tx(struct ieee80211_hw *hw,
3631 struct ieee80211_tx_control *control,
3632 struct sk_buff *skb)
3633{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003634 struct ath10k *ar = hw->priv;
Michal Kazior4b604552014-07-21 21:03:09 +03003635 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3636 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003637 struct ieee80211_sta *sta = control->sta;
Michal Kazior4b604552014-07-21 21:03:09 +03003638 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003639 __le16 fc = hdr->frame_control;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003640
3641 /* We should disable CCK RATE due to P2P */
3642 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003643 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003644
Michal Kazior4b604552014-07-21 21:03:09 +03003645 ATH10K_SKB_CB(skb)->htt.is_offchan = false;
Michal Kazior6fcafef2015-03-30 09:51:51 +03003646 ATH10K_SKB_CB(skb)->htt.freq = 0;
Michal Kazior4b604552014-07-21 21:03:09 +03003647 ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
David Liuccec9032015-07-24 20:25:32 +03003648 ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
Michal Kazior2b37c292014-09-02 11:00:22 +03003649 ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003650 ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003651 ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003652
Michal Kaziord740d8f2015-03-30 09:51:51 +03003653 switch (ATH10K_SKB_CB(skb)->txmode) {
3654 case ATH10K_HW_TXRX_MGMT:
3655 case ATH10K_HW_TXRX_NATIVE_WIFI:
Michal Kazior4b604552014-07-21 21:03:09 +03003656 ath10k_tx_h_nwifi(hw, skb);
Michal Kazior4b604552014-07-21 21:03:09 +03003657 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3658 ath10k_tx_h_seq_no(vif, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003659 break;
3660 case ATH10K_HW_TXRX_ETHERNET:
3661 ath10k_tx_h_8023(skb);
3662 break;
3663 case ATH10K_HW_TXRX_RAW:
David Liuccec9032015-07-24 20:25:32 +03003664 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3665 WARN_ON_ONCE(1);
3666 ieee80211_free_txskb(hw, skb);
3667 return;
3668 }
Michal Kaziorcf84bd42013-07-16 11:04:54 +02003669 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003670
Kalle Valo5e3dd152013-06-12 20:52:10 +03003671 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3672 spin_lock_bh(&ar->data_lock);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003673 ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003674 ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003675 spin_unlock_bh(&ar->data_lock);
3676
Michal Kazior8d6d3622014-11-24 14:58:31 +01003677 if (ath10k_mac_need_offchan_tx_work(ar)) {
3678 ATH10K_SKB_CB(skb)->htt.freq = 0;
3679 ATH10K_SKB_CB(skb)->htt.is_offchan = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003680
Michal Kazior8d6d3622014-11-24 14:58:31 +01003681 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
3682 skb);
3683
3684 skb_queue_tail(&ar->offchan_tx_queue, skb);
3685 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3686 return;
3687 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003688 }
3689
Michal Kaziord740d8f2015-03-30 09:51:51 +03003690 ath10k_mac_tx(ar, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003691}
3692
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003693/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01003694void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003695{
3696 /* make sure rcu-protected mac80211 tx path itself is drained */
3697 synchronize_net();
3698
3699 ath10k_offchan_tx_purge(ar);
3700 ath10k_mgmt_over_wmi_tx_purge(ar);
3701
3702 cancel_work_sync(&ar->offchan_tx_work);
3703 cancel_work_sync(&ar->wmi_mgmt_tx_work);
3704}
3705
Michal Kazioraffd3212013-07-16 09:54:35 +02003706void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02003707{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03003708 struct ath10k_vif *arvif;
3709
Michal Kazior818bdd12013-07-16 09:38:57 +02003710 lockdep_assert_held(&ar->conf_mutex);
3711
Michal Kazior19337472014-08-28 12:58:16 +02003712 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
3713 ar->filter_flags = 0;
3714 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00003715 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02003716
3717 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03003718 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02003719
3720 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00003721 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03003722
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003723 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02003724 ath10k_peer_cleanup_all(ar);
3725 ath10k_core_stop(ar);
3726 ath10k_hif_power_down(ar);
3727
3728 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03003729 list_for_each_entry(arvif, &ar->arvifs, list)
3730 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02003731 spin_unlock_bh(&ar->data_lock);
3732}
3733
Ben Greear46acf7b2014-05-16 17:15:38 +03003734static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
3735{
3736 struct ath10k *ar = hw->priv;
3737
3738 mutex_lock(&ar->conf_mutex);
3739
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05303740 *tx_ant = ar->cfg_tx_chainmask;
3741 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03003742
3743 mutex_unlock(&ar->conf_mutex);
3744
3745 return 0;
3746}
3747
Ben Greear5572a952014-11-24 16:22:10 +02003748static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
3749{
3750 /* It is not clear that allowing gaps in chainmask
3751 * is helpful. Probably it will not do what user
3752 * is hoping for, so warn in that case.
3753 */
3754 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
3755 return;
3756
3757 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
3758 dbg, cm);
3759}
3760
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05303761static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
3762{
3763 int nsts = ar->vht_cap_info;
3764
3765 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
3766 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
3767
3768 /* If firmware does not deliver to host number of space-time
3769 * streams supported, assume it support up to 4 BF STS and return
3770 * the value for VHT CAP: nsts-1)
3771 */
3772 if (nsts == 0)
3773 return 3;
3774
3775 return nsts;
3776}
3777
3778static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
3779{
3780 int sound_dim = ar->vht_cap_info;
3781
3782 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
3783 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
3784
3785 /* If the sounding dimension is not advertised by the firmware,
3786 * let's use a default value of 1
3787 */
3788 if (sound_dim == 0)
3789 return 1;
3790
3791 return sound_dim;
3792}
3793
3794static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
3795{
3796 struct ieee80211_sta_vht_cap vht_cap = {0};
3797 u16 mcs_map;
3798 u32 val;
3799 int i;
3800
3801 vht_cap.vht_supported = 1;
3802 vht_cap.cap = ar->vht_cap_info;
3803
3804 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
3805 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
3806 val = ath10k_mac_get_vht_cap_bf_sts(ar);
3807 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
3808 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
3809
3810 vht_cap.cap |= val;
3811 }
3812
3813 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
3814 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
3815 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
3816 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
3817 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
3818
3819 vht_cap.cap |= val;
3820 }
3821
3822 mcs_map = 0;
3823 for (i = 0; i < 8; i++) {
3824 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
3825 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
3826 else
3827 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
3828 }
3829
3830 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
3831 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
3832
3833 return vht_cap;
3834}
3835
3836static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
3837{
3838 int i;
3839 struct ieee80211_sta_ht_cap ht_cap = {0};
3840
3841 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
3842 return ht_cap;
3843
3844 ht_cap.ht_supported = 1;
3845 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
3846 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
3847 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
3848 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
3849 ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT;
3850
3851 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
3852 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
3853
3854 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
3855 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
3856
3857 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
3858 u32 smps;
3859
3860 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
3861 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
3862
3863 ht_cap.cap |= smps;
3864 }
3865
3866 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC)
3867 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
3868
3869 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
3870 u32 stbc;
3871
3872 stbc = ar->ht_cap_info;
3873 stbc &= WMI_HT_CAP_RX_STBC;
3874 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
3875 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
3876 stbc &= IEEE80211_HT_CAP_RX_STBC;
3877
3878 ht_cap.cap |= stbc;
3879 }
3880
3881 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
3882 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
3883
3884 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
3885 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
3886
3887 /* max AMSDU is implicitly taken from vht_cap_info */
3888 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
3889 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
3890
3891 for (i = 0; i < ar->num_rf_chains; i++) {
3892 if (ar->cfg_rx_chainmask & BIT(i))
3893 ht_cap.mcs.rx_mask[i] = 0xFF;
3894 }
3895
3896 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
3897
3898 return ht_cap;
3899}
3900
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05303901static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
3902{
3903 struct ieee80211_supported_band *band;
3904 struct ieee80211_sta_vht_cap vht_cap;
3905 struct ieee80211_sta_ht_cap ht_cap;
3906
3907 ht_cap = ath10k_get_ht_cap(ar);
3908 vht_cap = ath10k_create_vht_cap(ar);
3909
3910 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
3911 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
3912 band->ht_cap = ht_cap;
3913
3914 /* Enable the VHT support at 2.4 GHz */
3915 band->vht_cap = vht_cap;
3916 }
3917 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
3918 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
3919 band->ht_cap = ht_cap;
3920 band->vht_cap = vht_cap;
3921 }
3922}
3923
Ben Greear46acf7b2014-05-16 17:15:38 +03003924static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
3925{
3926 int ret;
3927
3928 lockdep_assert_held(&ar->conf_mutex);
3929
Ben Greear5572a952014-11-24 16:22:10 +02003930 ath10k_check_chain_mask(ar, tx_ant, "tx");
3931 ath10k_check_chain_mask(ar, rx_ant, "rx");
3932
Ben Greear46acf7b2014-05-16 17:15:38 +03003933 ar->cfg_tx_chainmask = tx_ant;
3934 ar->cfg_rx_chainmask = rx_ant;
3935
3936 if ((ar->state != ATH10K_STATE_ON) &&
3937 (ar->state != ATH10K_STATE_RESTARTED))
3938 return 0;
3939
3940 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
3941 tx_ant);
3942 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003943 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03003944 ret, tx_ant);
3945 return ret;
3946 }
3947
3948 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
3949 rx_ant);
3950 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003951 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03003952 ret, rx_ant);
3953 return ret;
3954 }
3955
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05303956 /* Reload HT/VHT capability */
3957 ath10k_mac_setup_ht_vht_cap(ar);
3958
Ben Greear46acf7b2014-05-16 17:15:38 +03003959 return 0;
3960}
3961
3962static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
3963{
3964 struct ath10k *ar = hw->priv;
3965 int ret;
3966
3967 mutex_lock(&ar->conf_mutex);
3968 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
3969 mutex_unlock(&ar->conf_mutex);
3970 return ret;
3971}
3972
Kalle Valo5e3dd152013-06-12 20:52:10 +03003973static int ath10k_start(struct ieee80211_hw *hw)
3974{
3975 struct ath10k *ar = hw->priv;
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03003976 u32 burst_enable;
Michal Kazior818bdd12013-07-16 09:38:57 +02003977 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003978
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003979 /*
3980 * This makes sense only when restarting hw. It is harmless to call
3981 * uncoditionally. This is necessary to make sure no HTT/WMI tx
3982 * commands will be submitted while restarting.
3983 */
3984 ath10k_drain_tx(ar);
3985
Michal Kazior548db542013-07-05 16:15:15 +03003986 mutex_lock(&ar->conf_mutex);
3987
Michal Kaziorc5058f52014-05-26 12:46:03 +03003988 switch (ar->state) {
3989 case ATH10K_STATE_OFF:
3990 ar->state = ATH10K_STATE_ON;
3991 break;
3992 case ATH10K_STATE_RESTARTING:
3993 ath10k_halt(ar);
3994 ar->state = ATH10K_STATE_RESTARTED;
3995 break;
3996 case ATH10K_STATE_ON:
3997 case ATH10K_STATE_RESTARTED:
3998 case ATH10K_STATE_WEDGED:
3999 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004000 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004001 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004002 case ATH10K_STATE_UTF:
4003 ret = -EBUSY;
4004 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004005 }
4006
4007 ret = ath10k_hif_power_up(ar);
4008 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004009 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004010 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004011 }
4012
Kalle Valo43d2a302014-09-10 18:23:30 +03004013 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02004014 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004015 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004016 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004017 }
4018
Bartosz Markowski226a3392013-09-26 17:47:16 +02004019 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004020 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004021 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004022 goto err_core_stop;
4023 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004024
Michal Kaziorc4dd0d02013-11-13 11:05:10 +01004025 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004026 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004027 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004028 goto err_core_stop;
4029 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004030
Michal Kaziorcf327842015-03-31 10:26:25 +00004031 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4032 ret = ath10k_wmi_adaptive_qcs(ar, true);
4033 if (ret) {
4034 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4035 ret);
4036 goto err_core_stop;
4037 }
4038 }
4039
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004040 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
4041 burst_enable = ar->wmi.pdev_param->burst_enable;
4042 ret = ath10k_wmi_pdev_set_param(ar, burst_enable, 0);
4043 if (ret) {
4044 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4045 goto err_core_stop;
4046 }
4047 }
4048
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304049 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7b2014-05-16 17:15:38 +03004050
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004051 /*
4052 * By default FW set ARP frames ac to voice (6). In that case ARP
4053 * exchange is not working properly for UAPSD enabled AP. ARP requests
4054 * which arrives with access category 0 are processed by network stack
4055 * and send back with access category 0, but FW changes access category
4056 * to 6. Set ARP frames access category to best effort (0) solves
4057 * this problem.
4058 */
4059
4060 ret = ath10k_wmi_pdev_set_param(ar,
4061 ar->wmi.pdev_param->arp_ac_override, 0);
4062 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004063 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004064 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004065 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004066 }
4067
Maharaja62f77f02015-10-21 11:49:18 +03004068 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
4069 ar->fw_features)) {
4070 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4071 WMI_CCA_DETECT_LEVEL_AUTO,
4072 WMI_CCA_DETECT_MARGIN_AUTO);
4073 if (ret) {
4074 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4075 ret);
4076 goto err_core_stop;
4077 }
4078 }
4079
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304080 ret = ath10k_wmi_pdev_set_param(ar,
4081 ar->wmi.pdev_param->ani_enable, 1);
4082 if (ret) {
4083 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4084 ret);
4085 goto err_core_stop;
4086 }
4087
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304088 ar->ani_enabled = true;
4089
Michal Kaziord6500972014-04-08 09:56:09 +03004090 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004091 ath10k_regd_update(ar);
4092
Simon Wunderlich855aed12014-08-02 09:12:54 +03004093 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304094 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004095
Michal Kaziorae254432014-05-26 12:46:02 +03004096 mutex_unlock(&ar->conf_mutex);
4097 return 0;
4098
4099err_core_stop:
4100 ath10k_core_stop(ar);
4101
4102err_power_down:
4103 ath10k_hif_power_down(ar);
4104
4105err_off:
4106 ar->state = ATH10K_STATE_OFF;
4107
4108err:
Michal Kazior548db542013-07-05 16:15:15 +03004109 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004110 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004111}
4112
4113static void ath10k_stop(struct ieee80211_hw *hw)
4114{
4115 struct ath10k *ar = hw->priv;
4116
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004117 ath10k_drain_tx(ar);
4118
Michal Kazior548db542013-07-05 16:15:15 +03004119 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004120 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004121 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004122 ar->state = ATH10K_STATE_OFF;
4123 }
Michal Kazior548db542013-07-05 16:15:15 +03004124 mutex_unlock(&ar->conf_mutex);
4125
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004126 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004127 cancel_work_sync(&ar->restart_work);
4128}
4129
Michal Kaziorad088bf2013-10-16 15:44:46 +03004130static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004131{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004132 struct ath10k_vif *arvif;
4133 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004134
4135 lockdep_assert_held(&ar->conf_mutex);
4136
Michal Kaziorad088bf2013-10-16 15:44:46 +03004137 list_for_each_entry(arvif, &ar->arvifs, list) {
4138 ret = ath10k_mac_vif_setup_ps(arvif);
4139 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004140 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004141 break;
4142 }
4143 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004144
Michal Kaziorad088bf2013-10-16 15:44:46 +03004145 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004146}
4147
Michal Kazior7d9d5582014-10-21 10:40:15 +03004148static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4149{
4150 int ret;
4151 u32 param;
4152
4153 lockdep_assert_held(&ar->conf_mutex);
4154
4155 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4156
4157 param = ar->wmi.pdev_param->txpower_limit2g;
4158 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4159 if (ret) {
4160 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4161 txpower, ret);
4162 return ret;
4163 }
4164
4165 param = ar->wmi.pdev_param->txpower_limit5g;
4166 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4167 if (ret) {
4168 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4169 txpower, ret);
4170 return ret;
4171 }
4172
4173 return 0;
4174}
4175
4176static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4177{
4178 struct ath10k_vif *arvif;
4179 int ret, txpower = -1;
4180
4181 lockdep_assert_held(&ar->conf_mutex);
4182
4183 list_for_each_entry(arvif, &ar->arvifs, list) {
4184 WARN_ON(arvif->txpower < 0);
4185
4186 if (txpower == -1)
4187 txpower = arvif->txpower;
4188 else
4189 txpower = min(txpower, arvif->txpower);
4190 }
4191
4192 if (WARN_ON(txpower == -1))
4193 return -EINVAL;
4194
4195 ret = ath10k_mac_txpower_setup(ar, txpower);
4196 if (ret) {
4197 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4198 txpower, ret);
4199 return ret;
4200 }
4201
4202 return 0;
4203}
4204
Kalle Valo5e3dd152013-06-12 20:52:10 +03004205static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4206{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004207 struct ath10k *ar = hw->priv;
4208 struct ieee80211_conf *conf = &hw->conf;
4209 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004210
4211 mutex_lock(&ar->conf_mutex);
4212
Michal Kazioraffd3212013-07-16 09:54:35 +02004213 if (changed & IEEE80211_CONF_CHANGE_PS)
4214 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004215
4216 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004217 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4218 ret = ath10k_monitor_recalc(ar);
4219 if (ret)
4220 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004221 }
4222
4223 mutex_unlock(&ar->conf_mutex);
4224 return ret;
4225}
4226
Ben Greear5572a952014-11-24 16:22:10 +02004227static u32 get_nss_from_chainmask(u16 chain_mask)
4228{
4229 if ((chain_mask & 0x15) == 0x15)
4230 return 4;
4231 else if ((chain_mask & 0x7) == 0x7)
4232 return 3;
4233 else if ((chain_mask & 0x3) == 0x3)
4234 return 2;
4235 return 1;
4236}
4237
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304238static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4239{
4240 u32 value = 0;
4241 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004242 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004243 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304244
4245 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4246 return 0;
4247
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004248 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304249 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4250 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004251 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304252
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004253 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304254 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4255 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004256 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304257
4258 if (!value)
4259 return 0;
4260
4261 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4262 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4263
4264 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4265 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4266 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4267
4268 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4269 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4270
4271 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4272 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4273 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4274
4275 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4276 ar->wmi.vdev_param->txbf, value);
4277}
4278
Kalle Valo5e3dd152013-06-12 20:52:10 +03004279/*
4280 * TODO:
4281 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4282 * because we will send mgmt frames without CCK. This requirement
4283 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4284 * in the TX packet.
4285 */
4286static int ath10k_add_interface(struct ieee80211_hw *hw,
4287 struct ieee80211_vif *vif)
4288{
4289 struct ath10k *ar = hw->priv;
4290 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4291 enum wmi_sta_powersave_param param;
4292 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004293 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004294 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004295 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004296 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004297
Johannes Berg848955c2014-11-11 12:48:42 +01004298 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4299
Kalle Valo5e3dd152013-06-12 20:52:10 +03004300 mutex_lock(&ar->conf_mutex);
4301
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004302 memset(arvif, 0, sizeof(*arvif));
4303
Kalle Valo5e3dd152013-06-12 20:52:10 +03004304 arvif->ar = ar;
4305 arvif->vif = vif;
4306
Ben Greeare63b33f2013-10-22 14:54:14 -07004307 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004308 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004309 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4310 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004311
Michal Kazior45c9abc2015-04-21 20:42:58 +03004312 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4313 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4314 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4315 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4316 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4317 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4318 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004319
Michal Kaziore04cafb2015-08-05 12:15:24 +02004320 if (ar->num_peers >= ar->max_num_peers) {
4321 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004322 ret = -ENOBUFS;
4323 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004324 }
4325
Ben Greeara9aefb32014-08-12 11:02:19 +03004326 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004327 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004328 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03004329 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004330 }
Ben Greear16c11172014-09-23 14:17:16 -07004331 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004332
Ben Greear16c11172014-09-23 14:17:16 -07004333 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4334 bit, ar->free_vdev_map);
4335
4336 arvif->vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004337 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004338
Kalle Valo5e3dd152013-06-12 20:52:10 +03004339 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004340 case NL80211_IFTYPE_P2P_DEVICE:
4341 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4342 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
4343 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004344 case NL80211_IFTYPE_UNSPECIFIED:
4345 case NL80211_IFTYPE_STATION:
4346 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4347 if (vif->p2p)
4348 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT;
4349 break;
4350 case NL80211_IFTYPE_ADHOC:
4351 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4352 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004353 case NL80211_IFTYPE_MESH_POINT:
4354 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4355 ret = -EINVAL;
4356 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
4357 goto err;
4358 }
4359 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4360 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004361 case NL80211_IFTYPE_AP:
4362 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4363
4364 if (vif->p2p)
4365 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO;
4366 break;
4367 case NL80211_IFTYPE_MONITOR:
4368 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4369 break;
4370 default:
4371 WARN_ON(1);
4372 break;
4373 }
4374
Michal Kazior96d828d2015-03-31 10:26:23 +00004375 /* Using vdev_id as queue number will make it very easy to do per-vif
4376 * tx queue locking. This shouldn't wrap due to interface combinations
4377 * but do a modulo for correctness sake and prevent using offchannel tx
4378 * queues for regular vif tx.
4379 */
4380 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4381 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4382 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4383
Michal Kazior64badcb2014-09-18 11:18:02 +03004384 /* Some firmware revisions don't wait for beacon tx completion before
4385 * sending another SWBA event. This could lead to hardware using old
4386 * (freed) beacon data in some cases, e.g. tx credit starvation
4387 * combined with missed TBTT. This is very very rare.
4388 *
4389 * On non-IOMMU-enabled hosts this could be a possible security issue
4390 * because hw could beacon some random data on the air. On
4391 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4392 * device would crash.
4393 *
4394 * Since there are no beacon tx completions (implicit nor explicit)
4395 * propagated to host the only workaround for this is to allocate a
4396 * DMA-coherent buffer for a lifetime of a vif and use it for all
4397 * beacon tx commands. Worst case for this approach is some beacons may
4398 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4399 */
4400 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004401 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03004402 vif->type == NL80211_IFTYPE_AP) {
4403 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4404 IEEE80211_MAX_FRAME_LEN,
4405 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304406 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004407 if (!arvif->beacon_buf) {
4408 ret = -ENOMEM;
4409 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4410 ret);
4411 goto err;
4412 }
4413 }
David Liuccec9032015-07-24 20:25:32 +03004414 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
4415 arvif->nohwcrypt = true;
4416
4417 if (arvif->nohwcrypt &&
4418 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4419 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
4420 goto err;
4421 }
Michal Kazior64badcb2014-09-18 11:18:02 +03004422
4423 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4424 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4425 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004426
4427 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4428 arvif->vdev_subtype, vif->addr);
4429 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004430 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004431 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004432 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004433 }
4434
Ben Greear16c11172014-09-23 14:17:16 -07004435 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Michal Kazior05791192013-10-16 15:44:45 +03004436 list_add(&arvif->list, &ar->arvifs);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004437
Michal Kazior46725b152015-01-28 09:57:49 +02004438 /* It makes no sense to have firmware do keepalives. mac80211 already
4439 * takes care of this with idle connection polling.
4440 */
4441 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004442 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02004443 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004444 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004445 goto err_vdev_delete;
4446 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004447
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004448 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004449
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004450 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4451 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004452 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004453 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03004454 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004455 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004456 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004457 goto err_vdev_delete;
4458 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004459
Ben Greear5572a952014-11-24 16:22:10 +02004460 if (ar->cfg_tx_chainmask) {
4461 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
4462
4463 vdev_param = ar->wmi.vdev_param->nss;
4464 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4465 nss);
4466 if (ret) {
4467 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
4468 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
4469 ret);
4470 goto err_vdev_delete;
4471 }
4472 }
4473
Michal Kaziore57e0572015-03-24 13:14:03 +00004474 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4475 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Marek Puzyniak7390ed32015-03-30 09:51:52 +03004476 ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr,
4477 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004478 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00004479 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004480 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004481 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004482 }
Michal Kaziore57e0572015-03-24 13:14:03 +00004483 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01004484
Michal Kaziore57e0572015-03-24 13:14:03 +00004485 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02004486 ret = ath10k_mac_set_kickout(arvif);
4487 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004488 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004489 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02004490 goto err_peer_delete;
4491 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004492 }
4493
4494 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
4495 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
4496 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
4497 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
4498 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004499 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004500 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004501 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004502 goto err_peer_delete;
4503 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004504
Michal Kazior9f9b5742014-12-12 12:41:36 +01004505 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004506 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004507 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004508 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004509 goto err_peer_delete;
4510 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004511
Michal Kazior9f9b5742014-12-12 12:41:36 +01004512 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004513 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004514 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004515 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004516 goto err_peer_delete;
4517 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004518 }
4519
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304520 ret = ath10k_mac_set_txbf_conf(arvif);
4521 if (ret) {
4522 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
4523 arvif->vdev_id, ret);
4524 goto err_peer_delete;
4525 }
4526
Michal Kazior424121c2013-07-22 14:13:31 +02004527 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004528 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004529 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03004530 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004531 goto err_peer_delete;
4532 }
Michal Kazior679c54a2013-07-05 16:15:04 +03004533
Michal Kazior7d9d5582014-10-21 10:40:15 +03004534 arvif->txpower = vif->bss_conf.txpower;
4535 ret = ath10k_mac_txpower_recalc(ar);
4536 if (ret) {
4537 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4538 goto err_peer_delete;
4539 }
4540
Michal Kazior500ff9f2015-03-31 10:26:21 +00004541 if (vif->type == NL80211_IFTYPE_MONITOR) {
4542 ar->monitor_arvif = arvif;
4543 ret = ath10k_monitor_recalc(ar);
4544 if (ret) {
4545 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
4546 goto err_peer_delete;
4547 }
4548 }
4549
Michal Kazior6d2d51e2015-08-07 09:08:21 +02004550 spin_lock_bh(&ar->htt.tx_lock);
4551 if (!ar->tx_paused)
4552 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
4553 spin_unlock_bh(&ar->htt.tx_lock);
4554
Kalle Valo5e3dd152013-06-12 20:52:10 +03004555 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004556 return 0;
4557
4558err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00004559 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4560 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14a2013-10-16 15:44:45 +03004561 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
4562
4563err_vdev_delete:
4564 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07004565 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004566 list_del(&arvif->list);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004567
4568err:
Michal Kazior64badcb2014-09-18 11:18:02 +03004569 if (arvif->beacon_buf) {
4570 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
4571 arvif->beacon_buf, arvif->beacon_paddr);
4572 arvif->beacon_buf = NULL;
4573 }
4574
Michal Kazior9dad14a2013-10-16 15:44:45 +03004575 mutex_unlock(&ar->conf_mutex);
4576
Kalle Valo5e3dd152013-06-12 20:52:10 +03004577 return ret;
4578}
4579
Michal Kaziorb4aa5392015-03-31 10:26:24 +00004580static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
4581{
4582 int i;
4583
4584 for (i = 0; i < BITS_PER_LONG; i++)
4585 ath10k_mac_vif_tx_unlock(arvif, i);
4586}
4587
Kalle Valo5e3dd152013-06-12 20:52:10 +03004588static void ath10k_remove_interface(struct ieee80211_hw *hw,
4589 struct ieee80211_vif *vif)
4590{
4591 struct ath10k *ar = hw->priv;
4592 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4593 int ret;
4594
Michal Kazior81a9a172015-03-05 16:02:17 +02004595 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004596 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02004597
Sujith Manoharan5d011f52014-11-25 11:47:00 +05304598 mutex_lock(&ar->conf_mutex);
4599
Michal Kaziored543882013-09-13 14:16:56 +02004600 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004601 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02004602 spin_unlock_bh(&ar->data_lock);
4603
Simon Wunderlich855aed12014-08-02 09:12:54 +03004604 ret = ath10k_spectral_vif_stop(arvif);
4605 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004606 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03004607 arvif->vdev_id, ret);
4608
Ben Greear16c11172014-09-23 14:17:16 -07004609 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004610 list_del(&arvif->list);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004611
Michal Kaziore57e0572015-03-24 13:14:03 +00004612 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4613 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02004614 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
4615 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004616 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00004617 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004618 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004619
4620 kfree(arvif->u.ap.noa_data);
4621 }
4622
Michal Kazior7aa7a722014-08-25 12:09:38 +02004623 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004624 arvif->vdev_id);
4625
Kalle Valo5e3dd152013-06-12 20:52:10 +03004626 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
4627 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004628 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004629 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004630
Michal Kazior2c512052015-02-15 16:50:40 +02004631 /* Some firmware revisions don't notify host about self-peer removal
4632 * until after associated vdev is deleted.
4633 */
Michal Kaziore57e0572015-03-24 13:14:03 +00004634 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4635 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02004636 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
4637 vif->addr);
4638 if (ret)
4639 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
4640 arvif->vdev_id, ret);
4641
4642 spin_lock_bh(&ar->data_lock);
4643 ar->num_peers--;
4644 spin_unlock_bh(&ar->data_lock);
4645 }
4646
Kalle Valo5e3dd152013-06-12 20:52:10 +03004647 ath10k_peer_cleanup(ar, arvif->vdev_id);
4648
Michal Kazior500ff9f2015-03-31 10:26:21 +00004649 if (vif->type == NL80211_IFTYPE_MONITOR) {
4650 ar->monitor_arvif = NULL;
4651 ret = ath10k_monitor_recalc(ar);
4652 if (ret)
4653 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
4654 }
4655
Michal Kaziorb4aa5392015-03-31 10:26:24 +00004656 spin_lock_bh(&ar->htt.tx_lock);
4657 ath10k_mac_vif_tx_unlock_all(arvif);
4658 spin_unlock_bh(&ar->htt.tx_lock);
4659
Kalle Valo5e3dd152013-06-12 20:52:10 +03004660 mutex_unlock(&ar->conf_mutex);
4661}
4662
4663/*
4664 * FIXME: Has to be verified.
4665 */
4666#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02004667 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03004668 FIF_CONTROL | \
4669 FIF_PSPOLL | \
4670 FIF_OTHER_BSS | \
4671 FIF_BCN_PRBRESP_PROMISC | \
4672 FIF_PROBE_REQ | \
4673 FIF_FCSFAIL)
4674
4675static void ath10k_configure_filter(struct ieee80211_hw *hw,
4676 unsigned int changed_flags,
4677 unsigned int *total_flags,
4678 u64 multicast)
4679{
4680 struct ath10k *ar = hw->priv;
4681 int ret;
4682
4683 mutex_lock(&ar->conf_mutex);
4684
4685 changed_flags &= SUPPORTED_FILTERS;
4686 *total_flags &= SUPPORTED_FILTERS;
4687 ar->filter_flags = *total_flags;
4688
Michal Kazior19337472014-08-28 12:58:16 +02004689 ret = ath10k_monitor_recalc(ar);
4690 if (ret)
4691 ath10k_warn(ar, "failed to recalc montior: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004692
4693 mutex_unlock(&ar->conf_mutex);
4694}
4695
4696static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
4697 struct ieee80211_vif *vif,
4698 struct ieee80211_bss_conf *info,
4699 u32 changed)
4700{
4701 struct ath10k *ar = hw->priv;
4702 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4703 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03004704 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004705
4706 mutex_lock(&ar->conf_mutex);
4707
4708 if (changed & BSS_CHANGED_IBSS)
4709 ath10k_control_ibss(arvif, info, vif->addr);
4710
4711 if (changed & BSS_CHANGED_BEACON_INT) {
4712 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004713 vdev_param = ar->wmi.vdev_param->beacon_interval;
4714 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004715 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02004716 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004717 "mac vdev %d beacon_interval %d\n",
4718 arvif->vdev_id, arvif->beacon_interval);
4719
Kalle Valo5e3dd152013-06-12 20:52:10 +03004720 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004721 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004722 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004723 }
4724
4725 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004726 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004727 "vdev %d set beacon tx mode to staggered\n",
4728 arvif->vdev_id);
4729
Bartosz Markowski226a3392013-09-26 17:47:16 +02004730 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
4731 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004732 WMI_BEACON_STAGGERED_MODE);
4733 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004734 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004735 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02004736
4737 ret = ath10k_mac_setup_bcn_tmpl(arvif);
4738 if (ret)
4739 ath10k_warn(ar, "failed to update beacon template: %d\n",
4740 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004741
4742 if (ieee80211_vif_is_mesh(vif)) {
4743 /* mesh doesn't use SSID but firmware needs it */
4744 strncpy(arvif->u.ap.ssid, "mesh",
4745 sizeof(arvif->u.ap.ssid));
4746 arvif->u.ap.ssid_len = 4;
4747 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004748 }
4749
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02004750 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
4751 ret = ath10k_mac_setup_prb_tmpl(arvif);
4752 if (ret)
4753 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
4754 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004755 }
4756
Michal Kaziorba2479f2015-01-24 12:14:51 +02004757 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004758 arvif->dtim_period = info->dtim_period;
4759
Michal Kazior7aa7a722014-08-25 12:09:38 +02004760 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004761 "mac vdev %d dtim_period %d\n",
4762 arvif->vdev_id, arvif->dtim_period);
4763
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004764 vdev_param = ar->wmi.vdev_param->dtim_period;
4765 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004766 arvif->dtim_period);
4767 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004768 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004769 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004770 }
4771
4772 if (changed & BSS_CHANGED_SSID &&
4773 vif->type == NL80211_IFTYPE_AP) {
4774 arvif->u.ap.ssid_len = info->ssid_len;
4775 if (info->ssid_len)
4776 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
4777 arvif->u.ap.hidden_ssid = info->hidden_ssid;
4778 }
4779
Michal Kazior077efc82014-10-21 10:10:29 +03004780 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
4781 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004782
4783 if (changed & BSS_CHANGED_BEACON_ENABLED)
4784 ath10k_control_beaconing(arvif, info);
4785
4786 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004787 arvif->use_cts_prot = info->use_cts_prot;
Michal Kazior7aa7a722014-08-25 12:09:38 +02004788 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004789 arvif->vdev_id, info->use_cts_prot);
Kalle Valo60c3daa2013-09-08 17:56:07 +03004790
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004791 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004792 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004793 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004794 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01004795
4796 vdev_param = ar->wmi.vdev_param->protection_mode;
4797 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4798 info->use_cts_prot ? 1 : 0);
4799 if (ret)
4800 ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
Kalle Valo617b0f42015-10-05 17:56:35 +03004801 info->use_cts_prot, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004802 }
4803
4804 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004805 if (info->use_short_slot)
4806 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
4807
4808 else
4809 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
4810
Michal Kazior7aa7a722014-08-25 12:09:38 +02004811 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004812 arvif->vdev_id, slottime);
4813
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004814 vdev_param = ar->wmi.vdev_param->slot_time;
4815 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004816 slottime);
4817 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004818 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004819 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004820 }
4821
4822 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004823 if (info->use_short_preamble)
4824 preamble = WMI_VDEV_PREAMBLE_SHORT;
4825 else
4826 preamble = WMI_VDEV_PREAMBLE_LONG;
4827
Michal Kazior7aa7a722014-08-25 12:09:38 +02004828 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004829 "mac vdev %d preamble %dn",
4830 arvif->vdev_id, preamble);
4831
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004832 vdev_param = ar->wmi.vdev_param->preamble;
4833 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004834 preamble);
4835 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004836 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004837 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004838 }
4839
4840 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02004841 if (info->assoc) {
4842 /* Workaround: Make sure monitor vdev is not running
4843 * when associating to prevent some firmware revisions
4844 * (e.g. 10.1 and 10.2) from crashing.
4845 */
4846 if (ar->monitor_started)
4847 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004848 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02004849 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03004850 } else {
4851 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02004852 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004853 }
4854
Michal Kazior7d9d5582014-10-21 10:40:15 +03004855 if (changed & BSS_CHANGED_TXPOWER) {
4856 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
4857 arvif->vdev_id, info->txpower);
4858
4859 arvif->txpower = info->txpower;
4860 ret = ath10k_mac_txpower_recalc(ar);
4861 if (ret)
4862 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4863 }
4864
Michal Kaziorbf14e652014-12-12 12:41:38 +01004865 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01004866 arvif->ps = vif->bss_conf.ps;
4867
4868 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01004869 if (ret)
4870 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
4871 arvif->vdev_id, ret);
4872 }
4873
Kalle Valo5e3dd152013-06-12 20:52:10 +03004874 mutex_unlock(&ar->conf_mutex);
4875}
4876
4877static int ath10k_hw_scan(struct ieee80211_hw *hw,
4878 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02004879 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004880{
4881 struct ath10k *ar = hw->priv;
4882 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02004883 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004884 struct wmi_start_scan_arg arg;
4885 int ret = 0;
4886 int i;
4887
4888 mutex_lock(&ar->conf_mutex);
4889
4890 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004891 switch (ar->scan.state) {
4892 case ATH10K_SCAN_IDLE:
4893 reinit_completion(&ar->scan.started);
4894 reinit_completion(&ar->scan.completed);
4895 ar->scan.state = ATH10K_SCAN_STARTING;
4896 ar->scan.is_roc = false;
4897 ar->scan.vdev_id = arvif->vdev_id;
4898 ret = 0;
4899 break;
4900 case ATH10K_SCAN_STARTING:
4901 case ATH10K_SCAN_RUNNING:
4902 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03004903 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004904 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004905 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004906 spin_unlock_bh(&ar->data_lock);
4907
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004908 if (ret)
4909 goto exit;
4910
Kalle Valo5e3dd152013-06-12 20:52:10 +03004911 memset(&arg, 0, sizeof(arg));
4912 ath10k_wmi_start_scan_init(ar, &arg);
4913 arg.vdev_id = arvif->vdev_id;
4914 arg.scan_id = ATH10K_SCAN_ID;
4915
Kalle Valo5e3dd152013-06-12 20:52:10 +03004916 if (req->ie_len) {
4917 arg.ie_len = req->ie_len;
4918 memcpy(arg.ie, req->ie, arg.ie_len);
4919 }
4920
4921 if (req->n_ssids) {
4922 arg.n_ssids = req->n_ssids;
4923 for (i = 0; i < arg.n_ssids; i++) {
4924 arg.ssids[i].len = req->ssids[i].ssid_len;
4925 arg.ssids[i].ssid = req->ssids[i].ssid;
4926 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02004927 } else {
4928 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004929 }
4930
4931 if (req->n_channels) {
4932 arg.n_channels = req->n_channels;
4933 for (i = 0; i < arg.n_channels; i++)
4934 arg.channels[i] = req->channels[i]->center_freq;
4935 }
4936
4937 ret = ath10k_start_scan(ar, &arg);
4938 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004939 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004940 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004941 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004942 spin_unlock_bh(&ar->data_lock);
4943 }
4944
Michal Kazior634349b2015-09-03 10:43:45 +02004945 /* Add a 200ms margin to account for event/command processing */
4946 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
4947 msecs_to_jiffies(arg.max_scan_time +
4948 200));
4949
Kalle Valo5e3dd152013-06-12 20:52:10 +03004950exit:
4951 mutex_unlock(&ar->conf_mutex);
4952 return ret;
4953}
4954
4955static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
4956 struct ieee80211_vif *vif)
4957{
4958 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004959
4960 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004961 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004962 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01004963
4964 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004965}
4966
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004967static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
4968 struct ath10k_vif *arvif,
4969 enum set_key_cmd cmd,
4970 struct ieee80211_key_conf *key)
4971{
4972 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
4973 int ret;
4974
4975 /* 10.1 firmware branch requires default key index to be set to group
4976 * key index after installing it. Otherwise FW/HW Txes corrupted
4977 * frames with multi-vif APs. This is not required for main firmware
4978 * branch (e.g. 636).
4979 *
Michal Kazior8461baf2015-04-10 13:23:22 +00004980 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
4981 *
4982 * FIXME: It remains unknown if this is required for multi-vif STA
4983 * interfaces on 10.1.
4984 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004985
Michal Kazior8461baf2015-04-10 13:23:22 +00004986 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
4987 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004988 return;
4989
4990 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
4991 return;
4992
4993 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
4994 return;
4995
4996 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
4997 return;
4998
4999 if (cmd != SET_KEY)
5000 return;
5001
5002 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5003 key->keyidx);
5004 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005005 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005006 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005007}
5008
Kalle Valo5e3dd152013-06-12 20:52:10 +03005009static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5010 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5011 struct ieee80211_key_conf *key)
5012{
5013 struct ath10k *ar = hw->priv;
5014 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5015 struct ath10k_peer *peer;
5016 const u8 *peer_addr;
5017 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5018 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5019 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005020 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005021 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005022 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005023
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005024 /* this one needs to be done in software */
5025 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
5026 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005027
David Liuccec9032015-07-24 20:25:32 +03005028 if (arvif->nohwcrypt)
5029 return 1;
5030
Kalle Valo5e3dd152013-06-12 20:52:10 +03005031 if (key->keyidx > WMI_MAX_KEY_INDEX)
5032 return -ENOSPC;
5033
5034 mutex_lock(&ar->conf_mutex);
5035
5036 if (sta)
5037 peer_addr = sta->addr;
5038 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5039 peer_addr = vif->bss_conf.bssid;
5040 else
5041 peer_addr = vif->addr;
5042
5043 key->hw_key_idx = key->keyidx;
5044
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005045 if (is_wep) {
5046 if (cmd == SET_KEY)
5047 arvif->wep_keys[key->keyidx] = key;
5048 else
5049 arvif->wep_keys[key->keyidx] = NULL;
5050 }
5051
Kalle Valo5e3dd152013-06-12 20:52:10 +03005052 /* the peer should not disappear in mid-way (unless FW goes awry) since
5053 * we already hold conf_mutex. we just make sure its there now. */
5054 spin_lock_bh(&ar->data_lock);
5055 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5056 spin_unlock_bh(&ar->data_lock);
5057
5058 if (!peer) {
5059 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005060 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005061 peer_addr);
5062 ret = -EOPNOTSUPP;
5063 goto exit;
5064 } else {
5065 /* if the peer doesn't exist there is no key to disable
5066 * anymore */
5067 goto exit;
5068 }
5069 }
5070
Michal Kazior7cc45732015-03-09 14:24:17 +01005071 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5072 flags |= WMI_KEY_PAIRWISE;
5073 else
5074 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005075
Kalle Valo5e3dd152013-06-12 20:52:10 +03005076 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005077 if (cmd == DISABLE_KEY)
5078 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005079
Michal Kaziorad325cb2015-02-18 14:02:27 +01005080 /* When WEP keys are uploaded it's possible that there are
5081 * stations associated already (e.g. when merging) without any
5082 * keys. Static WEP needs an explicit per-peer key upload.
5083 */
5084 if (vif->type == NL80211_IFTYPE_ADHOC &&
5085 cmd == SET_KEY)
5086 ath10k_mac_vif_update_wep_key(arvif, key);
5087
Michal Kazior370e5672015-02-18 14:02:26 +01005088 /* 802.1x never sets the def_wep_key_idx so each set_key()
5089 * call changes default tx key.
5090 *
5091 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5092 * after first set_key().
5093 */
5094 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5095 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005096 }
5097
Michal Kazior370e5672015-02-18 14:02:26 +01005098 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005099 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005100 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005101 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005102 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005103 goto exit;
5104 }
5105
Michal Kazior29a10002015-04-10 13:05:58 +00005106 /* mac80211 sets static WEP keys as groupwise while firmware requires
5107 * them to be installed twice as both pairwise and groupwise.
5108 */
5109 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5110 flags2 = flags;
5111 flags2 &= ~WMI_KEY_GROUP;
5112 flags2 |= WMI_KEY_PAIRWISE;
5113
5114 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5115 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005116 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005117 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5118 arvif->vdev_id, peer_addr, ret);
5119 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5120 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005121 if (ret2) {
5122 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005123 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5124 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005125 }
Michal Kazior29a10002015-04-10 13:05:58 +00005126 goto exit;
5127 }
5128 }
5129
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005130 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5131
Kalle Valo5e3dd152013-06-12 20:52:10 +03005132 spin_lock_bh(&ar->data_lock);
5133 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5134 if (peer && cmd == SET_KEY)
5135 peer->keys[key->keyidx] = key;
5136 else if (peer && cmd == DISABLE_KEY)
5137 peer->keys[key->keyidx] = NULL;
5138 else if (peer == NULL)
5139 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005140 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005141 spin_unlock_bh(&ar->data_lock);
5142
5143exit:
5144 mutex_unlock(&ar->conf_mutex);
5145 return ret;
5146}
5147
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005148static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5149 struct ieee80211_vif *vif,
5150 int keyidx)
5151{
5152 struct ath10k *ar = hw->priv;
5153 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5154 int ret;
5155
5156 mutex_lock(&arvif->ar->conf_mutex);
5157
5158 if (arvif->ar->state != ATH10K_STATE_ON)
5159 goto unlock;
5160
5161 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5162 arvif->vdev_id, keyidx);
5163
5164 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5165 arvif->vdev_id,
5166 arvif->ar->wmi.vdev_param->def_keyid,
5167 keyidx);
5168
5169 if (ret) {
5170 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5171 arvif->vdev_id,
5172 ret);
5173 goto unlock;
5174 }
5175
5176 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005177
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005178unlock:
5179 mutex_unlock(&arvif->ar->conf_mutex);
5180}
5181
Michal Kazior9797feb2014-02-14 14:49:48 +01005182static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5183{
5184 struct ath10k *ar;
5185 struct ath10k_vif *arvif;
5186 struct ath10k_sta *arsta;
5187 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005188 struct cfg80211_chan_def def;
5189 enum ieee80211_band band;
5190 const u8 *ht_mcs_mask;
5191 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005192 u32 changed, bw, nss, smps;
5193 int err;
5194
5195 arsta = container_of(wk, struct ath10k_sta, update_wk);
5196 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5197 arvif = arsta->arvif;
5198 ar = arvif->ar;
5199
Michal Kazior45c9abc2015-04-21 20:42:58 +03005200 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5201 return;
5202
5203 band = def.chan->band;
5204 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5205 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5206
Michal Kazior9797feb2014-02-14 14:49:48 +01005207 spin_lock_bh(&ar->data_lock);
5208
5209 changed = arsta->changed;
5210 arsta->changed = 0;
5211
5212 bw = arsta->bw;
5213 nss = arsta->nss;
5214 smps = arsta->smps;
5215
5216 spin_unlock_bh(&ar->data_lock);
5217
5218 mutex_lock(&ar->conf_mutex);
5219
Michal Kazior45c9abc2015-04-21 20:42:58 +03005220 nss = max_t(u32, 1, nss);
5221 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
5222 ath10k_mac_max_vht_nss(vht_mcs_mask)));
5223
Michal Kazior9797feb2014-02-14 14:49:48 +01005224 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005225 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005226 sta->addr, bw);
5227
5228 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5229 WMI_PEER_CHAN_WIDTH, bw);
5230 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005231 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005232 sta->addr, bw, err);
5233 }
5234
5235 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005236 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005237 sta->addr, nss);
5238
5239 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5240 WMI_PEER_NSS, nss);
5241 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005242 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005243 sta->addr, nss, err);
5244 }
5245
5246 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005247 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005248 sta->addr, smps);
5249
5250 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5251 WMI_PEER_SMPS_STATE, smps);
5252 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005253 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005254 sta->addr, smps, err);
5255 }
5256
Janusz Dziedzic55884c02014-12-17 12:30:02 +02005257 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
5258 changed & IEEE80211_RC_NSS_CHANGED) {
5259 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005260 sta->addr);
5261
Michal Kazior590922a2014-10-21 10:10:29 +03005262 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005263 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005264 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005265 sta->addr);
5266 }
5267
Michal Kazior9797feb2014-02-14 14:49:48 +01005268 mutex_unlock(&ar->conf_mutex);
5269}
5270
Marek Puzyniak7c354242015-03-30 09:51:52 +03005271static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
5272 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005273{
5274 struct ath10k *ar = arvif->ar;
5275
5276 lockdep_assert_held(&ar->conf_mutex);
5277
Marek Puzyniak7c354242015-03-30 09:51:52 +03005278 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005279 return 0;
5280
5281 if (ar->num_stations >= ar->max_num_stations)
5282 return -ENOBUFS;
5283
5284 ar->num_stations++;
5285
5286 return 0;
5287}
5288
Marek Puzyniak7c354242015-03-30 09:51:52 +03005289static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
5290 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005291{
5292 struct ath10k *ar = arvif->ar;
5293
5294 lockdep_assert_held(&ar->conf_mutex);
5295
Marek Puzyniak7c354242015-03-30 09:51:52 +03005296 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005297 return;
5298
5299 ar->num_stations--;
5300}
5301
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005302struct ath10k_mac_tdls_iter_data {
5303 u32 num_tdls_stations;
5304 struct ieee80211_vif *curr_vif;
5305};
5306
5307static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5308 struct ieee80211_sta *sta)
5309{
5310 struct ath10k_mac_tdls_iter_data *iter_data = data;
5311 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5312 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5313
5314 if (sta->tdls && sta_vif == iter_data->curr_vif)
5315 iter_data->num_tdls_stations++;
5316}
5317
5318static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5319 struct ieee80211_vif *vif)
5320{
5321 struct ath10k_mac_tdls_iter_data data = {};
5322
5323 data.curr_vif = vif;
5324
5325 ieee80211_iterate_stations_atomic(hw,
5326 ath10k_mac_tdls_vif_stations_count_iter,
5327 &data);
5328 return data.num_tdls_stations;
5329}
5330
5331static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5332 struct ieee80211_vif *vif)
5333{
5334 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5335 int *num_tdls_vifs = data;
5336
5337 if (vif->type != NL80211_IFTYPE_STATION)
5338 return;
5339
5340 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5341 (*num_tdls_vifs)++;
5342}
5343
5344static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5345{
5346 int num_tdls_vifs = 0;
5347
5348 ieee80211_iterate_active_interfaces_atomic(hw,
5349 IEEE80211_IFACE_ITER_NORMAL,
5350 ath10k_mac_tdls_vifs_count_iter,
5351 &num_tdls_vifs);
5352 return num_tdls_vifs;
5353}
5354
Kalle Valo5e3dd152013-06-12 20:52:10 +03005355static int ath10k_sta_state(struct ieee80211_hw *hw,
5356 struct ieee80211_vif *vif,
5357 struct ieee80211_sta *sta,
5358 enum ieee80211_sta_state old_state,
5359 enum ieee80211_sta_state new_state)
5360{
5361 struct ath10k *ar = hw->priv;
5362 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005363 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005364 int ret = 0;
5365
Michal Kazior76f90022014-02-25 09:29:57 +02005366 if (old_state == IEEE80211_STA_NOTEXIST &&
5367 new_state == IEEE80211_STA_NONE) {
5368 memset(arsta, 0, sizeof(*arsta));
5369 arsta->arvif = arvif;
5370 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
5371 }
5372
Michal Kazior9797feb2014-02-14 14:49:48 +01005373 /* cancel must be done outside the mutex to avoid deadlock */
5374 if ((old_state == IEEE80211_STA_NONE &&
5375 new_state == IEEE80211_STA_NOTEXIST))
5376 cancel_work_sync(&arsta->update_wk);
5377
Kalle Valo5e3dd152013-06-12 20:52:10 +03005378 mutex_lock(&ar->conf_mutex);
5379
5380 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005381 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005382 /*
5383 * New station addition.
5384 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005385 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5386 u32 num_tdls_stations;
5387 u32 num_tdls_vifs;
5388
Michal Kaziorcfd10612014-11-25 15:16:05 +01005389 ath10k_dbg(ar, ATH10K_DBG_MAC,
5390 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5391 arvif->vdev_id, sta->addr,
5392 ar->num_stations + 1, ar->max_num_stations,
5393 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005394
Marek Puzyniak7c354242015-03-30 09:51:52 +03005395 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005396 if (ret) {
5397 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5398 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005399 goto exit;
5400 }
5401
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005402 if (sta->tdls)
5403 peer_type = WMI_PEER_TYPE_TDLS;
5404
Marek Puzyniak7390ed32015-03-30 09:51:52 +03005405 ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr,
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005406 peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005407 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005408 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 -08005409 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005410 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005411 goto exit;
5412 }
Michal Kazior077efc82014-10-21 10:10:29 +03005413
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005414 if (!sta->tdls)
5415 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03005416
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005417 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
5418 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
5419
5420 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
5421 num_tdls_stations == 0) {
5422 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
5423 arvif->vdev_id, ar->max_num_tdls_vdevs);
5424 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5425 ath10k_mac_dec_num_stations(arvif, sta);
5426 ret = -ENOBUFS;
5427 goto exit;
5428 }
5429
5430 if (num_tdls_stations == 0) {
5431 /* This is the first tdls peer in current vif */
5432 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
5433
5434 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5435 state);
Michal Kazior077efc82014-10-21 10:10:29 +03005436 if (ret) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005437 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
Michal Kazior077efc82014-10-21 10:10:29 +03005438 arvif->vdev_id, ret);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005439 ath10k_peer_delete(ar, arvif->vdev_id,
5440 sta->addr);
5441 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03005442 goto exit;
5443 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005444 }
Michal Kazior077efc82014-10-21 10:10:29 +03005445
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005446 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5447 WMI_TDLS_PEER_STATE_PEERING);
5448 if (ret) {
5449 ath10k_warn(ar,
5450 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
5451 sta->addr, arvif->vdev_id, ret);
5452 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5453 ath10k_mac_dec_num_stations(arvif, sta);
5454
5455 if (num_tdls_stations != 0)
5456 goto exit;
5457 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5458 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03005459 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005460 } else if ((old_state == IEEE80211_STA_NONE &&
5461 new_state == IEEE80211_STA_NOTEXIST)) {
5462 /*
5463 * Existing station deletion.
5464 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005465 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005466 "mac vdev %d peer delete %pM (sta gone)\n",
5467 arvif->vdev_id, sta->addr);
Michal Kazior077efc82014-10-21 10:10:29 +03005468
Kalle Valo5e3dd152013-06-12 20:52:10 +03005469 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5470 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005471 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005472 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005473
Marek Puzyniak7c354242015-03-30 09:51:52 +03005474 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005475
5476 if (!sta->tdls)
5477 goto exit;
5478
5479 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
5480 goto exit;
5481
5482 /* This was the last tdls peer in current vif */
5483 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5484 WMI_TDLS_DISABLE);
5485 if (ret) {
5486 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
5487 arvif->vdev_id, ret);
5488 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005489 } else if (old_state == IEEE80211_STA_AUTH &&
5490 new_state == IEEE80211_STA_ASSOC &&
5491 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005492 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03005493 vif->type == NL80211_IFTYPE_ADHOC)) {
5494 /*
5495 * New association.
5496 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005497 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005498 sta->addr);
5499
Michal Kazior590922a2014-10-21 10:10:29 +03005500 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005501 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005502 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005503 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005504 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005505 new_state == IEEE80211_STA_AUTHORIZED &&
5506 sta->tdls) {
5507 /*
5508 * Tdls station authorized.
5509 */
5510 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
5511 sta->addr);
5512
5513 ret = ath10k_station_assoc(ar, vif, sta, false);
5514 if (ret) {
5515 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
5516 sta->addr, arvif->vdev_id, ret);
5517 goto exit;
5518 }
5519
5520 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5521 WMI_TDLS_PEER_STATE_CONNECTED);
5522 if (ret)
5523 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
5524 sta->addr, arvif->vdev_id, ret);
5525 } else if (old_state == IEEE80211_STA_ASSOC &&
5526 new_state == IEEE80211_STA_AUTH &&
5527 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005528 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005529 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005530 /*
5531 * Disassociation.
5532 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005533 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005534 sta->addr);
5535
Michal Kazior590922a2014-10-21 10:10:29 +03005536 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005537 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005538 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005539 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005540 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005541exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005542 mutex_unlock(&ar->conf_mutex);
5543 return ret;
5544}
5545
5546static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03005547 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005548{
5549 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02005550 struct wmi_sta_uapsd_auto_trig_arg arg = {};
5551 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005552 u32 value = 0;
5553 int ret = 0;
5554
Michal Kazior548db542013-07-05 16:15:15 +03005555 lockdep_assert_held(&ar->conf_mutex);
5556
Kalle Valo5e3dd152013-06-12 20:52:10 +03005557 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
5558 return 0;
5559
5560 switch (ac) {
5561 case IEEE80211_AC_VO:
5562 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
5563 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005564 prio = 7;
5565 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005566 break;
5567 case IEEE80211_AC_VI:
5568 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
5569 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005570 prio = 5;
5571 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005572 break;
5573 case IEEE80211_AC_BE:
5574 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
5575 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005576 prio = 2;
5577 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005578 break;
5579 case IEEE80211_AC_BK:
5580 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
5581 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005582 prio = 0;
5583 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005584 break;
5585 }
5586
5587 if (enable)
5588 arvif->u.sta.uapsd |= value;
5589 else
5590 arvif->u.sta.uapsd &= ~value;
5591
5592 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5593 WMI_STA_PS_PARAM_UAPSD,
5594 arvif->u.sta.uapsd);
5595 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005596 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005597 goto exit;
5598 }
5599
5600 if (arvif->u.sta.uapsd)
5601 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
5602 else
5603 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5604
5605 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5606 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
5607 value);
5608 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005609 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005610
Michal Kazior9f9b5742014-12-12 12:41:36 +01005611 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
5612 if (ret) {
5613 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
5614 arvif->vdev_id, ret);
5615 return ret;
5616 }
5617
5618 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
5619 if (ret) {
5620 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
5621 arvif->vdev_id, ret);
5622 return ret;
5623 }
5624
Michal Kaziorb0e56152015-01-24 12:14:52 +02005625 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
5626 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
5627 /* Only userspace can make an educated decision when to send
5628 * trigger frame. The following effectively disables u-UAPSD
5629 * autotrigger in firmware (which is enabled by default
5630 * provided the autotrigger service is available).
5631 */
5632
5633 arg.wmm_ac = acc;
5634 arg.user_priority = prio;
5635 arg.service_interval = 0;
5636 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
5637 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
5638
5639 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
5640 arvif->bssid, &arg, 1);
5641 if (ret) {
5642 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
5643 ret);
5644 return ret;
5645 }
5646 }
5647
Kalle Valo5e3dd152013-06-12 20:52:10 +03005648exit:
5649 return ret;
5650}
5651
5652static int ath10k_conf_tx(struct ieee80211_hw *hw,
5653 struct ieee80211_vif *vif, u16 ac,
5654 const struct ieee80211_tx_queue_params *params)
5655{
5656 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01005657 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005658 struct wmi_wmm_params_arg *p = NULL;
5659 int ret;
5660
5661 mutex_lock(&ar->conf_mutex);
5662
5663 switch (ac) {
5664 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01005665 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005666 break;
5667 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01005668 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005669 break;
5670 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01005671 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005672 break;
5673 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01005674 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005675 break;
5676 }
5677
5678 if (WARN_ON(!p)) {
5679 ret = -EINVAL;
5680 goto exit;
5681 }
5682
5683 p->cwmin = params->cw_min;
5684 p->cwmax = params->cw_max;
5685 p->aifs = params->aifs;
5686
5687 /*
5688 * The channel time duration programmed in the HW is in absolute
5689 * microseconds, while mac80211 gives the txop in units of
5690 * 32 microseconds.
5691 */
5692 p->txop = params->txop * 32;
5693
Michal Kazior7fc979a2015-01-28 09:57:28 +02005694 if (ar->wmi.ops->gen_vdev_wmm_conf) {
5695 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
5696 &arvif->wmm_params);
5697 if (ret) {
5698 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
5699 arvif->vdev_id, ret);
5700 goto exit;
5701 }
5702 } else {
5703 /* This won't work well with multi-interface cases but it's
5704 * better than nothing.
5705 */
5706 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
5707 if (ret) {
5708 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
5709 goto exit;
5710 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005711 }
5712
5713 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
5714 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005715 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005716
5717exit:
5718 mutex_unlock(&ar->conf_mutex);
5719 return ret;
5720}
5721
5722#define ATH10K_ROC_TIMEOUT_HZ (2*HZ)
5723
5724static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
5725 struct ieee80211_vif *vif,
5726 struct ieee80211_channel *chan,
5727 int duration,
5728 enum ieee80211_roc_type type)
5729{
5730 struct ath10k *ar = hw->priv;
5731 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5732 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005733 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00005734 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005735
5736 mutex_lock(&ar->conf_mutex);
5737
5738 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005739 switch (ar->scan.state) {
5740 case ATH10K_SCAN_IDLE:
5741 reinit_completion(&ar->scan.started);
5742 reinit_completion(&ar->scan.completed);
5743 reinit_completion(&ar->scan.on_channel);
5744 ar->scan.state = ATH10K_SCAN_STARTING;
5745 ar->scan.is_roc = true;
5746 ar->scan.vdev_id = arvif->vdev_id;
5747 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02005748 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005749 ret = 0;
5750 break;
5751 case ATH10K_SCAN_STARTING:
5752 case ATH10K_SCAN_RUNNING:
5753 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005754 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005755 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005756 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005757 spin_unlock_bh(&ar->data_lock);
5758
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005759 if (ret)
5760 goto exit;
5761
Michal Kaziorfcf98442015-03-31 11:03:47 +00005762 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01005763
Kalle Valo5e3dd152013-06-12 20:52:10 +03005764 memset(&arg, 0, sizeof(arg));
5765 ath10k_wmi_start_scan_init(ar, &arg);
5766 arg.vdev_id = arvif->vdev_id;
5767 arg.scan_id = ATH10K_SCAN_ID;
5768 arg.n_channels = 1;
5769 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00005770 arg.dwell_time_active = scan_time_msec;
5771 arg.dwell_time_passive = scan_time_msec;
5772 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005773 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
5774 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00005775 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005776
5777 ret = ath10k_start_scan(ar, &arg);
5778 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005779 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005780 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005781 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005782 spin_unlock_bh(&ar->data_lock);
5783 goto exit;
5784 }
5785
5786 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ);
5787 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005788 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005789
5790 ret = ath10k_scan_stop(ar);
5791 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005792 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005793
Kalle Valo5e3dd152013-06-12 20:52:10 +03005794 ret = -ETIMEDOUT;
5795 goto exit;
5796 }
5797
Michal Kaziorfcf98442015-03-31 11:03:47 +00005798 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5799 msecs_to_jiffies(duration));
5800
Kalle Valo5e3dd152013-06-12 20:52:10 +03005801 ret = 0;
5802exit:
5803 mutex_unlock(&ar->conf_mutex);
5804 return ret;
5805}
5806
5807static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
5808{
5809 struct ath10k *ar = hw->priv;
5810
5811 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02005812
5813 spin_lock_bh(&ar->data_lock);
5814 ar->scan.roc_notify = false;
5815 spin_unlock_bh(&ar->data_lock);
5816
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005817 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02005818
Kalle Valo5e3dd152013-06-12 20:52:10 +03005819 mutex_unlock(&ar->conf_mutex);
5820
Michal Kazior4eb2e162014-10-28 10:23:09 +01005821 cancel_delayed_work_sync(&ar->scan.timeout);
5822
Kalle Valo5e3dd152013-06-12 20:52:10 +03005823 return 0;
5824}
5825
5826/*
5827 * Both RTS and Fragmentation threshold are interface-specific
5828 * in ath10k, but device-specific in mac80211.
5829 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03005830
5831static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
5832{
Kalle Valo5e3dd152013-06-12 20:52:10 +03005833 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03005834 struct ath10k_vif *arvif;
5835 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03005836
Michal Kaziorad088bf2013-10-16 15:44:46 +03005837 mutex_lock(&ar->conf_mutex);
5838 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005839 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03005840 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03005841
Michal Kaziorad088bf2013-10-16 15:44:46 +03005842 ret = ath10k_mac_set_rts(arvif, value);
5843 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005844 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03005845 arvif->vdev_id, ret);
5846 break;
5847 }
5848 }
5849 mutex_unlock(&ar->conf_mutex);
5850
5851 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005852}
5853
Michal Kazior92092fe2015-08-03 11:16:43 +02005854static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
5855{
5856 /* Even though there's a WMI enum for fragmentation threshold no known
5857 * firmware actually implements it. Moreover it is not possible to rely
5858 * frame fragmentation to mac80211 because firmware clears the "more
5859 * fragments" bit in frame control making it impossible for remote
5860 * devices to reassemble frames.
5861 *
5862 * Hence implement a dummy callback just to say fragmentation isn't
5863 * supported. This effectively prevents mac80211 from doing frame
5864 * fragmentation in software.
5865 */
5866 return -EOPNOTSUPP;
5867}
5868
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02005869static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5870 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005871{
5872 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02005873 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03005874 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005875
5876 /* mac80211 doesn't care if we really xmit queued frames or not
5877 * we'll collect those frames either way if we stop/delete vdevs */
5878 if (drop)
5879 return;
5880
Michal Kazior548db542013-07-05 16:15:15 +03005881 mutex_lock(&ar->conf_mutex);
5882
Michal Kazioraffd3212013-07-16 09:54:35 +02005883 if (ar->state == ATH10K_STATE_WEDGED)
5884 goto skip;
5885
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03005886 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03005887 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02005888
Michal Kazioredb82362013-07-05 16:15:14 +03005889 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02005890 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03005891 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02005892
Michal Kazior7962b0d2014-10-28 10:34:38 +01005893 skip = (ar->state == ATH10K_STATE_WEDGED) ||
5894 test_bit(ATH10K_FLAG_CRASH_FLUSH,
5895 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02005896
5897 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005898 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02005899
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03005900 if (time_left == 0 || skip)
5901 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
5902 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03005903
Michal Kazioraffd3212013-07-16 09:54:35 +02005904skip:
Michal Kazior548db542013-07-05 16:15:15 +03005905 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005906}
5907
5908/* TODO: Implement this function properly
5909 * For now it is needed to reply to Probe Requests in IBSS mode.
5910 * Propably we need this information from FW.
5911 */
5912static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
5913{
5914 return 1;
5915}
5916
Eliad Pellercf2c92d2014-11-04 11:43:54 +02005917static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
5918 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02005919{
5920 struct ath10k *ar = hw->priv;
5921
Eliad Pellercf2c92d2014-11-04 11:43:54 +02005922 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
5923 return;
5924
Michal Kazioraffd3212013-07-16 09:54:35 +02005925 mutex_lock(&ar->conf_mutex);
5926
5927 /* If device failed to restart it will be in a different state, e.g.
5928 * ATH10K_STATE_WEDGED */
5929 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005930 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02005931 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01005932 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02005933 }
5934
5935 mutex_unlock(&ar->conf_mutex);
5936}
5937
Michal Kazior2e1dea42013-07-31 10:32:40 +02005938static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
5939 struct survey_info *survey)
5940{
5941 struct ath10k *ar = hw->priv;
5942 struct ieee80211_supported_band *sband;
5943 struct survey_info *ar_survey = &ar->survey[idx];
5944 int ret = 0;
5945
5946 mutex_lock(&ar->conf_mutex);
5947
5948 sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
5949 if (sband && idx >= sband->n_channels) {
5950 idx -= sband->n_channels;
5951 sband = NULL;
5952 }
5953
5954 if (!sband)
5955 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
5956
5957 if (!sband || idx >= sband->n_channels) {
5958 ret = -ENOENT;
5959 goto exit;
5960 }
5961
5962 spin_lock_bh(&ar->data_lock);
5963 memcpy(survey, ar_survey, sizeof(*survey));
5964 spin_unlock_bh(&ar->data_lock);
5965
5966 survey->channel = &sband->channels[idx];
5967
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03005968 if (ar->rx_channel == survey->channel)
5969 survey->filled |= SURVEY_INFO_IN_USE;
5970
Michal Kazior2e1dea42013-07-31 10:32:40 +02005971exit:
5972 mutex_unlock(&ar->conf_mutex);
5973 return ret;
5974}
5975
Michal Kazior3ae54222015-03-31 10:49:20 +00005976static bool
5977ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
5978 enum ieee80211_band band,
5979 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005980{
Michal Kazior3ae54222015-03-31 10:49:20 +00005981 int num_rates = 0;
5982 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005983
Michal Kazior3ae54222015-03-31 10:49:20 +00005984 num_rates += hweight32(mask->control[band].legacy);
5985
5986 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
5987 num_rates += hweight8(mask->control[band].ht_mcs[i]);
5988
5989 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
5990 num_rates += hweight16(mask->control[band].vht_mcs[i]);
5991
5992 return num_rates == 1;
5993}
5994
5995static bool
5996ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
5997 enum ieee80211_band band,
5998 const struct cfg80211_bitrate_mask *mask,
5999 int *nss)
6000{
6001 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6002 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6003 u8 ht_nss_mask = 0;
6004 u8 vht_nss_mask = 0;
6005 int i;
6006
6007 if (mask->control[band].legacy)
6008 return false;
6009
6010 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6011 if (mask->control[band].ht_mcs[i] == 0)
6012 continue;
6013 else if (mask->control[band].ht_mcs[i] ==
6014 sband->ht_cap.mcs.rx_mask[i])
6015 ht_nss_mask |= BIT(i);
6016 else
6017 return false;
6018 }
6019
6020 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6021 if (mask->control[band].vht_mcs[i] == 0)
6022 continue;
6023 else if (mask->control[band].vht_mcs[i] ==
6024 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6025 vht_nss_mask |= BIT(i);
6026 else
6027 return false;
6028 }
6029
6030 if (ht_nss_mask != vht_nss_mask)
6031 return false;
6032
6033 if (ht_nss_mask == 0)
6034 return false;
6035
6036 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6037 return false;
6038
6039 *nss = fls(ht_nss_mask);
6040
6041 return true;
6042}
6043
6044static int
6045ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
6046 enum ieee80211_band band,
6047 const struct cfg80211_bitrate_mask *mask,
6048 u8 *rate, u8 *nss)
6049{
6050 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6051 int rate_idx;
6052 int i;
6053 u16 bitrate;
6054 u8 preamble;
6055 u8 hw_rate;
6056
6057 if (hweight32(mask->control[band].legacy) == 1) {
6058 rate_idx = ffs(mask->control[band].legacy) - 1;
6059
6060 hw_rate = sband->bitrates[rate_idx].hw_value;
6061 bitrate = sband->bitrates[rate_idx].bitrate;
6062
6063 if (ath10k_mac_bitrate_is_cck(bitrate))
6064 preamble = WMI_RATE_PREAMBLE_CCK;
6065 else
6066 preamble = WMI_RATE_PREAMBLE_OFDM;
6067
6068 *nss = 1;
6069 *rate = preamble << 6 |
6070 (*nss - 1) << 4 |
6071 hw_rate << 0;
6072
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006073 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006074 }
6075
Michal Kazior3ae54222015-03-31 10:49:20 +00006076 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6077 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6078 *nss = i + 1;
6079 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6080 (*nss - 1) << 4 |
6081 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006082
Michal Kazior3ae54222015-03-31 10:49:20 +00006083 return 0;
6084 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006085 }
6086
Michal Kazior3ae54222015-03-31 10:49:20 +00006087 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6088 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6089 *nss = i + 1;
6090 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6091 (*nss - 1) << 4 |
6092 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006093
Michal Kazior3ae54222015-03-31 10:49:20 +00006094 return 0;
6095 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006096 }
6097
Michal Kazior3ae54222015-03-31 10:49:20 +00006098 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006099}
6100
Michal Kazior3ae54222015-03-31 10:49:20 +00006101static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306102 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006103{
6104 struct ath10k *ar = arvif->ar;
6105 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006106 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006107
Michal Kazior3ae54222015-03-31 10:49:20 +00006108 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006109
Michal Kazior3ae54222015-03-31 10:49:20 +00006110 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6111 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006112
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006113 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006114 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006115 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006116 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006117 rate, ret);
6118 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006119 }
6120
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006121 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006122 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006123 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006124 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6125 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006126 }
6127
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006128 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006129 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006130 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006131 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6132 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006133 }
6134
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306135 vdev_param = ar->wmi.vdev_param->ldpc;
6136 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6137 if (ret) {
6138 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6139 return ret;
6140 }
6141
Michal Kazior3ae54222015-03-31 10:49:20 +00006142 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006143}
6144
Michal Kazior45c9abc2015-04-21 20:42:58 +03006145static bool
6146ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
6147 enum ieee80211_band band,
6148 const struct cfg80211_bitrate_mask *mask)
6149{
6150 int i;
6151 u16 vht_mcs;
6152
6153 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6154 * to express all VHT MCS rate masks. Effectively only the following
6155 * ranges can be used: none, 0-7, 0-8 and 0-9.
6156 */
6157 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6158 vht_mcs = mask->control[band].vht_mcs[i];
6159
6160 switch (vht_mcs) {
6161 case 0:
6162 case BIT(8) - 1:
6163 case BIT(9) - 1:
6164 case BIT(10) - 1:
6165 break;
6166 default:
6167 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6168 return false;
6169 }
6170 }
6171
6172 return true;
6173}
6174
6175static void ath10k_mac_set_bitrate_mask_iter(void *data,
6176 struct ieee80211_sta *sta)
6177{
6178 struct ath10k_vif *arvif = data;
6179 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6180 struct ath10k *ar = arvif->ar;
6181
6182 if (arsta->arvif != arvif)
6183 return;
6184
6185 spin_lock_bh(&ar->data_lock);
6186 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
6187 spin_unlock_bh(&ar->data_lock);
6188
6189 ieee80211_queue_work(ar->hw, &arsta->update_wk);
6190}
6191
Michal Kazior3ae54222015-03-31 10:49:20 +00006192static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
6193 struct ieee80211_vif *vif,
6194 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006195{
6196 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006197 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006198 struct ath10k *ar = arvif->ar;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006199 enum ieee80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006200 const u8 *ht_mcs_mask;
6201 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00006202 u8 rate;
6203 u8 nss;
6204 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306205 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00006206 int single_nss;
6207 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006208
Michal Kazior500ff9f2015-03-31 10:26:21 +00006209 if (ath10k_mac_vif_chan(vif, &def))
6210 return -EPERM;
6211
Michal Kazior500ff9f2015-03-31 10:26:21 +00006212 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006213 ht_mcs_mask = mask->control[band].ht_mcs;
6214 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306215 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006216
Michal Kazior3ae54222015-03-31 10:49:20 +00006217 sgi = mask->control[band].gi;
6218 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006219 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006220
Michal Kazior3ae54222015-03-31 10:49:20 +00006221 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
6222 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
6223 &rate, &nss);
6224 if (ret) {
6225 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
6226 arvif->vdev_id, ret);
6227 return ret;
6228 }
6229 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
6230 &single_nss)) {
6231 rate = WMI_FIXED_RATE_NONE;
6232 nss = single_nss;
6233 } else {
6234 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006235 nss = min(ar->num_rf_chains,
6236 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6237 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6238
6239 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
6240 return -EINVAL;
6241
6242 mutex_lock(&ar->conf_mutex);
6243
6244 arvif->bitrate_mask = *mask;
6245 ieee80211_iterate_stations_atomic(ar->hw,
6246 ath10k_mac_set_bitrate_mask_iter,
6247 arvif);
6248
6249 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006250 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006251
6252 mutex_lock(&ar->conf_mutex);
6253
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306254 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006255 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006256 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
6257 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006258 goto exit;
6259 }
6260
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006261exit:
6262 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00006263
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006264 return ret;
6265}
6266
Michal Kazior9797feb2014-02-14 14:49:48 +01006267static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6268 struct ieee80211_vif *vif,
6269 struct ieee80211_sta *sta,
6270 u32 changed)
6271{
6272 struct ath10k *ar = hw->priv;
6273 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6274 u32 bw, smps;
6275
6276 spin_lock_bh(&ar->data_lock);
6277
Michal Kazior7aa7a722014-08-25 12:09:38 +02006278 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01006279 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
6280 sta->addr, changed, sta->bandwidth, sta->rx_nss,
6281 sta->smps_mode);
6282
6283 if (changed & IEEE80211_RC_BW_CHANGED) {
6284 bw = WMI_PEER_CHWIDTH_20MHZ;
6285
6286 switch (sta->bandwidth) {
6287 case IEEE80211_STA_RX_BW_20:
6288 bw = WMI_PEER_CHWIDTH_20MHZ;
6289 break;
6290 case IEEE80211_STA_RX_BW_40:
6291 bw = WMI_PEER_CHWIDTH_40MHZ;
6292 break;
6293 case IEEE80211_STA_RX_BW_80:
6294 bw = WMI_PEER_CHWIDTH_80MHZ;
6295 break;
6296 case IEEE80211_STA_RX_BW_160:
Masanari Iidad939be32015-02-27 23:52:31 +09006297 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006298 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006299 bw = WMI_PEER_CHWIDTH_20MHZ;
6300 break;
6301 }
6302
6303 arsta->bw = bw;
6304 }
6305
6306 if (changed & IEEE80211_RC_NSS_CHANGED)
6307 arsta->nss = sta->rx_nss;
6308
6309 if (changed & IEEE80211_RC_SMPS_CHANGED) {
6310 smps = WMI_PEER_SMPS_PS_NONE;
6311
6312 switch (sta->smps_mode) {
6313 case IEEE80211_SMPS_AUTOMATIC:
6314 case IEEE80211_SMPS_OFF:
6315 smps = WMI_PEER_SMPS_PS_NONE;
6316 break;
6317 case IEEE80211_SMPS_STATIC:
6318 smps = WMI_PEER_SMPS_STATIC;
6319 break;
6320 case IEEE80211_SMPS_DYNAMIC:
6321 smps = WMI_PEER_SMPS_DYNAMIC;
6322 break;
6323 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02006324 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006325 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006326 smps = WMI_PEER_SMPS_PS_NONE;
6327 break;
6328 }
6329
6330 arsta->smps = smps;
6331 }
6332
Michal Kazior9797feb2014-02-14 14:49:48 +01006333 arsta->changed |= changed;
6334
6335 spin_unlock_bh(&ar->data_lock);
6336
6337 ieee80211_queue_work(hw, &arsta->update_wk);
6338}
6339
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006340static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
6341{
6342 /*
6343 * FIXME: Return 0 for time being. Need to figure out whether FW
6344 * has the API to fetch 64-bit local TSF
6345 */
6346
6347 return 0;
6348}
6349
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006350static int ath10k_ampdu_action(struct ieee80211_hw *hw,
6351 struct ieee80211_vif *vif,
6352 enum ieee80211_ampdu_mlme_action action,
6353 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
Emmanuel Grumbache3abc8f2015-08-16 11:13:22 +03006354 u8 buf_size, bool amsdu)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006355{
Michal Kazior7aa7a722014-08-25 12:09:38 +02006356 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006357 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6358
Michal Kazior7aa7a722014-08-25 12:09:38 +02006359 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 +02006360 arvif->vdev_id, sta->addr, tid, action);
6361
6362 switch (action) {
6363 case IEEE80211_AMPDU_RX_START:
6364 case IEEE80211_AMPDU_RX_STOP:
6365 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
6366 * creation/removal. Do we need to verify this?
6367 */
6368 return 0;
6369 case IEEE80211_AMPDU_TX_START:
6370 case IEEE80211_AMPDU_TX_STOP_CONT:
6371 case IEEE80211_AMPDU_TX_STOP_FLUSH:
6372 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
6373 case IEEE80211_AMPDU_TX_OPERATIONAL:
6374 /* Firmware offloads Tx aggregation entirely so deny mac80211
6375 * Tx aggregation requests.
6376 */
6377 return -EOPNOTSUPP;
6378 }
6379
6380 return -EINVAL;
6381}
6382
Michal Kazior500ff9f2015-03-31 10:26:21 +00006383static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006384ath10k_mac_update_rx_channel(struct ath10k *ar,
6385 struct ieee80211_chanctx_conf *ctx,
6386 struct ieee80211_vif_chanctx_switch *vifs,
6387 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00006388{
6389 struct cfg80211_chan_def *def = NULL;
6390
6391 /* Both locks are required because ar->rx_channel is modified. This
6392 * allows readers to hold either lock.
6393 */
6394 lockdep_assert_held(&ar->conf_mutex);
6395 lockdep_assert_held(&ar->data_lock);
6396
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006397 WARN_ON(ctx && vifs);
6398 WARN_ON(vifs && n_vifs != 1);
6399
Michal Kazior500ff9f2015-03-31 10:26:21 +00006400 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
6401 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
6402 * ppdu on Rx may reduce performance on low-end systems. It should be
6403 * possible to make tables/hashmaps to speed the lookup up (be vary of
6404 * cpu data cache lines though regarding sizes) but to keep the initial
6405 * implementation simple and less intrusive fallback to the slow lookup
6406 * only for multi-channel cases. Single-channel cases will remain to
6407 * use the old channel derival and thus performance should not be
6408 * affected much.
6409 */
6410 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006411 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00006412 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03006413 ath10k_mac_get_any_chandef_iter,
6414 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006415
6416 if (vifs)
6417 def = &vifs[0].new_ctx->def;
6418
Michal Kazior500ff9f2015-03-31 10:26:21 +00006419 ar->rx_channel = def->chan;
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006420 } else if (ctx && ath10k_mac_num_chanctxs(ar) == 0) {
6421 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006422 } else {
6423 ar->rx_channel = NULL;
6424 }
6425 rcu_read_unlock();
6426}
6427
Michal Kazior7be6d1b2015-09-03 10:44:51 +02006428static void
6429ath10k_mac_update_vif_chan(struct ath10k *ar,
6430 struct ieee80211_vif_chanctx_switch *vifs,
6431 int n_vifs)
6432{
6433 struct ath10k_vif *arvif;
6434 int ret;
6435 int i;
6436
6437 lockdep_assert_held(&ar->conf_mutex);
6438
6439 /* First stop monitor interface. Some FW versions crash if there's a
6440 * lone monitor interface.
6441 */
6442 if (ar->monitor_started)
6443 ath10k_monitor_stop(ar);
6444
6445 for (i = 0; i < n_vifs; i++) {
6446 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6447
6448 ath10k_dbg(ar, ATH10K_DBG_MAC,
6449 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
6450 arvif->vdev_id,
6451 vifs[i].old_ctx->def.chan->center_freq,
6452 vifs[i].new_ctx->def.chan->center_freq,
6453 vifs[i].old_ctx->def.width,
6454 vifs[i].new_ctx->def.width);
6455
6456 if (WARN_ON(!arvif->is_started))
6457 continue;
6458
6459 if (WARN_ON(!arvif->is_up))
6460 continue;
6461
6462 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
6463 if (ret) {
6464 ath10k_warn(ar, "failed to down vdev %d: %d\n",
6465 arvif->vdev_id, ret);
6466 continue;
6467 }
6468 }
6469
6470 /* All relevant vdevs are downed and associated channel resources
6471 * should be available for the channel switch now.
6472 */
6473
6474 spin_lock_bh(&ar->data_lock);
6475 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
6476 spin_unlock_bh(&ar->data_lock);
6477
6478 for (i = 0; i < n_vifs; i++) {
6479 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6480
6481 if (WARN_ON(!arvif->is_started))
6482 continue;
6483
6484 if (WARN_ON(!arvif->is_up))
6485 continue;
6486
6487 ret = ath10k_mac_setup_bcn_tmpl(arvif);
6488 if (ret)
6489 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
6490 ret);
6491
6492 ret = ath10k_mac_setup_prb_tmpl(arvif);
6493 if (ret)
6494 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
6495 ret);
6496
6497 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
6498 if (ret) {
6499 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
6500 arvif->vdev_id, ret);
6501 continue;
6502 }
6503
6504 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
6505 arvif->bssid);
6506 if (ret) {
6507 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
6508 arvif->vdev_id, ret);
6509 continue;
6510 }
6511 }
6512
6513 ath10k_monitor_recalc(ar);
6514}
6515
Michal Kazior500ff9f2015-03-31 10:26:21 +00006516static int
6517ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
6518 struct ieee80211_chanctx_conf *ctx)
6519{
6520 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006521
6522 ath10k_dbg(ar, ATH10K_DBG_MAC,
6523 "mac chanctx add freq %hu width %d ptr %p\n",
6524 ctx->def.chan->center_freq, ctx->def.width, ctx);
6525
6526 mutex_lock(&ar->conf_mutex);
6527
6528 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006529 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006530 spin_unlock_bh(&ar->data_lock);
6531
6532 ath10k_recalc_radar_detection(ar);
6533 ath10k_monitor_recalc(ar);
6534
6535 mutex_unlock(&ar->conf_mutex);
6536
6537 return 0;
6538}
6539
6540static void
6541ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
6542 struct ieee80211_chanctx_conf *ctx)
6543{
6544 struct ath10k *ar = hw->priv;
6545
6546 ath10k_dbg(ar, ATH10K_DBG_MAC,
6547 "mac chanctx remove freq %hu width %d ptr %p\n",
6548 ctx->def.chan->center_freq, ctx->def.width, ctx);
6549
6550 mutex_lock(&ar->conf_mutex);
6551
6552 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006553 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006554 spin_unlock_bh(&ar->data_lock);
6555
6556 ath10k_recalc_radar_detection(ar);
6557 ath10k_monitor_recalc(ar);
6558
6559 mutex_unlock(&ar->conf_mutex);
6560}
6561
Michal Kazior9713e3d2015-09-03 10:44:52 +02006562struct ath10k_mac_change_chanctx_arg {
6563 struct ieee80211_chanctx_conf *ctx;
6564 struct ieee80211_vif_chanctx_switch *vifs;
6565 int n_vifs;
6566 int next_vif;
6567};
6568
6569static void
6570ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
6571 struct ieee80211_vif *vif)
6572{
6573 struct ath10k_mac_change_chanctx_arg *arg = data;
6574
6575 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
6576 return;
6577
6578 arg->n_vifs++;
6579}
6580
6581static void
6582ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
6583 struct ieee80211_vif *vif)
6584{
6585 struct ath10k_mac_change_chanctx_arg *arg = data;
6586 struct ieee80211_chanctx_conf *ctx;
6587
6588 ctx = rcu_access_pointer(vif->chanctx_conf);
6589 if (ctx != arg->ctx)
6590 return;
6591
6592 if (WARN_ON(arg->next_vif == arg->n_vifs))
6593 return;
6594
6595 arg->vifs[arg->next_vif].vif = vif;
6596 arg->vifs[arg->next_vif].old_ctx = ctx;
6597 arg->vifs[arg->next_vif].new_ctx = ctx;
6598 arg->next_vif++;
6599}
6600
Michal Kazior500ff9f2015-03-31 10:26:21 +00006601static void
6602ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
6603 struct ieee80211_chanctx_conf *ctx,
6604 u32 changed)
6605{
6606 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02006607 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00006608
6609 mutex_lock(&ar->conf_mutex);
6610
6611 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior089ab7a2015-06-03 12:16:55 +02006612 "mac chanctx change freq %hu width %d ptr %p changed %x\n",
6613 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006614
6615 /* This shouldn't really happen because channel switching should use
6616 * switch_vif_chanctx().
6617 */
6618 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
6619 goto unlock;
6620
Michal Kazior9713e3d2015-09-03 10:44:52 +02006621 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
6622 ieee80211_iterate_active_interfaces_atomic(
6623 hw,
6624 IEEE80211_IFACE_ITER_NORMAL,
6625 ath10k_mac_change_chanctx_cnt_iter,
6626 &arg);
6627 if (arg.n_vifs == 0)
6628 goto radar;
6629
6630 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
6631 GFP_KERNEL);
6632 if (!arg.vifs)
6633 goto radar;
6634
6635 ieee80211_iterate_active_interfaces_atomic(
6636 hw,
6637 IEEE80211_IFACE_ITER_NORMAL,
6638 ath10k_mac_change_chanctx_fill_iter,
6639 &arg);
6640 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
6641 kfree(arg.vifs);
6642 }
6643
6644radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00006645 ath10k_recalc_radar_detection(ar);
6646
6647 /* FIXME: How to configure Rx chains properly? */
6648
6649 /* No other actions are actually necessary. Firmware maintains channel
6650 * definitions per vdev internally and there's no host-side channel
6651 * context abstraction to configure, e.g. channel width.
6652 */
6653
6654unlock:
6655 mutex_unlock(&ar->conf_mutex);
6656}
6657
6658static int
6659ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
6660 struct ieee80211_vif *vif,
6661 struct ieee80211_chanctx_conf *ctx)
6662{
6663 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006664 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6665 int ret;
6666
6667 mutex_lock(&ar->conf_mutex);
6668
6669 ath10k_dbg(ar, ATH10K_DBG_MAC,
6670 "mac chanctx assign ptr %p vdev_id %i\n",
6671 ctx, arvif->vdev_id);
6672
6673 if (WARN_ON(arvif->is_started)) {
6674 mutex_unlock(&ar->conf_mutex);
6675 return -EBUSY;
6676 }
6677
Michal Kazior089ab7a2015-06-03 12:16:55 +02006678 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006679 if (ret) {
6680 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
6681 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02006682 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006683 goto err;
6684 }
6685
6686 arvif->is_started = true;
6687
Michal Kaziorf23e587e2015-07-09 13:08:37 +02006688 ret = ath10k_mac_vif_setup_ps(arvif);
6689 if (ret) {
6690 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
6691 arvif->vdev_id, ret);
6692 goto err_stop;
6693 }
6694
Michal Kazior500ff9f2015-03-31 10:26:21 +00006695 if (vif->type == NL80211_IFTYPE_MONITOR) {
6696 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
6697 if (ret) {
6698 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
6699 arvif->vdev_id, ret);
6700 goto err_stop;
6701 }
6702
6703 arvif->is_up = true;
6704 }
6705
6706 mutex_unlock(&ar->conf_mutex);
6707 return 0;
6708
6709err_stop:
6710 ath10k_vdev_stop(arvif);
6711 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02006712 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006713
6714err:
6715 mutex_unlock(&ar->conf_mutex);
6716 return ret;
6717}
6718
6719static void
6720ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
6721 struct ieee80211_vif *vif,
6722 struct ieee80211_chanctx_conf *ctx)
6723{
6724 struct ath10k *ar = hw->priv;
6725 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6726 int ret;
6727
6728 mutex_lock(&ar->conf_mutex);
6729
6730 ath10k_dbg(ar, ATH10K_DBG_MAC,
6731 "mac chanctx unassign ptr %p vdev_id %i\n",
6732 ctx, arvif->vdev_id);
6733
6734 WARN_ON(!arvif->is_started);
6735
6736 if (vif->type == NL80211_IFTYPE_MONITOR) {
6737 WARN_ON(!arvif->is_up);
6738
6739 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
6740 if (ret)
6741 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
6742 arvif->vdev_id, ret);
6743
6744 arvif->is_up = false;
6745 }
6746
6747 ret = ath10k_vdev_stop(arvif);
6748 if (ret)
6749 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
6750 arvif->vdev_id, ret);
6751
6752 arvif->is_started = false;
6753
6754 mutex_unlock(&ar->conf_mutex);
6755}
6756
6757static int
6758ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
6759 struct ieee80211_vif_chanctx_switch *vifs,
6760 int n_vifs,
6761 enum ieee80211_chanctx_switch_mode mode)
6762{
6763 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006764
6765 mutex_lock(&ar->conf_mutex);
6766
6767 ath10k_dbg(ar, ATH10K_DBG_MAC,
6768 "mac chanctx switch n_vifs %d mode %d\n",
6769 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02006770 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006771
6772 mutex_unlock(&ar->conf_mutex);
6773 return 0;
6774}
6775
Kalle Valo5e3dd152013-06-12 20:52:10 +03006776static const struct ieee80211_ops ath10k_ops = {
6777 .tx = ath10k_tx,
6778 .start = ath10k_start,
6779 .stop = ath10k_stop,
6780 .config = ath10k_config,
6781 .add_interface = ath10k_add_interface,
6782 .remove_interface = ath10k_remove_interface,
6783 .configure_filter = ath10k_configure_filter,
6784 .bss_info_changed = ath10k_bss_info_changed,
6785 .hw_scan = ath10k_hw_scan,
6786 .cancel_hw_scan = ath10k_cancel_hw_scan,
6787 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006788 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03006789 .sta_state = ath10k_sta_state,
6790 .conf_tx = ath10k_conf_tx,
6791 .remain_on_channel = ath10k_remain_on_channel,
6792 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
6793 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02006794 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03006795 .flush = ath10k_flush,
6796 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03006797 .set_antenna = ath10k_set_antenna,
6798 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006799 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02006800 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00006801 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01006802 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006803 .get_tsf = ath10k_get_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006804 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03006805 .get_et_sset_count = ath10k_debug_get_et_sset_count,
6806 .get_et_stats = ath10k_debug_get_et_stats,
6807 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00006808 .add_chanctx = ath10k_mac_op_add_chanctx,
6809 .remove_chanctx = ath10k_mac_op_remove_chanctx,
6810 .change_chanctx = ath10k_mac_op_change_chanctx,
6811 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
6812 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
6813 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Kalle Valo43d2a302014-09-10 18:23:30 +03006814
6815 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
6816
Michal Kazior8cd13ca2013-07-16 09:38:54 +02006817#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02006818 .suspend = ath10k_wow_op_suspend,
6819 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02006820#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02006821#ifdef CONFIG_MAC80211_DEBUGFS
6822 .sta_add_debugfs = ath10k_sta_add_debugfs,
6823#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03006824};
6825
Kalle Valo5e3dd152013-06-12 20:52:10 +03006826#define CHAN2G(_channel, _freq, _flags) { \
6827 .band = IEEE80211_BAND_2GHZ, \
6828 .hw_value = (_channel), \
6829 .center_freq = (_freq), \
6830 .flags = (_flags), \
6831 .max_antenna_gain = 0, \
6832 .max_power = 30, \
6833}
6834
6835#define CHAN5G(_channel, _freq, _flags) { \
6836 .band = IEEE80211_BAND_5GHZ, \
6837 .hw_value = (_channel), \
6838 .center_freq = (_freq), \
6839 .flags = (_flags), \
6840 .max_antenna_gain = 0, \
6841 .max_power = 30, \
6842}
6843
6844static const struct ieee80211_channel ath10k_2ghz_channels[] = {
6845 CHAN2G(1, 2412, 0),
6846 CHAN2G(2, 2417, 0),
6847 CHAN2G(3, 2422, 0),
6848 CHAN2G(4, 2427, 0),
6849 CHAN2G(5, 2432, 0),
6850 CHAN2G(6, 2437, 0),
6851 CHAN2G(7, 2442, 0),
6852 CHAN2G(8, 2447, 0),
6853 CHAN2G(9, 2452, 0),
6854 CHAN2G(10, 2457, 0),
6855 CHAN2G(11, 2462, 0),
6856 CHAN2G(12, 2467, 0),
6857 CHAN2G(13, 2472, 0),
6858 CHAN2G(14, 2484, 0),
6859};
6860
6861static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02006862 CHAN5G(36, 5180, 0),
6863 CHAN5G(40, 5200, 0),
6864 CHAN5G(44, 5220, 0),
6865 CHAN5G(48, 5240, 0),
6866 CHAN5G(52, 5260, 0),
6867 CHAN5G(56, 5280, 0),
6868 CHAN5G(60, 5300, 0),
6869 CHAN5G(64, 5320, 0),
6870 CHAN5G(100, 5500, 0),
6871 CHAN5G(104, 5520, 0),
6872 CHAN5G(108, 5540, 0),
6873 CHAN5G(112, 5560, 0),
6874 CHAN5G(116, 5580, 0),
6875 CHAN5G(120, 5600, 0),
6876 CHAN5G(124, 5620, 0),
6877 CHAN5G(128, 5640, 0),
6878 CHAN5G(132, 5660, 0),
6879 CHAN5G(136, 5680, 0),
6880 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07006881 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02006882 CHAN5G(149, 5745, 0),
6883 CHAN5G(153, 5765, 0),
6884 CHAN5G(157, 5785, 0),
6885 CHAN5G(161, 5805, 0),
6886 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03006887};
6888
Michal Kaziore7b54192014-08-07 11:03:27 +02006889struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006890{
6891 struct ieee80211_hw *hw;
6892 struct ath10k *ar;
6893
Michal Kaziore7b54192014-08-07 11:03:27 +02006894 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006895 if (!hw)
6896 return NULL;
6897
6898 ar = hw->priv;
6899 ar->hw = hw;
6900
6901 return ar;
6902}
6903
6904void ath10k_mac_destroy(struct ath10k *ar)
6905{
6906 ieee80211_free_hw(ar->hw);
6907}
6908
6909static const struct ieee80211_iface_limit ath10k_if_limits[] = {
6910 {
6911 .max = 8,
6912 .types = BIT(NL80211_IFTYPE_STATION)
6913 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02006914 },
6915 {
6916 .max = 3,
6917 .types = BIT(NL80211_IFTYPE_P2P_GO)
6918 },
6919 {
Michal Kazior75d2bd42014-12-12 12:41:39 +01006920 .max = 1,
6921 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
6922 },
6923 {
Michal Kaziord531cb82013-07-31 10:55:13 +02006924 .max = 7,
6925 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006926#ifdef CONFIG_MAC80211_MESH
6927 | BIT(NL80211_IFTYPE_MESH_POINT)
6928#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02006929 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03006930};
6931
Bartosz Markowskif2595092013-12-10 16:20:39 +01006932static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006933 {
6934 .max = 8,
6935 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006936#ifdef CONFIG_MAC80211_MESH
6937 | BIT(NL80211_IFTYPE_MESH_POINT)
6938#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006939 },
6940};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006941
6942static const struct ieee80211_iface_combination ath10k_if_comb[] = {
6943 {
6944 .limits = ath10k_if_limits,
6945 .n_limits = ARRAY_SIZE(ath10k_if_limits),
6946 .max_interfaces = 8,
6947 .num_different_channels = 1,
6948 .beacon_int_infra_match = true,
6949 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01006950};
6951
6952static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006953 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01006954 .limits = ath10k_10x_if_limits,
6955 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006956 .max_interfaces = 8,
6957 .num_different_channels = 1,
6958 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01006959#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006960 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
6961 BIT(NL80211_CHAN_WIDTH_20) |
6962 BIT(NL80211_CHAN_WIDTH_40) |
6963 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006964#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01006965 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03006966};
6967
Michal Kaziorcf327842015-03-31 10:26:25 +00006968static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
6969 {
6970 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02006971 .types = BIT(NL80211_IFTYPE_STATION),
6972 },
6973 {
6974 .max = 2,
6975 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006976#ifdef CONFIG_MAC80211_MESH
6977 BIT(NL80211_IFTYPE_MESH_POINT) |
6978#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00006979 BIT(NL80211_IFTYPE_P2P_CLIENT) |
6980 BIT(NL80211_IFTYPE_P2P_GO),
6981 },
6982 {
6983 .max = 1,
6984 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
6985 },
6986};
6987
Michal Kaziored25b112015-07-09 13:08:39 +02006988static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
6989 {
6990 .max = 2,
6991 .types = BIT(NL80211_IFTYPE_STATION),
6992 },
6993 {
6994 .max = 2,
6995 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
6996 },
6997 {
6998 .max = 1,
6999 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007000#ifdef CONFIG_MAC80211_MESH
7001 BIT(NL80211_IFTYPE_MESH_POINT) |
7002#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007003 BIT(NL80211_IFTYPE_P2P_GO),
7004 },
7005 {
7006 .max = 1,
7007 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7008 },
7009};
7010
Michal Kaziorcf327842015-03-31 10:26:25 +00007011static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7012 {
7013 .max = 1,
7014 .types = BIT(NL80211_IFTYPE_STATION),
7015 },
7016 {
7017 .max = 1,
7018 .types = BIT(NL80211_IFTYPE_ADHOC),
7019 },
7020};
7021
7022/* FIXME: This is not thouroughly tested. These combinations may over- or
7023 * underestimate hw/fw capabilities.
7024 */
7025static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7026 {
7027 .limits = ath10k_tlv_if_limit,
7028 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007029 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007030 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7031 },
7032 {
7033 .limits = ath10k_tlv_if_limit_ibss,
7034 .num_different_channels = 1,
7035 .max_interfaces = 2,
7036 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7037 },
7038};
7039
7040static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7041 {
7042 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007043 .num_different_channels = 1,
7044 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007045 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7046 },
7047 {
Michal Kaziored25b112015-07-09 13:08:39 +02007048 .limits = ath10k_tlv_qcs_if_limit,
7049 .num_different_channels = 2,
7050 .max_interfaces = 4,
7051 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7052 },
7053 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007054 .limits = ath10k_tlv_if_limit_ibss,
7055 .num_different_channels = 1,
7056 .max_interfaces = 2,
7057 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7058 },
7059};
7060
Raja Manicf36fef2015-06-22 20:22:25 +05307061static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
7062 {
7063 .max = 1,
7064 .types = BIT(NL80211_IFTYPE_STATION),
7065 },
7066 {
7067 .max = 16,
7068 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007069#ifdef CONFIG_MAC80211_MESH
7070 | BIT(NL80211_IFTYPE_MESH_POINT)
7071#endif
Raja Manicf36fef2015-06-22 20:22:25 +05307072 },
7073};
7074
7075static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
7076 {
7077 .limits = ath10k_10_4_if_limits,
7078 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
7079 .max_interfaces = 16,
7080 .num_different_channels = 1,
7081 .beacon_int_infra_match = true,
7082#ifdef CONFIG_ATH10K_DFS_CERTIFIED
7083 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7084 BIT(NL80211_CHAN_WIDTH_20) |
7085 BIT(NL80211_CHAN_WIDTH_40) |
7086 BIT(NL80211_CHAN_WIDTH_80),
7087#endif
7088 },
7089};
7090
Kalle Valo5e3dd152013-06-12 20:52:10 +03007091static void ath10k_get_arvif_iter(void *data, u8 *mac,
7092 struct ieee80211_vif *vif)
7093{
7094 struct ath10k_vif_iter *arvif_iter = data;
7095 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7096
7097 if (arvif->vdev_id == arvif_iter->vdev_id)
7098 arvif_iter->arvif = arvif;
7099}
7100
7101struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
7102{
7103 struct ath10k_vif_iter arvif_iter;
7104 u32 flags;
7105
7106 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
7107 arvif_iter.vdev_id = vdev_id;
7108
7109 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
7110 ieee80211_iterate_active_interfaces_atomic(ar->hw,
7111 flags,
7112 ath10k_get_arvif_iter,
7113 &arvif_iter);
7114 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007115 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007116 return NULL;
7117 }
7118
7119 return arvif_iter.arvif;
7120}
7121
7122int ath10k_mac_register(struct ath10k *ar)
7123{
Johannes Berg3cb10942015-01-22 21:38:45 +01007124 static const u32 cipher_suites[] = {
7125 WLAN_CIPHER_SUITE_WEP40,
7126 WLAN_CIPHER_SUITE_WEP104,
7127 WLAN_CIPHER_SUITE_TKIP,
7128 WLAN_CIPHER_SUITE_CCMP,
7129 WLAN_CIPHER_SUITE_AES_CMAC,
7130 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03007131 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007132 void *channels;
7133 int ret;
7134
7135 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
7136
7137 SET_IEEE80211_DEV(ar->hw, ar->dev);
7138
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00007139 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
7140 ARRAY_SIZE(ath10k_5ghz_channels)) !=
7141 ATH10K_NUM_CHANS);
7142
Kalle Valo5e3dd152013-06-12 20:52:10 +03007143 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
7144 channels = kmemdup(ath10k_2ghz_channels,
7145 sizeof(ath10k_2ghz_channels),
7146 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02007147 if (!channels) {
7148 ret = -ENOMEM;
7149 goto err_free;
7150 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007151
7152 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
7153 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
7154 band->channels = channels;
7155 band->n_bitrates = ath10k_g_rates_size;
7156 band->bitrates = ath10k_g_rates;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007157
7158 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
7159 }
7160
7161 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
7162 channels = kmemdup(ath10k_5ghz_channels,
7163 sizeof(ath10k_5ghz_channels),
7164 GFP_KERNEL);
7165 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02007166 ret = -ENOMEM;
7167 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007168 }
7169
7170 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
7171 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
7172 band->channels = channels;
7173 band->n_bitrates = ath10k_a_rates_size;
7174 band->bitrates = ath10k_a_rates;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007175 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
7176 }
7177
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05307178 ath10k_mac_setup_ht_vht_cap(ar);
7179
Kalle Valo5e3dd152013-06-12 20:52:10 +03007180 ar->hw->wiphy->interface_modes =
7181 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007182 BIT(NL80211_IFTYPE_AP) |
7183 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01007184
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05307185 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
7186 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03007187
Bartosz Markowskid3541812013-12-10 16:20:40 +01007188 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
7189 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01007190 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01007191 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7192 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007193
Johannes Berg30686bf2015-06-02 21:39:54 +02007194 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
7195 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
7196 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
7197 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
7198 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
7199 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
7200 ieee80211_hw_set(ar->hw, AP_LINK_PS);
7201 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02007202 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
7203 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
7204 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
7205 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
7206 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
7207 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007208
David Liuccec9032015-07-24 20:25:32 +03007209 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7210 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
7211
Eliad Peller0d8614b2014-09-10 14:07:36 +03007212 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00007213 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03007214
Kalle Valo5e3dd152013-06-12 20:52:10 +03007215 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03007216 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007217
7218 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02007219 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
7220 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007221 }
7222
7223 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
7224 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
7225
7226 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01007227 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007228
Kalle Valo5e3dd152013-06-12 20:52:10 +03007229 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
7230
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02007231 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
7232 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
7233
7234 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
7235 * that userspace (e.g. wpa_supplicant/hostapd) can generate
7236 * correct Probe Responses. This is more of a hack advert..
7237 */
7238 ar->hw->wiphy->probe_resp_offload |=
7239 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
7240 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
7241 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
7242 }
7243
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03007244 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
7245 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7246
Kalle Valo5e3dd152013-06-12 20:52:10 +03007247 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01007248 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007249 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
7250
7251 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02007252 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
7253
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01007254 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
7255
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007256 ret = ath10k_wow_init(ar);
7257 if (ret) {
7258 ath10k_warn(ar, "failed to init wow: %d\n", ret);
7259 goto err_free;
7260 }
7261
Janusz Dziedzicc7025342015-06-15 14:46:41 +03007262 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
7263
Kalle Valo5e3dd152013-06-12 20:52:10 +03007264 /*
7265 * on LL hardware queues are managed entirely by the FW
7266 * so we only advertise to mac we can do the queues thing
7267 */
Michal Kazior96d828d2015-03-31 10:26:23 +00007268 ar->hw->queues = IEEE80211_MAX_QUEUES;
7269
7270 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
7271 * something that vdev_ids can't reach so that we don't stop the queue
7272 * accidentally.
7273 */
7274 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007275
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007276 switch (ar->wmi.op_version) {
7277 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01007278 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
7279 ar->hw->wiphy->n_iface_combinations =
7280 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03007281 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007282 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00007283 case ATH10K_FW_WMI_OP_VERSION_TLV:
7284 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
7285 ar->hw->wiphy->iface_combinations =
7286 ath10k_tlv_qcs_if_comb;
7287 ar->hw->wiphy->n_iface_combinations =
7288 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
7289 } else {
7290 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
7291 ar->hw->wiphy->n_iface_combinations =
7292 ARRAY_SIZE(ath10k_tlv_if_comb);
7293 }
7294 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
7295 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007296 case ATH10K_FW_WMI_OP_VERSION_10_1:
7297 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02007298 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007299 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
7300 ar->hw->wiphy->n_iface_combinations =
7301 ARRAY_SIZE(ath10k_10x_if_comb);
7302 break;
Raja Mani9bd21322015-06-22 20:10:09 +05307303 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05307304 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
7305 ar->hw->wiphy->n_iface_combinations =
7306 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05307307 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007308 case ATH10K_FW_WMI_OP_VERSION_UNSET:
7309 case ATH10K_FW_WMI_OP_VERSION_MAX:
7310 WARN_ON(1);
7311 ret = -EINVAL;
7312 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01007313 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007314
David Liuccec9032015-07-24 20:25:32 +03007315 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7316 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02007317
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007318 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
7319 /* Init ath dfs pattern detector */
7320 ar->ath_common.debug_mask = ATH_DBG_DFS;
7321 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
7322 NL80211_DFS_UNSET);
7323
7324 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02007325 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007326 }
7327
Kalle Valo5e3dd152013-06-12 20:52:10 +03007328 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
7329 ath10k_reg_notifier);
7330 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007331 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007332 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007333 }
7334
Johannes Berg3cb10942015-01-22 21:38:45 +01007335 ar->hw->wiphy->cipher_suites = cipher_suites;
7336 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
7337
Kalle Valo5e3dd152013-06-12 20:52:10 +03007338 ret = ieee80211_register_hw(ar->hw);
7339 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007340 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007341 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007342 }
7343
7344 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
7345 ret = regulatory_hint(ar->hw->wiphy,
7346 ar->ath_common.regulatory.alpha2);
7347 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02007348 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007349 }
7350
7351 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02007352
7353err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03007354 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07007355
7356err_dfs_detector_exit:
7357 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7358 ar->dfs_detector->exit(ar->dfs_detector);
7359
Michal Kaziord6015b22013-07-22 14:13:30 +02007360err_free:
7361 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
7362 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
7363
Jeff Johnson0e339442015-10-08 09:15:53 -07007364 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007365 return ret;
7366}
7367
7368void ath10k_mac_unregister(struct ath10k *ar)
7369{
7370 ieee80211_unregister_hw(ar->hw);
7371
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007372 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7373 ar->dfs_detector->exit(ar->dfs_detector);
7374
Kalle Valo5e3dd152013-06-12 20:52:10 +03007375 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
7376 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
7377
7378 SET_IEEE80211_DEV(ar->hw, NULL);
7379}