blob: 76484a9477550880ba27644fa328a0387b22a8c9 [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,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02001971 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001972 struct wmi_peer_assoc_complete_arg *arg)
1973{
Kalle Valo5e3dd152013-06-12 20:52:10 +03001974 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00001975 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001976 struct cfg80211_bss *bss;
1977 const u8 *rsnie = NULL;
1978 const u8 *wpaie = NULL;
1979
Michal Kazior548db542013-07-05 16:15:15 +03001980 lockdep_assert_held(&ar->conf_mutex);
1981
Michal Kazior500ff9f2015-03-31 10:26:21 +00001982 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
1983 return;
1984
1985 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
1986 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001987 if (bss) {
1988 const struct cfg80211_bss_ies *ies;
1989
1990 rcu_read_lock();
1991 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
1992
1993 ies = rcu_dereference(bss->ies);
1994
1995 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03001996 WLAN_OUI_TYPE_MICROSOFT_WPA,
1997 ies->data,
1998 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001999 rcu_read_unlock();
2000 cfg80211_put_bss(ar->hw->wiphy, bss);
2001 }
2002
2003 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2004 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002005 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002006 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002007 }
2008
2009 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002010 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002011 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002012 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002013
2014 if (sta->mfp &&
2015 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT, ar->fw_features)) {
2016 arg->peer_flags |= ar->wmi.peer_flags->pmf;
2017 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002018}
2019
2020static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002021 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002022 struct ieee80211_sta *sta,
2023 struct wmi_peer_assoc_complete_arg *arg)
2024{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002025 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002026 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002027 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002028 const struct ieee80211_supported_band *sband;
2029 const struct ieee80211_rate *rates;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002030 enum ieee80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002031 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002032 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002033 int i;
2034
Michal Kazior548db542013-07-05 16:15:15 +03002035 lockdep_assert_held(&ar->conf_mutex);
2036
Michal Kazior500ff9f2015-03-31 10:26:21 +00002037 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2038 return;
2039
Michal Kazior45c9abc2015-04-21 20:42:58 +03002040 band = def.chan->band;
2041 sband = ar->hw->wiphy->bands[band];
2042 ratemask = sta->supp_rates[band];
2043 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002044 rates = sband->bitrates;
2045
2046 rateset->num_rates = 0;
2047
2048 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2049 if (!(ratemask & 1))
2050 continue;
2051
Michal Kazior486017c2015-03-30 09:51:54 +03002052 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2053 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002054 rateset->num_rates++;
2055 }
2056}
2057
Michal Kazior45c9abc2015-04-21 20:42:58 +03002058static bool
2059ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2060{
2061 int nss;
2062
2063 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2064 if (ht_mcs_mask[nss])
2065 return false;
2066
2067 return true;
2068}
2069
2070static bool
2071ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2072{
2073 int nss;
2074
2075 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2076 if (vht_mcs_mask[nss])
2077 return false;
2078
2079 return true;
2080}
2081
Kalle Valo5e3dd152013-06-12 20:52:10 +03002082static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002083 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002084 struct ieee80211_sta *sta,
2085 struct wmi_peer_assoc_complete_arg *arg)
2086{
2087 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002088 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2089 struct cfg80211_chan_def def;
2090 enum ieee80211_band band;
2091 const u8 *ht_mcs_mask;
2092 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002093 int i, n;
2094 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002095 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002096
Michal Kazior548db542013-07-05 16:15:15 +03002097 lockdep_assert_held(&ar->conf_mutex);
2098
Michal Kazior45c9abc2015-04-21 20:42:58 +03002099 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2100 return;
2101
Kalle Valo5e3dd152013-06-12 20:52:10 +03002102 if (!ht_cap->ht_supported)
2103 return;
2104
Michal Kazior45c9abc2015-04-21 20:42:58 +03002105 band = def.chan->band;
2106 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2107 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2108
2109 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2110 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2111 return;
2112
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002113 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002114 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2115 ht_cap->ampdu_factor)) - 1;
2116
2117 arg->peer_mpdu_density =
2118 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2119
2120 arg->peer_ht_caps = ht_cap->cap;
2121 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2122
2123 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002124 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002125
2126 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002127 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002128 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2129 }
2130
Michal Kazior45c9abc2015-04-21 20:42:58 +03002131 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2132 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2133 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002134
Michal Kazior45c9abc2015-04-21 20:42:58 +03002135 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2136 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2137 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002138
2139 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2140 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002141 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002142 }
2143
2144 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002145 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2146 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2147 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2148 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002149 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002150 }
2151
Kalle Valo5e3dd152013-06-12 20:52:10 +03002152 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2153 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2154 else if (ht_cap->mcs.rx_mask[1])
2155 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2156
Michal Kazior45c9abc2015-04-21 20:42:58 +03002157 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2158 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2159 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2160 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002161 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002162 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002163
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002164 /*
2165 * This is a workaround for HT-enabled STAs which break the spec
2166 * and have no HT capabilities RX mask (no HT RX MCS map).
2167 *
2168 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2169 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2170 *
2171 * Firmware asserts if such situation occurs.
2172 */
2173 if (n == 0) {
2174 arg->peer_ht_rates.num_rates = 8;
2175 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2176 arg->peer_ht_rates.rates[i] = i;
2177 } else {
2178 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002179 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002180 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002181
Michal Kazior7aa7a722014-08-25 12:09:38 +02002182 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002183 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002184 arg->peer_ht_rates.num_rates,
2185 arg->peer_num_spatial_streams);
2186}
2187
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002188static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2189 struct ath10k_vif *arvif,
2190 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002191{
2192 u32 uapsd = 0;
2193 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002194 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002195
Michal Kazior548db542013-07-05 16:15:15 +03002196 lockdep_assert_held(&ar->conf_mutex);
2197
Kalle Valo5e3dd152013-06-12 20:52:10 +03002198 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002199 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002200 sta->uapsd_queues, sta->max_sp);
2201
Kalle Valo5e3dd152013-06-12 20:52:10 +03002202 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2203 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2204 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2205 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2206 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2207 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2208 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2209 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2210 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2211 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2212 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2213 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2214
Kalle Valo5e3dd152013-06-12 20:52:10 +03002215 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2216 max_sp = sta->max_sp;
2217
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002218 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2219 sta->addr,
2220 WMI_AP_PS_PEER_PARAM_UAPSD,
2221 uapsd);
2222 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002223 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002224 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002225 return ret;
2226 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002227
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002228 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2229 sta->addr,
2230 WMI_AP_PS_PEER_PARAM_MAX_SP,
2231 max_sp);
2232 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002233 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002234 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002235 return ret;
2236 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002237
2238 /* TODO setup this based on STA listen interval and
2239 beacon interval. Currently we don't know
2240 sta->listen_interval - mac80211 patch required.
2241 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002242 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002243 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2244 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002245 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002246 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002247 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002248 return ret;
2249 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002250 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002251
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002252 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002253}
2254
Michal Kazior45c9abc2015-04-21 20:42:58 +03002255static u16
2256ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2257 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2258{
2259 int idx_limit;
2260 int nss;
2261 u16 mcs_map;
2262 u16 mcs;
2263
2264 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2265 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2266 vht_mcs_limit[nss];
2267
2268 if (mcs_map)
2269 idx_limit = fls(mcs_map) - 1;
2270 else
2271 idx_limit = -1;
2272
2273 switch (idx_limit) {
2274 case 0: /* fall through */
2275 case 1: /* fall through */
2276 case 2: /* fall through */
2277 case 3: /* fall through */
2278 case 4: /* fall through */
2279 case 5: /* fall through */
2280 case 6: /* fall through */
2281 default:
2282 /* see ath10k_mac_can_set_bitrate_mask() */
2283 WARN_ON(1);
2284 /* fall through */
2285 case -1:
2286 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2287 break;
2288 case 7:
2289 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2290 break;
2291 case 8:
2292 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2293 break;
2294 case 9:
2295 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2296 break;
2297 }
2298
2299 tx_mcs_set &= ~(0x3 << (nss * 2));
2300 tx_mcs_set |= mcs << (nss * 2);
2301 }
2302
2303 return tx_mcs_set;
2304}
2305
Kalle Valo5e3dd152013-06-12 20:52:10 +03002306static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002307 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002308 struct ieee80211_sta *sta,
2309 struct wmi_peer_assoc_complete_arg *arg)
2310{
2311 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002312 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002313 struct cfg80211_chan_def def;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002314 enum ieee80211_band band;
2315 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002316 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002317
Michal Kazior500ff9f2015-03-31 10:26:21 +00002318 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2319 return;
2320
Kalle Valo5e3dd152013-06-12 20:52:10 +03002321 if (!vht_cap->vht_supported)
2322 return;
2323
Michal Kazior45c9abc2015-04-21 20:42:58 +03002324 band = def.chan->band;
2325 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2326
2327 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2328 return;
2329
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002330 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002331
Michal Kazior500ff9f2015-03-31 10:26:21 +00002332 if (def.chan->band == IEEE80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002333 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002334
Kalle Valo5e3dd152013-06-12 20:52:10 +03002335 arg->peer_vht_caps = vht_cap->cap;
2336
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002337 ampdu_factor = (vht_cap->cap &
2338 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2339 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2340
2341 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2342 * zero in VHT IE. Using it would result in degraded throughput.
2343 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2344 * it if VHT max_mpdu is smaller. */
2345 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2346 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2347 ampdu_factor)) - 1);
2348
Kalle Valo5e3dd152013-06-12 20:52:10 +03002349 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002350 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002351
2352 arg->peer_vht_rates.rx_max_rate =
2353 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2354 arg->peer_vht_rates.rx_mcs_set =
2355 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2356 arg->peer_vht_rates.tx_max_rate =
2357 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002358 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2359 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002360
Michal Kazior7aa7a722014-08-25 12:09:38 +02002361 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002362 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002363}
2364
2365static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002366 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002367 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002368 struct wmi_peer_assoc_complete_arg *arg)
2369{
Michal Kazior590922a2014-10-21 10:10:29 +03002370 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2371
Kalle Valo5e3dd152013-06-12 20:52:10 +03002372 switch (arvif->vdev_type) {
2373 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002374 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002375 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002376
2377 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002378 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002379 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2380 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002381 break;
2382 case WMI_VDEV_TYPE_STA:
Michal Kazior590922a2014-10-21 10:10:29 +03002383 if (vif->bss_conf.qos)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002384 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002385 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002386 case WMI_VDEV_TYPE_IBSS:
2387 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002388 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002389 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002390 default:
2391 break;
2392 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002393
2394 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002395 sta->addr, !!(arg->peer_flags &
2396 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002397}
2398
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002399static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002400{
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002401 return sta->supp_rates[IEEE80211_BAND_2GHZ] >>
2402 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002403}
2404
Kalle Valo5e3dd152013-06-12 20:52:10 +03002405static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002406 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002407 struct ieee80211_sta *sta,
2408 struct wmi_peer_assoc_complete_arg *arg)
2409{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002410 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002411 struct cfg80211_chan_def def;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002412 enum ieee80211_band band;
2413 const u8 *ht_mcs_mask;
2414 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002415 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2416
Michal Kazior500ff9f2015-03-31 10:26:21 +00002417 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2418 return;
2419
Michal Kazior45c9abc2015-04-21 20:42:58 +03002420 band = def.chan->band;
2421 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2422 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2423
2424 switch (band) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002425 case IEEE80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002426 if (sta->vht_cap.vht_supported &&
2427 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002428 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2429 phymode = MODE_11AC_VHT40;
2430 else
2431 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002432 } else if (sta->ht_cap.ht_supported &&
2433 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002434 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2435 phymode = MODE_11NG_HT40;
2436 else
2437 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002438 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002439 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002440 } else {
2441 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002442 }
2443
2444 break;
2445 case IEEE80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002446 /*
2447 * Check VHT first.
2448 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002449 if (sta->vht_cap.vht_supported &&
2450 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002451 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2452 phymode = MODE_11AC_VHT80;
2453 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2454 phymode = MODE_11AC_VHT40;
2455 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2456 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002457 } else if (sta->ht_cap.ht_supported &&
2458 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2459 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002460 phymode = MODE_11NA_HT40;
2461 else
2462 phymode = MODE_11NA_HT20;
2463 } else {
2464 phymode = MODE_11A;
2465 }
2466
2467 break;
2468 default:
2469 break;
2470 }
2471
Michal Kazior7aa7a722014-08-25 12:09:38 +02002472 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002473 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002474
Kalle Valo5e3dd152013-06-12 20:52:10 +03002475 arg->peer_phymode = phymode;
2476 WARN_ON(phymode == MODE_UNKNOWN);
2477}
2478
Kalle Valob9ada652013-10-16 15:44:46 +03002479static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002480 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002481 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002482 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002483{
Michal Kazior548db542013-07-05 16:15:15 +03002484 lockdep_assert_held(&ar->conf_mutex);
2485
Kalle Valob9ada652013-10-16 15:44:46 +03002486 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002487
Michal Kazior590922a2014-10-21 10:10:29 +03002488 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002489 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002490 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002491 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002492 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002493 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2494 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002495
Kalle Valob9ada652013-10-16 15:44:46 +03002496 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002497}
2498
Michal Kazior90046f52014-02-14 14:45:51 +01002499static const u32 ath10k_smps_map[] = {
2500 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2501 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2502 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2503 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2504};
2505
2506static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2507 const u8 *addr,
2508 const struct ieee80211_sta_ht_cap *ht_cap)
2509{
2510 int smps;
2511
2512 if (!ht_cap->ht_supported)
2513 return 0;
2514
2515 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2516 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2517
2518 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2519 return -EINVAL;
2520
2521 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2522 WMI_PEER_SMPS_STATE,
2523 ath10k_smps_map[smps]);
2524}
2525
Michal Kazior139e1702015-02-15 16:50:42 +02002526static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2527 struct ieee80211_vif *vif,
2528 struct ieee80211_sta_vht_cap vht_cap)
2529{
2530 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2531 int ret;
2532 u32 param;
2533 u32 value;
2534
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302535 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2536 return 0;
2537
Michal Kazior139e1702015-02-15 16:50:42 +02002538 if (!(ar->vht_cap_info &
2539 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2540 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2541 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2542 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2543 return 0;
2544
2545 param = ar->wmi.vdev_param->txbf;
2546 value = 0;
2547
2548 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2549 return 0;
2550
2551 /* The following logic is correct. If a remote STA advertises support
2552 * for being a beamformer then we should enable us being a beamformee.
2553 */
2554
2555 if (ar->vht_cap_info &
2556 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2557 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2558 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2559 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2560
2561 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2562 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2563 }
2564
2565 if (ar->vht_cap_info &
2566 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2567 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2568 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2569 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2570
2571 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2572 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2573 }
2574
2575 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2576 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2577
2578 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2579 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2580
2581 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2582 if (ret) {
2583 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2584 value, ret);
2585 return ret;
2586 }
2587
2588 return 0;
2589}
2590
Kalle Valo5e3dd152013-06-12 20:52:10 +03002591/* can be called only in mac80211 callbacks due to `key_count` usage */
2592static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2593 struct ieee80211_vif *vif,
2594 struct ieee80211_bss_conf *bss_conf)
2595{
2596 struct ath10k *ar = hw->priv;
2597 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002598 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002599 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002600 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002601 struct ieee80211_sta *ap_sta;
2602 int ret;
2603
Michal Kazior548db542013-07-05 16:15:15 +03002604 lockdep_assert_held(&ar->conf_mutex);
2605
Michal Kazior077efc82014-10-21 10:10:29 +03002606 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2607 arvif->vdev_id, arvif->bssid, arvif->aid);
2608
Kalle Valo5e3dd152013-06-12 20:52:10 +03002609 rcu_read_lock();
2610
2611 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2612 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002613 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002614 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002615 rcu_read_unlock();
2616 return;
2617 }
2618
Michal Kazior90046f52014-02-14 14:45:51 +01002619 /* ap_sta must be accessed only within rcu section which must be left
2620 * before calling ath10k_setup_peer_smps() which might sleep. */
2621 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002622 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002623
Michal Kazior590922a2014-10-21 10:10:29 +03002624 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002625 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002626 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002627 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002628 rcu_read_unlock();
2629 return;
2630 }
2631
2632 rcu_read_unlock();
2633
Kalle Valob9ada652013-10-16 15:44:46 +03002634 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2635 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002636 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002637 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002638 return;
2639 }
2640
Michal Kazior90046f52014-02-14 14:45:51 +01002641 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2642 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002643 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002644 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002645 return;
2646 }
2647
Michal Kazior139e1702015-02-15 16:50:42 +02002648 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2649 if (ret) {
2650 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2651 arvif->vdev_id, bss_conf->bssid, ret);
2652 return;
2653 }
2654
Michal Kazior7aa7a722014-08-25 12:09:38 +02002655 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002656 "mac vdev %d up (associated) bssid %pM aid %d\n",
2657 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2658
Michal Kazior077efc82014-10-21 10:10:29 +03002659 WARN_ON(arvif->is_up);
2660
Michal Kaziorc930f742014-01-23 11:38:25 +01002661 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002662 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002663
2664 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2665 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002666 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002667 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002668 return;
2669 }
2670
2671 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002672
2673 /* Workaround: Some firmware revisions (tested with qca6174
2674 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2675 * poked with peer param command.
2676 */
2677 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2678 WMI_PEER_DUMMY_VAR, 1);
2679 if (ret) {
2680 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2681 arvif->bssid, arvif->vdev_id, ret);
2682 return;
2683 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002684}
2685
Kalle Valo5e3dd152013-06-12 20:52:10 +03002686static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2687 struct ieee80211_vif *vif)
2688{
2689 struct ath10k *ar = hw->priv;
2690 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002691 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002692 int ret;
2693
Michal Kazior548db542013-07-05 16:15:15 +03002694 lockdep_assert_held(&ar->conf_mutex);
2695
Michal Kazior077efc82014-10-21 10:10:29 +03002696 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2697 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002698
Kalle Valo5e3dd152013-06-12 20:52:10 +03002699 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002700 if (ret)
2701 ath10k_warn(ar, "faield to down vdev %i: %d\n",
2702 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002703
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002704 arvif->def_wep_key_idx = -1;
2705
Michal Kazior139e1702015-02-15 16:50:42 +02002706 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2707 if (ret) {
2708 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2709 arvif->vdev_id, ret);
2710 return;
2711 }
2712
Michal Kaziorc930f742014-01-23 11:38:25 +01002713 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002714
2715 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002716}
2717
Michal Kazior590922a2014-10-21 10:10:29 +03002718static int ath10k_station_assoc(struct ath10k *ar,
2719 struct ieee80211_vif *vif,
2720 struct ieee80211_sta *sta,
2721 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002722{
Michal Kazior590922a2014-10-21 10:10:29 +03002723 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002724 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002725 int ret = 0;
2726
Michal Kazior548db542013-07-05 16:15:15 +03002727 lockdep_assert_held(&ar->conf_mutex);
2728
Michal Kazior590922a2014-10-21 10:10:29 +03002729 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002730 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002731 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002732 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002733 return ret;
2734 }
2735
2736 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2737 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002738 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002739 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002740 return ret;
2741 }
2742
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002743 /* Re-assoc is run only to update supported rates for given station. It
2744 * doesn't make much sense to reconfigure the peer completely.
2745 */
2746 if (!reassoc) {
2747 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2748 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002749 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002750 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002751 arvif->vdev_id, ret);
2752 return ret;
2753 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002754
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002755 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2756 if (ret) {
2757 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2758 sta->addr, arvif->vdev_id, ret);
2759 return ret;
2760 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002761
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002762 if (!sta->wme) {
2763 arvif->num_legacy_stations++;
2764 ret = ath10k_recalc_rtscts_prot(arvif);
2765 if (ret) {
2766 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2767 arvif->vdev_id, ret);
2768 return ret;
2769 }
2770 }
2771
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002772 /* Plumb cached keys only for static WEP */
2773 if (arvif->def_wep_key_idx != -1) {
2774 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2775 if (ret) {
2776 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2777 arvif->vdev_id, ret);
2778 return ret;
2779 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002780 }
2781 }
2782
Kalle Valo5e3dd152013-06-12 20:52:10 +03002783 return ret;
2784}
2785
Michal Kazior590922a2014-10-21 10:10:29 +03002786static int ath10k_station_disassoc(struct ath10k *ar,
2787 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002788 struct ieee80211_sta *sta)
2789{
Michal Kazior590922a2014-10-21 10:10:29 +03002790 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002791 int ret = 0;
2792
2793 lockdep_assert_held(&ar->conf_mutex);
2794
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002795 if (!sta->wme) {
2796 arvif->num_legacy_stations--;
2797 ret = ath10k_recalc_rtscts_prot(arvif);
2798 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002799 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002800 arvif->vdev_id, ret);
2801 return ret;
2802 }
2803 }
2804
Kalle Valo5e3dd152013-06-12 20:52:10 +03002805 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2806 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002807 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002808 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002809 return ret;
2810 }
2811
2812 return ret;
2813}
2814
2815/**************/
2816/* Regulatory */
2817/**************/
2818
2819static int ath10k_update_channel_list(struct ath10k *ar)
2820{
2821 struct ieee80211_hw *hw = ar->hw;
2822 struct ieee80211_supported_band **bands;
2823 enum ieee80211_band band;
2824 struct ieee80211_channel *channel;
2825 struct wmi_scan_chan_list_arg arg = {0};
2826 struct wmi_channel_arg *ch;
2827 bool passive;
2828 int len;
2829 int ret;
2830 int i;
2831
Michal Kazior548db542013-07-05 16:15:15 +03002832 lockdep_assert_held(&ar->conf_mutex);
2833
Kalle Valo5e3dd152013-06-12 20:52:10 +03002834 bands = hw->wiphy->bands;
2835 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2836 if (!bands[band])
2837 continue;
2838
2839 for (i = 0; i < bands[band]->n_channels; i++) {
2840 if (bands[band]->channels[i].flags &
2841 IEEE80211_CHAN_DISABLED)
2842 continue;
2843
2844 arg.n_channels++;
2845 }
2846 }
2847
2848 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2849 arg.channels = kzalloc(len, GFP_KERNEL);
2850 if (!arg.channels)
2851 return -ENOMEM;
2852
2853 ch = arg.channels;
2854 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2855 if (!bands[band])
2856 continue;
2857
2858 for (i = 0; i < bands[band]->n_channels; i++) {
2859 channel = &bands[band]->channels[i];
2860
2861 if (channel->flags & IEEE80211_CHAN_DISABLED)
2862 continue;
2863
2864 ch->allow_ht = true;
2865
2866 /* FIXME: when should we really allow VHT? */
2867 ch->allow_vht = true;
2868
2869 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002870 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002871
2872 ch->ht40plus =
2873 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2874
Marek Puzyniake8a50f82013-11-20 09:59:47 +02002875 ch->chan_radar =
2876 !!(channel->flags & IEEE80211_CHAN_RADAR);
2877
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002878 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002879 ch->passive = passive;
2880
2881 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02002882 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07002883 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07002884 ch->max_power = channel->max_power * 2;
2885 ch->max_reg_power = channel->max_reg_power * 2;
2886 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002887 ch->reg_class_id = 0; /* FIXME */
2888
2889 /* FIXME: why use only legacy modes, why not any
2890 * HT/VHT modes? Would that even make any
2891 * difference? */
2892 if (channel->band == IEEE80211_BAND_2GHZ)
2893 ch->mode = MODE_11G;
2894 else
2895 ch->mode = MODE_11A;
2896
2897 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
2898 continue;
2899
Michal Kazior7aa7a722014-08-25 12:09:38 +02002900 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002901 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
2902 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002903 ch->freq, ch->max_power, ch->max_reg_power,
2904 ch->max_antenna_gain, ch->mode);
2905
2906 ch++;
2907 }
2908 }
2909
2910 ret = ath10k_wmi_scan_chan_list(ar, &arg);
2911 kfree(arg.channels);
2912
2913 return ret;
2914}
2915
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002916static enum wmi_dfs_region
2917ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
2918{
2919 switch (dfs_region) {
2920 case NL80211_DFS_UNSET:
2921 return WMI_UNINIT_DFS_DOMAIN;
2922 case NL80211_DFS_FCC:
2923 return WMI_FCC_DFS_DOMAIN;
2924 case NL80211_DFS_ETSI:
2925 return WMI_ETSI_DFS_DOMAIN;
2926 case NL80211_DFS_JP:
2927 return WMI_MKK4_DFS_DOMAIN;
2928 }
2929 return WMI_UNINIT_DFS_DOMAIN;
2930}
2931
Michal Kaziorf7843d72013-07-16 09:38:52 +02002932static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002933{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002934 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002935 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002936 enum wmi_dfs_region wmi_dfs_reg;
2937 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002938
Michal Kaziorf7843d72013-07-16 09:38:52 +02002939 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002940
2941 ret = ath10k_update_channel_list(ar);
2942 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002943 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002944
2945 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002946
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002947 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
2948 nl_dfs_reg = ar->dfs_detector->region;
2949 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
2950 } else {
2951 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
2952 }
2953
Kalle Valo5e3dd152013-06-12 20:52:10 +03002954 /* Target allows setting up per-band regdomain but ath_common provides
2955 * a combined one only */
2956 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02002957 regpair->reg_domain,
2958 regpair->reg_domain, /* 2ghz */
2959 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03002960 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002961 regpair->reg_5ghz_ctl,
2962 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002963 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002964 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02002965}
Michal Kazior548db542013-07-05 16:15:15 +03002966
Michal Kaziorf7843d72013-07-16 09:38:52 +02002967static void ath10k_reg_notifier(struct wiphy *wiphy,
2968 struct regulatory_request *request)
2969{
2970 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2971 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002972 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002973
2974 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
2975
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002976 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002977 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002978 request->dfs_region);
2979 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
2980 request->dfs_region);
2981 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002982 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002983 request->dfs_region);
2984 }
2985
Michal Kaziorf7843d72013-07-16 09:38:52 +02002986 mutex_lock(&ar->conf_mutex);
2987 if (ar->state == ATH10K_STATE_ON)
2988 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03002989 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002990}
2991
2992/***************/
2993/* TX handlers */
2994/***************/
2995
Michal Kazior96d828d2015-03-31 10:26:23 +00002996void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
2997{
2998 lockdep_assert_held(&ar->htt.tx_lock);
2999
3000 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3001 ar->tx_paused |= BIT(reason);
3002 ieee80211_stop_queues(ar->hw);
3003}
3004
3005static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3006 struct ieee80211_vif *vif)
3007{
3008 struct ath10k *ar = data;
3009 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3010
3011 if (arvif->tx_paused)
3012 return;
3013
3014 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3015}
3016
3017void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3018{
3019 lockdep_assert_held(&ar->htt.tx_lock);
3020
3021 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3022 ar->tx_paused &= ~BIT(reason);
3023
3024 if (ar->tx_paused)
3025 return;
3026
3027 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3028 IEEE80211_IFACE_ITER_RESUME_ALL,
3029 ath10k_mac_tx_unlock_iter,
3030 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003031
3032 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003033}
3034
3035void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3036{
3037 struct ath10k *ar = arvif->ar;
3038
3039 lockdep_assert_held(&ar->htt.tx_lock);
3040
3041 WARN_ON(reason >= BITS_PER_LONG);
3042 arvif->tx_paused |= BIT(reason);
3043 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3044}
3045
3046void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3047{
3048 struct ath10k *ar = arvif->ar;
3049
3050 lockdep_assert_held(&ar->htt.tx_lock);
3051
3052 WARN_ON(reason >= BITS_PER_LONG);
3053 arvif->tx_paused &= ~BIT(reason);
3054
3055 if (ar->tx_paused)
3056 return;
3057
3058 if (arvif->tx_paused)
3059 return;
3060
3061 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3062}
3063
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003064static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3065 enum wmi_tlv_tx_pause_id pause_id,
3066 enum wmi_tlv_tx_pause_action action)
3067{
3068 struct ath10k *ar = arvif->ar;
3069
3070 lockdep_assert_held(&ar->htt.tx_lock);
3071
Michal Kazioracd0b272015-07-09 13:08:38 +02003072 switch (action) {
3073 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3074 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003075 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003076 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3077 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3078 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003079 default:
Michal Kazioracd0b272015-07-09 13:08:38 +02003080 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
3081 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003082 break;
3083 }
3084}
3085
3086struct ath10k_mac_tx_pause {
3087 u32 vdev_id;
3088 enum wmi_tlv_tx_pause_id pause_id;
3089 enum wmi_tlv_tx_pause_action action;
3090};
3091
3092static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3093 struct ieee80211_vif *vif)
3094{
3095 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3096 struct ath10k_mac_tx_pause *arg = data;
3097
Michal Kazioracd0b272015-07-09 13:08:38 +02003098 if (arvif->vdev_id != arg->vdev_id)
3099 return;
3100
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003101 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3102}
3103
Michal Kazioracd0b272015-07-09 13:08:38 +02003104void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3105 enum wmi_tlv_tx_pause_id pause_id,
3106 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003107{
3108 struct ath10k_mac_tx_pause arg = {
3109 .vdev_id = vdev_id,
3110 .pause_id = pause_id,
3111 .action = action,
3112 };
3113
3114 spin_lock_bh(&ar->htt.tx_lock);
3115 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3116 IEEE80211_IFACE_ITER_RESUME_ALL,
3117 ath10k_mac_handle_tx_pause_iter,
3118 &arg);
3119 spin_unlock_bh(&ar->htt.tx_lock);
3120}
3121
Michal Kazior42c3aa62013-10-02 11:03:38 +02003122static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
3123{
3124 if (ieee80211_is_mgmt(hdr->frame_control))
3125 return HTT_DATA_TX_EXT_TID_MGMT;
3126
3127 if (!ieee80211_is_data_qos(hdr->frame_control))
3128 return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
3129
3130 if (!is_unicast_ether_addr(ieee80211_get_DA(hdr)))
3131 return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
3132
3133 return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
3134}
3135
Michal Kazior2b37c292014-09-02 11:00:22 +03003136static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003137{
Michal Kazior2b37c292014-09-02 11:00:22 +03003138 if (vif)
3139 return ath10k_vif_to_arvif(vif)->vdev_id;
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003140
Michal Kazior1bbc0972014-04-08 09:45:47 +03003141 if (ar->monitor_started)
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003142 return ar->monitor_vdev_id;
3143
Michal Kazior7aa7a722014-08-25 12:09:38 +02003144 ath10k_warn(ar, "failed to resolve vdev id\n");
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003145 return 0;
3146}
3147
Michal Kaziord740d8f2015-03-30 09:51:51 +03003148static enum ath10k_hw_txrx_mode
3149ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003150 struct ieee80211_sta *sta, struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003151{
3152 const struct ieee80211_hdr *hdr = (void *)skb->data;
3153 __le16 fc = hdr->frame_control;
3154
3155 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3156 return ATH10K_HW_TXRX_RAW;
3157
3158 if (ieee80211_is_mgmt(fc))
3159 return ATH10K_HW_TXRX_MGMT;
3160
3161 /* Workaround:
3162 *
3163 * NullFunc frames are mostly used to ping if a client or AP are still
3164 * reachable and responsive. This implies tx status reports must be
3165 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3166 * come to a conclusion that the other end disappeared and tear down
3167 * BSS connection or it can never disconnect from BSS/client (which is
3168 * the case).
3169 *
3170 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3171 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3172 * which seems to deliver correct tx reports for NullFunc frames. The
3173 * downside of using it is it ignores client powersave state so it can
3174 * end up disconnecting sleeping clients in AP mode. It should fix STA
3175 * mode though because AP don't sleep.
3176 */
3177 if (ar->htt.target_version_major < 3 &&
3178 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
3179 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, ar->fw_features))
3180 return ATH10K_HW_TXRX_MGMT;
3181
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003182 /* Workaround:
3183 *
3184 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3185 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3186 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003187 *
3188 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003189 */
3190 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3191 return ATH10K_HW_TXRX_ETHERNET;
3192
David Liuccec9032015-07-24 20:25:32 +03003193 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3194 return ATH10K_HW_TXRX_RAW;
3195
Michal Kaziord740d8f2015-03-30 09:51:51 +03003196 return ATH10K_HW_TXRX_NATIVE_WIFI;
3197}
3198
David Liuccec9032015-07-24 20:25:32 +03003199static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
3200 struct sk_buff *skb) {
3201 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3202 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3203 IEEE80211_TX_CTL_INJECTED;
3204 if ((info->flags & mask) == mask)
3205 return false;
3206 if (vif)
3207 return !ath10k_vif_to_arvif(vif)->nohwcrypt;
3208 return true;
3209}
3210
Michal Kazior4b604552014-07-21 21:03:09 +03003211/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3212 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003213 */
Michal Kazior4b604552014-07-21 21:03:09 +03003214static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003215{
3216 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003217 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003218 u8 *qos_ctl;
3219
3220 if (!ieee80211_is_data_qos(hdr->frame_control))
3221 return;
3222
3223 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003224 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3225 skb->data, (void *)qos_ctl - (void *)skb->data);
3226 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003227
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003228 /* Some firmware revisions don't handle sending QoS NullFunc well.
3229 * These frames are mainly used for CQM purposes so it doesn't really
3230 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003231 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003232 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003233 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003234 cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003235
3236 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003237}
3238
Michal Kaziord740d8f2015-03-30 09:51:51 +03003239static void ath10k_tx_h_8023(struct sk_buff *skb)
3240{
3241 struct ieee80211_hdr *hdr;
3242 struct rfc1042_hdr *rfc1042;
3243 struct ethhdr *eth;
3244 size_t hdrlen;
3245 u8 da[ETH_ALEN];
3246 u8 sa[ETH_ALEN];
3247 __be16 type;
3248
3249 hdr = (void *)skb->data;
3250 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3251 rfc1042 = (void *)skb->data + hdrlen;
3252
3253 ether_addr_copy(da, ieee80211_get_DA(hdr));
3254 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3255 type = rfc1042->snap_type;
3256
3257 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3258 skb_push(skb, sizeof(*eth));
3259
3260 eth = (void *)skb->data;
3261 ether_addr_copy(eth->h_dest, da);
3262 ether_addr_copy(eth->h_source, sa);
3263 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003264}
3265
Michal Kazior4b604552014-07-21 21:03:09 +03003266static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3267 struct ieee80211_vif *vif,
3268 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003269{
3270 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003271 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3272
3273 /* This is case only for P2P_GO */
3274 if (arvif->vdev_type != WMI_VDEV_TYPE_AP ||
3275 arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
3276 return;
3277
3278 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3279 spin_lock_bh(&ar->data_lock);
3280 if (arvif->u.ap.noa_data)
3281 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3282 GFP_ATOMIC))
3283 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3284 arvif->u.ap.noa_data,
3285 arvif->u.ap.noa_len);
3286 spin_unlock_bh(&ar->data_lock);
3287 }
3288}
3289
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303290bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003291{
3292 /* FIXME: Not really sure since when the behaviour changed. At some
3293 * point new firmware stopped requiring creation of peer entries for
3294 * offchannel tx (and actually creating them causes issues with wmi-htc
3295 * tx credit replenishment and reliability). Assuming it's at least 3.4
3296 * because that's when the `freq` was introduced to TX_FRM HTT command.
3297 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303298 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303299 ar->htt.target_version_minor >= 4 &&
3300 ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003301}
3302
Michal Kaziord740d8f2015-03-30 09:51:51 +03003303static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003304{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003305 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003306 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003307
Michal Kaziord740d8f2015-03-30 09:51:51 +03003308 spin_lock_bh(&ar->data_lock);
3309
3310 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3311 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3312 ret = -ENOSPC;
3313 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003314 }
3315
Michal Kaziord740d8f2015-03-30 09:51:51 +03003316 __skb_queue_tail(q, skb);
3317 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3318
3319unlock:
3320 spin_unlock_bh(&ar->data_lock);
3321
3322 return ret;
3323}
3324
3325static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
3326{
3327 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3328 struct ath10k_htt *htt = &ar->htt;
3329 int ret = 0;
3330
3331 switch (cb->txmode) {
3332 case ATH10K_HW_TXRX_RAW:
3333 case ATH10K_HW_TXRX_NATIVE_WIFI:
3334 case ATH10K_HW_TXRX_ETHERNET:
3335 ret = ath10k_htt_tx(htt, skb);
3336 break;
3337 case ATH10K_HW_TXRX_MGMT:
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003338 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Michal Kaziord740d8f2015-03-30 09:51:51 +03003339 ar->fw_features))
3340 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3341 else if (ar->htt.target_version_major >= 3)
3342 ret = ath10k_htt_tx(htt, skb);
3343 else
3344 ret = ath10k_htt_mgmt_tx(htt, skb);
3345 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003346 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003347
3348 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003349 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3350 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003351 ieee80211_free_txskb(ar->hw, skb);
3352 }
3353}
3354
3355void ath10k_offchan_tx_purge(struct ath10k *ar)
3356{
3357 struct sk_buff *skb;
3358
3359 for (;;) {
3360 skb = skb_dequeue(&ar->offchan_tx_queue);
3361 if (!skb)
3362 break;
3363
3364 ieee80211_free_txskb(ar->hw, skb);
3365 }
3366}
3367
3368void ath10k_offchan_tx_work(struct work_struct *work)
3369{
3370 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3371 struct ath10k_peer *peer;
3372 struct ieee80211_hdr *hdr;
3373 struct sk_buff *skb;
3374 const u8 *peer_addr;
3375 int vdev_id;
3376 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003377 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003378 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003379
3380 /* FW requirement: We must create a peer before FW will send out
3381 * an offchannel frame. Otherwise the frame will be stuck and
3382 * never transmitted. We delete the peer upon tx completion.
3383 * It is unlikely that a peer for offchannel tx will already be
3384 * present. However it may be in some rare cases so account for that.
3385 * Otherwise we might remove a legitimate peer and break stuff. */
3386
3387 for (;;) {
3388 skb = skb_dequeue(&ar->offchan_tx_queue);
3389 if (!skb)
3390 break;
3391
3392 mutex_lock(&ar->conf_mutex);
3393
Michal Kazior7aa7a722014-08-25 12:09:38 +02003394 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003395 skb);
3396
3397 hdr = (struct ieee80211_hdr *)skb->data;
3398 peer_addr = ieee80211_get_DA(hdr);
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003399 vdev_id = ATH10K_SKB_CB(skb)->vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003400
3401 spin_lock_bh(&ar->data_lock);
3402 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3403 spin_unlock_bh(&ar->data_lock);
3404
3405 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003406 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003407 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003408 peer_addr, vdev_id);
3409
3410 if (!peer) {
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003411 ret = ath10k_peer_create(ar, vdev_id, peer_addr,
3412 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003413 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003414 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003415 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003416 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003417 }
3418
3419 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003420 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003421 ar->offchan_tx_skb = skb;
3422 spin_unlock_bh(&ar->data_lock);
3423
Michal Kaziord740d8f2015-03-30 09:51:51 +03003424 ath10k_mac_tx(ar, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003425
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003426 time_left =
3427 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3428 if (time_left == 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003429 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003430 skb);
3431
Michal Kazioradaeed72015-08-05 12:15:23 +02003432 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003433 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3434 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003435 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003436 peer_addr, vdev_id, ret);
3437 }
3438
3439 mutex_unlock(&ar->conf_mutex);
3440 }
3441}
3442
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003443void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3444{
3445 struct sk_buff *skb;
3446
3447 for (;;) {
3448 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3449 if (!skb)
3450 break;
3451
3452 ieee80211_free_txskb(ar->hw, skb);
3453 }
3454}
3455
3456void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3457{
3458 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3459 struct sk_buff *skb;
3460 int ret;
3461
3462 for (;;) {
3463 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3464 if (!skb)
3465 break;
3466
3467 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003468 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003469 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003470 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003471 ieee80211_free_txskb(ar->hw, skb);
3472 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003473 }
3474}
3475
Kalle Valo5e3dd152013-06-12 20:52:10 +03003476/************/
3477/* Scanning */
3478/************/
3479
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003480void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003481{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003482 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003483
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003484 switch (ar->scan.state) {
3485 case ATH10K_SCAN_IDLE:
3486 break;
3487 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01003488 case ATH10K_SCAN_ABORTING:
3489 if (!ar->scan.is_roc)
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003490 ieee80211_scan_completed(ar->hw,
3491 (ar->scan.state ==
3492 ATH10K_SCAN_ABORTING));
Michal Kaziord710e752015-07-09 13:08:36 +02003493 else if (ar->scan.roc_notify)
3494 ieee80211_remain_on_channel_expired(ar->hw);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003495 /* fall through */
3496 case ATH10K_SCAN_STARTING:
3497 ar->scan.state = ATH10K_SCAN_IDLE;
3498 ar->scan_channel = NULL;
3499 ath10k_offchan_tx_purge(ar);
3500 cancel_delayed_work(&ar->scan.timeout);
3501 complete_all(&ar->scan.completed);
3502 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003503 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003504}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003505
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003506void ath10k_scan_finish(struct ath10k *ar)
3507{
3508 spin_lock_bh(&ar->data_lock);
3509 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003510 spin_unlock_bh(&ar->data_lock);
3511}
3512
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003513static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003514{
3515 struct wmi_stop_scan_arg arg = {
3516 .req_id = 1, /* FIXME */
3517 .req_type = WMI_SCAN_STOP_ONE,
3518 .u.scan_id = ATH10K_SCAN_ID,
3519 };
3520 int ret;
3521
3522 lockdep_assert_held(&ar->conf_mutex);
3523
Kalle Valo5e3dd152013-06-12 20:52:10 +03003524 ret = ath10k_wmi_stop_scan(ar, &arg);
3525 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003526 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003527 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003528 }
3529
Kalle Valo5e3dd152013-06-12 20:52:10 +03003530 ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003531 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003532 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003533 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003534 } else if (ret > 0) {
3535 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003536 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003537
3538out:
3539 /* Scan state should be updated upon scan completion but in case
3540 * firmware fails to deliver the event (for whatever reason) it is
3541 * desired to clean up scan state anyway. Firmware may have just
3542 * dropped the scan completion event delivery due to transport pipe
3543 * being overflown with data and/or it can recover on its own before
3544 * next scan request is submitted.
3545 */
3546 spin_lock_bh(&ar->data_lock);
3547 if (ar->scan.state != ATH10K_SCAN_IDLE)
3548 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003549 spin_unlock_bh(&ar->data_lock);
3550
3551 return ret;
3552}
3553
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003554static void ath10k_scan_abort(struct ath10k *ar)
3555{
3556 int ret;
3557
3558 lockdep_assert_held(&ar->conf_mutex);
3559
3560 spin_lock_bh(&ar->data_lock);
3561
3562 switch (ar->scan.state) {
3563 case ATH10K_SCAN_IDLE:
3564 /* This can happen if timeout worker kicked in and called
3565 * abortion while scan completion was being processed.
3566 */
3567 break;
3568 case ATH10K_SCAN_STARTING:
3569 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02003570 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003571 ath10k_scan_state_str(ar->scan.state),
3572 ar->scan.state);
3573 break;
3574 case ATH10K_SCAN_RUNNING:
3575 ar->scan.state = ATH10K_SCAN_ABORTING;
3576 spin_unlock_bh(&ar->data_lock);
3577
3578 ret = ath10k_scan_stop(ar);
3579 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003580 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003581
3582 spin_lock_bh(&ar->data_lock);
3583 break;
3584 }
3585
3586 spin_unlock_bh(&ar->data_lock);
3587}
3588
3589void ath10k_scan_timeout_work(struct work_struct *work)
3590{
3591 struct ath10k *ar = container_of(work, struct ath10k,
3592 scan.timeout.work);
3593
3594 mutex_lock(&ar->conf_mutex);
3595 ath10k_scan_abort(ar);
3596 mutex_unlock(&ar->conf_mutex);
3597}
3598
Kalle Valo5e3dd152013-06-12 20:52:10 +03003599static int ath10k_start_scan(struct ath10k *ar,
3600 const struct wmi_start_scan_arg *arg)
3601{
3602 int ret;
3603
3604 lockdep_assert_held(&ar->conf_mutex);
3605
3606 ret = ath10k_wmi_start_scan(ar, arg);
3607 if (ret)
3608 return ret;
3609
Kalle Valo5e3dd152013-06-12 20:52:10 +03003610 ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ);
3611 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003612 ret = ath10k_scan_stop(ar);
3613 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003614 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003615
3616 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003617 }
3618
Ben Greear2f9eec02015-02-15 16:50:38 +02003619 /* If we failed to start the scan, return error code at
3620 * this point. This is probably due to some issue in the
3621 * firmware, but no need to wedge the driver due to that...
3622 */
3623 spin_lock_bh(&ar->data_lock);
3624 if (ar->scan.state == ATH10K_SCAN_IDLE) {
3625 spin_unlock_bh(&ar->data_lock);
3626 return -EINVAL;
3627 }
3628 spin_unlock_bh(&ar->data_lock);
3629
Kalle Valo5e3dd152013-06-12 20:52:10 +03003630 return 0;
3631}
3632
3633/**********************/
3634/* mac80211 callbacks */
3635/**********************/
3636
3637static void ath10k_tx(struct ieee80211_hw *hw,
3638 struct ieee80211_tx_control *control,
3639 struct sk_buff *skb)
3640{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003641 struct ath10k *ar = hw->priv;
Michal Kazior4b604552014-07-21 21:03:09 +03003642 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3643 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003644 struct ieee80211_sta *sta = control->sta;
Michal Kazior4b604552014-07-21 21:03:09 +03003645 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003646 __le16 fc = hdr->frame_control;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003647
3648 /* We should disable CCK RATE due to P2P */
3649 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003650 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003651
Michal Kazior4b604552014-07-21 21:03:09 +03003652 ATH10K_SKB_CB(skb)->htt.is_offchan = false;
Michal Kazior6fcafef2015-03-30 09:51:51 +03003653 ATH10K_SKB_CB(skb)->htt.freq = 0;
Michal Kazior4b604552014-07-21 21:03:09 +03003654 ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
David Liuccec9032015-07-24 20:25:32 +03003655 ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
Michal Kazior2b37c292014-09-02 11:00:22 +03003656 ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003657 ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003658 ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003659
Michal Kaziord740d8f2015-03-30 09:51:51 +03003660 switch (ATH10K_SKB_CB(skb)->txmode) {
3661 case ATH10K_HW_TXRX_MGMT:
3662 case ATH10K_HW_TXRX_NATIVE_WIFI:
Michal Kazior4b604552014-07-21 21:03:09 +03003663 ath10k_tx_h_nwifi(hw, skb);
Michal Kazior4b604552014-07-21 21:03:09 +03003664 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3665 ath10k_tx_h_seq_no(vif, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003666 break;
3667 case ATH10K_HW_TXRX_ETHERNET:
3668 ath10k_tx_h_8023(skb);
3669 break;
3670 case ATH10K_HW_TXRX_RAW:
David Liuccec9032015-07-24 20:25:32 +03003671 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3672 WARN_ON_ONCE(1);
3673 ieee80211_free_txskb(hw, skb);
3674 return;
3675 }
Michal Kaziorcf84bd42013-07-16 11:04:54 +02003676 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003677
Kalle Valo5e3dd152013-06-12 20:52:10 +03003678 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3679 spin_lock_bh(&ar->data_lock);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003680 ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003681 ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003682 spin_unlock_bh(&ar->data_lock);
3683
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303684 if (!ath10k_mac_tx_frm_has_freq(ar)) {
Michal Kazior8d6d3622014-11-24 14:58:31 +01003685 ATH10K_SKB_CB(skb)->htt.freq = 0;
3686 ATH10K_SKB_CB(skb)->htt.is_offchan = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003687
Michal Kazior8d6d3622014-11-24 14:58:31 +01003688 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
3689 skb);
3690
3691 skb_queue_tail(&ar->offchan_tx_queue, skb);
3692 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3693 return;
3694 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003695 }
3696
Michal Kaziord740d8f2015-03-30 09:51:51 +03003697 ath10k_mac_tx(ar, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003698}
3699
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003700/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01003701void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003702{
3703 /* make sure rcu-protected mac80211 tx path itself is drained */
3704 synchronize_net();
3705
3706 ath10k_offchan_tx_purge(ar);
3707 ath10k_mgmt_over_wmi_tx_purge(ar);
3708
3709 cancel_work_sync(&ar->offchan_tx_work);
3710 cancel_work_sync(&ar->wmi_mgmt_tx_work);
3711}
3712
Michal Kazioraffd3212013-07-16 09:54:35 +02003713void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02003714{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03003715 struct ath10k_vif *arvif;
3716
Michal Kazior818bdd12013-07-16 09:38:57 +02003717 lockdep_assert_held(&ar->conf_mutex);
3718
Michal Kazior19337472014-08-28 12:58:16 +02003719 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
3720 ar->filter_flags = 0;
3721 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00003722 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02003723
3724 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03003725 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02003726
3727 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00003728 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03003729
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003730 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02003731 ath10k_peer_cleanup_all(ar);
3732 ath10k_core_stop(ar);
3733 ath10k_hif_power_down(ar);
3734
3735 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03003736 list_for_each_entry(arvif, &ar->arvifs, list)
3737 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02003738 spin_unlock_bh(&ar->data_lock);
3739}
3740
Ben Greear46acf7bb2014-05-16 17:15:38 +03003741static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
3742{
3743 struct ath10k *ar = hw->priv;
3744
3745 mutex_lock(&ar->conf_mutex);
3746
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05303747 *tx_ant = ar->cfg_tx_chainmask;
3748 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03003749
3750 mutex_unlock(&ar->conf_mutex);
3751
3752 return 0;
3753}
3754
Ben Greear5572a952014-11-24 16:22:10 +02003755static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
3756{
3757 /* It is not clear that allowing gaps in chainmask
3758 * is helpful. Probably it will not do what user
3759 * is hoping for, so warn in that case.
3760 */
3761 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
3762 return;
3763
3764 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
3765 dbg, cm);
3766}
3767
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05303768static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
3769{
3770 int nsts = ar->vht_cap_info;
3771
3772 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
3773 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
3774
3775 /* If firmware does not deliver to host number of space-time
3776 * streams supported, assume it support up to 4 BF STS and return
3777 * the value for VHT CAP: nsts-1)
3778 */
3779 if (nsts == 0)
3780 return 3;
3781
3782 return nsts;
3783}
3784
3785static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
3786{
3787 int sound_dim = ar->vht_cap_info;
3788
3789 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
3790 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
3791
3792 /* If the sounding dimension is not advertised by the firmware,
3793 * let's use a default value of 1
3794 */
3795 if (sound_dim == 0)
3796 return 1;
3797
3798 return sound_dim;
3799}
3800
3801static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
3802{
3803 struct ieee80211_sta_vht_cap vht_cap = {0};
3804 u16 mcs_map;
3805 u32 val;
3806 int i;
3807
3808 vht_cap.vht_supported = 1;
3809 vht_cap.cap = ar->vht_cap_info;
3810
3811 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
3812 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
3813 val = ath10k_mac_get_vht_cap_bf_sts(ar);
3814 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
3815 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
3816
3817 vht_cap.cap |= val;
3818 }
3819
3820 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
3821 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
3822 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
3823 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
3824 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
3825
3826 vht_cap.cap |= val;
3827 }
3828
3829 mcs_map = 0;
3830 for (i = 0; i < 8; i++) {
3831 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
3832 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
3833 else
3834 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
3835 }
3836
3837 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
3838 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
3839
3840 return vht_cap;
3841}
3842
3843static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
3844{
3845 int i;
3846 struct ieee80211_sta_ht_cap ht_cap = {0};
3847
3848 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
3849 return ht_cap;
3850
3851 ht_cap.ht_supported = 1;
3852 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
3853 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
3854 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
3855 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
3856 ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT;
3857
3858 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
3859 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
3860
3861 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
3862 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
3863
3864 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
3865 u32 smps;
3866
3867 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
3868 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
3869
3870 ht_cap.cap |= smps;
3871 }
3872
3873 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC)
3874 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
3875
3876 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
3877 u32 stbc;
3878
3879 stbc = ar->ht_cap_info;
3880 stbc &= WMI_HT_CAP_RX_STBC;
3881 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
3882 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
3883 stbc &= IEEE80211_HT_CAP_RX_STBC;
3884
3885 ht_cap.cap |= stbc;
3886 }
3887
3888 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
3889 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
3890
3891 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
3892 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
3893
3894 /* max AMSDU is implicitly taken from vht_cap_info */
3895 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
3896 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
3897
3898 for (i = 0; i < ar->num_rf_chains; i++) {
3899 if (ar->cfg_rx_chainmask & BIT(i))
3900 ht_cap.mcs.rx_mask[i] = 0xFF;
3901 }
3902
3903 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
3904
3905 return ht_cap;
3906}
3907
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05303908static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
3909{
3910 struct ieee80211_supported_band *band;
3911 struct ieee80211_sta_vht_cap vht_cap;
3912 struct ieee80211_sta_ht_cap ht_cap;
3913
3914 ht_cap = ath10k_get_ht_cap(ar);
3915 vht_cap = ath10k_create_vht_cap(ar);
3916
3917 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
3918 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
3919 band->ht_cap = ht_cap;
3920
3921 /* Enable the VHT support at 2.4 GHz */
3922 band->vht_cap = vht_cap;
3923 }
3924 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
3925 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
3926 band->ht_cap = ht_cap;
3927 band->vht_cap = vht_cap;
3928 }
3929}
3930
Ben Greear46acf7bb2014-05-16 17:15:38 +03003931static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
3932{
3933 int ret;
3934
3935 lockdep_assert_held(&ar->conf_mutex);
3936
Ben Greear5572a952014-11-24 16:22:10 +02003937 ath10k_check_chain_mask(ar, tx_ant, "tx");
3938 ath10k_check_chain_mask(ar, rx_ant, "rx");
3939
Ben Greear46acf7bb2014-05-16 17:15:38 +03003940 ar->cfg_tx_chainmask = tx_ant;
3941 ar->cfg_rx_chainmask = rx_ant;
3942
3943 if ((ar->state != ATH10K_STATE_ON) &&
3944 (ar->state != ATH10K_STATE_RESTARTED))
3945 return 0;
3946
3947 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
3948 tx_ant);
3949 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003950 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03003951 ret, tx_ant);
3952 return ret;
3953 }
3954
3955 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
3956 rx_ant);
3957 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003958 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03003959 ret, rx_ant);
3960 return ret;
3961 }
3962
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05303963 /* Reload HT/VHT capability */
3964 ath10k_mac_setup_ht_vht_cap(ar);
3965
Ben Greear46acf7bb2014-05-16 17:15:38 +03003966 return 0;
3967}
3968
3969static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
3970{
3971 struct ath10k *ar = hw->priv;
3972 int ret;
3973
3974 mutex_lock(&ar->conf_mutex);
3975 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
3976 mutex_unlock(&ar->conf_mutex);
3977 return ret;
3978}
3979
Kalle Valo5e3dd152013-06-12 20:52:10 +03003980static int ath10k_start(struct ieee80211_hw *hw)
3981{
3982 struct ath10k *ar = hw->priv;
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03003983 u32 burst_enable;
Michal Kazior818bdd12013-07-16 09:38:57 +02003984 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003985
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003986 /*
3987 * This makes sense only when restarting hw. It is harmless to call
3988 * uncoditionally. This is necessary to make sure no HTT/WMI tx
3989 * commands will be submitted while restarting.
3990 */
3991 ath10k_drain_tx(ar);
3992
Michal Kazior548db542013-07-05 16:15:15 +03003993 mutex_lock(&ar->conf_mutex);
3994
Michal Kaziorc5058f52014-05-26 12:46:03 +03003995 switch (ar->state) {
3996 case ATH10K_STATE_OFF:
3997 ar->state = ATH10K_STATE_ON;
3998 break;
3999 case ATH10K_STATE_RESTARTING:
4000 ath10k_halt(ar);
4001 ar->state = ATH10K_STATE_RESTARTED;
4002 break;
4003 case ATH10K_STATE_ON:
4004 case ATH10K_STATE_RESTARTED:
4005 case ATH10K_STATE_WEDGED:
4006 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004007 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004008 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004009 case ATH10K_STATE_UTF:
4010 ret = -EBUSY;
4011 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004012 }
4013
4014 ret = ath10k_hif_power_up(ar);
4015 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004016 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004017 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004018 }
4019
Kalle Valo43d2a302014-09-10 18:23:30 +03004020 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02004021 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004022 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004023 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004024 }
4025
Bartosz Markowski226a3392013-09-26 17:47:16 +02004026 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004027 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004028 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004029 goto err_core_stop;
4030 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004031
Michal Kaziorc4dd0d02013-11-13 11:05:10 +01004032 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004033 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004034 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004035 goto err_core_stop;
4036 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004037
Michal Kaziorcf327842015-03-31 10:26:25 +00004038 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4039 ret = ath10k_wmi_adaptive_qcs(ar, true);
4040 if (ret) {
4041 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4042 ret);
4043 goto err_core_stop;
4044 }
4045 }
4046
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004047 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
4048 burst_enable = ar->wmi.pdev_param->burst_enable;
4049 ret = ath10k_wmi_pdev_set_param(ar, burst_enable, 0);
4050 if (ret) {
4051 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4052 goto err_core_stop;
4053 }
4054 }
4055
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304056 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7bb2014-05-16 17:15:38 +03004057
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004058 /*
4059 * By default FW set ARP frames ac to voice (6). In that case ARP
4060 * exchange is not working properly for UAPSD enabled AP. ARP requests
4061 * which arrives with access category 0 are processed by network stack
4062 * and send back with access category 0, but FW changes access category
4063 * to 6. Set ARP frames access category to best effort (0) solves
4064 * this problem.
4065 */
4066
4067 ret = ath10k_wmi_pdev_set_param(ar,
4068 ar->wmi.pdev_param->arp_ac_override, 0);
4069 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004070 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004071 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004072 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004073 }
4074
Maharaja62f77f02015-10-21 11:49:18 +03004075 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
4076 ar->fw_features)) {
4077 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4078 WMI_CCA_DETECT_LEVEL_AUTO,
4079 WMI_CCA_DETECT_MARGIN_AUTO);
4080 if (ret) {
4081 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4082 ret);
4083 goto err_core_stop;
4084 }
4085 }
4086
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304087 ret = ath10k_wmi_pdev_set_param(ar,
4088 ar->wmi.pdev_param->ani_enable, 1);
4089 if (ret) {
4090 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4091 ret);
4092 goto err_core_stop;
4093 }
4094
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304095 ar->ani_enabled = true;
4096
Michal Kaziord6500972014-04-08 09:56:09 +03004097 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004098 ath10k_regd_update(ar);
4099
Simon Wunderlich855aed12014-08-02 09:12:54 +03004100 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304101 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004102
Michal Kaziorae254432014-05-26 12:46:02 +03004103 mutex_unlock(&ar->conf_mutex);
4104 return 0;
4105
4106err_core_stop:
4107 ath10k_core_stop(ar);
4108
4109err_power_down:
4110 ath10k_hif_power_down(ar);
4111
4112err_off:
4113 ar->state = ATH10K_STATE_OFF;
4114
4115err:
Michal Kazior548db542013-07-05 16:15:15 +03004116 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004117 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004118}
4119
4120static void ath10k_stop(struct ieee80211_hw *hw)
4121{
4122 struct ath10k *ar = hw->priv;
4123
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004124 ath10k_drain_tx(ar);
4125
Michal Kazior548db542013-07-05 16:15:15 +03004126 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004127 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004128 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004129 ar->state = ATH10K_STATE_OFF;
4130 }
Michal Kazior548db542013-07-05 16:15:15 +03004131 mutex_unlock(&ar->conf_mutex);
4132
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004133 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004134 cancel_work_sync(&ar->restart_work);
4135}
4136
Michal Kaziorad088bf2013-10-16 15:44:46 +03004137static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004138{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004139 struct ath10k_vif *arvif;
4140 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004141
4142 lockdep_assert_held(&ar->conf_mutex);
4143
Michal Kaziorad088bf2013-10-16 15:44:46 +03004144 list_for_each_entry(arvif, &ar->arvifs, list) {
4145 ret = ath10k_mac_vif_setup_ps(arvif);
4146 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004147 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004148 break;
4149 }
4150 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004151
Michal Kaziorad088bf2013-10-16 15:44:46 +03004152 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004153}
4154
Michal Kazior7d9d5582014-10-21 10:40:15 +03004155static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4156{
4157 int ret;
4158 u32 param;
4159
4160 lockdep_assert_held(&ar->conf_mutex);
4161
4162 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4163
4164 param = ar->wmi.pdev_param->txpower_limit2g;
4165 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4166 if (ret) {
4167 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4168 txpower, ret);
4169 return ret;
4170 }
4171
4172 param = ar->wmi.pdev_param->txpower_limit5g;
4173 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4174 if (ret) {
4175 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4176 txpower, ret);
4177 return ret;
4178 }
4179
4180 return 0;
4181}
4182
4183static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4184{
4185 struct ath10k_vif *arvif;
4186 int ret, txpower = -1;
4187
4188 lockdep_assert_held(&ar->conf_mutex);
4189
4190 list_for_each_entry(arvif, &ar->arvifs, list) {
4191 WARN_ON(arvif->txpower < 0);
4192
4193 if (txpower == -1)
4194 txpower = arvif->txpower;
4195 else
4196 txpower = min(txpower, arvif->txpower);
4197 }
4198
4199 if (WARN_ON(txpower == -1))
4200 return -EINVAL;
4201
4202 ret = ath10k_mac_txpower_setup(ar, txpower);
4203 if (ret) {
4204 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4205 txpower, ret);
4206 return ret;
4207 }
4208
4209 return 0;
4210}
4211
Kalle Valo5e3dd152013-06-12 20:52:10 +03004212static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4213{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004214 struct ath10k *ar = hw->priv;
4215 struct ieee80211_conf *conf = &hw->conf;
4216 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004217
4218 mutex_lock(&ar->conf_mutex);
4219
Michal Kazioraffd3212013-07-16 09:54:35 +02004220 if (changed & IEEE80211_CONF_CHANGE_PS)
4221 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004222
4223 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004224 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4225 ret = ath10k_monitor_recalc(ar);
4226 if (ret)
4227 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004228 }
4229
4230 mutex_unlock(&ar->conf_mutex);
4231 return ret;
4232}
4233
Ben Greear5572a952014-11-24 16:22:10 +02004234static u32 get_nss_from_chainmask(u16 chain_mask)
4235{
4236 if ((chain_mask & 0x15) == 0x15)
4237 return 4;
4238 else if ((chain_mask & 0x7) == 0x7)
4239 return 3;
4240 else if ((chain_mask & 0x3) == 0x3)
4241 return 2;
4242 return 1;
4243}
4244
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304245static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4246{
4247 u32 value = 0;
4248 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004249 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004250 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304251
4252 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4253 return 0;
4254
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004255 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304256 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4257 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004258 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304259
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004260 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304261 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4262 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004263 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304264
4265 if (!value)
4266 return 0;
4267
4268 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4269 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4270
4271 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4272 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4273 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4274
4275 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4276 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4277
4278 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4279 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4280 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4281
4282 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4283 ar->wmi.vdev_param->txbf, value);
4284}
4285
Kalle Valo5e3dd152013-06-12 20:52:10 +03004286/*
4287 * TODO:
4288 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4289 * because we will send mgmt frames without CCK. This requirement
4290 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4291 * in the TX packet.
4292 */
4293static int ath10k_add_interface(struct ieee80211_hw *hw,
4294 struct ieee80211_vif *vif)
4295{
4296 struct ath10k *ar = hw->priv;
4297 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4298 enum wmi_sta_powersave_param param;
4299 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004300 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004301 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004302 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004303 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004304
Johannes Berg848955c2014-11-11 12:48:42 +01004305 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4306
Kalle Valo5e3dd152013-06-12 20:52:10 +03004307 mutex_lock(&ar->conf_mutex);
4308
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004309 memset(arvif, 0, sizeof(*arvif));
4310
Kalle Valo5e3dd152013-06-12 20:52:10 +03004311 arvif->ar = ar;
4312 arvif->vif = vif;
4313
Ben Greeare63b33f2013-10-22 14:54:14 -07004314 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004315 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004316 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4317 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004318
Michal Kazior45c9abc2015-04-21 20:42:58 +03004319 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4320 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4321 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4322 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4323 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4324 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4325 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004326
Michal Kaziore04cafb2015-08-05 12:15:24 +02004327 if (ar->num_peers >= ar->max_num_peers) {
4328 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004329 ret = -ENOBUFS;
4330 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004331 }
4332
Ben Greeara9aefb32014-08-12 11:02:19 +03004333 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004334 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004335 ret = -EBUSY;
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004336 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004337 }
Ben Greear16c11172014-09-23 14:17:16 -07004338 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004339
Ben Greear16c11172014-09-23 14:17:16 -07004340 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4341 bit, ar->free_vdev_map);
4342
4343 arvif->vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004344 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004345
Kalle Valo5e3dd152013-06-12 20:52:10 +03004346 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004347 case NL80211_IFTYPE_P2P_DEVICE:
4348 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4349 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
4350 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004351 case NL80211_IFTYPE_UNSPECIFIED:
4352 case NL80211_IFTYPE_STATION:
4353 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4354 if (vif->p2p)
4355 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT;
4356 break;
4357 case NL80211_IFTYPE_ADHOC:
4358 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4359 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004360 case NL80211_IFTYPE_MESH_POINT:
4361 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4362 ret = -EINVAL;
4363 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
4364 goto err;
4365 }
4366 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4367 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004368 case NL80211_IFTYPE_AP:
4369 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4370
4371 if (vif->p2p)
4372 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO;
4373 break;
4374 case NL80211_IFTYPE_MONITOR:
4375 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4376 break;
4377 default:
4378 WARN_ON(1);
4379 break;
4380 }
4381
Michal Kazior96d828d2015-03-31 10:26:23 +00004382 /* Using vdev_id as queue number will make it very easy to do per-vif
4383 * tx queue locking. This shouldn't wrap due to interface combinations
4384 * but do a modulo for correctness sake and prevent using offchannel tx
4385 * queues for regular vif tx.
4386 */
4387 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4388 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4389 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4390
Michal Kazior64badcb2014-09-18 11:18:02 +03004391 /* Some firmware revisions don't wait for beacon tx completion before
4392 * sending another SWBA event. This could lead to hardware using old
4393 * (freed) beacon data in some cases, e.g. tx credit starvation
4394 * combined with missed TBTT. This is very very rare.
4395 *
4396 * On non-IOMMU-enabled hosts this could be a possible security issue
4397 * because hw could beacon some random data on the air. On
4398 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4399 * device would crash.
4400 *
4401 * Since there are no beacon tx completions (implicit nor explicit)
4402 * propagated to host the only workaround for this is to allocate a
4403 * DMA-coherent buffer for a lifetime of a vif and use it for all
4404 * beacon tx commands. Worst case for this approach is some beacons may
4405 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4406 */
4407 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004408 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03004409 vif->type == NL80211_IFTYPE_AP) {
4410 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4411 IEEE80211_MAX_FRAME_LEN,
4412 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304413 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004414 if (!arvif->beacon_buf) {
4415 ret = -ENOMEM;
4416 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4417 ret);
4418 goto err;
4419 }
4420 }
David Liuccec9032015-07-24 20:25:32 +03004421 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
4422 arvif->nohwcrypt = true;
4423
4424 if (arvif->nohwcrypt &&
4425 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4426 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
4427 goto err;
4428 }
Michal Kazior64badcb2014-09-18 11:18:02 +03004429
4430 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4431 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4432 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004433
4434 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4435 arvif->vdev_subtype, vif->addr);
4436 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004437 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004438 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004439 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004440 }
4441
Ben Greear16c11172014-09-23 14:17:16 -07004442 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Michal Kazior05791192013-10-16 15:44:45 +03004443 list_add(&arvif->list, &ar->arvifs);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004444
Michal Kazior46725b152015-01-28 09:57:49 +02004445 /* It makes no sense to have firmware do keepalives. mac80211 already
4446 * takes care of this with idle connection polling.
4447 */
4448 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004449 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02004450 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004451 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004452 goto err_vdev_delete;
4453 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004454
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004455 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004456
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004457 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4458 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004459 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004460 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004461 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004462 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004463 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004464 goto err_vdev_delete;
4465 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004466
Ben Greear5572a952014-11-24 16:22:10 +02004467 if (ar->cfg_tx_chainmask) {
4468 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
4469
4470 vdev_param = ar->wmi.vdev_param->nss;
4471 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4472 nss);
4473 if (ret) {
4474 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
4475 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
4476 ret);
4477 goto err_vdev_delete;
4478 }
4479 }
4480
Michal Kaziore57e0572015-03-24 13:14:03 +00004481 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4482 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Marek Puzyniak7390ed32015-03-30 09:51:52 +03004483 ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr,
4484 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004485 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00004486 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004487 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004488 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004489 }
Michal Kaziore57e0572015-03-24 13:14:03 +00004490 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01004491
Michal Kaziore57e0572015-03-24 13:14:03 +00004492 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02004493 ret = ath10k_mac_set_kickout(arvif);
4494 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004495 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004496 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02004497 goto err_peer_delete;
4498 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004499 }
4500
4501 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
4502 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
4503 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
4504 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
4505 param, value);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004506 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004507 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004508 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-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_wake_threshold(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004513 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004514 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004515 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004516 goto err_peer_delete;
4517 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004518
Michal Kazior9f9b5742014-12-12 12:41:36 +01004519 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004520 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004521 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004522 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004523 goto err_peer_delete;
4524 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004525 }
4526
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304527 ret = ath10k_mac_set_txbf_conf(arvif);
4528 if (ret) {
4529 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
4530 arvif->vdev_id, ret);
4531 goto err_peer_delete;
4532 }
4533
Michal Kazior424121c2013-07-22 14:13:31 +02004534 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004535 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004536 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03004537 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004538 goto err_peer_delete;
4539 }
Michal Kazior679c54a2013-07-05 16:15:04 +03004540
Michal Kazior7d9d5582014-10-21 10:40:15 +03004541 arvif->txpower = vif->bss_conf.txpower;
4542 ret = ath10k_mac_txpower_recalc(ar);
4543 if (ret) {
4544 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4545 goto err_peer_delete;
4546 }
4547
Michal Kazior500ff9f2015-03-31 10:26:21 +00004548 if (vif->type == NL80211_IFTYPE_MONITOR) {
4549 ar->monitor_arvif = arvif;
4550 ret = ath10k_monitor_recalc(ar);
4551 if (ret) {
4552 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
4553 goto err_peer_delete;
4554 }
4555 }
4556
Michal Kazior6d2d51e2015-08-07 09:08:21 +02004557 spin_lock_bh(&ar->htt.tx_lock);
4558 if (!ar->tx_paused)
4559 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
4560 spin_unlock_bh(&ar->htt.tx_lock);
4561
Kalle Valo5e3dd152013-06-12 20:52:10 +03004562 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004563 return 0;
4564
4565err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00004566 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4567 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004568 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
4569
4570err_vdev_delete:
4571 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07004572 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004573 list_del(&arvif->list);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004574
4575err:
Michal Kazior64badcb2014-09-18 11:18:02 +03004576 if (arvif->beacon_buf) {
4577 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
4578 arvif->beacon_buf, arvif->beacon_paddr);
4579 arvif->beacon_buf = NULL;
4580 }
4581
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004582 mutex_unlock(&ar->conf_mutex);
4583
Kalle Valo5e3dd152013-06-12 20:52:10 +03004584 return ret;
4585}
4586
Michal Kaziorb4aa5392015-03-31 10:26:24 +00004587static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
4588{
4589 int i;
4590
4591 for (i = 0; i < BITS_PER_LONG; i++)
4592 ath10k_mac_vif_tx_unlock(arvif, i);
4593}
4594
Kalle Valo5e3dd152013-06-12 20:52:10 +03004595static void ath10k_remove_interface(struct ieee80211_hw *hw,
4596 struct ieee80211_vif *vif)
4597{
4598 struct ath10k *ar = hw->priv;
4599 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4600 int ret;
4601
Michal Kazior81a9a172015-03-05 16:02:17 +02004602 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004603 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02004604
Sujith Manoharan5d011f52014-11-25 11:47:00 +05304605 mutex_lock(&ar->conf_mutex);
4606
Michal Kaziored543882013-09-13 14:16:56 +02004607 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004608 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02004609 spin_unlock_bh(&ar->data_lock);
4610
Simon Wunderlich855aed12014-08-02 09:12:54 +03004611 ret = ath10k_spectral_vif_stop(arvif);
4612 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004613 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03004614 arvif->vdev_id, ret);
4615
Ben Greear16c11172014-09-23 14:17:16 -07004616 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004617 list_del(&arvif->list);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004618
Michal Kaziore57e0572015-03-24 13:14:03 +00004619 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4620 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02004621 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
4622 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004623 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00004624 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004625 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004626
4627 kfree(arvif->u.ap.noa_data);
4628 }
4629
Michal Kazior7aa7a722014-08-25 12:09:38 +02004630 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004631 arvif->vdev_id);
4632
Kalle Valo5e3dd152013-06-12 20:52:10 +03004633 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
4634 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004635 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004636 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004637
Michal Kazior2c512052015-02-15 16:50:40 +02004638 /* Some firmware revisions don't notify host about self-peer removal
4639 * until after associated vdev is deleted.
4640 */
Michal Kaziore57e0572015-03-24 13:14:03 +00004641 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4642 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02004643 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
4644 vif->addr);
4645 if (ret)
4646 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
4647 arvif->vdev_id, ret);
4648
4649 spin_lock_bh(&ar->data_lock);
4650 ar->num_peers--;
4651 spin_unlock_bh(&ar->data_lock);
4652 }
4653
Kalle Valo5e3dd152013-06-12 20:52:10 +03004654 ath10k_peer_cleanup(ar, arvif->vdev_id);
4655
Michal Kazior500ff9f2015-03-31 10:26:21 +00004656 if (vif->type == NL80211_IFTYPE_MONITOR) {
4657 ar->monitor_arvif = NULL;
4658 ret = ath10k_monitor_recalc(ar);
4659 if (ret)
4660 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
4661 }
4662
Michal Kaziorb4aa5392015-03-31 10:26:24 +00004663 spin_lock_bh(&ar->htt.tx_lock);
4664 ath10k_mac_vif_tx_unlock_all(arvif);
4665 spin_unlock_bh(&ar->htt.tx_lock);
4666
Kalle Valo5e3dd152013-06-12 20:52:10 +03004667 mutex_unlock(&ar->conf_mutex);
4668}
4669
4670/*
4671 * FIXME: Has to be verified.
4672 */
4673#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02004674 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03004675 FIF_CONTROL | \
4676 FIF_PSPOLL | \
4677 FIF_OTHER_BSS | \
4678 FIF_BCN_PRBRESP_PROMISC | \
4679 FIF_PROBE_REQ | \
4680 FIF_FCSFAIL)
4681
4682static void ath10k_configure_filter(struct ieee80211_hw *hw,
4683 unsigned int changed_flags,
4684 unsigned int *total_flags,
4685 u64 multicast)
4686{
4687 struct ath10k *ar = hw->priv;
4688 int ret;
4689
4690 mutex_lock(&ar->conf_mutex);
4691
4692 changed_flags &= SUPPORTED_FILTERS;
4693 *total_flags &= SUPPORTED_FILTERS;
4694 ar->filter_flags = *total_flags;
4695
Michal Kazior19337472014-08-28 12:58:16 +02004696 ret = ath10k_monitor_recalc(ar);
4697 if (ret)
4698 ath10k_warn(ar, "failed to recalc montior: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004699
4700 mutex_unlock(&ar->conf_mutex);
4701}
4702
4703static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
4704 struct ieee80211_vif *vif,
4705 struct ieee80211_bss_conf *info,
4706 u32 changed)
4707{
4708 struct ath10k *ar = hw->priv;
4709 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4710 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03004711 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004712
4713 mutex_lock(&ar->conf_mutex);
4714
4715 if (changed & BSS_CHANGED_IBSS)
4716 ath10k_control_ibss(arvif, info, vif->addr);
4717
4718 if (changed & BSS_CHANGED_BEACON_INT) {
4719 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004720 vdev_param = ar->wmi.vdev_param->beacon_interval;
4721 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004722 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02004723 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004724 "mac vdev %d beacon_interval %d\n",
4725 arvif->vdev_id, arvif->beacon_interval);
4726
Kalle Valo5e3dd152013-06-12 20:52:10 +03004727 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004728 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004729 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004730 }
4731
4732 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004733 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004734 "vdev %d set beacon tx mode to staggered\n",
4735 arvif->vdev_id);
4736
Bartosz Markowski226a3392013-09-26 17:47:16 +02004737 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
4738 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004739 WMI_BEACON_STAGGERED_MODE);
4740 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004741 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004742 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02004743
4744 ret = ath10k_mac_setup_bcn_tmpl(arvif);
4745 if (ret)
4746 ath10k_warn(ar, "failed to update beacon template: %d\n",
4747 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004748
4749 if (ieee80211_vif_is_mesh(vif)) {
4750 /* mesh doesn't use SSID but firmware needs it */
4751 strncpy(arvif->u.ap.ssid, "mesh",
4752 sizeof(arvif->u.ap.ssid));
4753 arvif->u.ap.ssid_len = 4;
4754 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004755 }
4756
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02004757 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
4758 ret = ath10k_mac_setup_prb_tmpl(arvif);
4759 if (ret)
4760 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
4761 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004762 }
4763
Michal Kaziorba2479f2015-01-24 12:14:51 +02004764 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004765 arvif->dtim_period = info->dtim_period;
4766
Michal Kazior7aa7a722014-08-25 12:09:38 +02004767 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004768 "mac vdev %d dtim_period %d\n",
4769 arvif->vdev_id, arvif->dtim_period);
4770
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004771 vdev_param = ar->wmi.vdev_param->dtim_period;
4772 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004773 arvif->dtim_period);
4774 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004775 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004776 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004777 }
4778
4779 if (changed & BSS_CHANGED_SSID &&
4780 vif->type == NL80211_IFTYPE_AP) {
4781 arvif->u.ap.ssid_len = info->ssid_len;
4782 if (info->ssid_len)
4783 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
4784 arvif->u.ap.hidden_ssid = info->hidden_ssid;
4785 }
4786
Michal Kazior077efc82014-10-21 10:10:29 +03004787 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
4788 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004789
4790 if (changed & BSS_CHANGED_BEACON_ENABLED)
4791 ath10k_control_beaconing(arvif, info);
4792
4793 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004794 arvif->use_cts_prot = info->use_cts_prot;
Michal Kazior7aa7a722014-08-25 12:09:38 +02004795 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004796 arvif->vdev_id, info->use_cts_prot);
Kalle Valo60c3daa2013-09-08 17:56:07 +03004797
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004798 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004799 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004800 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004801 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01004802
4803 vdev_param = ar->wmi.vdev_param->protection_mode;
4804 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4805 info->use_cts_prot ? 1 : 0);
4806 if (ret)
4807 ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
Kalle Valo617b0f42015-10-05 17:56:35 +03004808 info->use_cts_prot, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004809 }
4810
4811 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004812 if (info->use_short_slot)
4813 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
4814
4815 else
4816 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
4817
Michal Kazior7aa7a722014-08-25 12:09:38 +02004818 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004819 arvif->vdev_id, slottime);
4820
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004821 vdev_param = ar->wmi.vdev_param->slot_time;
4822 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004823 slottime);
4824 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004825 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004826 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004827 }
4828
4829 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004830 if (info->use_short_preamble)
4831 preamble = WMI_VDEV_PREAMBLE_SHORT;
4832 else
4833 preamble = WMI_VDEV_PREAMBLE_LONG;
4834
Michal Kazior7aa7a722014-08-25 12:09:38 +02004835 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004836 "mac vdev %d preamble %dn",
4837 arvif->vdev_id, preamble);
4838
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004839 vdev_param = ar->wmi.vdev_param->preamble;
4840 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004841 preamble);
4842 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004843 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004844 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004845 }
4846
4847 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02004848 if (info->assoc) {
4849 /* Workaround: Make sure monitor vdev is not running
4850 * when associating to prevent some firmware revisions
4851 * (e.g. 10.1 and 10.2) from crashing.
4852 */
4853 if (ar->monitor_started)
4854 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004855 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02004856 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03004857 } else {
4858 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02004859 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004860 }
4861
Michal Kazior7d9d5582014-10-21 10:40:15 +03004862 if (changed & BSS_CHANGED_TXPOWER) {
4863 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
4864 arvif->vdev_id, info->txpower);
4865
4866 arvif->txpower = info->txpower;
4867 ret = ath10k_mac_txpower_recalc(ar);
4868 if (ret)
4869 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4870 }
4871
Michal Kaziorbf14e652014-12-12 12:41:38 +01004872 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01004873 arvif->ps = vif->bss_conf.ps;
4874
4875 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01004876 if (ret)
4877 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
4878 arvif->vdev_id, ret);
4879 }
4880
Kalle Valo5e3dd152013-06-12 20:52:10 +03004881 mutex_unlock(&ar->conf_mutex);
4882}
4883
4884static int ath10k_hw_scan(struct ieee80211_hw *hw,
4885 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02004886 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004887{
4888 struct ath10k *ar = hw->priv;
4889 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02004890 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004891 struct wmi_start_scan_arg arg;
4892 int ret = 0;
4893 int i;
4894
4895 mutex_lock(&ar->conf_mutex);
4896
4897 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004898 switch (ar->scan.state) {
4899 case ATH10K_SCAN_IDLE:
4900 reinit_completion(&ar->scan.started);
4901 reinit_completion(&ar->scan.completed);
4902 ar->scan.state = ATH10K_SCAN_STARTING;
4903 ar->scan.is_roc = false;
4904 ar->scan.vdev_id = arvif->vdev_id;
4905 ret = 0;
4906 break;
4907 case ATH10K_SCAN_STARTING:
4908 case ATH10K_SCAN_RUNNING:
4909 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03004910 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004911 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004912 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004913 spin_unlock_bh(&ar->data_lock);
4914
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004915 if (ret)
4916 goto exit;
4917
Kalle Valo5e3dd152013-06-12 20:52:10 +03004918 memset(&arg, 0, sizeof(arg));
4919 ath10k_wmi_start_scan_init(ar, &arg);
4920 arg.vdev_id = arvif->vdev_id;
4921 arg.scan_id = ATH10K_SCAN_ID;
4922
Kalle Valo5e3dd152013-06-12 20:52:10 +03004923 if (req->ie_len) {
4924 arg.ie_len = req->ie_len;
4925 memcpy(arg.ie, req->ie, arg.ie_len);
4926 }
4927
4928 if (req->n_ssids) {
4929 arg.n_ssids = req->n_ssids;
4930 for (i = 0; i < arg.n_ssids; i++) {
4931 arg.ssids[i].len = req->ssids[i].ssid_len;
4932 arg.ssids[i].ssid = req->ssids[i].ssid;
4933 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02004934 } else {
4935 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004936 }
4937
4938 if (req->n_channels) {
4939 arg.n_channels = req->n_channels;
4940 for (i = 0; i < arg.n_channels; i++)
4941 arg.channels[i] = req->channels[i]->center_freq;
4942 }
4943
4944 ret = ath10k_start_scan(ar, &arg);
4945 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004946 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004947 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004948 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004949 spin_unlock_bh(&ar->data_lock);
4950 }
4951
Michal Kazior634349b2015-09-03 10:43:45 +02004952 /* Add a 200ms margin to account for event/command processing */
4953 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
4954 msecs_to_jiffies(arg.max_scan_time +
4955 200));
4956
Kalle Valo5e3dd152013-06-12 20:52:10 +03004957exit:
4958 mutex_unlock(&ar->conf_mutex);
4959 return ret;
4960}
4961
4962static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
4963 struct ieee80211_vif *vif)
4964{
4965 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004966
4967 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004968 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004969 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01004970
4971 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004972}
4973
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004974static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
4975 struct ath10k_vif *arvif,
4976 enum set_key_cmd cmd,
4977 struct ieee80211_key_conf *key)
4978{
4979 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
4980 int ret;
4981
4982 /* 10.1 firmware branch requires default key index to be set to group
4983 * key index after installing it. Otherwise FW/HW Txes corrupted
4984 * frames with multi-vif APs. This is not required for main firmware
4985 * branch (e.g. 636).
4986 *
Michal Kazior8461baf2015-04-10 13:23:22 +00004987 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
4988 *
4989 * FIXME: It remains unknown if this is required for multi-vif STA
4990 * interfaces on 10.1.
4991 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004992
Michal Kazior8461baf2015-04-10 13:23:22 +00004993 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
4994 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004995 return;
4996
4997 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
4998 return;
4999
5000 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
5001 return;
5002
5003 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5004 return;
5005
5006 if (cmd != SET_KEY)
5007 return;
5008
5009 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5010 key->keyidx);
5011 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005012 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005013 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005014}
5015
Kalle Valo5e3dd152013-06-12 20:52:10 +03005016static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5017 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5018 struct ieee80211_key_conf *key)
5019{
5020 struct ath10k *ar = hw->priv;
5021 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5022 struct ath10k_peer *peer;
5023 const u8 *peer_addr;
5024 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5025 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5026 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005027 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005028 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005029 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005030
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005031 /* this one needs to be done in software */
5032 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
5033 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005034
David Liuccec9032015-07-24 20:25:32 +03005035 if (arvif->nohwcrypt)
5036 return 1;
5037
Kalle Valo5e3dd152013-06-12 20:52:10 +03005038 if (key->keyidx > WMI_MAX_KEY_INDEX)
5039 return -ENOSPC;
5040
5041 mutex_lock(&ar->conf_mutex);
5042
5043 if (sta)
5044 peer_addr = sta->addr;
5045 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5046 peer_addr = vif->bss_conf.bssid;
5047 else
5048 peer_addr = vif->addr;
5049
5050 key->hw_key_idx = key->keyidx;
5051
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005052 if (is_wep) {
5053 if (cmd == SET_KEY)
5054 arvif->wep_keys[key->keyidx] = key;
5055 else
5056 arvif->wep_keys[key->keyidx] = NULL;
5057 }
5058
Kalle Valo5e3dd152013-06-12 20:52:10 +03005059 /* the peer should not disappear in mid-way (unless FW goes awry) since
5060 * we already hold conf_mutex. we just make sure its there now. */
5061 spin_lock_bh(&ar->data_lock);
5062 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5063 spin_unlock_bh(&ar->data_lock);
5064
5065 if (!peer) {
5066 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005067 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005068 peer_addr);
5069 ret = -EOPNOTSUPP;
5070 goto exit;
5071 } else {
5072 /* if the peer doesn't exist there is no key to disable
5073 * anymore */
5074 goto exit;
5075 }
5076 }
5077
Michal Kazior7cc45732015-03-09 14:24:17 +01005078 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5079 flags |= WMI_KEY_PAIRWISE;
5080 else
5081 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005082
Kalle Valo5e3dd152013-06-12 20:52:10 +03005083 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005084 if (cmd == DISABLE_KEY)
5085 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005086
Michal Kaziorad325cb2015-02-18 14:02:27 +01005087 /* When WEP keys are uploaded it's possible that there are
5088 * stations associated already (e.g. when merging) without any
5089 * keys. Static WEP needs an explicit per-peer key upload.
5090 */
5091 if (vif->type == NL80211_IFTYPE_ADHOC &&
5092 cmd == SET_KEY)
5093 ath10k_mac_vif_update_wep_key(arvif, key);
5094
Michal Kazior370e5672015-02-18 14:02:26 +01005095 /* 802.1x never sets the def_wep_key_idx so each set_key()
5096 * call changes default tx key.
5097 *
5098 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5099 * after first set_key().
5100 */
5101 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5102 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005103 }
5104
Michal Kazior370e5672015-02-18 14:02:26 +01005105 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005106 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005107 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005108 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005109 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005110 goto exit;
5111 }
5112
Michal Kazior29a10002015-04-10 13:05:58 +00005113 /* mac80211 sets static WEP keys as groupwise while firmware requires
5114 * them to be installed twice as both pairwise and groupwise.
5115 */
5116 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5117 flags2 = flags;
5118 flags2 &= ~WMI_KEY_GROUP;
5119 flags2 |= WMI_KEY_PAIRWISE;
5120
5121 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5122 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005123 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005124 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5125 arvif->vdev_id, peer_addr, ret);
5126 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5127 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005128 if (ret2) {
5129 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005130 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5131 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005132 }
Michal Kazior29a10002015-04-10 13:05:58 +00005133 goto exit;
5134 }
5135 }
5136
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005137 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5138
Kalle Valo5e3dd152013-06-12 20:52:10 +03005139 spin_lock_bh(&ar->data_lock);
5140 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5141 if (peer && cmd == SET_KEY)
5142 peer->keys[key->keyidx] = key;
5143 else if (peer && cmd == DISABLE_KEY)
5144 peer->keys[key->keyidx] = NULL;
5145 else if (peer == NULL)
5146 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005147 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005148 spin_unlock_bh(&ar->data_lock);
5149
5150exit:
5151 mutex_unlock(&ar->conf_mutex);
5152 return ret;
5153}
5154
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005155static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5156 struct ieee80211_vif *vif,
5157 int keyidx)
5158{
5159 struct ath10k *ar = hw->priv;
5160 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5161 int ret;
5162
5163 mutex_lock(&arvif->ar->conf_mutex);
5164
5165 if (arvif->ar->state != ATH10K_STATE_ON)
5166 goto unlock;
5167
5168 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5169 arvif->vdev_id, keyidx);
5170
5171 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5172 arvif->vdev_id,
5173 arvif->ar->wmi.vdev_param->def_keyid,
5174 keyidx);
5175
5176 if (ret) {
5177 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5178 arvif->vdev_id,
5179 ret);
5180 goto unlock;
5181 }
5182
5183 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005184
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005185unlock:
5186 mutex_unlock(&arvif->ar->conf_mutex);
5187}
5188
Michal Kazior9797feb2014-02-14 14:49:48 +01005189static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5190{
5191 struct ath10k *ar;
5192 struct ath10k_vif *arvif;
5193 struct ath10k_sta *arsta;
5194 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005195 struct cfg80211_chan_def def;
5196 enum ieee80211_band band;
5197 const u8 *ht_mcs_mask;
5198 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005199 u32 changed, bw, nss, smps;
5200 int err;
5201
5202 arsta = container_of(wk, struct ath10k_sta, update_wk);
5203 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5204 arvif = arsta->arvif;
5205 ar = arvif->ar;
5206
Michal Kazior45c9abc2015-04-21 20:42:58 +03005207 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5208 return;
5209
5210 band = def.chan->band;
5211 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5212 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5213
Michal Kazior9797feb2014-02-14 14:49:48 +01005214 spin_lock_bh(&ar->data_lock);
5215
5216 changed = arsta->changed;
5217 arsta->changed = 0;
5218
5219 bw = arsta->bw;
5220 nss = arsta->nss;
5221 smps = arsta->smps;
5222
5223 spin_unlock_bh(&ar->data_lock);
5224
5225 mutex_lock(&ar->conf_mutex);
5226
Michal Kazior45c9abc2015-04-21 20:42:58 +03005227 nss = max_t(u32, 1, nss);
5228 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
5229 ath10k_mac_max_vht_nss(vht_mcs_mask)));
5230
Michal Kazior9797feb2014-02-14 14:49:48 +01005231 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005232 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005233 sta->addr, bw);
5234
5235 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5236 WMI_PEER_CHAN_WIDTH, bw);
5237 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005238 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005239 sta->addr, bw, err);
5240 }
5241
5242 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005243 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005244 sta->addr, nss);
5245
5246 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5247 WMI_PEER_NSS, nss);
5248 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005249 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005250 sta->addr, nss, err);
5251 }
5252
5253 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005254 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005255 sta->addr, smps);
5256
5257 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5258 WMI_PEER_SMPS_STATE, smps);
5259 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005260 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005261 sta->addr, smps, err);
5262 }
5263
Janusz Dziedzic55884c02014-12-17 12:30:02 +02005264 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
5265 changed & IEEE80211_RC_NSS_CHANGED) {
5266 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005267 sta->addr);
5268
Michal Kazior590922a2014-10-21 10:10:29 +03005269 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005270 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005271 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005272 sta->addr);
5273 }
5274
Michal Kazior9797feb2014-02-14 14:49:48 +01005275 mutex_unlock(&ar->conf_mutex);
5276}
5277
Marek Puzyniak7c354242015-03-30 09:51:52 +03005278static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
5279 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005280{
5281 struct ath10k *ar = arvif->ar;
5282
5283 lockdep_assert_held(&ar->conf_mutex);
5284
Marek Puzyniak7c354242015-03-30 09:51:52 +03005285 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005286 return 0;
5287
5288 if (ar->num_stations >= ar->max_num_stations)
5289 return -ENOBUFS;
5290
5291 ar->num_stations++;
5292
5293 return 0;
5294}
5295
Marek Puzyniak7c354242015-03-30 09:51:52 +03005296static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
5297 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005298{
5299 struct ath10k *ar = arvif->ar;
5300
5301 lockdep_assert_held(&ar->conf_mutex);
5302
Marek Puzyniak7c354242015-03-30 09:51:52 +03005303 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005304 return;
5305
5306 ar->num_stations--;
5307}
5308
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005309struct ath10k_mac_tdls_iter_data {
5310 u32 num_tdls_stations;
5311 struct ieee80211_vif *curr_vif;
5312};
5313
5314static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5315 struct ieee80211_sta *sta)
5316{
5317 struct ath10k_mac_tdls_iter_data *iter_data = data;
5318 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5319 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5320
5321 if (sta->tdls && sta_vif == iter_data->curr_vif)
5322 iter_data->num_tdls_stations++;
5323}
5324
5325static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5326 struct ieee80211_vif *vif)
5327{
5328 struct ath10k_mac_tdls_iter_data data = {};
5329
5330 data.curr_vif = vif;
5331
5332 ieee80211_iterate_stations_atomic(hw,
5333 ath10k_mac_tdls_vif_stations_count_iter,
5334 &data);
5335 return data.num_tdls_stations;
5336}
5337
5338static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5339 struct ieee80211_vif *vif)
5340{
5341 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5342 int *num_tdls_vifs = data;
5343
5344 if (vif->type != NL80211_IFTYPE_STATION)
5345 return;
5346
5347 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5348 (*num_tdls_vifs)++;
5349}
5350
5351static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5352{
5353 int num_tdls_vifs = 0;
5354
5355 ieee80211_iterate_active_interfaces_atomic(hw,
5356 IEEE80211_IFACE_ITER_NORMAL,
5357 ath10k_mac_tdls_vifs_count_iter,
5358 &num_tdls_vifs);
5359 return num_tdls_vifs;
5360}
5361
Kalle Valo5e3dd152013-06-12 20:52:10 +03005362static int ath10k_sta_state(struct ieee80211_hw *hw,
5363 struct ieee80211_vif *vif,
5364 struct ieee80211_sta *sta,
5365 enum ieee80211_sta_state old_state,
5366 enum ieee80211_sta_state new_state)
5367{
5368 struct ath10k *ar = hw->priv;
5369 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005370 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005371 int ret = 0;
5372
Michal Kazior76f90022014-02-25 09:29:57 +02005373 if (old_state == IEEE80211_STA_NOTEXIST &&
5374 new_state == IEEE80211_STA_NONE) {
5375 memset(arsta, 0, sizeof(*arsta));
5376 arsta->arvif = arvif;
5377 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
5378 }
5379
Michal Kazior9797feb2014-02-14 14:49:48 +01005380 /* cancel must be done outside the mutex to avoid deadlock */
5381 if ((old_state == IEEE80211_STA_NONE &&
5382 new_state == IEEE80211_STA_NOTEXIST))
5383 cancel_work_sync(&arsta->update_wk);
5384
Kalle Valo5e3dd152013-06-12 20:52:10 +03005385 mutex_lock(&ar->conf_mutex);
5386
5387 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005388 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005389 /*
5390 * New station addition.
5391 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005392 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5393 u32 num_tdls_stations;
5394 u32 num_tdls_vifs;
5395
Michal Kaziorcfd10612014-11-25 15:16:05 +01005396 ath10k_dbg(ar, ATH10K_DBG_MAC,
5397 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5398 arvif->vdev_id, sta->addr,
5399 ar->num_stations + 1, ar->max_num_stations,
5400 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005401
Marek Puzyniak7c354242015-03-30 09:51:52 +03005402 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005403 if (ret) {
5404 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5405 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005406 goto exit;
5407 }
5408
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005409 if (sta->tdls)
5410 peer_type = WMI_PEER_TYPE_TDLS;
5411
Marek Puzyniak7390ed32015-03-30 09:51:52 +03005412 ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr,
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005413 peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005414 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005415 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 -08005416 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005417 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005418 goto exit;
5419 }
Michal Kazior077efc82014-10-21 10:10:29 +03005420
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005421 if (!sta->tdls)
5422 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03005423
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005424 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
5425 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
5426
5427 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
5428 num_tdls_stations == 0) {
5429 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
5430 arvif->vdev_id, ar->max_num_tdls_vdevs);
5431 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5432 ath10k_mac_dec_num_stations(arvif, sta);
5433 ret = -ENOBUFS;
5434 goto exit;
5435 }
5436
5437 if (num_tdls_stations == 0) {
5438 /* This is the first tdls peer in current vif */
5439 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
5440
5441 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5442 state);
Michal Kazior077efc82014-10-21 10:10:29 +03005443 if (ret) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005444 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
Michal Kazior077efc82014-10-21 10:10:29 +03005445 arvif->vdev_id, ret);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005446 ath10k_peer_delete(ar, arvif->vdev_id,
5447 sta->addr);
5448 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03005449 goto exit;
5450 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005451 }
Michal Kazior077efc82014-10-21 10:10:29 +03005452
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005453 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5454 WMI_TDLS_PEER_STATE_PEERING);
5455 if (ret) {
5456 ath10k_warn(ar,
5457 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
5458 sta->addr, arvif->vdev_id, ret);
5459 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5460 ath10k_mac_dec_num_stations(arvif, sta);
5461
5462 if (num_tdls_stations != 0)
5463 goto exit;
5464 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5465 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03005466 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005467 } else if ((old_state == IEEE80211_STA_NONE &&
5468 new_state == IEEE80211_STA_NOTEXIST)) {
5469 /*
5470 * Existing station deletion.
5471 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005472 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005473 "mac vdev %d peer delete %pM (sta gone)\n",
5474 arvif->vdev_id, sta->addr);
Michal Kazior077efc82014-10-21 10:10:29 +03005475
Kalle Valo5e3dd152013-06-12 20:52:10 +03005476 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5477 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005478 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005479 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005480
Marek Puzyniak7c354242015-03-30 09:51:52 +03005481 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005482
5483 if (!sta->tdls)
5484 goto exit;
5485
5486 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
5487 goto exit;
5488
5489 /* This was the last tdls peer in current vif */
5490 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5491 WMI_TDLS_DISABLE);
5492 if (ret) {
5493 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
5494 arvif->vdev_id, ret);
5495 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005496 } else if (old_state == IEEE80211_STA_AUTH &&
5497 new_state == IEEE80211_STA_ASSOC &&
5498 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005499 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03005500 vif->type == NL80211_IFTYPE_ADHOC)) {
5501 /*
5502 * New association.
5503 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005504 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005505 sta->addr);
5506
Michal Kazior590922a2014-10-21 10:10:29 +03005507 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005508 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005509 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005510 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005511 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005512 new_state == IEEE80211_STA_AUTHORIZED &&
5513 sta->tdls) {
5514 /*
5515 * Tdls station authorized.
5516 */
5517 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
5518 sta->addr);
5519
5520 ret = ath10k_station_assoc(ar, vif, sta, false);
5521 if (ret) {
5522 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
5523 sta->addr, arvif->vdev_id, ret);
5524 goto exit;
5525 }
5526
5527 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5528 WMI_TDLS_PEER_STATE_CONNECTED);
5529 if (ret)
5530 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
5531 sta->addr, arvif->vdev_id, ret);
5532 } else if (old_state == IEEE80211_STA_ASSOC &&
5533 new_state == IEEE80211_STA_AUTH &&
5534 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005535 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005536 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005537 /*
5538 * Disassociation.
5539 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005540 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005541 sta->addr);
5542
Michal Kazior590922a2014-10-21 10:10:29 +03005543 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005544 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005545 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005546 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005547 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005548exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005549 mutex_unlock(&ar->conf_mutex);
5550 return ret;
5551}
5552
5553static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03005554 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005555{
5556 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02005557 struct wmi_sta_uapsd_auto_trig_arg arg = {};
5558 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005559 u32 value = 0;
5560 int ret = 0;
5561
Michal Kazior548db542013-07-05 16:15:15 +03005562 lockdep_assert_held(&ar->conf_mutex);
5563
Kalle Valo5e3dd152013-06-12 20:52:10 +03005564 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
5565 return 0;
5566
5567 switch (ac) {
5568 case IEEE80211_AC_VO:
5569 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
5570 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005571 prio = 7;
5572 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005573 break;
5574 case IEEE80211_AC_VI:
5575 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
5576 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005577 prio = 5;
5578 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005579 break;
5580 case IEEE80211_AC_BE:
5581 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
5582 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005583 prio = 2;
5584 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005585 break;
5586 case IEEE80211_AC_BK:
5587 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
5588 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005589 prio = 0;
5590 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005591 break;
5592 }
5593
5594 if (enable)
5595 arvif->u.sta.uapsd |= value;
5596 else
5597 arvif->u.sta.uapsd &= ~value;
5598
5599 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5600 WMI_STA_PS_PARAM_UAPSD,
5601 arvif->u.sta.uapsd);
5602 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005603 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005604 goto exit;
5605 }
5606
5607 if (arvif->u.sta.uapsd)
5608 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
5609 else
5610 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5611
5612 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5613 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
5614 value);
5615 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005616 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005617
Michal Kazior9f9b5742014-12-12 12:41:36 +01005618 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
5619 if (ret) {
5620 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
5621 arvif->vdev_id, ret);
5622 return ret;
5623 }
5624
5625 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
5626 if (ret) {
5627 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
5628 arvif->vdev_id, ret);
5629 return ret;
5630 }
5631
Michal Kaziorb0e56152015-01-24 12:14:52 +02005632 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
5633 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
5634 /* Only userspace can make an educated decision when to send
5635 * trigger frame. The following effectively disables u-UAPSD
5636 * autotrigger in firmware (which is enabled by default
5637 * provided the autotrigger service is available).
5638 */
5639
5640 arg.wmm_ac = acc;
5641 arg.user_priority = prio;
5642 arg.service_interval = 0;
5643 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
5644 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
5645
5646 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
5647 arvif->bssid, &arg, 1);
5648 if (ret) {
5649 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
5650 ret);
5651 return ret;
5652 }
5653 }
5654
Kalle Valo5e3dd152013-06-12 20:52:10 +03005655exit:
5656 return ret;
5657}
5658
5659static int ath10k_conf_tx(struct ieee80211_hw *hw,
5660 struct ieee80211_vif *vif, u16 ac,
5661 const struct ieee80211_tx_queue_params *params)
5662{
5663 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01005664 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005665 struct wmi_wmm_params_arg *p = NULL;
5666 int ret;
5667
5668 mutex_lock(&ar->conf_mutex);
5669
5670 switch (ac) {
5671 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01005672 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005673 break;
5674 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01005675 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005676 break;
5677 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01005678 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005679 break;
5680 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01005681 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005682 break;
5683 }
5684
5685 if (WARN_ON(!p)) {
5686 ret = -EINVAL;
5687 goto exit;
5688 }
5689
5690 p->cwmin = params->cw_min;
5691 p->cwmax = params->cw_max;
5692 p->aifs = params->aifs;
5693
5694 /*
5695 * The channel time duration programmed in the HW is in absolute
5696 * microseconds, while mac80211 gives the txop in units of
5697 * 32 microseconds.
5698 */
5699 p->txop = params->txop * 32;
5700
Michal Kazior7fc979a2015-01-28 09:57:28 +02005701 if (ar->wmi.ops->gen_vdev_wmm_conf) {
5702 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
5703 &arvif->wmm_params);
5704 if (ret) {
5705 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
5706 arvif->vdev_id, ret);
5707 goto exit;
5708 }
5709 } else {
5710 /* This won't work well with multi-interface cases but it's
5711 * better than nothing.
5712 */
5713 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
5714 if (ret) {
5715 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
5716 goto exit;
5717 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005718 }
5719
5720 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
5721 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005722 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005723
5724exit:
5725 mutex_unlock(&ar->conf_mutex);
5726 return ret;
5727}
5728
5729#define ATH10K_ROC_TIMEOUT_HZ (2*HZ)
5730
5731static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
5732 struct ieee80211_vif *vif,
5733 struct ieee80211_channel *chan,
5734 int duration,
5735 enum ieee80211_roc_type type)
5736{
5737 struct ath10k *ar = hw->priv;
5738 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5739 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005740 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00005741 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005742
5743 mutex_lock(&ar->conf_mutex);
5744
5745 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005746 switch (ar->scan.state) {
5747 case ATH10K_SCAN_IDLE:
5748 reinit_completion(&ar->scan.started);
5749 reinit_completion(&ar->scan.completed);
5750 reinit_completion(&ar->scan.on_channel);
5751 ar->scan.state = ATH10K_SCAN_STARTING;
5752 ar->scan.is_roc = true;
5753 ar->scan.vdev_id = arvif->vdev_id;
5754 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02005755 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005756 ret = 0;
5757 break;
5758 case ATH10K_SCAN_STARTING:
5759 case ATH10K_SCAN_RUNNING:
5760 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005761 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005762 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005763 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005764 spin_unlock_bh(&ar->data_lock);
5765
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005766 if (ret)
5767 goto exit;
5768
Michal Kaziorfcf98442015-03-31 11:03:47 +00005769 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01005770
Kalle Valo5e3dd152013-06-12 20:52:10 +03005771 memset(&arg, 0, sizeof(arg));
5772 ath10k_wmi_start_scan_init(ar, &arg);
5773 arg.vdev_id = arvif->vdev_id;
5774 arg.scan_id = ATH10K_SCAN_ID;
5775 arg.n_channels = 1;
5776 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00005777 arg.dwell_time_active = scan_time_msec;
5778 arg.dwell_time_passive = scan_time_msec;
5779 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005780 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
5781 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00005782 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005783
5784 ret = ath10k_start_scan(ar, &arg);
5785 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005786 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005787 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005788 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005789 spin_unlock_bh(&ar->data_lock);
5790 goto exit;
5791 }
5792
5793 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ);
5794 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005795 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005796
5797 ret = ath10k_scan_stop(ar);
5798 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005799 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005800
Kalle Valo5e3dd152013-06-12 20:52:10 +03005801 ret = -ETIMEDOUT;
5802 goto exit;
5803 }
5804
Michal Kaziorfcf98442015-03-31 11:03:47 +00005805 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5806 msecs_to_jiffies(duration));
5807
Kalle Valo5e3dd152013-06-12 20:52:10 +03005808 ret = 0;
5809exit:
5810 mutex_unlock(&ar->conf_mutex);
5811 return ret;
5812}
5813
5814static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
5815{
5816 struct ath10k *ar = hw->priv;
5817
5818 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02005819
5820 spin_lock_bh(&ar->data_lock);
5821 ar->scan.roc_notify = false;
5822 spin_unlock_bh(&ar->data_lock);
5823
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005824 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02005825
Kalle Valo5e3dd152013-06-12 20:52:10 +03005826 mutex_unlock(&ar->conf_mutex);
5827
Michal Kazior4eb2e162014-10-28 10:23:09 +01005828 cancel_delayed_work_sync(&ar->scan.timeout);
5829
Kalle Valo5e3dd152013-06-12 20:52:10 +03005830 return 0;
5831}
5832
5833/*
5834 * Both RTS and Fragmentation threshold are interface-specific
5835 * in ath10k, but device-specific in mac80211.
5836 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03005837
5838static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
5839{
Kalle Valo5e3dd152013-06-12 20:52:10 +03005840 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03005841 struct ath10k_vif *arvif;
5842 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03005843
Michal Kaziorad088bf2013-10-16 15:44:46 +03005844 mutex_lock(&ar->conf_mutex);
5845 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005846 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03005847 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03005848
Michal Kaziorad088bf2013-10-16 15:44:46 +03005849 ret = ath10k_mac_set_rts(arvif, value);
5850 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005851 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03005852 arvif->vdev_id, ret);
5853 break;
5854 }
5855 }
5856 mutex_unlock(&ar->conf_mutex);
5857
5858 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005859}
5860
Michal Kazior92092fe2015-08-03 11:16:43 +02005861static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
5862{
5863 /* Even though there's a WMI enum for fragmentation threshold no known
5864 * firmware actually implements it. Moreover it is not possible to rely
5865 * frame fragmentation to mac80211 because firmware clears the "more
5866 * fragments" bit in frame control making it impossible for remote
5867 * devices to reassemble frames.
5868 *
5869 * Hence implement a dummy callback just to say fragmentation isn't
5870 * supported. This effectively prevents mac80211 from doing frame
5871 * fragmentation in software.
5872 */
5873 return -EOPNOTSUPP;
5874}
5875
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02005876static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5877 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005878{
5879 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02005880 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03005881 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005882
5883 /* mac80211 doesn't care if we really xmit queued frames or not
5884 * we'll collect those frames either way if we stop/delete vdevs */
5885 if (drop)
5886 return;
5887
Michal Kazior548db542013-07-05 16:15:15 +03005888 mutex_lock(&ar->conf_mutex);
5889
Michal Kazioraffd3212013-07-16 09:54:35 +02005890 if (ar->state == ATH10K_STATE_WEDGED)
5891 goto skip;
5892
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03005893 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03005894 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02005895
Michal Kazioredb82362013-07-05 16:15:14 +03005896 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02005897 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03005898 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02005899
Michal Kazior7962b0d2014-10-28 10:34:38 +01005900 skip = (ar->state == ATH10K_STATE_WEDGED) ||
5901 test_bit(ATH10K_FLAG_CRASH_FLUSH,
5902 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02005903
5904 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005905 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02005906
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03005907 if (time_left == 0 || skip)
5908 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
5909 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03005910
Michal Kazioraffd3212013-07-16 09:54:35 +02005911skip:
Michal Kazior548db542013-07-05 16:15:15 +03005912 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005913}
5914
5915/* TODO: Implement this function properly
5916 * For now it is needed to reply to Probe Requests in IBSS mode.
5917 * Propably we need this information from FW.
5918 */
5919static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
5920{
5921 return 1;
5922}
5923
Eliad Pellercf2c92d2014-11-04 11:43:54 +02005924static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
5925 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02005926{
5927 struct ath10k *ar = hw->priv;
5928
Eliad Pellercf2c92d2014-11-04 11:43:54 +02005929 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
5930 return;
5931
Michal Kazioraffd3212013-07-16 09:54:35 +02005932 mutex_lock(&ar->conf_mutex);
5933
5934 /* If device failed to restart it will be in a different state, e.g.
5935 * ATH10K_STATE_WEDGED */
5936 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005937 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02005938 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01005939 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02005940 }
5941
5942 mutex_unlock(&ar->conf_mutex);
5943}
5944
Michal Kazior2e1dea42013-07-31 10:32:40 +02005945static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
5946 struct survey_info *survey)
5947{
5948 struct ath10k *ar = hw->priv;
5949 struct ieee80211_supported_band *sband;
5950 struct survey_info *ar_survey = &ar->survey[idx];
5951 int ret = 0;
5952
5953 mutex_lock(&ar->conf_mutex);
5954
5955 sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
5956 if (sband && idx >= sband->n_channels) {
5957 idx -= sband->n_channels;
5958 sband = NULL;
5959 }
5960
5961 if (!sband)
5962 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
5963
5964 if (!sband || idx >= sband->n_channels) {
5965 ret = -ENOENT;
5966 goto exit;
5967 }
5968
5969 spin_lock_bh(&ar->data_lock);
5970 memcpy(survey, ar_survey, sizeof(*survey));
5971 spin_unlock_bh(&ar->data_lock);
5972
5973 survey->channel = &sband->channels[idx];
5974
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03005975 if (ar->rx_channel == survey->channel)
5976 survey->filled |= SURVEY_INFO_IN_USE;
5977
Michal Kazior2e1dea42013-07-31 10:32:40 +02005978exit:
5979 mutex_unlock(&ar->conf_mutex);
5980 return ret;
5981}
5982
Michal Kazior3ae54222015-03-31 10:49:20 +00005983static bool
5984ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
5985 enum ieee80211_band band,
5986 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005987{
Michal Kazior3ae54222015-03-31 10:49:20 +00005988 int num_rates = 0;
5989 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005990
Michal Kazior3ae54222015-03-31 10:49:20 +00005991 num_rates += hweight32(mask->control[band].legacy);
5992
5993 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
5994 num_rates += hweight8(mask->control[band].ht_mcs[i]);
5995
5996 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
5997 num_rates += hweight16(mask->control[band].vht_mcs[i]);
5998
5999 return num_rates == 1;
6000}
6001
6002static bool
6003ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
6004 enum ieee80211_band band,
6005 const struct cfg80211_bitrate_mask *mask,
6006 int *nss)
6007{
6008 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6009 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6010 u8 ht_nss_mask = 0;
6011 u8 vht_nss_mask = 0;
6012 int i;
6013
6014 if (mask->control[band].legacy)
6015 return false;
6016
6017 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6018 if (mask->control[band].ht_mcs[i] == 0)
6019 continue;
6020 else if (mask->control[band].ht_mcs[i] ==
6021 sband->ht_cap.mcs.rx_mask[i])
6022 ht_nss_mask |= BIT(i);
6023 else
6024 return false;
6025 }
6026
6027 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6028 if (mask->control[band].vht_mcs[i] == 0)
6029 continue;
6030 else if (mask->control[band].vht_mcs[i] ==
6031 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6032 vht_nss_mask |= BIT(i);
6033 else
6034 return false;
6035 }
6036
6037 if (ht_nss_mask != vht_nss_mask)
6038 return false;
6039
6040 if (ht_nss_mask == 0)
6041 return false;
6042
6043 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6044 return false;
6045
6046 *nss = fls(ht_nss_mask);
6047
6048 return true;
6049}
6050
6051static int
6052ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
6053 enum ieee80211_band band,
6054 const struct cfg80211_bitrate_mask *mask,
6055 u8 *rate, u8 *nss)
6056{
6057 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6058 int rate_idx;
6059 int i;
6060 u16 bitrate;
6061 u8 preamble;
6062 u8 hw_rate;
6063
6064 if (hweight32(mask->control[band].legacy) == 1) {
6065 rate_idx = ffs(mask->control[band].legacy) - 1;
6066
6067 hw_rate = sband->bitrates[rate_idx].hw_value;
6068 bitrate = sband->bitrates[rate_idx].bitrate;
6069
6070 if (ath10k_mac_bitrate_is_cck(bitrate))
6071 preamble = WMI_RATE_PREAMBLE_CCK;
6072 else
6073 preamble = WMI_RATE_PREAMBLE_OFDM;
6074
6075 *nss = 1;
6076 *rate = preamble << 6 |
6077 (*nss - 1) << 4 |
6078 hw_rate << 0;
6079
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006080 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006081 }
6082
Michal Kazior3ae54222015-03-31 10:49:20 +00006083 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6084 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6085 *nss = i + 1;
6086 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6087 (*nss - 1) << 4 |
6088 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006089
Michal Kazior3ae54222015-03-31 10:49:20 +00006090 return 0;
6091 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006092 }
6093
Michal Kazior3ae54222015-03-31 10:49:20 +00006094 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6095 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6096 *nss = i + 1;
6097 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6098 (*nss - 1) << 4 |
6099 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006100
Michal Kazior3ae54222015-03-31 10:49:20 +00006101 return 0;
6102 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006103 }
6104
Michal Kazior3ae54222015-03-31 10:49:20 +00006105 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006106}
6107
Michal Kazior3ae54222015-03-31 10:49:20 +00006108static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306109 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006110{
6111 struct ath10k *ar = arvif->ar;
6112 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006113 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006114
Michal Kazior3ae54222015-03-31 10:49:20 +00006115 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006116
Michal Kazior3ae54222015-03-31 10:49:20 +00006117 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6118 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006119
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006120 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006121 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006122 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006123 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006124 rate, ret);
6125 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006126 }
6127
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006128 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006129 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006130 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006131 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6132 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006133 }
6134
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006135 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006136 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006137 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006138 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6139 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006140 }
6141
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306142 vdev_param = ar->wmi.vdev_param->ldpc;
6143 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6144 if (ret) {
6145 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6146 return ret;
6147 }
6148
Michal Kazior3ae54222015-03-31 10:49:20 +00006149 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006150}
6151
Michal Kazior45c9abc2015-04-21 20:42:58 +03006152static bool
6153ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
6154 enum ieee80211_band band,
6155 const struct cfg80211_bitrate_mask *mask)
6156{
6157 int i;
6158 u16 vht_mcs;
6159
6160 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6161 * to express all VHT MCS rate masks. Effectively only the following
6162 * ranges can be used: none, 0-7, 0-8 and 0-9.
6163 */
6164 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6165 vht_mcs = mask->control[band].vht_mcs[i];
6166
6167 switch (vht_mcs) {
6168 case 0:
6169 case BIT(8) - 1:
6170 case BIT(9) - 1:
6171 case BIT(10) - 1:
6172 break;
6173 default:
6174 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6175 return false;
6176 }
6177 }
6178
6179 return true;
6180}
6181
6182static void ath10k_mac_set_bitrate_mask_iter(void *data,
6183 struct ieee80211_sta *sta)
6184{
6185 struct ath10k_vif *arvif = data;
6186 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6187 struct ath10k *ar = arvif->ar;
6188
6189 if (arsta->arvif != arvif)
6190 return;
6191
6192 spin_lock_bh(&ar->data_lock);
6193 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
6194 spin_unlock_bh(&ar->data_lock);
6195
6196 ieee80211_queue_work(ar->hw, &arsta->update_wk);
6197}
6198
Michal Kazior3ae54222015-03-31 10:49:20 +00006199static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
6200 struct ieee80211_vif *vif,
6201 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006202{
6203 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006204 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006205 struct ath10k *ar = arvif->ar;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006206 enum ieee80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006207 const u8 *ht_mcs_mask;
6208 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00006209 u8 rate;
6210 u8 nss;
6211 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306212 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00006213 int single_nss;
6214 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006215
Michal Kazior500ff9f2015-03-31 10:26:21 +00006216 if (ath10k_mac_vif_chan(vif, &def))
6217 return -EPERM;
6218
Michal Kazior500ff9f2015-03-31 10:26:21 +00006219 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006220 ht_mcs_mask = mask->control[band].ht_mcs;
6221 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306222 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006223
Michal Kazior3ae54222015-03-31 10:49:20 +00006224 sgi = mask->control[band].gi;
6225 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006226 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006227
Michal Kazior3ae54222015-03-31 10:49:20 +00006228 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
6229 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
6230 &rate, &nss);
6231 if (ret) {
6232 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
6233 arvif->vdev_id, ret);
6234 return ret;
6235 }
6236 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
6237 &single_nss)) {
6238 rate = WMI_FIXED_RATE_NONE;
6239 nss = single_nss;
6240 } else {
6241 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006242 nss = min(ar->num_rf_chains,
6243 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6244 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6245
6246 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
6247 return -EINVAL;
6248
6249 mutex_lock(&ar->conf_mutex);
6250
6251 arvif->bitrate_mask = *mask;
6252 ieee80211_iterate_stations_atomic(ar->hw,
6253 ath10k_mac_set_bitrate_mask_iter,
6254 arvif);
6255
6256 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006257 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006258
6259 mutex_lock(&ar->conf_mutex);
6260
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306261 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006262 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006263 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
6264 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006265 goto exit;
6266 }
6267
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006268exit:
6269 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00006270
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006271 return ret;
6272}
6273
Michal Kazior9797feb2014-02-14 14:49:48 +01006274static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6275 struct ieee80211_vif *vif,
6276 struct ieee80211_sta *sta,
6277 u32 changed)
6278{
6279 struct ath10k *ar = hw->priv;
6280 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6281 u32 bw, smps;
6282
6283 spin_lock_bh(&ar->data_lock);
6284
Michal Kazior7aa7a722014-08-25 12:09:38 +02006285 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01006286 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
6287 sta->addr, changed, sta->bandwidth, sta->rx_nss,
6288 sta->smps_mode);
6289
6290 if (changed & IEEE80211_RC_BW_CHANGED) {
6291 bw = WMI_PEER_CHWIDTH_20MHZ;
6292
6293 switch (sta->bandwidth) {
6294 case IEEE80211_STA_RX_BW_20:
6295 bw = WMI_PEER_CHWIDTH_20MHZ;
6296 break;
6297 case IEEE80211_STA_RX_BW_40:
6298 bw = WMI_PEER_CHWIDTH_40MHZ;
6299 break;
6300 case IEEE80211_STA_RX_BW_80:
6301 bw = WMI_PEER_CHWIDTH_80MHZ;
6302 break;
6303 case IEEE80211_STA_RX_BW_160:
Masanari Iidad939be32015-02-27 23:52:31 +09006304 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006305 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006306 bw = WMI_PEER_CHWIDTH_20MHZ;
6307 break;
6308 }
6309
6310 arsta->bw = bw;
6311 }
6312
6313 if (changed & IEEE80211_RC_NSS_CHANGED)
6314 arsta->nss = sta->rx_nss;
6315
6316 if (changed & IEEE80211_RC_SMPS_CHANGED) {
6317 smps = WMI_PEER_SMPS_PS_NONE;
6318
6319 switch (sta->smps_mode) {
6320 case IEEE80211_SMPS_AUTOMATIC:
6321 case IEEE80211_SMPS_OFF:
6322 smps = WMI_PEER_SMPS_PS_NONE;
6323 break;
6324 case IEEE80211_SMPS_STATIC:
6325 smps = WMI_PEER_SMPS_STATIC;
6326 break;
6327 case IEEE80211_SMPS_DYNAMIC:
6328 smps = WMI_PEER_SMPS_DYNAMIC;
6329 break;
6330 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02006331 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006332 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006333 smps = WMI_PEER_SMPS_PS_NONE;
6334 break;
6335 }
6336
6337 arsta->smps = smps;
6338 }
6339
Michal Kazior9797feb2014-02-14 14:49:48 +01006340 arsta->changed |= changed;
6341
6342 spin_unlock_bh(&ar->data_lock);
6343
6344 ieee80211_queue_work(hw, &arsta->update_wk);
6345}
6346
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006347static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
6348{
6349 /*
6350 * FIXME: Return 0 for time being. Need to figure out whether FW
6351 * has the API to fetch 64-bit local TSF
6352 */
6353
6354 return 0;
6355}
6356
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006357static int ath10k_ampdu_action(struct ieee80211_hw *hw,
6358 struct ieee80211_vif *vif,
6359 enum ieee80211_ampdu_mlme_action action,
6360 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
Emmanuel Grumbache3abc8f2015-08-16 11:13:22 +03006361 u8 buf_size, bool amsdu)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006362{
Michal Kazior7aa7a722014-08-25 12:09:38 +02006363 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006364 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6365
Michal Kazior7aa7a722014-08-25 12:09:38 +02006366 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 +02006367 arvif->vdev_id, sta->addr, tid, action);
6368
6369 switch (action) {
6370 case IEEE80211_AMPDU_RX_START:
6371 case IEEE80211_AMPDU_RX_STOP:
6372 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
6373 * creation/removal. Do we need to verify this?
6374 */
6375 return 0;
6376 case IEEE80211_AMPDU_TX_START:
6377 case IEEE80211_AMPDU_TX_STOP_CONT:
6378 case IEEE80211_AMPDU_TX_STOP_FLUSH:
6379 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
6380 case IEEE80211_AMPDU_TX_OPERATIONAL:
6381 /* Firmware offloads Tx aggregation entirely so deny mac80211
6382 * Tx aggregation requests.
6383 */
6384 return -EOPNOTSUPP;
6385 }
6386
6387 return -EINVAL;
6388}
6389
Michal Kazior500ff9f2015-03-31 10:26:21 +00006390static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006391ath10k_mac_update_rx_channel(struct ath10k *ar,
6392 struct ieee80211_chanctx_conf *ctx,
6393 struct ieee80211_vif_chanctx_switch *vifs,
6394 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00006395{
6396 struct cfg80211_chan_def *def = NULL;
6397
6398 /* Both locks are required because ar->rx_channel is modified. This
6399 * allows readers to hold either lock.
6400 */
6401 lockdep_assert_held(&ar->conf_mutex);
6402 lockdep_assert_held(&ar->data_lock);
6403
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006404 WARN_ON(ctx && vifs);
6405 WARN_ON(vifs && n_vifs != 1);
6406
Michal Kazior500ff9f2015-03-31 10:26:21 +00006407 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
6408 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
6409 * ppdu on Rx may reduce performance on low-end systems. It should be
6410 * possible to make tables/hashmaps to speed the lookup up (be vary of
6411 * cpu data cache lines though regarding sizes) but to keep the initial
6412 * implementation simple and less intrusive fallback to the slow lookup
6413 * only for multi-channel cases. Single-channel cases will remain to
6414 * use the old channel derival and thus performance should not be
6415 * affected much.
6416 */
6417 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006418 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00006419 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03006420 ath10k_mac_get_any_chandef_iter,
6421 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006422
6423 if (vifs)
6424 def = &vifs[0].new_ctx->def;
6425
Michal Kazior500ff9f2015-03-31 10:26:21 +00006426 ar->rx_channel = def->chan;
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006427 } else if (ctx && ath10k_mac_num_chanctxs(ar) == 0) {
6428 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006429 } else {
6430 ar->rx_channel = NULL;
6431 }
6432 rcu_read_unlock();
6433}
6434
Michal Kazior7be6d1b2015-09-03 10:44:51 +02006435static void
6436ath10k_mac_update_vif_chan(struct ath10k *ar,
6437 struct ieee80211_vif_chanctx_switch *vifs,
6438 int n_vifs)
6439{
6440 struct ath10k_vif *arvif;
6441 int ret;
6442 int i;
6443
6444 lockdep_assert_held(&ar->conf_mutex);
6445
6446 /* First stop monitor interface. Some FW versions crash if there's a
6447 * lone monitor interface.
6448 */
6449 if (ar->monitor_started)
6450 ath10k_monitor_stop(ar);
6451
6452 for (i = 0; i < n_vifs; i++) {
6453 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6454
6455 ath10k_dbg(ar, ATH10K_DBG_MAC,
6456 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
6457 arvif->vdev_id,
6458 vifs[i].old_ctx->def.chan->center_freq,
6459 vifs[i].new_ctx->def.chan->center_freq,
6460 vifs[i].old_ctx->def.width,
6461 vifs[i].new_ctx->def.width);
6462
6463 if (WARN_ON(!arvif->is_started))
6464 continue;
6465
6466 if (WARN_ON(!arvif->is_up))
6467 continue;
6468
6469 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
6470 if (ret) {
6471 ath10k_warn(ar, "failed to down vdev %d: %d\n",
6472 arvif->vdev_id, ret);
6473 continue;
6474 }
6475 }
6476
6477 /* All relevant vdevs are downed and associated channel resources
6478 * should be available for the channel switch now.
6479 */
6480
6481 spin_lock_bh(&ar->data_lock);
6482 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
6483 spin_unlock_bh(&ar->data_lock);
6484
6485 for (i = 0; i < n_vifs; i++) {
6486 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6487
6488 if (WARN_ON(!arvif->is_started))
6489 continue;
6490
6491 if (WARN_ON(!arvif->is_up))
6492 continue;
6493
6494 ret = ath10k_mac_setup_bcn_tmpl(arvif);
6495 if (ret)
6496 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
6497 ret);
6498
6499 ret = ath10k_mac_setup_prb_tmpl(arvif);
6500 if (ret)
6501 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
6502 ret);
6503
6504 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
6505 if (ret) {
6506 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
6507 arvif->vdev_id, ret);
6508 continue;
6509 }
6510
6511 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
6512 arvif->bssid);
6513 if (ret) {
6514 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
6515 arvif->vdev_id, ret);
6516 continue;
6517 }
6518 }
6519
6520 ath10k_monitor_recalc(ar);
6521}
6522
Michal Kazior500ff9f2015-03-31 10:26:21 +00006523static int
6524ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
6525 struct ieee80211_chanctx_conf *ctx)
6526{
6527 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006528
6529 ath10k_dbg(ar, ATH10K_DBG_MAC,
6530 "mac chanctx add freq %hu width %d ptr %p\n",
6531 ctx->def.chan->center_freq, ctx->def.width, ctx);
6532
6533 mutex_lock(&ar->conf_mutex);
6534
6535 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006536 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006537 spin_unlock_bh(&ar->data_lock);
6538
6539 ath10k_recalc_radar_detection(ar);
6540 ath10k_monitor_recalc(ar);
6541
6542 mutex_unlock(&ar->conf_mutex);
6543
6544 return 0;
6545}
6546
6547static void
6548ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
6549 struct ieee80211_chanctx_conf *ctx)
6550{
6551 struct ath10k *ar = hw->priv;
6552
6553 ath10k_dbg(ar, ATH10K_DBG_MAC,
6554 "mac chanctx remove freq %hu width %d ptr %p\n",
6555 ctx->def.chan->center_freq, ctx->def.width, ctx);
6556
6557 mutex_lock(&ar->conf_mutex);
6558
6559 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006560 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006561 spin_unlock_bh(&ar->data_lock);
6562
6563 ath10k_recalc_radar_detection(ar);
6564 ath10k_monitor_recalc(ar);
6565
6566 mutex_unlock(&ar->conf_mutex);
6567}
6568
Michal Kazior9713e3d2015-09-03 10:44:52 +02006569struct ath10k_mac_change_chanctx_arg {
6570 struct ieee80211_chanctx_conf *ctx;
6571 struct ieee80211_vif_chanctx_switch *vifs;
6572 int n_vifs;
6573 int next_vif;
6574};
6575
6576static void
6577ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
6578 struct ieee80211_vif *vif)
6579{
6580 struct ath10k_mac_change_chanctx_arg *arg = data;
6581
6582 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
6583 return;
6584
6585 arg->n_vifs++;
6586}
6587
6588static void
6589ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
6590 struct ieee80211_vif *vif)
6591{
6592 struct ath10k_mac_change_chanctx_arg *arg = data;
6593 struct ieee80211_chanctx_conf *ctx;
6594
6595 ctx = rcu_access_pointer(vif->chanctx_conf);
6596 if (ctx != arg->ctx)
6597 return;
6598
6599 if (WARN_ON(arg->next_vif == arg->n_vifs))
6600 return;
6601
6602 arg->vifs[arg->next_vif].vif = vif;
6603 arg->vifs[arg->next_vif].old_ctx = ctx;
6604 arg->vifs[arg->next_vif].new_ctx = ctx;
6605 arg->next_vif++;
6606}
6607
Michal Kazior500ff9f2015-03-31 10:26:21 +00006608static void
6609ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
6610 struct ieee80211_chanctx_conf *ctx,
6611 u32 changed)
6612{
6613 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02006614 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00006615
6616 mutex_lock(&ar->conf_mutex);
6617
6618 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior089ab7a2015-06-03 12:16:55 +02006619 "mac chanctx change freq %hu width %d ptr %p changed %x\n",
6620 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006621
6622 /* This shouldn't really happen because channel switching should use
6623 * switch_vif_chanctx().
6624 */
6625 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
6626 goto unlock;
6627
Michal Kazior9713e3d2015-09-03 10:44:52 +02006628 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
6629 ieee80211_iterate_active_interfaces_atomic(
6630 hw,
6631 IEEE80211_IFACE_ITER_NORMAL,
6632 ath10k_mac_change_chanctx_cnt_iter,
6633 &arg);
6634 if (arg.n_vifs == 0)
6635 goto radar;
6636
6637 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
6638 GFP_KERNEL);
6639 if (!arg.vifs)
6640 goto radar;
6641
6642 ieee80211_iterate_active_interfaces_atomic(
6643 hw,
6644 IEEE80211_IFACE_ITER_NORMAL,
6645 ath10k_mac_change_chanctx_fill_iter,
6646 &arg);
6647 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
6648 kfree(arg.vifs);
6649 }
6650
6651radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00006652 ath10k_recalc_radar_detection(ar);
6653
6654 /* FIXME: How to configure Rx chains properly? */
6655
6656 /* No other actions are actually necessary. Firmware maintains channel
6657 * definitions per vdev internally and there's no host-side channel
6658 * context abstraction to configure, e.g. channel width.
6659 */
6660
6661unlock:
6662 mutex_unlock(&ar->conf_mutex);
6663}
6664
6665static int
6666ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
6667 struct ieee80211_vif *vif,
6668 struct ieee80211_chanctx_conf *ctx)
6669{
6670 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006671 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6672 int ret;
6673
6674 mutex_lock(&ar->conf_mutex);
6675
6676 ath10k_dbg(ar, ATH10K_DBG_MAC,
6677 "mac chanctx assign ptr %p vdev_id %i\n",
6678 ctx, arvif->vdev_id);
6679
6680 if (WARN_ON(arvif->is_started)) {
6681 mutex_unlock(&ar->conf_mutex);
6682 return -EBUSY;
6683 }
6684
Michal Kazior089ab7a2015-06-03 12:16:55 +02006685 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006686 if (ret) {
6687 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
6688 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02006689 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006690 goto err;
6691 }
6692
6693 arvif->is_started = true;
6694
Michal Kaziorf23e587e2015-07-09 13:08:37 +02006695 ret = ath10k_mac_vif_setup_ps(arvif);
6696 if (ret) {
6697 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
6698 arvif->vdev_id, ret);
6699 goto err_stop;
6700 }
6701
Michal Kazior500ff9f2015-03-31 10:26:21 +00006702 if (vif->type == NL80211_IFTYPE_MONITOR) {
6703 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
6704 if (ret) {
6705 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
6706 arvif->vdev_id, ret);
6707 goto err_stop;
6708 }
6709
6710 arvif->is_up = true;
6711 }
6712
6713 mutex_unlock(&ar->conf_mutex);
6714 return 0;
6715
6716err_stop:
6717 ath10k_vdev_stop(arvif);
6718 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02006719 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006720
6721err:
6722 mutex_unlock(&ar->conf_mutex);
6723 return ret;
6724}
6725
6726static void
6727ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
6728 struct ieee80211_vif *vif,
6729 struct ieee80211_chanctx_conf *ctx)
6730{
6731 struct ath10k *ar = hw->priv;
6732 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6733 int ret;
6734
6735 mutex_lock(&ar->conf_mutex);
6736
6737 ath10k_dbg(ar, ATH10K_DBG_MAC,
6738 "mac chanctx unassign ptr %p vdev_id %i\n",
6739 ctx, arvif->vdev_id);
6740
6741 WARN_ON(!arvif->is_started);
6742
6743 if (vif->type == NL80211_IFTYPE_MONITOR) {
6744 WARN_ON(!arvif->is_up);
6745
6746 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
6747 if (ret)
6748 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
6749 arvif->vdev_id, ret);
6750
6751 arvif->is_up = false;
6752 }
6753
6754 ret = ath10k_vdev_stop(arvif);
6755 if (ret)
6756 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
6757 arvif->vdev_id, ret);
6758
6759 arvif->is_started = false;
6760
6761 mutex_unlock(&ar->conf_mutex);
6762}
6763
6764static int
6765ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
6766 struct ieee80211_vif_chanctx_switch *vifs,
6767 int n_vifs,
6768 enum ieee80211_chanctx_switch_mode mode)
6769{
6770 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006771
6772 mutex_lock(&ar->conf_mutex);
6773
6774 ath10k_dbg(ar, ATH10K_DBG_MAC,
6775 "mac chanctx switch n_vifs %d mode %d\n",
6776 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02006777 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006778
6779 mutex_unlock(&ar->conf_mutex);
6780 return 0;
6781}
6782
Kalle Valo5e3dd152013-06-12 20:52:10 +03006783static const struct ieee80211_ops ath10k_ops = {
6784 .tx = ath10k_tx,
6785 .start = ath10k_start,
6786 .stop = ath10k_stop,
6787 .config = ath10k_config,
6788 .add_interface = ath10k_add_interface,
6789 .remove_interface = ath10k_remove_interface,
6790 .configure_filter = ath10k_configure_filter,
6791 .bss_info_changed = ath10k_bss_info_changed,
6792 .hw_scan = ath10k_hw_scan,
6793 .cancel_hw_scan = ath10k_cancel_hw_scan,
6794 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006795 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03006796 .sta_state = ath10k_sta_state,
6797 .conf_tx = ath10k_conf_tx,
6798 .remain_on_channel = ath10k_remain_on_channel,
6799 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
6800 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02006801 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03006802 .flush = ath10k_flush,
6803 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7bb2014-05-16 17:15:38 +03006804 .set_antenna = ath10k_set_antenna,
6805 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006806 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02006807 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00006808 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01006809 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006810 .get_tsf = ath10k_get_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006811 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03006812 .get_et_sset_count = ath10k_debug_get_et_sset_count,
6813 .get_et_stats = ath10k_debug_get_et_stats,
6814 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00006815 .add_chanctx = ath10k_mac_op_add_chanctx,
6816 .remove_chanctx = ath10k_mac_op_remove_chanctx,
6817 .change_chanctx = ath10k_mac_op_change_chanctx,
6818 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
6819 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
6820 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Kalle Valo43d2a302014-09-10 18:23:30 +03006821
6822 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
6823
Michal Kazior8cd13ca2013-07-16 09:38:54 +02006824#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02006825 .suspend = ath10k_wow_op_suspend,
6826 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02006827#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02006828#ifdef CONFIG_MAC80211_DEBUGFS
6829 .sta_add_debugfs = ath10k_sta_add_debugfs,
6830#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03006831};
6832
Kalle Valo5e3dd152013-06-12 20:52:10 +03006833#define CHAN2G(_channel, _freq, _flags) { \
6834 .band = IEEE80211_BAND_2GHZ, \
6835 .hw_value = (_channel), \
6836 .center_freq = (_freq), \
6837 .flags = (_flags), \
6838 .max_antenna_gain = 0, \
6839 .max_power = 30, \
6840}
6841
6842#define CHAN5G(_channel, _freq, _flags) { \
6843 .band = IEEE80211_BAND_5GHZ, \
6844 .hw_value = (_channel), \
6845 .center_freq = (_freq), \
6846 .flags = (_flags), \
6847 .max_antenna_gain = 0, \
6848 .max_power = 30, \
6849}
6850
6851static const struct ieee80211_channel ath10k_2ghz_channels[] = {
6852 CHAN2G(1, 2412, 0),
6853 CHAN2G(2, 2417, 0),
6854 CHAN2G(3, 2422, 0),
6855 CHAN2G(4, 2427, 0),
6856 CHAN2G(5, 2432, 0),
6857 CHAN2G(6, 2437, 0),
6858 CHAN2G(7, 2442, 0),
6859 CHAN2G(8, 2447, 0),
6860 CHAN2G(9, 2452, 0),
6861 CHAN2G(10, 2457, 0),
6862 CHAN2G(11, 2462, 0),
6863 CHAN2G(12, 2467, 0),
6864 CHAN2G(13, 2472, 0),
6865 CHAN2G(14, 2484, 0),
6866};
6867
6868static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02006869 CHAN5G(36, 5180, 0),
6870 CHAN5G(40, 5200, 0),
6871 CHAN5G(44, 5220, 0),
6872 CHAN5G(48, 5240, 0),
6873 CHAN5G(52, 5260, 0),
6874 CHAN5G(56, 5280, 0),
6875 CHAN5G(60, 5300, 0),
6876 CHAN5G(64, 5320, 0),
6877 CHAN5G(100, 5500, 0),
6878 CHAN5G(104, 5520, 0),
6879 CHAN5G(108, 5540, 0),
6880 CHAN5G(112, 5560, 0),
6881 CHAN5G(116, 5580, 0),
6882 CHAN5G(120, 5600, 0),
6883 CHAN5G(124, 5620, 0),
6884 CHAN5G(128, 5640, 0),
6885 CHAN5G(132, 5660, 0),
6886 CHAN5G(136, 5680, 0),
6887 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07006888 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02006889 CHAN5G(149, 5745, 0),
6890 CHAN5G(153, 5765, 0),
6891 CHAN5G(157, 5785, 0),
6892 CHAN5G(161, 5805, 0),
6893 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03006894};
6895
Michal Kaziore7b54192014-08-07 11:03:27 +02006896struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006897{
6898 struct ieee80211_hw *hw;
6899 struct ath10k *ar;
6900
Michal Kaziore7b54192014-08-07 11:03:27 +02006901 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006902 if (!hw)
6903 return NULL;
6904
6905 ar = hw->priv;
6906 ar->hw = hw;
6907
6908 return ar;
6909}
6910
6911void ath10k_mac_destroy(struct ath10k *ar)
6912{
6913 ieee80211_free_hw(ar->hw);
6914}
6915
6916static const struct ieee80211_iface_limit ath10k_if_limits[] = {
6917 {
6918 .max = 8,
6919 .types = BIT(NL80211_IFTYPE_STATION)
6920 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02006921 },
6922 {
6923 .max = 3,
6924 .types = BIT(NL80211_IFTYPE_P2P_GO)
6925 },
6926 {
Michal Kazior75d2bd42014-12-12 12:41:39 +01006927 .max = 1,
6928 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
6929 },
6930 {
Michal Kaziord531cb82013-07-31 10:55:13 +02006931 .max = 7,
6932 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006933#ifdef CONFIG_MAC80211_MESH
6934 | BIT(NL80211_IFTYPE_MESH_POINT)
6935#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02006936 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03006937};
6938
Bartosz Markowskif2595092013-12-10 16:20:39 +01006939static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006940 {
6941 .max = 8,
6942 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006943#ifdef CONFIG_MAC80211_MESH
6944 | BIT(NL80211_IFTYPE_MESH_POINT)
6945#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006946 },
6947};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006948
6949static const struct ieee80211_iface_combination ath10k_if_comb[] = {
6950 {
6951 .limits = ath10k_if_limits,
6952 .n_limits = ARRAY_SIZE(ath10k_if_limits),
6953 .max_interfaces = 8,
6954 .num_different_channels = 1,
6955 .beacon_int_infra_match = true,
6956 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01006957};
6958
6959static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006960 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01006961 .limits = ath10k_10x_if_limits,
6962 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006963 .max_interfaces = 8,
6964 .num_different_channels = 1,
6965 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01006966#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006967 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
6968 BIT(NL80211_CHAN_WIDTH_20) |
6969 BIT(NL80211_CHAN_WIDTH_40) |
6970 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006971#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01006972 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03006973};
6974
Michal Kaziorcf327842015-03-31 10:26:25 +00006975static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
6976 {
6977 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02006978 .types = BIT(NL80211_IFTYPE_STATION),
6979 },
6980 {
6981 .max = 2,
6982 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006983#ifdef CONFIG_MAC80211_MESH
6984 BIT(NL80211_IFTYPE_MESH_POINT) |
6985#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00006986 BIT(NL80211_IFTYPE_P2P_CLIENT) |
6987 BIT(NL80211_IFTYPE_P2P_GO),
6988 },
6989 {
6990 .max = 1,
6991 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
6992 },
6993};
6994
Michal Kaziored25b112015-07-09 13:08:39 +02006995static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
6996 {
6997 .max = 2,
6998 .types = BIT(NL80211_IFTYPE_STATION),
6999 },
7000 {
7001 .max = 2,
7002 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
7003 },
7004 {
7005 .max = 1,
7006 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007007#ifdef CONFIG_MAC80211_MESH
7008 BIT(NL80211_IFTYPE_MESH_POINT) |
7009#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007010 BIT(NL80211_IFTYPE_P2P_GO),
7011 },
7012 {
7013 .max = 1,
7014 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7015 },
7016};
7017
Michal Kaziorcf327842015-03-31 10:26:25 +00007018static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7019 {
7020 .max = 1,
7021 .types = BIT(NL80211_IFTYPE_STATION),
7022 },
7023 {
7024 .max = 1,
7025 .types = BIT(NL80211_IFTYPE_ADHOC),
7026 },
7027};
7028
7029/* FIXME: This is not thouroughly tested. These combinations may over- or
7030 * underestimate hw/fw capabilities.
7031 */
7032static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7033 {
7034 .limits = ath10k_tlv_if_limit,
7035 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007036 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007037 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7038 },
7039 {
7040 .limits = ath10k_tlv_if_limit_ibss,
7041 .num_different_channels = 1,
7042 .max_interfaces = 2,
7043 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7044 },
7045};
7046
7047static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7048 {
7049 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007050 .num_different_channels = 1,
7051 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007052 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7053 },
7054 {
Michal Kaziored25b112015-07-09 13:08:39 +02007055 .limits = ath10k_tlv_qcs_if_limit,
7056 .num_different_channels = 2,
7057 .max_interfaces = 4,
7058 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7059 },
7060 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007061 .limits = ath10k_tlv_if_limit_ibss,
7062 .num_different_channels = 1,
7063 .max_interfaces = 2,
7064 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7065 },
7066};
7067
Raja Manicf36fef2015-06-22 20:22:25 +05307068static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
7069 {
7070 .max = 1,
7071 .types = BIT(NL80211_IFTYPE_STATION),
7072 },
7073 {
7074 .max = 16,
7075 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007076#ifdef CONFIG_MAC80211_MESH
7077 | BIT(NL80211_IFTYPE_MESH_POINT)
7078#endif
Raja Manicf36fef2015-06-22 20:22:25 +05307079 },
7080};
7081
7082static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
7083 {
7084 .limits = ath10k_10_4_if_limits,
7085 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
7086 .max_interfaces = 16,
7087 .num_different_channels = 1,
7088 .beacon_int_infra_match = true,
7089#ifdef CONFIG_ATH10K_DFS_CERTIFIED
7090 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7091 BIT(NL80211_CHAN_WIDTH_20) |
7092 BIT(NL80211_CHAN_WIDTH_40) |
7093 BIT(NL80211_CHAN_WIDTH_80),
7094#endif
7095 },
7096};
7097
Kalle Valo5e3dd152013-06-12 20:52:10 +03007098static void ath10k_get_arvif_iter(void *data, u8 *mac,
7099 struct ieee80211_vif *vif)
7100{
7101 struct ath10k_vif_iter *arvif_iter = data;
7102 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7103
7104 if (arvif->vdev_id == arvif_iter->vdev_id)
7105 arvif_iter->arvif = arvif;
7106}
7107
7108struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
7109{
7110 struct ath10k_vif_iter arvif_iter;
7111 u32 flags;
7112
7113 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
7114 arvif_iter.vdev_id = vdev_id;
7115
7116 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
7117 ieee80211_iterate_active_interfaces_atomic(ar->hw,
7118 flags,
7119 ath10k_get_arvif_iter,
7120 &arvif_iter);
7121 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007122 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007123 return NULL;
7124 }
7125
7126 return arvif_iter.arvif;
7127}
7128
7129int ath10k_mac_register(struct ath10k *ar)
7130{
Johannes Berg3cb10942015-01-22 21:38:45 +01007131 static const u32 cipher_suites[] = {
7132 WLAN_CIPHER_SUITE_WEP40,
7133 WLAN_CIPHER_SUITE_WEP104,
7134 WLAN_CIPHER_SUITE_TKIP,
7135 WLAN_CIPHER_SUITE_CCMP,
7136 WLAN_CIPHER_SUITE_AES_CMAC,
7137 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03007138 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007139 void *channels;
7140 int ret;
7141
7142 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
7143
7144 SET_IEEE80211_DEV(ar->hw, ar->dev);
7145
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00007146 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
7147 ARRAY_SIZE(ath10k_5ghz_channels)) !=
7148 ATH10K_NUM_CHANS);
7149
Kalle Valo5e3dd152013-06-12 20:52:10 +03007150 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
7151 channels = kmemdup(ath10k_2ghz_channels,
7152 sizeof(ath10k_2ghz_channels),
7153 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02007154 if (!channels) {
7155 ret = -ENOMEM;
7156 goto err_free;
7157 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007158
7159 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
7160 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
7161 band->channels = channels;
7162 band->n_bitrates = ath10k_g_rates_size;
7163 band->bitrates = ath10k_g_rates;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007164
7165 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
7166 }
7167
7168 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
7169 channels = kmemdup(ath10k_5ghz_channels,
7170 sizeof(ath10k_5ghz_channels),
7171 GFP_KERNEL);
7172 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02007173 ret = -ENOMEM;
7174 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007175 }
7176
7177 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
7178 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
7179 band->channels = channels;
7180 band->n_bitrates = ath10k_a_rates_size;
7181 band->bitrates = ath10k_a_rates;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007182 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
7183 }
7184
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05307185 ath10k_mac_setup_ht_vht_cap(ar);
7186
Kalle Valo5e3dd152013-06-12 20:52:10 +03007187 ar->hw->wiphy->interface_modes =
7188 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007189 BIT(NL80211_IFTYPE_AP) |
7190 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01007191
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05307192 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
7193 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03007194
Bartosz Markowskid3541812013-12-10 16:20:40 +01007195 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
7196 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01007197 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01007198 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7199 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007200
Johannes Berg30686bf2015-06-02 21:39:54 +02007201 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
7202 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
7203 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
7204 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
7205 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
7206 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
7207 ieee80211_hw_set(ar->hw, AP_LINK_PS);
7208 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02007209 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
7210 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
7211 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
7212 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
7213 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
7214 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007215
David Liuccec9032015-07-24 20:25:32 +03007216 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7217 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
7218
Eliad Peller0d8614b2014-09-10 14:07:36 +03007219 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00007220 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03007221
Kalle Valo5e3dd152013-06-12 20:52:10 +03007222 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03007223 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007224
7225 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02007226 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
7227 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007228 }
7229
7230 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
7231 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
7232
7233 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01007234 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007235
Kalle Valo5e3dd152013-06-12 20:52:10 +03007236 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
7237
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02007238 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
7239 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
7240
7241 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
7242 * that userspace (e.g. wpa_supplicant/hostapd) can generate
7243 * correct Probe Responses. This is more of a hack advert..
7244 */
7245 ar->hw->wiphy->probe_resp_offload |=
7246 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
7247 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
7248 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
7249 }
7250
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03007251 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
7252 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7253
Kalle Valo5e3dd152013-06-12 20:52:10 +03007254 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01007255 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007256 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
7257
7258 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02007259 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
7260
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01007261 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
7262
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007263 ret = ath10k_wow_init(ar);
7264 if (ret) {
7265 ath10k_warn(ar, "failed to init wow: %d\n", ret);
7266 goto err_free;
7267 }
7268
Janusz Dziedzicc7025342015-06-15 14:46:41 +03007269 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
7270
Kalle Valo5e3dd152013-06-12 20:52:10 +03007271 /*
7272 * on LL hardware queues are managed entirely by the FW
7273 * so we only advertise to mac we can do the queues thing
7274 */
Michal Kazior96d828d2015-03-31 10:26:23 +00007275 ar->hw->queues = IEEE80211_MAX_QUEUES;
7276
7277 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
7278 * something that vdev_ids can't reach so that we don't stop the queue
7279 * accidentally.
7280 */
7281 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007282
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007283 switch (ar->wmi.op_version) {
7284 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01007285 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
7286 ar->hw->wiphy->n_iface_combinations =
7287 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03007288 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007289 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00007290 case ATH10K_FW_WMI_OP_VERSION_TLV:
7291 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
7292 ar->hw->wiphy->iface_combinations =
7293 ath10k_tlv_qcs_if_comb;
7294 ar->hw->wiphy->n_iface_combinations =
7295 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
7296 } else {
7297 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
7298 ar->hw->wiphy->n_iface_combinations =
7299 ARRAY_SIZE(ath10k_tlv_if_comb);
7300 }
7301 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
7302 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007303 case ATH10K_FW_WMI_OP_VERSION_10_1:
7304 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02007305 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007306 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
7307 ar->hw->wiphy->n_iface_combinations =
7308 ARRAY_SIZE(ath10k_10x_if_comb);
7309 break;
Raja Mani9bd21322015-06-22 20:10:09 +05307310 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05307311 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
7312 ar->hw->wiphy->n_iface_combinations =
7313 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05307314 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007315 case ATH10K_FW_WMI_OP_VERSION_UNSET:
7316 case ATH10K_FW_WMI_OP_VERSION_MAX:
7317 WARN_ON(1);
7318 ret = -EINVAL;
7319 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01007320 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007321
David Liuccec9032015-07-24 20:25:32 +03007322 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7323 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02007324
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007325 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
7326 /* Init ath dfs pattern detector */
7327 ar->ath_common.debug_mask = ATH_DBG_DFS;
7328 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
7329 NL80211_DFS_UNSET);
7330
7331 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02007332 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007333 }
7334
Kalle Valo5e3dd152013-06-12 20:52:10 +03007335 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
7336 ath10k_reg_notifier);
7337 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007338 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007339 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007340 }
7341
Johannes Berg3cb10942015-01-22 21:38:45 +01007342 ar->hw->wiphy->cipher_suites = cipher_suites;
7343 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
7344
Kalle Valo5e3dd152013-06-12 20:52:10 +03007345 ret = ieee80211_register_hw(ar->hw);
7346 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007347 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007348 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007349 }
7350
7351 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
7352 ret = regulatory_hint(ar->hw->wiphy,
7353 ar->ath_common.regulatory.alpha2);
7354 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02007355 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007356 }
7357
7358 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02007359
7360err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03007361 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07007362
7363err_dfs_detector_exit:
7364 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7365 ar->dfs_detector->exit(ar->dfs_detector);
7366
Michal Kaziord6015b22013-07-22 14:13:30 +02007367err_free:
7368 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
7369 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
7370
Jeff Johnson0e339442015-10-08 09:15:53 -07007371 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007372 return ret;
7373}
7374
7375void ath10k_mac_unregister(struct ath10k *ar)
7376{
7377 ieee80211_unregister_hw(ar->hw);
7378
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007379 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7380 ar->dfs_detector->exit(ar->dfs_detector);
7381
Kalle Valo5e3dd152013-06-12 20:52:10 +03007382 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
7383 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
7384
7385 SET_IEEE80211_DEV(ar->hw, NULL);
7386}