blob: 36afe7cb3fc6780bd2bb401fb5bbc30c4112fd1a [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"
31#include "wmi-ops.h"
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +020032#include "wow.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030033
Michal Kaziordcc33092015-03-30 09:51:54 +030034/*********/
35/* Rates */
36/*********/
37
38#define RATETAB_ENT(_rate, _rateid, _flags) { \
39 .bitrate = (_rate), \
40 .flags = (_flags), \
41 .hw_value = (_rateid), \
42}
43
44static struct ieee80211_rate ath10k_rates[] = {
45 /* CCK */
46 RATETAB_ENT(10, 0x82, 0),
47 RATETAB_ENT(20, 0x84, 0),
48 RATETAB_ENT(55, 0x8b, 0),
49 RATETAB_ENT(110, 0x96, 0),
50 /* OFDM */
51 RATETAB_ENT(60, 0x0c, 0),
52 RATETAB_ENT(90, 0x12, 0),
53 RATETAB_ENT(120, 0x18, 0),
54 RATETAB_ENT(180, 0x24, 0),
55 RATETAB_ENT(240, 0x30, 0),
56 RATETAB_ENT(360, 0x48, 0),
57 RATETAB_ENT(480, 0x60, 0),
58 RATETAB_ENT(540, 0x6c, 0),
59};
60
61#define ath10k_a_rates (ath10k_rates + 4)
62#define ath10k_a_rates_size (ARRAY_SIZE(ath10k_rates) - 4)
63#define ath10k_g_rates (ath10k_rates + 0)
64#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
65
Kalle Valo5e3dd152013-06-12 20:52:10 +030066/**********/
67/* Crypto */
68/**********/
69
70static int ath10k_send_key(struct ath10k_vif *arvif,
71 struct ieee80211_key_conf *key,
72 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +010073 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +030074{
Michal Kazior7aa7a722014-08-25 12:09:38 +020075 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +030076 struct wmi_vdev_install_key_arg arg = {
77 .vdev_id = arvif->vdev_id,
78 .key_idx = key->keyidx,
79 .key_len = key->keylen,
80 .key_data = key->key,
Michal Kazior370e5672015-02-18 14:02:26 +010081 .key_flags = flags,
Kalle Valo5e3dd152013-06-12 20:52:10 +030082 .macaddr = macaddr,
83 };
84
Michal Kazior548db542013-07-05 16:15:15 +030085 lockdep_assert_held(&arvif->ar->conf_mutex);
86
Kalle Valo5e3dd152013-06-12 20:52:10 +030087 switch (key->cipher) {
88 case WLAN_CIPHER_SUITE_CCMP:
89 arg.key_cipher = WMI_CIPHER_AES_CCM;
Marek Kwaczynskie4e82e92015-01-24 12:14:53 +020090 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
Kalle Valo5e3dd152013-06-12 20:52:10 +030091 break;
92 case WLAN_CIPHER_SUITE_TKIP:
Kalle Valo5e3dd152013-06-12 20:52:10 +030093 arg.key_cipher = WMI_CIPHER_TKIP;
94 arg.key_txmic_len = 8;
95 arg.key_rxmic_len = 8;
96 break;
97 case WLAN_CIPHER_SUITE_WEP40:
98 case WLAN_CIPHER_SUITE_WEP104:
99 arg.key_cipher = WMI_CIPHER_WEP;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300100 break;
Johannes Berg3cb10942015-01-22 21:38:45 +0100101 case WLAN_CIPHER_SUITE_AES_CMAC:
Bartosz Markowskid7131c02015-03-10 14:32:19 +0100102 WARN_ON(1);
103 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300104 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200105 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300106 return -EOPNOTSUPP;
107 }
108
109 if (cmd == DISABLE_KEY) {
110 arg.key_cipher = WMI_CIPHER_NONE;
111 arg.key_data = NULL;
112 }
113
114 return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
115}
116
117static int ath10k_install_key(struct ath10k_vif *arvif,
118 struct ieee80211_key_conf *key,
119 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100120 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300121{
122 struct ath10k *ar = arvif->ar;
123 int ret;
124
Michal Kazior548db542013-07-05 16:15:15 +0300125 lockdep_assert_held(&ar->conf_mutex);
126
Wolfram Sang16735d02013-11-14 14:32:02 -0800127 reinit_completion(&ar->install_key_done);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300128
Michal Kazior370e5672015-02-18 14:02:26 +0100129 ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300130 if (ret)
131 return ret;
132
133 ret = wait_for_completion_timeout(&ar->install_key_done, 3*HZ);
134 if (ret == 0)
135 return -ETIMEDOUT;
136
137 return 0;
138}
139
140static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
141 const u8 *addr)
142{
143 struct ath10k *ar = arvif->ar;
144 struct ath10k_peer *peer;
145 int ret;
146 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100147 u32 flags;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300148
149 lockdep_assert_held(&ar->conf_mutex);
150
151 spin_lock_bh(&ar->data_lock);
152 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
153 spin_unlock_bh(&ar->data_lock);
154
155 if (!peer)
156 return -ENOENT;
157
158 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
159 if (arvif->wep_keys[i] == NULL)
160 continue;
Michal Kazior370e5672015-02-18 14:02:26 +0100161
162 flags = 0;
163 flags |= WMI_KEY_PAIRWISE;
164
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200165 /* set TX_USAGE flag for default key id */
166 if (arvif->def_wep_key_idx == i)
Michal Kazior370e5672015-02-18 14:02:26 +0100167 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300168
169 ret = ath10k_install_key(arvif, arvif->wep_keys[i], SET_KEY,
Michal Kazior370e5672015-02-18 14:02:26 +0100170 addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300171 if (ret)
172 return ret;
173
Sujith Manoharanae167132014-11-25 11:46:59 +0530174 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300175 peer->keys[i] = arvif->wep_keys[i];
Sujith Manoharanae167132014-11-25 11:46:59 +0530176 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300177 }
178
179 return 0;
180}
181
182static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
183 const u8 *addr)
184{
185 struct ath10k *ar = arvif->ar;
186 struct ath10k_peer *peer;
187 int first_errno = 0;
188 int ret;
189 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100190 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300191
192 lockdep_assert_held(&ar->conf_mutex);
193
194 spin_lock_bh(&ar->data_lock);
195 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
196 spin_unlock_bh(&ar->data_lock);
197
198 if (!peer)
199 return -ENOENT;
200
201 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
202 if (peer->keys[i] == NULL)
203 continue;
204
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200205 /* key flags are not required to delete the key */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300206 ret = ath10k_install_key(arvif, peer->keys[i],
Michal Kazior370e5672015-02-18 14:02:26 +0100207 DISABLE_KEY, addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300208 if (ret && first_errno == 0)
209 first_errno = ret;
210
211 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200212 ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300213 i, ret);
214
Sujith Manoharanae167132014-11-25 11:46:59 +0530215 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300216 peer->keys[i] = NULL;
Sujith Manoharanae167132014-11-25 11:46:59 +0530217 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300218 }
219
220 return first_errno;
221}
222
Sujith Manoharan504f6cd2014-11-25 11:46:58 +0530223bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
224 u8 keyidx)
225{
226 struct ath10k_peer *peer;
227 int i;
228
229 lockdep_assert_held(&ar->data_lock);
230
231 /* We don't know which vdev this peer belongs to,
232 * since WMI doesn't give us that information.
233 *
234 * FIXME: multi-bss needs to be handled.
235 */
236 peer = ath10k_peer_find(ar, 0, addr);
237 if (!peer)
238 return false;
239
240 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
241 if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)
242 return true;
243 }
244
245 return false;
246}
247
Kalle Valo5e3dd152013-06-12 20:52:10 +0300248static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
249 struct ieee80211_key_conf *key)
250{
251 struct ath10k *ar = arvif->ar;
252 struct ath10k_peer *peer;
253 u8 addr[ETH_ALEN];
254 int first_errno = 0;
255 int ret;
256 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100257 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300258
259 lockdep_assert_held(&ar->conf_mutex);
260
261 for (;;) {
262 /* since ath10k_install_key we can't hold data_lock all the
263 * time, so we try to remove the keys incrementally */
264 spin_lock_bh(&ar->data_lock);
265 i = 0;
266 list_for_each_entry(peer, &ar->peers, list) {
267 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
268 if (peer->keys[i] == key) {
Kalle Valob25f32c2014-09-14 12:50:49 +0300269 ether_addr_copy(addr, peer->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300270 peer->keys[i] = NULL;
271 break;
272 }
273 }
274
275 if (i < ARRAY_SIZE(peer->keys))
276 break;
277 }
278 spin_unlock_bh(&ar->data_lock);
279
280 if (i == ARRAY_SIZE(peer->keys))
281 break;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200282 /* key flags are not required to delete the key */
Michal Kazior370e5672015-02-18 14:02:26 +0100283 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300284 if (ret && first_errno == 0)
285 first_errno = ret;
286
287 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200288 ath10k_warn(ar, "failed to remove key for %pM: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +0200289 addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300290 }
291
292 return first_errno;
293}
294
Michal Kazior370e5672015-02-18 14:02:26 +0100295static int ath10k_mac_vif_sta_fix_wep_key(struct ath10k_vif *arvif)
296{
297 struct ath10k *ar = arvif->ar;
298 enum nl80211_iftype iftype = arvif->vif->type;
299 struct ieee80211_key_conf *key;
300 u32 flags = 0;
301 int num = 0;
302 int i;
303 int ret;
304
305 lockdep_assert_held(&ar->conf_mutex);
306
307 if (iftype != NL80211_IFTYPE_STATION)
308 return 0;
309
310 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
311 if (arvif->wep_keys[i]) {
312 key = arvif->wep_keys[i];
313 ++num;
314 }
315 }
316
317 if (num != 1)
318 return 0;
319
320 flags |= WMI_KEY_PAIRWISE;
321 flags |= WMI_KEY_TX_USAGE;
322
323 ret = ath10k_install_key(arvif, key, SET_KEY, arvif->bssid, flags);
324 if (ret) {
325 ath10k_warn(ar, "failed to install key %i on vdev %i: %d\n",
326 key->keyidx, arvif->vdev_id, ret);
327 return ret;
328 }
329
330 return 0;
331}
332
Michal Kaziorad325cb2015-02-18 14:02:27 +0100333static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
334 struct ieee80211_key_conf *key)
335{
336 struct ath10k *ar = arvif->ar;
337 struct ath10k_peer *peer;
338 int ret;
339
340 lockdep_assert_held(&ar->conf_mutex);
341
342 list_for_each_entry(peer, &ar->peers, list) {
343 if (!memcmp(peer->addr, arvif->vif->addr, ETH_ALEN))
344 continue;
345
346 if (!memcmp(peer->addr, arvif->bssid, ETH_ALEN))
347 continue;
348
349 if (peer->keys[key->keyidx] == key)
350 continue;
351
352 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
353 arvif->vdev_id, key->keyidx);
354
355 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
356 if (ret) {
357 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
358 arvif->vdev_id, peer->addr, ret);
359 return ret;
360 }
361 }
362
363 return 0;
364}
365
Kalle Valo5e3dd152013-06-12 20:52:10 +0300366/*********************/
367/* General utilities */
368/*********************/
369
370static inline enum wmi_phy_mode
371chan_to_phymode(const struct cfg80211_chan_def *chandef)
372{
373 enum wmi_phy_mode phymode = MODE_UNKNOWN;
374
375 switch (chandef->chan->band) {
376 case IEEE80211_BAND_2GHZ:
377 switch (chandef->width) {
378 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800379 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
380 phymode = MODE_11B;
381 else
382 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300383 break;
384 case NL80211_CHAN_WIDTH_20:
385 phymode = MODE_11NG_HT20;
386 break;
387 case NL80211_CHAN_WIDTH_40:
388 phymode = MODE_11NG_HT40;
389 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400390 case NL80211_CHAN_WIDTH_5:
391 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300392 case NL80211_CHAN_WIDTH_80:
393 case NL80211_CHAN_WIDTH_80P80:
394 case NL80211_CHAN_WIDTH_160:
395 phymode = MODE_UNKNOWN;
396 break;
397 }
398 break;
399 case IEEE80211_BAND_5GHZ:
400 switch (chandef->width) {
401 case NL80211_CHAN_WIDTH_20_NOHT:
402 phymode = MODE_11A;
403 break;
404 case NL80211_CHAN_WIDTH_20:
405 phymode = MODE_11NA_HT20;
406 break;
407 case NL80211_CHAN_WIDTH_40:
408 phymode = MODE_11NA_HT40;
409 break;
410 case NL80211_CHAN_WIDTH_80:
411 phymode = MODE_11AC_VHT80;
412 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400413 case NL80211_CHAN_WIDTH_5:
414 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300415 case NL80211_CHAN_WIDTH_80P80:
416 case NL80211_CHAN_WIDTH_160:
417 phymode = MODE_UNKNOWN;
418 break;
419 }
420 break;
421 default:
422 break;
423 }
424
425 WARN_ON(phymode == MODE_UNKNOWN);
426 return phymode;
427}
428
429static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
430{
431/*
432 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
433 * 0 for no restriction
434 * 1 for 1/4 us
435 * 2 for 1/2 us
436 * 3 for 1 us
437 * 4 for 2 us
438 * 5 for 4 us
439 * 6 for 8 us
440 * 7 for 16 us
441 */
442 switch (mpdudensity) {
443 case 0:
444 return 0;
445 case 1:
446 case 2:
447 case 3:
448 /* Our lower layer calculations limit our precision to
449 1 microsecond */
450 return 1;
451 case 4:
452 return 2;
453 case 5:
454 return 4;
455 case 6:
456 return 8;
457 case 7:
458 return 16;
459 default:
460 return 0;
461 }
462}
463
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300464static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr,
465 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300466{
467 int ret;
468
469 lockdep_assert_held(&ar->conf_mutex);
470
Michal Kaziorcfd10612014-11-25 15:16:05 +0100471 if (ar->num_peers >= ar->max_num_peers)
472 return -ENOBUFS;
473
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300474 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800475 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200476 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200477 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300478 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800479 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300480
481 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800482 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200483 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200484 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300485 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800486 }
Michal Kazior292a7532014-11-25 15:16:04 +0100487
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100488 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300489
490 return 0;
491}
492
Kalle Valo5a13e762014-01-20 11:01:46 +0200493static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
494{
495 struct ath10k *ar = arvif->ar;
496 u32 param;
497 int ret;
498
499 param = ar->wmi.pdev_param->sta_kickout_th;
500 ret = ath10k_wmi_pdev_set_param(ar, param,
501 ATH10K_KICKOUT_THRESHOLD);
502 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200503 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200504 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200505 return ret;
506 }
507
508 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
509 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
510 ATH10K_KEEPALIVE_MIN_IDLE);
511 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200512 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200513 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200514 return ret;
515 }
516
517 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
518 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
519 ATH10K_KEEPALIVE_MAX_IDLE);
520 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200521 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200522 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200523 return ret;
524 }
525
526 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
527 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
528 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
529 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200530 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200531 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200532 return ret;
533 }
534
535 return 0;
536}
537
Vivek Natarajanacab6402014-11-26 09:06:12 +0200538static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200539{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200540 struct ath10k *ar = arvif->ar;
541 u32 vdev_param;
542
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200543 vdev_param = ar->wmi.vdev_param->rts_threshold;
544 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200545}
546
547static int ath10k_mac_set_frag(struct ath10k_vif *arvif, u32 value)
548{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200549 struct ath10k *ar = arvif->ar;
550 u32 vdev_param;
551
Michal Kazior424121c2013-07-22 14:13:31 +0200552 if (value != 0xFFFFFFFF)
553 value = clamp_t(u32, arvif->ar->hw->wiphy->frag_threshold,
554 ATH10K_FRAGMT_THRESHOLD_MIN,
555 ATH10K_FRAGMT_THRESHOLD_MAX);
556
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200557 vdev_param = ar->wmi.vdev_param->fragmentation_threshold;
558 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200559}
560
Kalle Valo5e3dd152013-06-12 20:52:10 +0300561static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
562{
563 int ret;
564
565 lockdep_assert_held(&ar->conf_mutex);
566
567 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
568 if (ret)
569 return ret;
570
571 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
572 if (ret)
573 return ret;
574
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100575 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100576
Kalle Valo5e3dd152013-06-12 20:52:10 +0300577 return 0;
578}
579
580static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
581{
582 struct ath10k_peer *peer, *tmp;
583
584 lockdep_assert_held(&ar->conf_mutex);
585
586 spin_lock_bh(&ar->data_lock);
587 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
588 if (peer->vdev_id != vdev_id)
589 continue;
590
Michal Kazior7aa7a722014-08-25 12:09:38 +0200591 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300592 peer->addr, vdev_id);
593
594 list_del(&peer->list);
595 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100596 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300597 }
598 spin_unlock_bh(&ar->data_lock);
599}
600
Michal Kaziora96d7742013-07-16 09:38:56 +0200601static void ath10k_peer_cleanup_all(struct ath10k *ar)
602{
603 struct ath10k_peer *peer, *tmp;
604
605 lockdep_assert_held(&ar->conf_mutex);
606
607 spin_lock_bh(&ar->data_lock);
608 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
609 list_del(&peer->list);
610 kfree(peer);
611 }
612 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100613
614 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100615 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200616}
617
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300618static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
619 struct ieee80211_sta *sta,
620 enum wmi_tdls_peer_state state)
621{
622 int ret;
623 struct wmi_tdls_peer_update_cmd_arg arg = {};
624 struct wmi_tdls_peer_capab_arg cap = {};
625 struct wmi_channel_arg chan_arg = {};
626
627 lockdep_assert_held(&ar->conf_mutex);
628
629 arg.vdev_id = vdev_id;
630 arg.peer_state = state;
631 ether_addr_copy(arg.addr, sta->addr);
632
633 cap.peer_max_sp = sta->max_sp;
634 cap.peer_uapsd_queues = sta->uapsd_queues;
635
636 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
637 !sta->tdls_initiator)
638 cap.is_peer_responder = 1;
639
640 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
641 if (ret) {
642 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
643 arg.addr, vdev_id, ret);
644 return ret;
645 }
646
647 return 0;
648}
649
Kalle Valo5e3dd152013-06-12 20:52:10 +0300650/************************/
651/* Interface management */
652/************************/
653
Michal Kazior64badcb2014-09-18 11:18:02 +0300654void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
655{
656 struct ath10k *ar = arvif->ar;
657
658 lockdep_assert_held(&ar->data_lock);
659
660 if (!arvif->beacon)
661 return;
662
663 if (!arvif->beacon_buf)
664 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
665 arvif->beacon->len, DMA_TO_DEVICE);
666
Michal Kazioraf213192015-01-29 14:29:52 +0200667 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
668 arvif->beacon_state != ATH10K_BEACON_SENT))
669 return;
670
Michal Kazior64badcb2014-09-18 11:18:02 +0300671 dev_kfree_skb_any(arvif->beacon);
672
673 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200674 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300675}
676
677static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
678{
679 struct ath10k *ar = arvif->ar;
680
681 lockdep_assert_held(&ar->data_lock);
682
683 ath10k_mac_vif_beacon_free(arvif);
684
685 if (arvif->beacon_buf) {
686 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
687 arvif->beacon_buf, arvif->beacon_paddr);
688 arvif->beacon_buf = NULL;
689 }
690}
691
Kalle Valo5e3dd152013-06-12 20:52:10 +0300692static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
693{
694 int ret;
695
Michal Kazior548db542013-07-05 16:15:15 +0300696 lockdep_assert_held(&ar->conf_mutex);
697
Michal Kazior7962b0d2014-10-28 10:34:38 +0100698 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
699 return -ESHUTDOWN;
700
Kalle Valo5e3dd152013-06-12 20:52:10 +0300701 ret = wait_for_completion_timeout(&ar->vdev_setup_done,
702 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
703 if (ret == 0)
704 return -ETIMEDOUT;
705
706 return 0;
707}
708
Michal Kazior1bbc0972014-04-08 09:45:47 +0300709static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300710{
Michal Kaziorc930f742014-01-23 11:38:25 +0100711 struct cfg80211_chan_def *chandef = &ar->chandef;
712 struct ieee80211_channel *channel = chandef->chan;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300713 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300714 int ret = 0;
715
716 lockdep_assert_held(&ar->conf_mutex);
717
Kalle Valo5e3dd152013-06-12 20:52:10 +0300718 arg.vdev_id = vdev_id;
719 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +0100720 arg.channel.band_center_freq1 = chandef->center_freq1;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300721
722 /* TODO setup this dynamically, what in case we
723 don't have any vifs? */
Michal Kaziorc930f742014-01-23 11:38:25 +0100724 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200725 arg.channel.chan_radar =
726 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300727
Michal Kazior89c5c842013-10-23 04:02:13 -0700728 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -0700729 arg.channel.max_power = channel->max_power * 2;
730 arg.channel.max_reg_power = channel->max_reg_power * 2;
731 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300732
Michal Kazior7962b0d2014-10-28 10:34:38 +0100733 reinit_completion(&ar->vdev_setup_done);
734
Kalle Valo5e3dd152013-06-12 20:52:10 +0300735 ret = ath10k_wmi_vdev_start(ar, &arg);
736 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200737 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200738 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300739 return ret;
740 }
741
742 ret = ath10k_vdev_setup_sync(ar);
743 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +0200744 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200745 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300746 return ret;
747 }
748
749 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
750 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200751 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200752 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300753 goto vdev_stop;
754 }
755
756 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300757
Michal Kazior7aa7a722014-08-25 12:09:38 +0200758 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300759 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300760 return 0;
761
762vdev_stop:
763 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
764 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200765 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200766 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300767
768 return ret;
769}
770
Michal Kazior1bbc0972014-04-08 09:45:47 +0300771static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300772{
773 int ret = 0;
774
775 lockdep_assert_held(&ar->conf_mutex);
776
Marek Puzyniak52fa0192013-09-24 14:06:24 +0200777 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
778 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200779 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200780 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300781
Michal Kazior7962b0d2014-10-28 10:34:38 +0100782 reinit_completion(&ar->vdev_setup_done);
783
Kalle Valo5e3dd152013-06-12 20:52:10 +0300784 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
785 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200786 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200787 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300788
789 ret = ath10k_vdev_setup_sync(ar);
790 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +0200791 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200792 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300793
Michal Kazior7aa7a722014-08-25 12:09:38 +0200794 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300795 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300796 return ret;
797}
798
Michal Kazior1bbc0972014-04-08 09:45:47 +0300799static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300800{
801 int bit, ret = 0;
802
803 lockdep_assert_held(&ar->conf_mutex);
804
Ben Greeara9aefb32014-08-12 11:02:19 +0300805 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200806 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300807 return -ENOMEM;
808 }
809
Ben Greear16c11172014-09-23 14:17:16 -0700810 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +0300811
Ben Greear16c11172014-09-23 14:17:16 -0700812 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300813
814 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
815 WMI_VDEV_TYPE_MONITOR,
816 0, ar->mac_addr);
817 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200818 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200819 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +0300820 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300821 }
822
Ben Greear16c11172014-09-23 14:17:16 -0700823 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +0200824 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300825 ar->monitor_vdev_id);
826
Kalle Valo5e3dd152013-06-12 20:52:10 +0300827 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300828}
829
Michal Kazior1bbc0972014-04-08 09:45:47 +0300830static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300831{
832 int ret = 0;
833
834 lockdep_assert_held(&ar->conf_mutex);
835
Kalle Valo5e3dd152013-06-12 20:52:10 +0300836 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
837 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200838 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200839 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300840 return ret;
841 }
842
Ben Greear16c11172014-09-23 14:17:16 -0700843 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300844
Michal Kazior7aa7a722014-08-25 12:09:38 +0200845 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300846 ar->monitor_vdev_id);
847 return ret;
848}
849
Michal Kazior1bbc0972014-04-08 09:45:47 +0300850static int ath10k_monitor_start(struct ath10k *ar)
851{
852 int ret;
853
854 lockdep_assert_held(&ar->conf_mutex);
855
Michal Kazior1bbc0972014-04-08 09:45:47 +0300856 ret = ath10k_monitor_vdev_create(ar);
857 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200858 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +0300859 return ret;
860 }
861
862 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
863 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200864 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +0300865 ath10k_monitor_vdev_delete(ar);
866 return ret;
867 }
868
869 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +0200870 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +0300871
872 return 0;
873}
874
Michal Kazior19337472014-08-28 12:58:16 +0200875static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +0300876{
877 int ret;
878
879 lockdep_assert_held(&ar->conf_mutex);
880
Michal Kazior1bbc0972014-04-08 09:45:47 +0300881 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +0200882 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200883 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +0200884 return ret;
885 }
Michal Kazior1bbc0972014-04-08 09:45:47 +0300886
887 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +0200888 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200889 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +0200890 return ret;
891 }
Michal Kazior1bbc0972014-04-08 09:45:47 +0300892
893 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +0200894 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +0200895
896 return 0;
897}
898
Vasanthakumar Thiagarajan54846212015-03-02 17:45:28 +0530899static bool ath10k_mac_should_disable_promisc(struct ath10k *ar)
900{
901 struct ath10k_vif *arvif;
902
903 if (!(ar->filter_flags & FIF_PROMISC_IN_BSS))
904 return true;
905
906 if (!ar->num_started_vdevs)
907 return false;
908
909 list_for_each_entry(arvif, &ar->arvifs, list)
910 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
911 return false;
912
913 ath10k_dbg(ar, ATH10K_DBG_MAC,
914 "mac disabling promiscuous mode because vdev is started\n");
915 return true;
916}
917
Michal Kazior19337472014-08-28 12:58:16 +0200918static int ath10k_monitor_recalc(struct ath10k *ar)
919{
920 bool should_start;
921
922 lockdep_assert_held(&ar->conf_mutex);
923
924 should_start = ar->monitor ||
Michal Kaziorbff414c2015-03-09 14:20:55 +0100925 !ath10k_mac_should_disable_promisc(ar) ||
Michal Kazior19337472014-08-28 12:58:16 +0200926 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
927
928 ath10k_dbg(ar, ATH10K_DBG_MAC,
929 "mac monitor recalc started? %d should? %d\n",
930 ar->monitor_started, should_start);
931
932 if (should_start == ar->monitor_started)
933 return 0;
934
935 if (should_start)
936 return ath10k_monitor_start(ar);
Kalle Valod8bb26b2014-09-14 12:50:33 +0300937
938 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +0300939}
940
Marek Kwaczynskie81bd102014-03-11 12:58:00 +0200941static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
942{
943 struct ath10k *ar = arvif->ar;
944 u32 vdev_param, rts_cts = 0;
945
946 lockdep_assert_held(&ar->conf_mutex);
947
948 vdev_param = ar->wmi.vdev_param->enable_rtscts;
949
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +0200950 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +0200951
952 if (arvif->num_legacy_stations > 0)
953 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
954 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +0200955 else
956 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
957 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +0200958
959 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
960 rts_cts);
961}
962
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200963static int ath10k_start_cac(struct ath10k *ar)
964{
965 int ret;
966
967 lockdep_assert_held(&ar->conf_mutex);
968
969 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
970
Michal Kazior19337472014-08-28 12:58:16 +0200971 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200972 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200973 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200974 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
975 return ret;
976 }
977
Michal Kazior7aa7a722014-08-25 12:09:38 +0200978 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200979 ar->monitor_vdev_id);
980
981 return 0;
982}
983
984static int ath10k_stop_cac(struct ath10k *ar)
985{
986 lockdep_assert_held(&ar->conf_mutex);
987
988 /* CAC is not running - do nothing */
989 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
990 return 0;
991
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200992 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +0300993 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200994
Michal Kazior7aa7a722014-08-25 12:09:38 +0200995 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200996
997 return 0;
998}
999
Michal Kaziord6500972014-04-08 09:56:09 +03001000static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001001{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001002 int ret;
1003
1004 lockdep_assert_held(&ar->conf_mutex);
1005
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001006 ath10k_stop_cac(ar);
1007
Michal Kaziord6500972014-04-08 09:56:09 +03001008 if (!ar->radar_enabled)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001009 return;
1010
Michal Kaziord6500972014-04-08 09:56:09 +03001011 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001012 return;
1013
1014 ret = ath10k_start_cac(ar);
1015 if (ret) {
1016 /*
1017 * Not possible to start CAC on current channel so starting
1018 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1019 * by indicating that radar was detected.
1020 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001021 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001022 ieee80211_radar_detected(ar->hw);
1023 }
1024}
1025
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301026static int ath10k_vdev_stop(struct ath10k_vif *arvif)
1027{
1028 struct ath10k *ar = arvif->ar;
1029 int ret;
1030
1031 lockdep_assert_held(&ar->conf_mutex);
1032
1033 reinit_completion(&ar->vdev_setup_done);
1034
1035 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1036 if (ret) {
1037 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1038 arvif->vdev_id, ret);
1039 return ret;
1040 }
1041
1042 ret = ath10k_vdev_setup_sync(ar);
1043 if (ret) {
1044 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
1045 arvif->vdev_id, ret);
1046 return ret;
1047 }
1048
1049 WARN_ON(ar->num_started_vdevs == 0);
1050
1051 if (ar->num_started_vdevs != 0) {
1052 ar->num_started_vdevs--;
1053 ath10k_recalc_radar_detection(ar);
1054 }
1055
1056 return ret;
1057}
1058
Michal Kaziordc55e302014-07-29 12:53:36 +03001059static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001060{
1061 struct ath10k *ar = arvif->ar;
1062 struct cfg80211_chan_def *chandef = &ar->chandef;
1063 struct wmi_vdev_start_request_arg arg = {};
Vasanthakumar Thiagarajan54846212015-03-02 17:45:28 +05301064 int ret = 0, ret2;
Michal Kazior72654fa2014-04-08 09:56:09 +03001065
1066 lockdep_assert_held(&ar->conf_mutex);
1067
1068 reinit_completion(&ar->vdev_setup_done);
1069
1070 arg.vdev_id = arvif->vdev_id;
1071 arg.dtim_period = arvif->dtim_period;
1072 arg.bcn_intval = arvif->beacon_interval;
1073
1074 arg.channel.freq = chandef->chan->center_freq;
1075 arg.channel.band_center_freq1 = chandef->center_freq1;
1076 arg.channel.mode = chan_to_phymode(chandef);
1077
1078 arg.channel.min_power = 0;
1079 arg.channel.max_power = chandef->chan->max_power * 2;
1080 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1081 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1082
1083 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1084 arg.ssid = arvif->u.ap.ssid;
1085 arg.ssid_len = arvif->u.ap.ssid_len;
1086 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1087
1088 /* For now allow DFS for AP mode */
1089 arg.channel.chan_radar =
1090 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1091 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1092 arg.ssid = arvif->vif->bss_conf.ssid;
1093 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1094 }
1095
Michal Kazior7aa7a722014-08-25 12:09:38 +02001096 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001097 "mac vdev %d start center_freq %d phymode %s\n",
1098 arg.vdev_id, arg.channel.freq,
1099 ath10k_wmi_phymode_str(arg.channel.mode));
1100
Michal Kaziordc55e302014-07-29 12:53:36 +03001101 if (restart)
1102 ret = ath10k_wmi_vdev_restart(ar, &arg);
1103 else
1104 ret = ath10k_wmi_vdev_start(ar, &arg);
1105
Michal Kazior72654fa2014-04-08 09:56:09 +03001106 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001107 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001108 arg.vdev_id, ret);
1109 return ret;
1110 }
1111
1112 ret = ath10k_vdev_setup_sync(ar);
1113 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001114 ath10k_warn(ar,
1115 "failed to synchronize setup for vdev %i restart %d: %d\n",
1116 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001117 return ret;
1118 }
1119
Michal Kaziord6500972014-04-08 09:56:09 +03001120 ar->num_started_vdevs++;
1121 ath10k_recalc_radar_detection(ar);
1122
Vasanthakumar Thiagarajan54846212015-03-02 17:45:28 +05301123 ret = ath10k_monitor_recalc(ar);
1124 if (ret) {
1125 ath10k_warn(ar, "mac failed to recalc monitor for vdev %i restart %d: %d\n",
1126 arg.vdev_id, restart, ret);
1127 ret2 = ath10k_vdev_stop(arvif);
1128 if (ret2)
1129 ath10k_warn(ar, "mac failed to stop vdev %i restart %d: %d\n",
1130 arg.vdev_id, restart, ret2);
1131 }
1132
Michal Kazior72654fa2014-04-08 09:56:09 +03001133 return ret;
1134}
1135
Michal Kaziordc55e302014-07-29 12:53:36 +03001136static int ath10k_vdev_start(struct ath10k_vif *arvif)
1137{
1138 return ath10k_vdev_start_restart(arvif, false);
1139}
1140
1141static int ath10k_vdev_restart(struct ath10k_vif *arvif)
1142{
1143 return ath10k_vdev_start_restart(arvif, true);
1144}
1145
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001146static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1147 struct sk_buff *bcn)
1148{
1149 struct ath10k *ar = arvif->ar;
1150 struct ieee80211_mgmt *mgmt;
1151 const u8 *p2p_ie;
1152 int ret;
1153
1154 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1155 return 0;
1156
1157 if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
1158 return 0;
1159
1160 mgmt = (void *)bcn->data;
1161 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1162 mgmt->u.beacon.variable,
1163 bcn->len - (mgmt->u.beacon.variable -
1164 bcn->data));
1165 if (!p2p_ie)
1166 return -ENOENT;
1167
1168 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1169 if (ret) {
1170 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1171 arvif->vdev_id, ret);
1172 return ret;
1173 }
1174
1175 return 0;
1176}
1177
1178static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1179 u8 oui_type, size_t ie_offset)
1180{
1181 size_t len;
1182 const u8 *next;
1183 const u8 *end;
1184 u8 *ie;
1185
1186 if (WARN_ON(skb->len < ie_offset))
1187 return -EINVAL;
1188
1189 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1190 skb->data + ie_offset,
1191 skb->len - ie_offset);
1192 if (!ie)
1193 return -ENOENT;
1194
1195 len = ie[1] + 2;
1196 end = skb->data + skb->len;
1197 next = ie + len;
1198
1199 if (WARN_ON(next > end))
1200 return -EINVAL;
1201
1202 memmove(ie, next, end - next);
1203 skb_trim(skb, skb->len - len);
1204
1205 return 0;
1206}
1207
1208static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1209{
1210 struct ath10k *ar = arvif->ar;
1211 struct ieee80211_hw *hw = ar->hw;
1212 struct ieee80211_vif *vif = arvif->vif;
1213 struct ieee80211_mutable_offsets offs = {};
1214 struct sk_buff *bcn;
1215 int ret;
1216
1217 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1218 return 0;
1219
Michal Kazior81a9a172015-03-05 16:02:17 +02001220 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1221 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1222 return 0;
1223
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001224 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1225 if (!bcn) {
1226 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1227 return -EPERM;
1228 }
1229
1230 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1231 if (ret) {
1232 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1233 kfree_skb(bcn);
1234 return ret;
1235 }
1236
1237 /* P2P IE is inserted by firmware automatically (as configured above)
1238 * so remove it from the base beacon template to avoid duplicate P2P
1239 * IEs in beacon frames.
1240 */
1241 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1242 offsetof(struct ieee80211_mgmt,
1243 u.beacon.variable));
1244
1245 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1246 0, NULL, 0);
1247 kfree_skb(bcn);
1248
1249 if (ret) {
1250 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1251 ret);
1252 return ret;
1253 }
1254
1255 return 0;
1256}
1257
1258static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1259{
1260 struct ath10k *ar = arvif->ar;
1261 struct ieee80211_hw *hw = ar->hw;
1262 struct ieee80211_vif *vif = arvif->vif;
1263 struct sk_buff *prb;
1264 int ret;
1265
1266 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1267 return 0;
1268
Michal Kazior81a9a172015-03-05 16:02:17 +02001269 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1270 return 0;
1271
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001272 prb = ieee80211_proberesp_get(hw, vif);
1273 if (!prb) {
1274 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1275 return -EPERM;
1276 }
1277
1278 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1279 kfree_skb(prb);
1280
1281 if (ret) {
1282 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1283 ret);
1284 return ret;
1285 }
1286
1287 return 0;
1288}
1289
Kalle Valo5e3dd152013-06-12 20:52:10 +03001290static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001291 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001292{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001293 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001294 int ret = 0;
1295
Michal Kazior548db542013-07-05 16:15:15 +03001296 lockdep_assert_held(&arvif->ar->conf_mutex);
1297
Kalle Valo5e3dd152013-06-12 20:52:10 +03001298 if (!info->enable_beacon) {
1299 ath10k_vdev_stop(arvif);
Michal Kaziorc930f742014-01-23 11:38:25 +01001300
1301 arvif->is_started = false;
1302 arvif->is_up = false;
Michal Kazior8513d952015-03-09 14:19:24 +01001303
1304 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001305 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001306 spin_unlock_bh(&arvif->ar->data_lock);
1307
Kalle Valo5e3dd152013-06-12 20:52:10 +03001308 return;
1309 }
1310
1311 arvif->tx_seq_no = 0x1000;
1312
1313 ret = ath10k_vdev_start(arvif);
1314 if (ret)
1315 return;
1316
Michal Kaziorc930f742014-01-23 11:38:25 +01001317 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001318 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001319
1320 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1321 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001322 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001323 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001324 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001325 ath10k_vdev_stop(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001326 return;
1327 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001328
1329 arvif->is_started = true;
1330 arvif->is_up = true;
1331
Michal Kazior7aa7a722014-08-25 12:09:38 +02001332 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001333}
1334
1335static void ath10k_control_ibss(struct ath10k_vif *arvif,
1336 struct ieee80211_bss_conf *info,
1337 const u8 self_peer[ETH_ALEN])
1338{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001339 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001340 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001341 int ret = 0;
1342
Michal Kazior548db542013-07-05 16:15:15 +03001343 lockdep_assert_held(&arvif->ar->conf_mutex);
1344
Kalle Valo5e3dd152013-06-12 20:52:10 +03001345 if (!info->ibss_joined) {
1346 ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer);
1347 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001348 ath10k_warn(ar, "failed to delete IBSS self peer %pM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001349 self_peer, arvif->vdev_id, ret);
1350
Michal Kaziorc930f742014-01-23 11:38:25 +01001351 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001352 return;
1353
Michal Kaziorc930f742014-01-23 11:38:25 +01001354 memset(arvif->bssid, 0, ETH_ALEN);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001355
1356 return;
1357 }
1358
Marek Puzyniak7390ed32015-03-30 09:51:52 +03001359 ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer,
1360 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001361 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001362 ath10k_warn(ar, "failed to create IBSS self peer %pM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001363 self_peer, arvif->vdev_id, ret);
1364 return;
1365 }
1366
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001367 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1368 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001369 ATH10K_DEFAULT_ATIM);
1370 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001371 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001372 arvif->vdev_id, ret);
1373}
1374
Michal Kazior9f9b5742014-12-12 12:41:36 +01001375static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1376{
1377 struct ath10k *ar = arvif->ar;
1378 u32 param;
1379 u32 value;
1380 int ret;
1381
1382 lockdep_assert_held(&arvif->ar->conf_mutex);
1383
1384 if (arvif->u.sta.uapsd)
1385 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1386 else
1387 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1388
1389 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1390 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1391 if (ret) {
1392 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1393 value, arvif->vdev_id, ret);
1394 return ret;
1395 }
1396
1397 return 0;
1398}
1399
1400static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1401{
1402 struct ath10k *ar = arvif->ar;
1403 u32 param;
1404 u32 value;
1405 int ret;
1406
1407 lockdep_assert_held(&arvif->ar->conf_mutex);
1408
1409 if (arvif->u.sta.uapsd)
1410 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1411 else
1412 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1413
1414 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1415 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1416 param, value);
1417 if (ret) {
1418 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1419 value, arvif->vdev_id, ret);
1420 return ret;
1421 }
1422
1423 return 0;
1424}
1425
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001426static int ath10k_mac_ps_vif_count(struct ath10k *ar)
1427{
1428 struct ath10k_vif *arvif;
1429 int num = 0;
1430
1431 lockdep_assert_held(&ar->conf_mutex);
1432
1433 list_for_each_entry(arvif, &ar->arvifs, list)
1434 if (arvif->ps)
1435 num++;
1436
1437 return num;
1438}
1439
Michal Kaziorad088bf2013-10-16 15:44:46 +03001440static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001441{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001442 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001443 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001444 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001445 enum wmi_sta_powersave_param param;
1446 enum wmi_sta_ps_mode psmode;
1447 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001448 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001449 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001450
Michal Kazior548db542013-07-05 16:15:15 +03001451 lockdep_assert_held(&arvif->ar->conf_mutex);
1452
Michal Kaziorad088bf2013-10-16 15:44:46 +03001453 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1454 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001455
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001456 enable_ps = arvif->ps;
1457
1458 if (enable_ps && ath10k_mac_ps_vif_count(ar) > 1 &&
1459 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
1460 ar->fw_features)) {
1461 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1462 arvif->vdev_id);
1463 enable_ps = false;
1464 }
1465
1466 if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001467 psmode = WMI_STA_PS_MODE_ENABLED;
1468 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1469
Michal Kazior526549a2014-12-12 12:41:37 +01001470 ps_timeout = conf->dynamic_ps_timeout;
1471 if (ps_timeout == 0) {
1472 /* Firmware doesn't like 0 */
1473 ps_timeout = ieee80211_tu_to_usec(
1474 vif->bss_conf.beacon_int) / 1000;
1475 }
1476
Michal Kaziorad088bf2013-10-16 15:44:46 +03001477 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001478 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001479 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001480 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001481 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001482 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001483 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001484 } else {
1485 psmode = WMI_STA_PS_MODE_DISABLED;
1486 }
1487
Michal Kazior7aa7a722014-08-25 12:09:38 +02001488 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001489 arvif->vdev_id, psmode ? "enable" : "disable");
1490
Michal Kaziorad088bf2013-10-16 15:44:46 +03001491 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1492 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001493 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001494 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001495 return ret;
1496 }
1497
1498 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001499}
1500
Michal Kazior46725b152015-01-28 09:57:49 +02001501static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1502{
1503 struct ath10k *ar = arvif->ar;
1504 struct wmi_sta_keepalive_arg arg = {};
1505 int ret;
1506
1507 lockdep_assert_held(&arvif->ar->conf_mutex);
1508
1509 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1510 return 0;
1511
1512 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1513 return 0;
1514
1515 /* Some firmware revisions have a bug and ignore the `enabled` field.
1516 * Instead use the interval to disable the keepalive.
1517 */
1518 arg.vdev_id = arvif->vdev_id;
1519 arg.enabled = 1;
1520 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1521 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1522
1523 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1524 if (ret) {
1525 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1526 arvif->vdev_id, ret);
1527 return ret;
1528 }
1529
1530 return 0;
1531}
1532
Michal Kazior81a9a172015-03-05 16:02:17 +02001533static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1534{
1535 struct ath10k *ar = arvif->ar;
1536 struct ieee80211_vif *vif = arvif->vif;
1537 int ret;
1538
Michal Kazior8513d952015-03-09 14:19:24 +01001539 lockdep_assert_held(&arvif->ar->conf_mutex);
1540
1541 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1542 return;
1543
Michal Kazior81a9a172015-03-05 16:02:17 +02001544 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1545 return;
1546
1547 if (!vif->csa_active)
1548 return;
1549
1550 if (!arvif->is_up)
1551 return;
1552
1553 if (!ieee80211_csa_is_complete(vif)) {
1554 ieee80211_csa_update_counter(vif);
1555
1556 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1557 if (ret)
1558 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1559 ret);
1560
1561 ret = ath10k_mac_setup_prb_tmpl(arvif);
1562 if (ret)
1563 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1564 ret);
1565 } else {
1566 ieee80211_csa_finish(vif);
1567 }
1568}
1569
1570static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1571{
1572 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1573 ap_csa_work);
1574 struct ath10k *ar = arvif->ar;
1575
1576 mutex_lock(&ar->conf_mutex);
1577 ath10k_mac_vif_ap_csa_count_down(arvif);
1578 mutex_unlock(&ar->conf_mutex);
1579}
1580
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001581static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1582 struct ieee80211_vif *vif)
1583{
1584 struct sk_buff *skb = data;
1585 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1586 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1587
1588 if (vif->type != NL80211_IFTYPE_STATION)
1589 return;
1590
1591 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1592 return;
1593
1594 cancel_delayed_work(&arvif->connection_loss_work);
1595}
1596
1597void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
1598{
1599 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1600 IEEE80211_IFACE_ITER_NORMAL,
1601 ath10k_mac_handle_beacon_iter,
1602 skb);
1603}
1604
1605static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
1606 struct ieee80211_vif *vif)
1607{
1608 u32 *vdev_id = data;
1609 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1610 struct ath10k *ar = arvif->ar;
1611 struct ieee80211_hw *hw = ar->hw;
1612
1613 if (arvif->vdev_id != *vdev_id)
1614 return;
1615
1616 if (!arvif->is_up)
1617 return;
1618
1619 ieee80211_beacon_loss(vif);
1620
1621 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
1622 * (done by mac80211) succeeds but beacons do not resume then it
1623 * doesn't make sense to continue operation. Queue connection loss work
1624 * which can be cancelled when beacon is received.
1625 */
1626 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
1627 ATH10K_CONNECTION_LOSS_HZ);
1628}
1629
1630void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
1631{
1632 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1633 IEEE80211_IFACE_ITER_NORMAL,
1634 ath10k_mac_handle_beacon_miss_iter,
1635 &vdev_id);
1636}
1637
1638static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
1639{
1640 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1641 connection_loss_work.work);
1642 struct ieee80211_vif *vif = arvif->vif;
1643
1644 if (!arvif->is_up)
1645 return;
1646
1647 ieee80211_connection_loss(vif);
1648}
1649
Kalle Valo5e3dd152013-06-12 20:52:10 +03001650/**********************/
1651/* Station management */
1652/**********************/
1653
Michal Kazior590922a2014-10-21 10:10:29 +03001654static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
1655 struct ieee80211_vif *vif)
1656{
1657 /* Some firmware revisions have unstable STA powersave when listen
1658 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
1659 * generate NullFunc frames properly even if buffered frames have been
1660 * indicated in Beacon TIM. Firmware would seldom wake up to pull
1661 * buffered frames. Often pinging the device from AP would simply fail.
1662 *
1663 * As a workaround set it to 1.
1664 */
1665 if (vif->type == NL80211_IFTYPE_STATION)
1666 return 1;
1667
1668 return ar->hw->conf.listen_interval;
1669}
1670
Kalle Valo5e3dd152013-06-12 20:52:10 +03001671static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001672 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001673 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001674 struct wmi_peer_assoc_complete_arg *arg)
1675{
Michal Kazior590922a2014-10-21 10:10:29 +03001676 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1677
Michal Kazior548db542013-07-05 16:15:15 +03001678 lockdep_assert_held(&ar->conf_mutex);
1679
Kalle Valob25f32c2014-09-14 12:50:49 +03001680 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001681 arg->vdev_id = arvif->vdev_id;
1682 arg->peer_aid = sta->aid;
1683 arg->peer_flags |= WMI_PEER_AUTH;
Michal Kazior590922a2014-10-21 10:10:29 +03001684 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001685 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03001686 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001687}
1688
1689static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001690 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001691 struct wmi_peer_assoc_complete_arg *arg)
1692{
Kalle Valo5e3dd152013-06-12 20:52:10 +03001693 struct ieee80211_bss_conf *info = &vif->bss_conf;
1694 struct cfg80211_bss *bss;
1695 const u8 *rsnie = NULL;
1696 const u8 *wpaie = NULL;
1697
Michal Kazior548db542013-07-05 16:15:15 +03001698 lockdep_assert_held(&ar->conf_mutex);
1699
Kalle Valo5e3dd152013-06-12 20:52:10 +03001700 bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan,
Dedy Lansky6eb18132015-02-08 15:52:03 +02001701 info->bssid, NULL, 0, IEEE80211_BSS_TYPE_ANY,
1702 IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001703 if (bss) {
1704 const struct cfg80211_bss_ies *ies;
1705
1706 rcu_read_lock();
1707 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
1708
1709 ies = rcu_dereference(bss->ies);
1710
1711 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03001712 WLAN_OUI_TYPE_MICROSOFT_WPA,
1713 ies->data,
1714 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001715 rcu_read_unlock();
1716 cfg80211_put_bss(ar->hw->wiphy, bss);
1717 }
1718
1719 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
1720 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001721 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001722 arg->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
1723 }
1724
1725 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001726 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001727 arg->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
1728 }
1729}
1730
1731static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
1732 struct ieee80211_sta *sta,
1733 struct wmi_peer_assoc_complete_arg *arg)
1734{
1735 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
1736 const struct ieee80211_supported_band *sband;
1737 const struct ieee80211_rate *rates;
1738 u32 ratemask;
1739 int i;
1740
Michal Kazior548db542013-07-05 16:15:15 +03001741 lockdep_assert_held(&ar->conf_mutex);
1742
Kalle Valo5e3dd152013-06-12 20:52:10 +03001743 sband = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band];
1744 ratemask = sta->supp_rates[ar->hw->conf.chandef.chan->band];
1745 rates = sband->bitrates;
1746
1747 rateset->num_rates = 0;
1748
1749 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
1750 if (!(ratemask & 1))
1751 continue;
1752
1753 rateset->rates[rateset->num_rates] = rates->hw_value;
1754 rateset->num_rates++;
1755 }
1756}
1757
1758static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
1759 struct ieee80211_sta *sta,
1760 struct wmi_peer_assoc_complete_arg *arg)
1761{
1762 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001763 int i, n;
Kalle Valoaf762c02014-09-14 12:50:17 +03001764 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001765
Michal Kazior548db542013-07-05 16:15:15 +03001766 lockdep_assert_held(&ar->conf_mutex);
1767
Kalle Valo5e3dd152013-06-12 20:52:10 +03001768 if (!ht_cap->ht_supported)
1769 return;
1770
1771 arg->peer_flags |= WMI_PEER_HT;
1772 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
1773 ht_cap->ampdu_factor)) - 1;
1774
1775 arg->peer_mpdu_density =
1776 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
1777
1778 arg->peer_ht_caps = ht_cap->cap;
1779 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
1780
1781 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
1782 arg->peer_flags |= WMI_PEER_LDPC;
1783
1784 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
1785 arg->peer_flags |= WMI_PEER_40MHZ;
1786 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
1787 }
1788
1789 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
1790 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
1791
1792 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
1793 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
1794
1795 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
1796 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
1797 arg->peer_flags |= WMI_PEER_STBC;
1798 }
1799
1800 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001801 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
1802 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
1803 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
1804 arg->peer_rate_caps |= stbc;
1805 arg->peer_flags |= WMI_PEER_STBC;
1806 }
1807
Kalle Valo5e3dd152013-06-12 20:52:10 +03001808 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
1809 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
1810 else if (ht_cap->mcs.rx_mask[1])
1811 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
1812
1813 for (i = 0, n = 0; i < IEEE80211_HT_MCS_MASK_LEN*8; i++)
1814 if (ht_cap->mcs.rx_mask[i/8] & (1 << i%8))
1815 arg->peer_ht_rates.rates[n++] = i;
1816
Bartosz Markowskifd71f802014-02-10 13:12:55 +01001817 /*
1818 * This is a workaround for HT-enabled STAs which break the spec
1819 * and have no HT capabilities RX mask (no HT RX MCS map).
1820 *
1821 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
1822 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
1823 *
1824 * Firmware asserts if such situation occurs.
1825 */
1826 if (n == 0) {
1827 arg->peer_ht_rates.num_rates = 8;
1828 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
1829 arg->peer_ht_rates.rates[i] = i;
1830 } else {
1831 arg->peer_ht_rates.num_rates = n;
1832 arg->peer_num_spatial_streams = sta->rx_nss;
1833 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001834
Michal Kazior7aa7a722014-08-25 12:09:38 +02001835 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001836 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001837 arg->peer_ht_rates.num_rates,
1838 arg->peer_num_spatial_streams);
1839}
1840
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001841static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
1842 struct ath10k_vif *arvif,
1843 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001844{
1845 u32 uapsd = 0;
1846 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001847 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001848
Michal Kazior548db542013-07-05 16:15:15 +03001849 lockdep_assert_held(&ar->conf_mutex);
1850
Kalle Valo5e3dd152013-06-12 20:52:10 +03001851 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001852 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001853 sta->uapsd_queues, sta->max_sp);
1854
Kalle Valo5e3dd152013-06-12 20:52:10 +03001855 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
1856 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
1857 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
1858 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
1859 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
1860 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
1861 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
1862 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
1863 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
1864 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
1865 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
1866 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
1867
Kalle Valo5e3dd152013-06-12 20:52:10 +03001868 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
1869 max_sp = sta->max_sp;
1870
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001871 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
1872 sta->addr,
1873 WMI_AP_PS_PEER_PARAM_UAPSD,
1874 uapsd);
1875 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001876 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001877 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001878 return ret;
1879 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001880
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001881 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
1882 sta->addr,
1883 WMI_AP_PS_PEER_PARAM_MAX_SP,
1884 max_sp);
1885 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001886 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001887 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001888 return ret;
1889 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001890
1891 /* TODO setup this based on STA listen interval and
1892 beacon interval. Currently we don't know
1893 sta->listen_interval - mac80211 patch required.
1894 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001895 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03001896 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
1897 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001898 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001899 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001900 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001901 return ret;
1902 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001903 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001904
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001905 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001906}
1907
1908static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
1909 struct ieee80211_sta *sta,
1910 struct wmi_peer_assoc_complete_arg *arg)
1911{
1912 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07001913 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001914
1915 if (!vht_cap->vht_supported)
1916 return;
1917
1918 arg->peer_flags |= WMI_PEER_VHT;
Yanbo Lid68bb122015-01-23 08:18:20 +08001919
1920 if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
1921 arg->peer_flags |= WMI_PEER_VHT_2G;
1922
Kalle Valo5e3dd152013-06-12 20:52:10 +03001923 arg->peer_vht_caps = vht_cap->cap;
1924
Sujith Manoharana24b88b2013-10-07 19:51:57 -07001925 ampdu_factor = (vht_cap->cap &
1926 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
1927 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
1928
1929 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
1930 * zero in VHT IE. Using it would result in degraded throughput.
1931 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
1932 * it if VHT max_mpdu is smaller. */
1933 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
1934 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
1935 ampdu_factor)) - 1);
1936
Kalle Valo5e3dd152013-06-12 20:52:10 +03001937 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
1938 arg->peer_flags |= WMI_PEER_80MHZ;
1939
1940 arg->peer_vht_rates.rx_max_rate =
1941 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
1942 arg->peer_vht_rates.rx_mcs_set =
1943 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
1944 arg->peer_vht_rates.tx_max_rate =
1945 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
1946 arg->peer_vht_rates.tx_mcs_set =
1947 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
1948
Michal Kazior7aa7a722014-08-25 12:09:38 +02001949 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001950 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001951}
1952
1953static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001954 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001955 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001956 struct wmi_peer_assoc_complete_arg *arg)
1957{
Michal Kazior590922a2014-10-21 10:10:29 +03001958 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1959
Kalle Valo5e3dd152013-06-12 20:52:10 +03001960 switch (arvif->vdev_type) {
1961 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001962 if (sta->wme)
1963 arg->peer_flags |= WMI_PEER_QOS;
1964
1965 if (sta->wme && sta->uapsd_queues) {
1966 arg->peer_flags |= WMI_PEER_APSD;
1967 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
1968 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001969 break;
1970 case WMI_VDEV_TYPE_STA:
Michal Kazior590922a2014-10-21 10:10:29 +03001971 if (vif->bss_conf.qos)
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01001972 arg->peer_flags |= WMI_PEER_QOS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001973 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02001974 case WMI_VDEV_TYPE_IBSS:
1975 if (sta->wme)
1976 arg->peer_flags |= WMI_PEER_QOS;
1977 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001978 default:
1979 break;
1980 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02001981
1982 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
1983 sta->addr, !!(arg->peer_flags & WMI_PEER_QOS));
Kalle Valo5e3dd152013-06-12 20:52:10 +03001984}
1985
Michal Kazior91b12082014-12-12 12:41:35 +01001986static bool ath10k_mac_sta_has_11g_rates(struct ieee80211_sta *sta)
1987{
1988 /* First 4 rates in ath10k_rates are CCK (11b) rates. */
1989 return sta->supp_rates[IEEE80211_BAND_2GHZ] >> 4;
1990}
1991
Kalle Valo5e3dd152013-06-12 20:52:10 +03001992static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001993 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001994 struct ieee80211_sta *sta,
1995 struct wmi_peer_assoc_complete_arg *arg)
1996{
1997 enum wmi_phy_mode phymode = MODE_UNKNOWN;
1998
Kalle Valo5e3dd152013-06-12 20:52:10 +03001999 switch (ar->hw->conf.chandef.chan->band) {
2000 case IEEE80211_BAND_2GHZ:
Yanbo Lid68bb122015-01-23 08:18:20 +08002001 if (sta->vht_cap.vht_supported) {
2002 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2003 phymode = MODE_11AC_VHT40;
2004 else
2005 phymode = MODE_11AC_VHT20;
2006 } else if (sta->ht_cap.ht_supported) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002007 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2008 phymode = MODE_11NG_HT40;
2009 else
2010 phymode = MODE_11NG_HT20;
Michal Kazior91b12082014-12-12 12:41:35 +01002011 } else if (ath10k_mac_sta_has_11g_rates(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002012 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002013 } else {
2014 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002015 }
2016
2017 break;
2018 case IEEE80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002019 /*
2020 * Check VHT first.
2021 */
2022 if (sta->vht_cap.vht_supported) {
2023 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2024 phymode = MODE_11AC_VHT80;
2025 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2026 phymode = MODE_11AC_VHT40;
2027 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2028 phymode = MODE_11AC_VHT20;
2029 } else if (sta->ht_cap.ht_supported) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002030 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2031 phymode = MODE_11NA_HT40;
2032 else
2033 phymode = MODE_11NA_HT20;
2034 } else {
2035 phymode = MODE_11A;
2036 }
2037
2038 break;
2039 default:
2040 break;
2041 }
2042
Michal Kazior7aa7a722014-08-25 12:09:38 +02002043 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002044 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002045
Kalle Valo5e3dd152013-06-12 20:52:10 +03002046 arg->peer_phymode = phymode;
2047 WARN_ON(phymode == MODE_UNKNOWN);
2048}
2049
Kalle Valob9ada652013-10-16 15:44:46 +03002050static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002051 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002052 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002053 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002054{
Michal Kazior548db542013-07-05 16:15:15 +03002055 lockdep_assert_held(&ar->conf_mutex);
2056
Kalle Valob9ada652013-10-16 15:44:46 +03002057 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002058
Michal Kazior590922a2014-10-21 10:10:29 +03002059 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
2060 ath10k_peer_assoc_h_crypto(ar, vif, arg);
Kalle Valob9ada652013-10-16 15:44:46 +03002061 ath10k_peer_assoc_h_rates(ar, sta, arg);
2062 ath10k_peer_assoc_h_ht(ar, sta, arg);
2063 ath10k_peer_assoc_h_vht(ar, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002064 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2065 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002066
Kalle Valob9ada652013-10-16 15:44:46 +03002067 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002068}
2069
Michal Kazior90046f52014-02-14 14:45:51 +01002070static const u32 ath10k_smps_map[] = {
2071 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2072 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2073 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2074 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2075};
2076
2077static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2078 const u8 *addr,
2079 const struct ieee80211_sta_ht_cap *ht_cap)
2080{
2081 int smps;
2082
2083 if (!ht_cap->ht_supported)
2084 return 0;
2085
2086 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2087 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2088
2089 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2090 return -EINVAL;
2091
2092 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2093 WMI_PEER_SMPS_STATE,
2094 ath10k_smps_map[smps]);
2095}
2096
Michal Kazior139e1702015-02-15 16:50:42 +02002097static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2098 struct ieee80211_vif *vif,
2099 struct ieee80211_sta_vht_cap vht_cap)
2100{
2101 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2102 int ret;
2103 u32 param;
2104 u32 value;
2105
2106 if (!(ar->vht_cap_info &
2107 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2108 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2109 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2110 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2111 return 0;
2112
2113 param = ar->wmi.vdev_param->txbf;
2114 value = 0;
2115
2116 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2117 return 0;
2118
2119 /* The following logic is correct. If a remote STA advertises support
2120 * for being a beamformer then we should enable us being a beamformee.
2121 */
2122
2123 if (ar->vht_cap_info &
2124 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2125 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2126 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2127 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2128
2129 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2130 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2131 }
2132
2133 if (ar->vht_cap_info &
2134 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2135 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2136 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2137 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2138
2139 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2140 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2141 }
2142
2143 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2144 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2145
2146 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2147 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2148
2149 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2150 if (ret) {
2151 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2152 value, ret);
2153 return ret;
2154 }
2155
2156 return 0;
2157}
2158
Kalle Valo5e3dd152013-06-12 20:52:10 +03002159/* can be called only in mac80211 callbacks due to `key_count` usage */
2160static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2161 struct ieee80211_vif *vif,
2162 struct ieee80211_bss_conf *bss_conf)
2163{
2164 struct ath10k *ar = hw->priv;
2165 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002166 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002167 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002168 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002169 struct ieee80211_sta *ap_sta;
2170 int ret;
2171
Michal Kazior548db542013-07-05 16:15:15 +03002172 lockdep_assert_held(&ar->conf_mutex);
2173
Michal Kazior077efc82014-10-21 10:10:29 +03002174 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2175 arvif->vdev_id, arvif->bssid, arvif->aid);
2176
Kalle Valo5e3dd152013-06-12 20:52:10 +03002177 rcu_read_lock();
2178
2179 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2180 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002181 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002182 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002183 rcu_read_unlock();
2184 return;
2185 }
2186
Michal Kazior90046f52014-02-14 14:45:51 +01002187 /* ap_sta must be accessed only within rcu section which must be left
2188 * before calling ath10k_setup_peer_smps() which might sleep. */
2189 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002190 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002191
Michal Kazior590922a2014-10-21 10:10:29 +03002192 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002193 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002194 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002195 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002196 rcu_read_unlock();
2197 return;
2198 }
2199
2200 rcu_read_unlock();
2201
Kalle Valob9ada652013-10-16 15:44:46 +03002202 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2203 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002204 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002205 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002206 return;
2207 }
2208
Michal Kazior90046f52014-02-14 14:45:51 +01002209 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2210 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002211 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002212 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002213 return;
2214 }
2215
Michal Kazior139e1702015-02-15 16:50:42 +02002216 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2217 if (ret) {
2218 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2219 arvif->vdev_id, bss_conf->bssid, ret);
2220 return;
2221 }
2222
Michal Kazior7aa7a722014-08-25 12:09:38 +02002223 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002224 "mac vdev %d up (associated) bssid %pM aid %d\n",
2225 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2226
Michal Kazior077efc82014-10-21 10:10:29 +03002227 WARN_ON(arvif->is_up);
2228
Michal Kaziorc930f742014-01-23 11:38:25 +01002229 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002230 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002231
2232 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2233 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002234 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002235 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002236 return;
2237 }
2238
2239 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002240
2241 /* Workaround: Some firmware revisions (tested with qca6174
2242 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2243 * poked with peer param command.
2244 */
2245 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2246 WMI_PEER_DUMMY_VAR, 1);
2247 if (ret) {
2248 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2249 arvif->bssid, arvif->vdev_id, ret);
2250 return;
2251 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002252}
2253
Kalle Valo5e3dd152013-06-12 20:52:10 +03002254static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2255 struct ieee80211_vif *vif)
2256{
2257 struct ath10k *ar = hw->priv;
2258 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002259 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002260 int ret;
2261
Michal Kazior548db542013-07-05 16:15:15 +03002262 lockdep_assert_held(&ar->conf_mutex);
2263
Michal Kazior077efc82014-10-21 10:10:29 +03002264 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2265 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002266
Kalle Valo5e3dd152013-06-12 20:52:10 +03002267 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002268 if (ret)
2269 ath10k_warn(ar, "faield to down vdev %i: %d\n",
2270 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002271
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002272 arvif->def_wep_key_idx = -1;
2273
Michal Kazior139e1702015-02-15 16:50:42 +02002274 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2275 if (ret) {
2276 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2277 arvif->vdev_id, ret);
2278 return;
2279 }
2280
Michal Kaziorc930f742014-01-23 11:38:25 +01002281 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002282
2283 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002284}
2285
Michal Kazior590922a2014-10-21 10:10:29 +03002286static int ath10k_station_assoc(struct ath10k *ar,
2287 struct ieee80211_vif *vif,
2288 struct ieee80211_sta *sta,
2289 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002290{
Michal Kazior590922a2014-10-21 10:10:29 +03002291 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002292 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002293 int ret = 0;
2294
Michal Kazior548db542013-07-05 16:15:15 +03002295 lockdep_assert_held(&ar->conf_mutex);
2296
Michal Kazior590922a2014-10-21 10:10:29 +03002297 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002298 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002299 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002300 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002301 return ret;
2302 }
2303
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02002304 peer_arg.peer_reassoc = reassoc;
Kalle Valob9ada652013-10-16 15:44:46 +03002305 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2306 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002307 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002308 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002309 return ret;
2310 }
2311
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002312 /* Re-assoc is run only to update supported rates for given station. It
2313 * doesn't make much sense to reconfigure the peer completely.
2314 */
2315 if (!reassoc) {
2316 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2317 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002318 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002319 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002320 arvif->vdev_id, ret);
2321 return ret;
2322 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002323
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002324 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2325 if (ret) {
2326 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2327 sta->addr, arvif->vdev_id, ret);
2328 return ret;
2329 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002330
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002331 if (!sta->wme) {
2332 arvif->num_legacy_stations++;
2333 ret = ath10k_recalc_rtscts_prot(arvif);
2334 if (ret) {
2335 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2336 arvif->vdev_id, ret);
2337 return ret;
2338 }
2339 }
2340
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002341 /* Plumb cached keys only for static WEP */
2342 if (arvif->def_wep_key_idx != -1) {
2343 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2344 if (ret) {
2345 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2346 arvif->vdev_id, ret);
2347 return ret;
2348 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002349 }
2350 }
2351
Kalle Valo5e3dd152013-06-12 20:52:10 +03002352 return ret;
2353}
2354
Michal Kazior590922a2014-10-21 10:10:29 +03002355static int ath10k_station_disassoc(struct ath10k *ar,
2356 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002357 struct ieee80211_sta *sta)
2358{
Michal Kazior590922a2014-10-21 10:10:29 +03002359 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002360 int ret = 0;
2361
2362 lockdep_assert_held(&ar->conf_mutex);
2363
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002364 if (!sta->wme) {
2365 arvif->num_legacy_stations--;
2366 ret = ath10k_recalc_rtscts_prot(arvif);
2367 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002368 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002369 arvif->vdev_id, ret);
2370 return ret;
2371 }
2372 }
2373
Kalle Valo5e3dd152013-06-12 20:52:10 +03002374 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2375 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002376 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002377 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002378 return ret;
2379 }
2380
2381 return ret;
2382}
2383
2384/**************/
2385/* Regulatory */
2386/**************/
2387
2388static int ath10k_update_channel_list(struct ath10k *ar)
2389{
2390 struct ieee80211_hw *hw = ar->hw;
2391 struct ieee80211_supported_band **bands;
2392 enum ieee80211_band band;
2393 struct ieee80211_channel *channel;
2394 struct wmi_scan_chan_list_arg arg = {0};
2395 struct wmi_channel_arg *ch;
2396 bool passive;
2397 int len;
2398 int ret;
2399 int i;
2400
Michal Kazior548db542013-07-05 16:15:15 +03002401 lockdep_assert_held(&ar->conf_mutex);
2402
Kalle Valo5e3dd152013-06-12 20:52:10 +03002403 bands = hw->wiphy->bands;
2404 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2405 if (!bands[band])
2406 continue;
2407
2408 for (i = 0; i < bands[band]->n_channels; i++) {
2409 if (bands[band]->channels[i].flags &
2410 IEEE80211_CHAN_DISABLED)
2411 continue;
2412
2413 arg.n_channels++;
2414 }
2415 }
2416
2417 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2418 arg.channels = kzalloc(len, GFP_KERNEL);
2419 if (!arg.channels)
2420 return -ENOMEM;
2421
2422 ch = arg.channels;
2423 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2424 if (!bands[band])
2425 continue;
2426
2427 for (i = 0; i < bands[band]->n_channels; i++) {
2428 channel = &bands[band]->channels[i];
2429
2430 if (channel->flags & IEEE80211_CHAN_DISABLED)
2431 continue;
2432
2433 ch->allow_ht = true;
2434
2435 /* FIXME: when should we really allow VHT? */
2436 ch->allow_vht = true;
2437
2438 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002439 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002440
2441 ch->ht40plus =
2442 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2443
Marek Puzyniake8a50f82013-11-20 09:59:47 +02002444 ch->chan_radar =
2445 !!(channel->flags & IEEE80211_CHAN_RADAR);
2446
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002447 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002448 ch->passive = passive;
2449
2450 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02002451 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07002452 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07002453 ch->max_power = channel->max_power * 2;
2454 ch->max_reg_power = channel->max_reg_power * 2;
2455 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002456 ch->reg_class_id = 0; /* FIXME */
2457
2458 /* FIXME: why use only legacy modes, why not any
2459 * HT/VHT modes? Would that even make any
2460 * difference? */
2461 if (channel->band == IEEE80211_BAND_2GHZ)
2462 ch->mode = MODE_11G;
2463 else
2464 ch->mode = MODE_11A;
2465
2466 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
2467 continue;
2468
Michal Kazior7aa7a722014-08-25 12:09:38 +02002469 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002470 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
2471 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002472 ch->freq, ch->max_power, ch->max_reg_power,
2473 ch->max_antenna_gain, ch->mode);
2474
2475 ch++;
2476 }
2477 }
2478
2479 ret = ath10k_wmi_scan_chan_list(ar, &arg);
2480 kfree(arg.channels);
2481
2482 return ret;
2483}
2484
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002485static enum wmi_dfs_region
2486ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
2487{
2488 switch (dfs_region) {
2489 case NL80211_DFS_UNSET:
2490 return WMI_UNINIT_DFS_DOMAIN;
2491 case NL80211_DFS_FCC:
2492 return WMI_FCC_DFS_DOMAIN;
2493 case NL80211_DFS_ETSI:
2494 return WMI_ETSI_DFS_DOMAIN;
2495 case NL80211_DFS_JP:
2496 return WMI_MKK4_DFS_DOMAIN;
2497 }
2498 return WMI_UNINIT_DFS_DOMAIN;
2499}
2500
Michal Kaziorf7843d72013-07-16 09:38:52 +02002501static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002502{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002503 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002504 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002505 enum wmi_dfs_region wmi_dfs_reg;
2506 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002507
Michal Kaziorf7843d72013-07-16 09:38:52 +02002508 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002509
2510 ret = ath10k_update_channel_list(ar);
2511 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002512 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002513
2514 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002515
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002516 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
2517 nl_dfs_reg = ar->dfs_detector->region;
2518 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
2519 } else {
2520 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
2521 }
2522
Kalle Valo5e3dd152013-06-12 20:52:10 +03002523 /* Target allows setting up per-band regdomain but ath_common provides
2524 * a combined one only */
2525 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02002526 regpair->reg_domain,
2527 regpair->reg_domain, /* 2ghz */
2528 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03002529 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002530 regpair->reg_5ghz_ctl,
2531 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002532 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002533 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02002534}
Michal Kazior548db542013-07-05 16:15:15 +03002535
Michal Kaziorf7843d72013-07-16 09:38:52 +02002536static void ath10k_reg_notifier(struct wiphy *wiphy,
2537 struct regulatory_request *request)
2538{
2539 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2540 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002541 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002542
2543 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
2544
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002545 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002546 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002547 request->dfs_region);
2548 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
2549 request->dfs_region);
2550 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002551 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002552 request->dfs_region);
2553 }
2554
Michal Kaziorf7843d72013-07-16 09:38:52 +02002555 mutex_lock(&ar->conf_mutex);
2556 if (ar->state == ATH10K_STATE_ON)
2557 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03002558 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002559}
2560
2561/***************/
2562/* TX handlers */
2563/***************/
2564
Michal Kazior42c3aa62013-10-02 11:03:38 +02002565static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
2566{
2567 if (ieee80211_is_mgmt(hdr->frame_control))
2568 return HTT_DATA_TX_EXT_TID_MGMT;
2569
2570 if (!ieee80211_is_data_qos(hdr->frame_control))
2571 return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
2572
2573 if (!is_unicast_ether_addr(ieee80211_get_DA(hdr)))
2574 return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
2575
2576 return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
2577}
2578
Michal Kazior2b37c292014-09-02 11:00:22 +03002579static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
Michal Kaziorddb6ad72013-10-02 11:03:39 +02002580{
Michal Kazior2b37c292014-09-02 11:00:22 +03002581 if (vif)
2582 return ath10k_vif_to_arvif(vif)->vdev_id;
Michal Kaziorddb6ad72013-10-02 11:03:39 +02002583
Michal Kazior1bbc0972014-04-08 09:45:47 +03002584 if (ar->monitor_started)
Michal Kaziorddb6ad72013-10-02 11:03:39 +02002585 return ar->monitor_vdev_id;
2586
Michal Kazior7aa7a722014-08-25 12:09:38 +02002587 ath10k_warn(ar, "failed to resolve vdev id\n");
Michal Kaziorddb6ad72013-10-02 11:03:39 +02002588 return 0;
2589}
2590
Michal Kaziord740d8f2015-03-30 09:51:51 +03002591static enum ath10k_hw_txrx_mode
2592ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03002593 struct ieee80211_sta *sta, struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03002594{
2595 const struct ieee80211_hdr *hdr = (void *)skb->data;
2596 __le16 fc = hdr->frame_control;
2597
2598 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
2599 return ATH10K_HW_TXRX_RAW;
2600
2601 if (ieee80211_is_mgmt(fc))
2602 return ATH10K_HW_TXRX_MGMT;
2603
2604 /* Workaround:
2605 *
2606 * NullFunc frames are mostly used to ping if a client or AP are still
2607 * reachable and responsive. This implies tx status reports must be
2608 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
2609 * come to a conclusion that the other end disappeared and tear down
2610 * BSS connection or it can never disconnect from BSS/client (which is
2611 * the case).
2612 *
2613 * Firmware with HTT older than 3.0 delivers incorrect tx status for
2614 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
2615 * which seems to deliver correct tx reports for NullFunc frames. The
2616 * downside of using it is it ignores client powersave state so it can
2617 * end up disconnecting sleeping clients in AP mode. It should fix STA
2618 * mode though because AP don't sleep.
2619 */
2620 if (ar->htt.target_version_major < 3 &&
2621 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
2622 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, ar->fw_features))
2623 return ATH10K_HW_TXRX_MGMT;
2624
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03002625 /* Workaround:
2626 *
2627 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
2628 * NativeWifi txmode - it selects AP key instead of peer key. It seems
2629 * to work with Ethernet txmode so use it.
2630 */
2631 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
2632 return ATH10K_HW_TXRX_ETHERNET;
2633
Michal Kaziord740d8f2015-03-30 09:51:51 +03002634 return ATH10K_HW_TXRX_NATIVE_WIFI;
2635}
2636
Michal Kazior4b604552014-07-21 21:03:09 +03002637/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
2638 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03002639 */
Michal Kazior4b604552014-07-21 21:03:09 +03002640static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002641{
2642 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03002643 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002644 u8 *qos_ctl;
2645
2646 if (!ieee80211_is_data_qos(hdr->frame_control))
2647 return;
2648
2649 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02002650 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
2651 skb->data, (void *)qos_ctl - (void *)skb->data);
2652 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03002653
Michal Kazior8bad8dc2015-03-11 14:25:26 +01002654 /* Some firmware revisions don't handle sending QoS NullFunc well.
2655 * These frames are mainly used for CQM purposes so it doesn't really
2656 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03002657 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02002658 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01002659 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kaziorc21c64d2014-07-21 21:03:10 +03002660 cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01002661
2662 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002663}
2664
Michal Kaziord740d8f2015-03-30 09:51:51 +03002665static void ath10k_tx_h_8023(struct sk_buff *skb)
2666{
2667 struct ieee80211_hdr *hdr;
2668 struct rfc1042_hdr *rfc1042;
2669 struct ethhdr *eth;
2670 size_t hdrlen;
2671 u8 da[ETH_ALEN];
2672 u8 sa[ETH_ALEN];
2673 __be16 type;
2674
2675 hdr = (void *)skb->data;
2676 hdrlen = ieee80211_hdrlen(hdr->frame_control);
2677 rfc1042 = (void *)skb->data + hdrlen;
2678
2679 ether_addr_copy(da, ieee80211_get_DA(hdr));
2680 ether_addr_copy(sa, ieee80211_get_SA(hdr));
2681 type = rfc1042->snap_type;
2682
2683 skb_pull(skb, hdrlen + sizeof(*rfc1042));
2684 skb_push(skb, sizeof(*eth));
2685
2686 eth = (void *)skb->data;
2687 ether_addr_copy(eth->h_dest, da);
2688 ether_addr_copy(eth->h_source, sa);
2689 eth->h_proto = type;
2690}
2691
Michal Kazior4b604552014-07-21 21:03:09 +03002692static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
2693 struct ieee80211_vif *vif,
2694 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002695{
2696 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002697 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2698
2699 /* This is case only for P2P_GO */
2700 if (arvif->vdev_type != WMI_VDEV_TYPE_AP ||
2701 arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
2702 return;
2703
2704 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
2705 spin_lock_bh(&ar->data_lock);
2706 if (arvif->u.ap.noa_data)
2707 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
2708 GFP_ATOMIC))
2709 memcpy(skb_put(skb, arvif->u.ap.noa_len),
2710 arvif->u.ap.noa_data,
2711 arvif->u.ap.noa_len);
2712 spin_unlock_bh(&ar->data_lock);
2713 }
2714}
2715
Michal Kazior8d6d3622014-11-24 14:58:31 +01002716static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
2717{
2718 /* FIXME: Not really sure since when the behaviour changed. At some
2719 * point new firmware stopped requiring creation of peer entries for
2720 * offchannel tx (and actually creating them causes issues with wmi-htc
2721 * tx credit replenishment and reliability). Assuming it's at least 3.4
2722 * because that's when the `freq` was introduced to TX_FRM HTT command.
2723 */
2724 return !(ar->htt.target_version_major >= 3 &&
2725 ar->htt.target_version_minor >= 4);
2726}
2727
Michal Kaziord740d8f2015-03-30 09:51:51 +03002728static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002729{
Michal Kaziord740d8f2015-03-30 09:51:51 +03002730 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02002731 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002732
Michal Kaziord740d8f2015-03-30 09:51:51 +03002733 spin_lock_bh(&ar->data_lock);
2734
2735 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
2736 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
2737 ret = -ENOSPC;
2738 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02002739 }
2740
Michal Kaziord740d8f2015-03-30 09:51:51 +03002741 __skb_queue_tail(q, skb);
2742 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
2743
2744unlock:
2745 spin_unlock_bh(&ar->data_lock);
2746
2747 return ret;
2748}
2749
2750static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
2751{
2752 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
2753 struct ath10k_htt *htt = &ar->htt;
2754 int ret = 0;
2755
2756 switch (cb->txmode) {
2757 case ATH10K_HW_TXRX_RAW:
2758 case ATH10K_HW_TXRX_NATIVE_WIFI:
2759 case ATH10K_HW_TXRX_ETHERNET:
2760 ret = ath10k_htt_tx(htt, skb);
2761 break;
2762 case ATH10K_HW_TXRX_MGMT:
Bartosz Markowski5e00d312013-09-26 17:47:12 +02002763 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Michal Kaziord740d8f2015-03-30 09:51:51 +03002764 ar->fw_features))
2765 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
2766 else if (ar->htt.target_version_major >= 3)
2767 ret = ath10k_htt_tx(htt, skb);
2768 else
2769 ret = ath10k_htt_mgmt_tx(htt, skb);
2770 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02002771 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002772
2773 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002774 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
2775 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002776 ieee80211_free_txskb(ar->hw, skb);
2777 }
2778}
2779
2780void ath10k_offchan_tx_purge(struct ath10k *ar)
2781{
2782 struct sk_buff *skb;
2783
2784 for (;;) {
2785 skb = skb_dequeue(&ar->offchan_tx_queue);
2786 if (!skb)
2787 break;
2788
2789 ieee80211_free_txskb(ar->hw, skb);
2790 }
2791}
2792
2793void ath10k_offchan_tx_work(struct work_struct *work)
2794{
2795 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
2796 struct ath10k_peer *peer;
2797 struct ieee80211_hdr *hdr;
2798 struct sk_buff *skb;
2799 const u8 *peer_addr;
2800 int vdev_id;
2801 int ret;
2802
2803 /* FW requirement: We must create a peer before FW will send out
2804 * an offchannel frame. Otherwise the frame will be stuck and
2805 * never transmitted. We delete the peer upon tx completion.
2806 * It is unlikely that a peer for offchannel tx will already be
2807 * present. However it may be in some rare cases so account for that.
2808 * Otherwise we might remove a legitimate peer and break stuff. */
2809
2810 for (;;) {
2811 skb = skb_dequeue(&ar->offchan_tx_queue);
2812 if (!skb)
2813 break;
2814
2815 mutex_lock(&ar->conf_mutex);
2816
Michal Kazior7aa7a722014-08-25 12:09:38 +02002817 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002818 skb);
2819
2820 hdr = (struct ieee80211_hdr *)skb->data;
2821 peer_addr = ieee80211_get_DA(hdr);
Bartosz Markowski5e00d312013-09-26 17:47:12 +02002822 vdev_id = ATH10K_SKB_CB(skb)->vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002823
2824 spin_lock_bh(&ar->data_lock);
2825 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
2826 spin_unlock_bh(&ar->data_lock);
2827
2828 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03002829 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02002830 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002831 peer_addr, vdev_id);
2832
2833 if (!peer) {
Marek Puzyniak7390ed32015-03-30 09:51:52 +03002834 ret = ath10k_peer_create(ar, vdev_id, peer_addr,
2835 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002836 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002837 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002838 peer_addr, vdev_id, ret);
2839 }
2840
2841 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08002842 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002843 ar->offchan_tx_skb = skb;
2844 spin_unlock_bh(&ar->data_lock);
2845
Michal Kaziord740d8f2015-03-30 09:51:51 +03002846 ath10k_mac_tx(ar, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002847
2848 ret = wait_for_completion_timeout(&ar->offchan_tx_completed,
2849 3 * HZ);
Nicholas Mc Guire38e2a642015-01-08 13:27:34 +01002850 if (ret == 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002851 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002852 skb);
2853
2854 if (!peer) {
2855 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
2856 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002857 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002858 peer_addr, vdev_id, ret);
2859 }
2860
2861 mutex_unlock(&ar->conf_mutex);
2862 }
2863}
2864
Bartosz Markowski5e00d312013-09-26 17:47:12 +02002865void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
2866{
2867 struct sk_buff *skb;
2868
2869 for (;;) {
2870 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
2871 if (!skb)
2872 break;
2873
2874 ieee80211_free_txskb(ar->hw, skb);
2875 }
2876}
2877
2878void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
2879{
2880 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
2881 struct sk_buff *skb;
2882 int ret;
2883
2884 for (;;) {
2885 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
2886 if (!skb)
2887 break;
2888
2889 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01002890 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002891 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02002892 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01002893 ieee80211_free_txskb(ar->hw, skb);
2894 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02002895 }
2896}
2897
Kalle Valo5e3dd152013-06-12 20:52:10 +03002898/************/
2899/* Scanning */
2900/************/
2901
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002902void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002903{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002904 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002905
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002906 switch (ar->scan.state) {
2907 case ATH10K_SCAN_IDLE:
2908 break;
2909 case ATH10K_SCAN_RUNNING:
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002910 if (ar->scan.is_roc)
2911 ieee80211_remain_on_channel_expired(ar->hw);
John W. Linvillef6eaf1e2015-01-12 16:07:02 -05002912 /* fall through */
Michal Kazior7305d3e2014-11-24 14:58:33 +01002913 case ATH10K_SCAN_ABORTING:
2914 if (!ar->scan.is_roc)
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002915 ieee80211_scan_completed(ar->hw,
2916 (ar->scan.state ==
2917 ATH10K_SCAN_ABORTING));
2918 /* fall through */
2919 case ATH10K_SCAN_STARTING:
2920 ar->scan.state = ATH10K_SCAN_IDLE;
2921 ar->scan_channel = NULL;
2922 ath10k_offchan_tx_purge(ar);
2923 cancel_delayed_work(&ar->scan.timeout);
2924 complete_all(&ar->scan.completed);
2925 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002926 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002927}
Kalle Valo5e3dd152013-06-12 20:52:10 +03002928
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002929void ath10k_scan_finish(struct ath10k *ar)
2930{
2931 spin_lock_bh(&ar->data_lock);
2932 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002933 spin_unlock_bh(&ar->data_lock);
2934}
2935
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002936static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002937{
2938 struct wmi_stop_scan_arg arg = {
2939 .req_id = 1, /* FIXME */
2940 .req_type = WMI_SCAN_STOP_ONE,
2941 .u.scan_id = ATH10K_SCAN_ID,
2942 };
2943 int ret;
2944
2945 lockdep_assert_held(&ar->conf_mutex);
2946
Kalle Valo5e3dd152013-06-12 20:52:10 +03002947 ret = ath10k_wmi_stop_scan(ar, &arg);
2948 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002949 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002950 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002951 }
2952
Kalle Valo5e3dd152013-06-12 20:52:10 +03002953 ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002954 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002955 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03002956 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002957 } else if (ret > 0) {
2958 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002959 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002960
2961out:
2962 /* Scan state should be updated upon scan completion but in case
2963 * firmware fails to deliver the event (for whatever reason) it is
2964 * desired to clean up scan state anyway. Firmware may have just
2965 * dropped the scan completion event delivery due to transport pipe
2966 * being overflown with data and/or it can recover on its own before
2967 * next scan request is submitted.
2968 */
2969 spin_lock_bh(&ar->data_lock);
2970 if (ar->scan.state != ATH10K_SCAN_IDLE)
2971 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002972 spin_unlock_bh(&ar->data_lock);
2973
2974 return ret;
2975}
2976
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002977static void ath10k_scan_abort(struct ath10k *ar)
2978{
2979 int ret;
2980
2981 lockdep_assert_held(&ar->conf_mutex);
2982
2983 spin_lock_bh(&ar->data_lock);
2984
2985 switch (ar->scan.state) {
2986 case ATH10K_SCAN_IDLE:
2987 /* This can happen if timeout worker kicked in and called
2988 * abortion while scan completion was being processed.
2989 */
2990 break;
2991 case ATH10K_SCAN_STARTING:
2992 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02002993 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02002994 ath10k_scan_state_str(ar->scan.state),
2995 ar->scan.state);
2996 break;
2997 case ATH10K_SCAN_RUNNING:
2998 ar->scan.state = ATH10K_SCAN_ABORTING;
2999 spin_unlock_bh(&ar->data_lock);
3000
3001 ret = ath10k_scan_stop(ar);
3002 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003003 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003004
3005 spin_lock_bh(&ar->data_lock);
3006 break;
3007 }
3008
3009 spin_unlock_bh(&ar->data_lock);
3010}
3011
3012void ath10k_scan_timeout_work(struct work_struct *work)
3013{
3014 struct ath10k *ar = container_of(work, struct ath10k,
3015 scan.timeout.work);
3016
3017 mutex_lock(&ar->conf_mutex);
3018 ath10k_scan_abort(ar);
3019 mutex_unlock(&ar->conf_mutex);
3020}
3021
Kalle Valo5e3dd152013-06-12 20:52:10 +03003022static int ath10k_start_scan(struct ath10k *ar,
3023 const struct wmi_start_scan_arg *arg)
3024{
3025 int ret;
3026
3027 lockdep_assert_held(&ar->conf_mutex);
3028
3029 ret = ath10k_wmi_start_scan(ar, arg);
3030 if (ret)
3031 return ret;
3032
Kalle Valo5e3dd152013-06-12 20:52:10 +03003033 ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ);
3034 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003035 ret = ath10k_scan_stop(ar);
3036 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003037 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003038
3039 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003040 }
3041
Ben Greear2f9eec02015-02-15 16:50:38 +02003042 /* If we failed to start the scan, return error code at
3043 * this point. This is probably due to some issue in the
3044 * firmware, but no need to wedge the driver due to that...
3045 */
3046 spin_lock_bh(&ar->data_lock);
3047 if (ar->scan.state == ATH10K_SCAN_IDLE) {
3048 spin_unlock_bh(&ar->data_lock);
3049 return -EINVAL;
3050 }
3051 spin_unlock_bh(&ar->data_lock);
3052
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003053 /* Add a 200ms margin to account for event/command processing */
3054 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
3055 msecs_to_jiffies(arg->max_scan_time+200));
Kalle Valo5e3dd152013-06-12 20:52:10 +03003056 return 0;
3057}
3058
3059/**********************/
3060/* mac80211 callbacks */
3061/**********************/
3062
3063static void ath10k_tx(struct ieee80211_hw *hw,
3064 struct ieee80211_tx_control *control,
3065 struct sk_buff *skb)
3066{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003067 struct ath10k *ar = hw->priv;
Michal Kazior4b604552014-07-21 21:03:09 +03003068 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3069 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003070 struct ieee80211_sta *sta = control->sta;
Michal Kazior4b604552014-07-21 21:03:09 +03003071 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003072 __le16 fc = hdr->frame_control;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003073
3074 /* We should disable CCK RATE due to P2P */
3075 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003076 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003077
Michal Kazior4b604552014-07-21 21:03:09 +03003078 ATH10K_SKB_CB(skb)->htt.is_offchan = false;
Michal Kazior6fcafef2015-03-30 09:51:51 +03003079 ATH10K_SKB_CB(skb)->htt.freq = 0;
Michal Kazior4b604552014-07-21 21:03:09 +03003080 ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
Michal Kazior2b37c292014-09-02 11:00:22 +03003081 ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003082 ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003083 ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003084
Michal Kaziord740d8f2015-03-30 09:51:51 +03003085 switch (ATH10K_SKB_CB(skb)->txmode) {
3086 case ATH10K_HW_TXRX_MGMT:
3087 case ATH10K_HW_TXRX_NATIVE_WIFI:
Michal Kazior4b604552014-07-21 21:03:09 +03003088 ath10k_tx_h_nwifi(hw, skb);
Michal Kazior4b604552014-07-21 21:03:09 +03003089 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3090 ath10k_tx_h_seq_no(vif, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003091 break;
3092 case ATH10K_HW_TXRX_ETHERNET:
3093 ath10k_tx_h_8023(skb);
3094 break;
3095 case ATH10K_HW_TXRX_RAW:
3096 /* FIXME: Packet injection isn't implemented. It should be
3097 * doable with firmware 10.2 on qca988x.
3098 */
3099 WARN_ON_ONCE(1);
3100 ieee80211_free_txskb(hw, skb);
3101 return;
Michal Kaziorcf84bd42013-07-16 11:04:54 +02003102 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003103
Kalle Valo5e3dd152013-06-12 20:52:10 +03003104 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3105 spin_lock_bh(&ar->data_lock);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003106 ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003107 ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003108 spin_unlock_bh(&ar->data_lock);
3109
Michal Kazior8d6d3622014-11-24 14:58:31 +01003110 if (ath10k_mac_need_offchan_tx_work(ar)) {
3111 ATH10K_SKB_CB(skb)->htt.freq = 0;
3112 ATH10K_SKB_CB(skb)->htt.is_offchan = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003113
Michal Kazior8d6d3622014-11-24 14:58:31 +01003114 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
3115 skb);
3116
3117 skb_queue_tail(&ar->offchan_tx_queue, skb);
3118 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3119 return;
3120 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003121 }
3122
Michal Kaziord740d8f2015-03-30 09:51:51 +03003123 ath10k_mac_tx(ar, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003124}
3125
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003126/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01003127void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003128{
3129 /* make sure rcu-protected mac80211 tx path itself is drained */
3130 synchronize_net();
3131
3132 ath10k_offchan_tx_purge(ar);
3133 ath10k_mgmt_over_wmi_tx_purge(ar);
3134
3135 cancel_work_sync(&ar->offchan_tx_work);
3136 cancel_work_sync(&ar->wmi_mgmt_tx_work);
3137}
3138
Michal Kazioraffd3212013-07-16 09:54:35 +02003139void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02003140{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03003141 struct ath10k_vif *arvif;
3142
Michal Kazior818bdd12013-07-16 09:38:57 +02003143 lockdep_assert_held(&ar->conf_mutex);
3144
Michal Kazior19337472014-08-28 12:58:16 +02003145 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
3146 ar->filter_flags = 0;
3147 ar->monitor = false;
3148
3149 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03003150 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02003151
3152 ar->monitor_started = false;
Michal Kazior1bbc0972014-04-08 09:45:47 +03003153
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003154 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02003155 ath10k_peer_cleanup_all(ar);
3156 ath10k_core_stop(ar);
3157 ath10k_hif_power_down(ar);
3158
3159 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03003160 list_for_each_entry(arvif, &ar->arvifs, list)
3161 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02003162 spin_unlock_bh(&ar->data_lock);
3163}
3164
Ben Greear46acf7b2014-05-16 17:15:38 +03003165static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
3166{
3167 struct ath10k *ar = hw->priv;
3168
3169 mutex_lock(&ar->conf_mutex);
3170
3171 if (ar->cfg_tx_chainmask) {
3172 *tx_ant = ar->cfg_tx_chainmask;
3173 *rx_ant = ar->cfg_rx_chainmask;
3174 } else {
3175 *tx_ant = ar->supp_tx_chainmask;
3176 *rx_ant = ar->supp_rx_chainmask;
3177 }
3178
3179 mutex_unlock(&ar->conf_mutex);
3180
3181 return 0;
3182}
3183
Ben Greear5572a952014-11-24 16:22:10 +02003184static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
3185{
3186 /* It is not clear that allowing gaps in chainmask
3187 * is helpful. Probably it will not do what user
3188 * is hoping for, so warn in that case.
3189 */
3190 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
3191 return;
3192
3193 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
3194 dbg, cm);
3195}
3196
Ben Greear46acf7b2014-05-16 17:15:38 +03003197static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
3198{
3199 int ret;
3200
3201 lockdep_assert_held(&ar->conf_mutex);
3202
Ben Greear5572a952014-11-24 16:22:10 +02003203 ath10k_check_chain_mask(ar, tx_ant, "tx");
3204 ath10k_check_chain_mask(ar, rx_ant, "rx");
3205
Ben Greear46acf7b2014-05-16 17:15:38 +03003206 ar->cfg_tx_chainmask = tx_ant;
3207 ar->cfg_rx_chainmask = rx_ant;
3208
3209 if ((ar->state != ATH10K_STATE_ON) &&
3210 (ar->state != ATH10K_STATE_RESTARTED))
3211 return 0;
3212
3213 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
3214 tx_ant);
3215 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003216 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03003217 ret, tx_ant);
3218 return ret;
3219 }
3220
3221 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
3222 rx_ant);
3223 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003224 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03003225 ret, rx_ant);
3226 return ret;
3227 }
3228
3229 return 0;
3230}
3231
3232static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
3233{
3234 struct ath10k *ar = hw->priv;
3235 int ret;
3236
3237 mutex_lock(&ar->conf_mutex);
3238 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
3239 mutex_unlock(&ar->conf_mutex);
3240 return ret;
3241}
3242
Kalle Valo5e3dd152013-06-12 20:52:10 +03003243static int ath10k_start(struct ieee80211_hw *hw)
3244{
3245 struct ath10k *ar = hw->priv;
Michal Kazior818bdd12013-07-16 09:38:57 +02003246 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003247
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003248 /*
3249 * This makes sense only when restarting hw. It is harmless to call
3250 * uncoditionally. This is necessary to make sure no HTT/WMI tx
3251 * commands will be submitted while restarting.
3252 */
3253 ath10k_drain_tx(ar);
3254
Michal Kazior548db542013-07-05 16:15:15 +03003255 mutex_lock(&ar->conf_mutex);
3256
Michal Kaziorc5058f52014-05-26 12:46:03 +03003257 switch (ar->state) {
3258 case ATH10K_STATE_OFF:
3259 ar->state = ATH10K_STATE_ON;
3260 break;
3261 case ATH10K_STATE_RESTARTING:
3262 ath10k_halt(ar);
3263 ar->state = ATH10K_STATE_RESTARTED;
3264 break;
3265 case ATH10K_STATE_ON:
3266 case ATH10K_STATE_RESTARTED:
3267 case ATH10K_STATE_WEDGED:
3268 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02003269 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03003270 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03003271 case ATH10K_STATE_UTF:
3272 ret = -EBUSY;
3273 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02003274 }
3275
3276 ret = ath10k_hif_power_up(ar);
3277 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003278 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003279 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02003280 }
3281
Kalle Valo43d2a302014-09-10 18:23:30 +03003282 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02003283 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003284 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003285 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02003286 }
3287
Bartosz Markowski226a3392013-09-26 17:47:16 +02003288 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03003289 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003290 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003291 goto err_core_stop;
3292 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003293
Michal Kaziorc4dd0d02013-11-13 11:05:10 +01003294 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03003295 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003296 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003297 goto err_core_stop;
3298 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003299
Ben Greear46acf7b2014-05-16 17:15:38 +03003300 if (ar->cfg_tx_chainmask)
3301 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask,
3302 ar->cfg_rx_chainmask);
3303
Marek Puzyniakab6258e2014-01-29 15:03:31 +02003304 /*
3305 * By default FW set ARP frames ac to voice (6). In that case ARP
3306 * exchange is not working properly for UAPSD enabled AP. ARP requests
3307 * which arrives with access category 0 are processed by network stack
3308 * and send back with access category 0, but FW changes access category
3309 * to 6. Set ARP frames access category to best effort (0) solves
3310 * this problem.
3311 */
3312
3313 ret = ath10k_wmi_pdev_set_param(ar,
3314 ar->wmi.pdev_param->arp_ac_override, 0);
3315 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003316 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02003317 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003318 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02003319 }
3320
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05303321 ret = ath10k_wmi_pdev_set_param(ar,
3322 ar->wmi.pdev_param->ani_enable, 1);
3323 if (ret) {
3324 ath10k_warn(ar, "failed to enable ani by default: %d\n",
3325 ret);
3326 goto err_core_stop;
3327 }
3328
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05303329 ar->ani_enabled = true;
3330
Michal Kaziord6500972014-04-08 09:56:09 +03003331 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003332 ath10k_regd_update(ar);
3333
Simon Wunderlich855aed12014-08-02 09:12:54 +03003334 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05303335 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03003336
Michal Kaziorae254432014-05-26 12:46:02 +03003337 mutex_unlock(&ar->conf_mutex);
3338 return 0;
3339
3340err_core_stop:
3341 ath10k_core_stop(ar);
3342
3343err_power_down:
3344 ath10k_hif_power_down(ar);
3345
3346err_off:
3347 ar->state = ATH10K_STATE_OFF;
3348
3349err:
Michal Kazior548db542013-07-05 16:15:15 +03003350 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01003351 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003352}
3353
3354static void ath10k_stop(struct ieee80211_hw *hw)
3355{
3356 struct ath10k *ar = hw->priv;
3357
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003358 ath10k_drain_tx(ar);
3359
Michal Kazior548db542013-07-05 16:15:15 +03003360 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03003361 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02003362 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03003363 ar->state = ATH10K_STATE_OFF;
3364 }
Michal Kazior548db542013-07-05 16:15:15 +03003365 mutex_unlock(&ar->conf_mutex);
3366
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003367 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02003368 cancel_work_sync(&ar->restart_work);
3369}
3370
Michal Kaziorad088bf2013-10-16 15:44:46 +03003371static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02003372{
Michal Kaziorad088bf2013-10-16 15:44:46 +03003373 struct ath10k_vif *arvif;
3374 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02003375
3376 lockdep_assert_held(&ar->conf_mutex);
3377
Michal Kaziorad088bf2013-10-16 15:44:46 +03003378 list_for_each_entry(arvif, &ar->arvifs, list) {
3379 ret = ath10k_mac_vif_setup_ps(arvif);
3380 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003381 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03003382 break;
3383 }
3384 }
Michal Kazioraffd3212013-07-16 09:54:35 +02003385
Michal Kaziorad088bf2013-10-16 15:44:46 +03003386 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003387}
3388
Michal Kaziorc930f742014-01-23 11:38:25 +01003389static const char *chandef_get_width(enum nl80211_chan_width width)
3390{
3391 switch (width) {
3392 case NL80211_CHAN_WIDTH_20_NOHT:
3393 return "20 (noht)";
3394 case NL80211_CHAN_WIDTH_20:
3395 return "20";
3396 case NL80211_CHAN_WIDTH_40:
3397 return "40";
3398 case NL80211_CHAN_WIDTH_80:
3399 return "80";
3400 case NL80211_CHAN_WIDTH_80P80:
3401 return "80+80";
3402 case NL80211_CHAN_WIDTH_160:
3403 return "160";
3404 case NL80211_CHAN_WIDTH_5:
3405 return "5";
3406 case NL80211_CHAN_WIDTH_10:
3407 return "10";
3408 }
3409 return "?";
3410}
3411
3412static void ath10k_config_chan(struct ath10k *ar)
3413{
3414 struct ath10k_vif *arvif;
Michal Kaziorc930f742014-01-23 11:38:25 +01003415 int ret;
3416
3417 lockdep_assert_held(&ar->conf_mutex);
3418
Michal Kazior7aa7a722014-08-25 12:09:38 +02003419 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kaziorc930f742014-01-23 11:38:25 +01003420 "mac config channel to %dMHz (cf1 %dMHz cf2 %dMHz width %s)\n",
3421 ar->chandef.chan->center_freq,
3422 ar->chandef.center_freq1,
3423 ar->chandef.center_freq2,
3424 chandef_get_width(ar->chandef.width));
3425
3426 /* First stop monitor interface. Some FW versions crash if there's a
3427 * lone monitor interface. */
Michal Kazior1bbc0972014-04-08 09:45:47 +03003428 if (ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02003429 ath10k_monitor_stop(ar);
Michal Kaziorc930f742014-01-23 11:38:25 +01003430
3431 list_for_each_entry(arvif, &ar->arvifs, list) {
3432 if (!arvif->is_started)
3433 continue;
3434
Michal Kaziordc55e302014-07-29 12:53:36 +03003435 if (!arvif->is_up)
3436 continue;
3437
Michal Kaziorc930f742014-01-23 11:38:25 +01003438 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
3439 continue;
3440
Michal Kaziordc55e302014-07-29 12:53:36 +03003441 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kaziorc930f742014-01-23 11:38:25 +01003442 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003443 ath10k_warn(ar, "failed to down vdev %d: %d\n",
Michal Kaziorc930f742014-01-23 11:38:25 +01003444 arvif->vdev_id, ret);
3445 continue;
3446 }
3447 }
3448
Michal Kaziordc55e302014-07-29 12:53:36 +03003449 /* all vdevs are downed now - attempt to restart and re-up them */
Michal Kaziorc930f742014-01-23 11:38:25 +01003450
3451 list_for_each_entry(arvif, &ar->arvifs, list) {
3452 if (!arvif->is_started)
3453 continue;
3454
3455 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
3456 continue;
3457
Michal Kazior81a9a172015-03-05 16:02:17 +02003458 ret = ath10k_mac_setup_bcn_tmpl(arvif);
3459 if (ret)
3460 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
3461 ret);
3462
3463 ret = ath10k_mac_setup_prb_tmpl(arvif);
3464 if (ret)
3465 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
3466 ret);
3467
Michal Kaziordc55e302014-07-29 12:53:36 +03003468 ret = ath10k_vdev_restart(arvif);
Michal Kaziorc930f742014-01-23 11:38:25 +01003469 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003470 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
Michal Kaziorc930f742014-01-23 11:38:25 +01003471 arvif->vdev_id, ret);
3472 continue;
3473 }
3474
3475 if (!arvif->is_up)
3476 continue;
3477
3478 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
3479 arvif->bssid);
3480 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003481 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
Michal Kaziorc930f742014-01-23 11:38:25 +01003482 arvif->vdev_id, ret);
3483 continue;
3484 }
3485 }
3486
Michal Kazior19337472014-08-28 12:58:16 +02003487 ath10k_monitor_recalc(ar);
Michal Kaziorc930f742014-01-23 11:38:25 +01003488}
3489
Michal Kazior7d9d5582014-10-21 10:40:15 +03003490static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
3491{
3492 int ret;
3493 u32 param;
3494
3495 lockdep_assert_held(&ar->conf_mutex);
3496
3497 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
3498
3499 param = ar->wmi.pdev_param->txpower_limit2g;
3500 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
3501 if (ret) {
3502 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
3503 txpower, ret);
3504 return ret;
3505 }
3506
3507 param = ar->wmi.pdev_param->txpower_limit5g;
3508 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
3509 if (ret) {
3510 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
3511 txpower, ret);
3512 return ret;
3513 }
3514
3515 return 0;
3516}
3517
3518static int ath10k_mac_txpower_recalc(struct ath10k *ar)
3519{
3520 struct ath10k_vif *arvif;
3521 int ret, txpower = -1;
3522
3523 lockdep_assert_held(&ar->conf_mutex);
3524
3525 list_for_each_entry(arvif, &ar->arvifs, list) {
3526 WARN_ON(arvif->txpower < 0);
3527
3528 if (txpower == -1)
3529 txpower = arvif->txpower;
3530 else
3531 txpower = min(txpower, arvif->txpower);
3532 }
3533
3534 if (WARN_ON(txpower == -1))
3535 return -EINVAL;
3536
3537 ret = ath10k_mac_txpower_setup(ar, txpower);
3538 if (ret) {
3539 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
3540 txpower, ret);
3541 return ret;
3542 }
3543
3544 return 0;
3545}
3546
Kalle Valo5e3dd152013-06-12 20:52:10 +03003547static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
3548{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003549 struct ath10k *ar = hw->priv;
3550 struct ieee80211_conf *conf = &hw->conf;
3551 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003552
3553 mutex_lock(&ar->conf_mutex);
3554
3555 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003556 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kaziord6500972014-04-08 09:56:09 +03003557 "mac config channel %dMHz flags 0x%x radar %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02003558 conf->chandef.chan->center_freq,
Michal Kaziord6500972014-04-08 09:56:09 +03003559 conf->chandef.chan->flags,
3560 conf->radar_enabled);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02003561
Kalle Valo5e3dd152013-06-12 20:52:10 +03003562 spin_lock_bh(&ar->data_lock);
3563 ar->rx_channel = conf->chandef.chan;
3564 spin_unlock_bh(&ar->data_lock);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02003565
Michal Kaziord6500972014-04-08 09:56:09 +03003566 ar->radar_enabled = conf->radar_enabled;
3567 ath10k_recalc_radar_detection(ar);
Michal Kaziorc930f742014-01-23 11:38:25 +01003568
3569 if (!cfg80211_chandef_identical(&ar->chandef, &conf->chandef)) {
3570 ar->chandef = conf->chandef;
3571 ath10k_config_chan(ar);
3572 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003573 }
3574
Michal Kazioraffd3212013-07-16 09:54:35 +02003575 if (changed & IEEE80211_CONF_CHANGE_PS)
3576 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003577
3578 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02003579 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
3580 ret = ath10k_monitor_recalc(ar);
3581 if (ret)
3582 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003583 }
3584
3585 mutex_unlock(&ar->conf_mutex);
3586 return ret;
3587}
3588
Ben Greear5572a952014-11-24 16:22:10 +02003589static u32 get_nss_from_chainmask(u16 chain_mask)
3590{
3591 if ((chain_mask & 0x15) == 0x15)
3592 return 4;
3593 else if ((chain_mask & 0x7) == 0x7)
3594 return 3;
3595 else if ((chain_mask & 0x3) == 0x3)
3596 return 2;
3597 return 1;
3598}
3599
Kalle Valo5e3dd152013-06-12 20:52:10 +03003600/*
3601 * TODO:
3602 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
3603 * because we will send mgmt frames without CCK. This requirement
3604 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
3605 * in the TX packet.
3606 */
3607static int ath10k_add_interface(struct ieee80211_hw *hw,
3608 struct ieee80211_vif *vif)
3609{
3610 struct ath10k *ar = hw->priv;
3611 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3612 enum wmi_sta_powersave_param param;
3613 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02003614 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003615 int bit;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02003616 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003617
Johannes Berg848955c2014-11-11 12:48:42 +01003618 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
3619
Kalle Valo5e3dd152013-06-12 20:52:10 +03003620 mutex_lock(&ar->conf_mutex);
3621
Michal Kazior0dbd09e2013-07-31 10:55:14 +02003622 memset(arvif, 0, sizeof(*arvif));
3623
Kalle Valo5e3dd152013-06-12 20:52:10 +03003624 arvif->ar = ar;
3625 arvif->vif = vif;
3626
Ben Greeare63b33f2013-10-22 14:54:14 -07003627 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02003628 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02003629 INIT_DELAYED_WORK(&arvif->connection_loss_work,
3630 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03003631
Ben Greeara9aefb32014-08-12 11:02:19 +03003632 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003633 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003634 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03003635 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003636 }
Ben Greear16c11172014-09-23 14:17:16 -07003637 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003638
Ben Greear16c11172014-09-23 14:17:16 -07003639 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
3640 bit, ar->free_vdev_map);
3641
3642 arvif->vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003643 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003644
Kalle Valo5e3dd152013-06-12 20:52:10 +03003645 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01003646 case NL80211_IFTYPE_P2P_DEVICE:
3647 arvif->vdev_type = WMI_VDEV_TYPE_STA;
3648 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
3649 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003650 case NL80211_IFTYPE_UNSPECIFIED:
3651 case NL80211_IFTYPE_STATION:
3652 arvif->vdev_type = WMI_VDEV_TYPE_STA;
3653 if (vif->p2p)
3654 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT;
3655 break;
3656 case NL80211_IFTYPE_ADHOC:
3657 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
3658 break;
3659 case NL80211_IFTYPE_AP:
3660 arvif->vdev_type = WMI_VDEV_TYPE_AP;
3661
3662 if (vif->p2p)
3663 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO;
3664 break;
3665 case NL80211_IFTYPE_MONITOR:
3666 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
3667 break;
3668 default:
3669 WARN_ON(1);
3670 break;
3671 }
3672
Michal Kazior64badcb2014-09-18 11:18:02 +03003673 /* Some firmware revisions don't wait for beacon tx completion before
3674 * sending another SWBA event. This could lead to hardware using old
3675 * (freed) beacon data in some cases, e.g. tx credit starvation
3676 * combined with missed TBTT. This is very very rare.
3677 *
3678 * On non-IOMMU-enabled hosts this could be a possible security issue
3679 * because hw could beacon some random data on the air. On
3680 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
3681 * device would crash.
3682 *
3683 * Since there are no beacon tx completions (implicit nor explicit)
3684 * propagated to host the only workaround for this is to allocate a
3685 * DMA-coherent buffer for a lifetime of a vif and use it for all
3686 * beacon tx commands. Worst case for this approach is some beacons may
3687 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
3688 */
3689 if (vif->type == NL80211_IFTYPE_ADHOC ||
3690 vif->type == NL80211_IFTYPE_AP) {
3691 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
3692 IEEE80211_MAX_FRAME_LEN,
3693 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05303694 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03003695 if (!arvif->beacon_buf) {
3696 ret = -ENOMEM;
3697 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
3698 ret);
3699 goto err;
3700 }
3701 }
3702
3703 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
3704 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
3705 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003706
3707 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
3708 arvif->vdev_subtype, vif->addr);
3709 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003710 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003711 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003712 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003713 }
3714
Ben Greear16c11172014-09-23 14:17:16 -07003715 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Michal Kazior05791192013-10-16 15:44:45 +03003716 list_add(&arvif->list, &ar->arvifs);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003717
Michal Kazior46725b152015-01-28 09:57:49 +02003718 /* It makes no sense to have firmware do keepalives. mac80211 already
3719 * takes care of this with idle connection polling.
3720 */
3721 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003722 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02003723 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003724 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003725 goto err_vdev_delete;
3726 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003727
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02003728 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003729
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02003730 vdev_param = ar->wmi.vdev_param->tx_encap_type;
3731 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003732 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02003733 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03003734 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003735 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003736 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003737 goto err_vdev_delete;
3738 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003739
Ben Greear5572a952014-11-24 16:22:10 +02003740 if (ar->cfg_tx_chainmask) {
3741 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
3742
3743 vdev_param = ar->wmi.vdev_param->nss;
3744 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
3745 nss);
3746 if (ret) {
3747 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
3748 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
3749 ret);
3750 goto err_vdev_delete;
3751 }
3752 }
3753
Kalle Valo5e3dd152013-06-12 20:52:10 +03003754 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003755 ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr,
3756 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003757 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003758 ath10k_warn(ar, "failed to create vdev %i peer for AP: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003759 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003760 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003761 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01003762
Kalle Valo5a13e762014-01-20 11:01:46 +02003763 ret = ath10k_mac_set_kickout(arvif);
3764 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003765 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003766 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02003767 goto err_peer_delete;
3768 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003769 }
3770
3771 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
3772 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
3773 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
3774 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
3775 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003776 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003777 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003778 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003779 goto err_peer_delete;
3780 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003781
Michal Kazior9f9b5742014-12-12 12:41:36 +01003782 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003783 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01003784 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003785 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003786 goto err_peer_delete;
3787 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003788
Michal Kazior9f9b5742014-12-12 12:41:36 +01003789 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003790 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01003791 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003792 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003793 goto err_peer_delete;
3794 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003795 }
3796
Michal Kazior424121c2013-07-22 14:13:31 +02003797 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003798 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003799 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03003800 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003801 goto err_peer_delete;
3802 }
Michal Kazior679c54a2013-07-05 16:15:04 +03003803
Michal Kazior424121c2013-07-22 14:13:31 +02003804 ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003805 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003806 ath10k_warn(ar, "failed to set frag threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03003807 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003808 goto err_peer_delete;
3809 }
Michal Kazior679c54a2013-07-05 16:15:04 +03003810
Michal Kazior7d9d5582014-10-21 10:40:15 +03003811 arvif->txpower = vif->bss_conf.txpower;
3812 ret = ath10k_mac_txpower_recalc(ar);
3813 if (ret) {
3814 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
3815 goto err_peer_delete;
3816 }
3817
Kalle Valo5e3dd152013-06-12 20:52:10 +03003818 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003819 return 0;
3820
3821err_peer_delete:
3822 if (arvif->vdev_type == WMI_VDEV_TYPE_AP)
3823 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
3824
3825err_vdev_delete:
3826 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07003827 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03003828 list_del(&arvif->list);
Michal Kazior9dad14a2013-10-16 15:44:45 +03003829
3830err:
Michal Kazior64badcb2014-09-18 11:18:02 +03003831 if (arvif->beacon_buf) {
3832 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
3833 arvif->beacon_buf, arvif->beacon_paddr);
3834 arvif->beacon_buf = NULL;
3835 }
3836
Michal Kazior9dad14a2013-10-16 15:44:45 +03003837 mutex_unlock(&ar->conf_mutex);
3838
Kalle Valo5e3dd152013-06-12 20:52:10 +03003839 return ret;
3840}
3841
3842static void ath10k_remove_interface(struct ieee80211_hw *hw,
3843 struct ieee80211_vif *vif)
3844{
3845 struct ath10k *ar = hw->priv;
3846 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3847 int ret;
3848
Michal Kazior81a9a172015-03-05 16:02:17 +02003849 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02003850 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02003851
Sujith Manoharan5d011f52014-11-25 11:47:00 +05303852 mutex_lock(&ar->conf_mutex);
3853
Michal Kaziored543882013-09-13 14:16:56 +02003854 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03003855 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02003856 spin_unlock_bh(&ar->data_lock);
3857
Simon Wunderlich855aed12014-08-02 09:12:54 +03003858 ret = ath10k_spectral_vif_stop(arvif);
3859 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003860 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03003861 arvif->vdev_id, ret);
3862
Ben Greear16c11172014-09-23 14:17:16 -07003863 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03003864 list_del(&arvif->list);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003865
3866 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Michal Kazior2c512052015-02-15 16:50:40 +02003867 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
3868 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003869 if (ret)
Michal Kazior2c512052015-02-15 16:50:40 +02003870 ath10k_warn(ar, "failed to submit AP self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003871 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003872
3873 kfree(arvif->u.ap.noa_data);
3874 }
3875
Michal Kazior7aa7a722014-08-25 12:09:38 +02003876 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03003877 arvif->vdev_id);
3878
Kalle Valo5e3dd152013-06-12 20:52:10 +03003879 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
3880 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003881 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02003882 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003883
Michal Kazior2c512052015-02-15 16:50:40 +02003884 /* Some firmware revisions don't notify host about self-peer removal
3885 * until after associated vdev is deleted.
3886 */
3887 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
3888 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
3889 vif->addr);
3890 if (ret)
3891 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
3892 arvif->vdev_id, ret);
3893
3894 spin_lock_bh(&ar->data_lock);
3895 ar->num_peers--;
3896 spin_unlock_bh(&ar->data_lock);
3897 }
3898
Kalle Valo5e3dd152013-06-12 20:52:10 +03003899 ath10k_peer_cleanup(ar, arvif->vdev_id);
3900
3901 mutex_unlock(&ar->conf_mutex);
3902}
3903
3904/*
3905 * FIXME: Has to be verified.
3906 */
3907#define SUPPORTED_FILTERS \
3908 (FIF_PROMISC_IN_BSS | \
3909 FIF_ALLMULTI | \
3910 FIF_CONTROL | \
3911 FIF_PSPOLL | \
3912 FIF_OTHER_BSS | \
3913 FIF_BCN_PRBRESP_PROMISC | \
3914 FIF_PROBE_REQ | \
3915 FIF_FCSFAIL)
3916
3917static void ath10k_configure_filter(struct ieee80211_hw *hw,
3918 unsigned int changed_flags,
3919 unsigned int *total_flags,
3920 u64 multicast)
3921{
3922 struct ath10k *ar = hw->priv;
3923 int ret;
3924
3925 mutex_lock(&ar->conf_mutex);
3926
3927 changed_flags &= SUPPORTED_FILTERS;
3928 *total_flags &= SUPPORTED_FILTERS;
3929 ar->filter_flags = *total_flags;
3930
Michal Kazior19337472014-08-28 12:58:16 +02003931 ret = ath10k_monitor_recalc(ar);
3932 if (ret)
3933 ath10k_warn(ar, "failed to recalc montior: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003934
3935 mutex_unlock(&ar->conf_mutex);
3936}
3937
3938static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
3939 struct ieee80211_vif *vif,
3940 struct ieee80211_bss_conf *info,
3941 u32 changed)
3942{
3943 struct ath10k *ar = hw->priv;
3944 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3945 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03003946 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003947
3948 mutex_lock(&ar->conf_mutex);
3949
3950 if (changed & BSS_CHANGED_IBSS)
3951 ath10k_control_ibss(arvif, info, vif->addr);
3952
3953 if (changed & BSS_CHANGED_BEACON_INT) {
3954 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02003955 vdev_param = ar->wmi.vdev_param->beacon_interval;
3956 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003957 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02003958 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03003959 "mac vdev %d beacon_interval %d\n",
3960 arvif->vdev_id, arvif->beacon_interval);
3961
Kalle Valo5e3dd152013-06-12 20:52:10 +03003962 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003963 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02003964 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003965 }
3966
3967 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003968 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03003969 "vdev %d set beacon tx mode to staggered\n",
3970 arvif->vdev_id);
3971
Bartosz Markowski226a3392013-09-26 17:47:16 +02003972 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
3973 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003974 WMI_BEACON_STAGGERED_MODE);
3975 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003976 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02003977 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02003978
3979 ret = ath10k_mac_setup_bcn_tmpl(arvif);
3980 if (ret)
3981 ath10k_warn(ar, "failed to update beacon template: %d\n",
3982 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003983 }
3984
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02003985 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
3986 ret = ath10k_mac_setup_prb_tmpl(arvif);
3987 if (ret)
3988 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
3989 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003990 }
3991
Michal Kaziorba2479f2015-01-24 12:14:51 +02003992 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003993 arvif->dtim_period = info->dtim_period;
3994
Michal Kazior7aa7a722014-08-25 12:09:38 +02003995 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03003996 "mac vdev %d dtim_period %d\n",
3997 arvif->vdev_id, arvif->dtim_period);
3998
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02003999 vdev_param = ar->wmi.vdev_param->dtim_period;
4000 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004001 arvif->dtim_period);
4002 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004003 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004004 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004005 }
4006
4007 if (changed & BSS_CHANGED_SSID &&
4008 vif->type == NL80211_IFTYPE_AP) {
4009 arvif->u.ap.ssid_len = info->ssid_len;
4010 if (info->ssid_len)
4011 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
4012 arvif->u.ap.hidden_ssid = info->hidden_ssid;
4013 }
4014
Michal Kazior077efc82014-10-21 10:10:29 +03004015 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
4016 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004017
4018 if (changed & BSS_CHANGED_BEACON_ENABLED)
4019 ath10k_control_beaconing(arvif, info);
4020
4021 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004022 arvif->use_cts_prot = info->use_cts_prot;
Michal Kazior7aa7a722014-08-25 12:09:38 +02004023 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004024 arvif->vdev_id, info->use_cts_prot);
Kalle Valo60c3daa2013-09-08 17:56:07 +03004025
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004026 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004027 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004028 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004029 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01004030
4031 vdev_param = ar->wmi.vdev_param->protection_mode;
4032 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4033 info->use_cts_prot ? 1 : 0);
4034 if (ret)
4035 ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
4036 info->use_cts_prot, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004037 }
4038
4039 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004040 if (info->use_short_slot)
4041 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
4042
4043 else
4044 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
4045
Michal Kazior7aa7a722014-08-25 12:09:38 +02004046 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004047 arvif->vdev_id, slottime);
4048
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004049 vdev_param = ar->wmi.vdev_param->slot_time;
4050 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004051 slottime);
4052 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004053 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004054 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004055 }
4056
4057 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004058 if (info->use_short_preamble)
4059 preamble = WMI_VDEV_PREAMBLE_SHORT;
4060 else
4061 preamble = WMI_VDEV_PREAMBLE_LONG;
4062
Michal Kazior7aa7a722014-08-25 12:09:38 +02004063 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004064 "mac vdev %d preamble %dn",
4065 arvif->vdev_id, preamble);
4066
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004067 vdev_param = ar->wmi.vdev_param->preamble;
4068 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004069 preamble);
4070 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004071 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004072 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004073 }
4074
4075 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02004076 if (info->assoc) {
4077 /* Workaround: Make sure monitor vdev is not running
4078 * when associating to prevent some firmware revisions
4079 * (e.g. 10.1 and 10.2) from crashing.
4080 */
4081 if (ar->monitor_started)
4082 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004083 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02004084 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03004085 } else {
4086 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02004087 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004088 }
4089
Michal Kazior7d9d5582014-10-21 10:40:15 +03004090 if (changed & BSS_CHANGED_TXPOWER) {
4091 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
4092 arvif->vdev_id, info->txpower);
4093
4094 arvif->txpower = info->txpower;
4095 ret = ath10k_mac_txpower_recalc(ar);
4096 if (ret)
4097 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4098 }
4099
Michal Kaziorbf14e652014-12-12 12:41:38 +01004100 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01004101 arvif->ps = vif->bss_conf.ps;
4102
4103 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01004104 if (ret)
4105 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
4106 arvif->vdev_id, ret);
4107 }
4108
Kalle Valo5e3dd152013-06-12 20:52:10 +03004109 mutex_unlock(&ar->conf_mutex);
4110}
4111
4112static int ath10k_hw_scan(struct ieee80211_hw *hw,
4113 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02004114 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004115{
4116 struct ath10k *ar = hw->priv;
4117 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02004118 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004119 struct wmi_start_scan_arg arg;
4120 int ret = 0;
4121 int i;
4122
4123 mutex_lock(&ar->conf_mutex);
4124
4125 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004126 switch (ar->scan.state) {
4127 case ATH10K_SCAN_IDLE:
4128 reinit_completion(&ar->scan.started);
4129 reinit_completion(&ar->scan.completed);
4130 ar->scan.state = ATH10K_SCAN_STARTING;
4131 ar->scan.is_roc = false;
4132 ar->scan.vdev_id = arvif->vdev_id;
4133 ret = 0;
4134 break;
4135 case ATH10K_SCAN_STARTING:
4136 case ATH10K_SCAN_RUNNING:
4137 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03004138 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004139 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004140 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004141 spin_unlock_bh(&ar->data_lock);
4142
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004143 if (ret)
4144 goto exit;
4145
Kalle Valo5e3dd152013-06-12 20:52:10 +03004146 memset(&arg, 0, sizeof(arg));
4147 ath10k_wmi_start_scan_init(ar, &arg);
4148 arg.vdev_id = arvif->vdev_id;
4149 arg.scan_id = ATH10K_SCAN_ID;
4150
4151 if (!req->no_cck)
4152 arg.scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES;
4153
4154 if (req->ie_len) {
4155 arg.ie_len = req->ie_len;
4156 memcpy(arg.ie, req->ie, arg.ie_len);
4157 }
4158
4159 if (req->n_ssids) {
4160 arg.n_ssids = req->n_ssids;
4161 for (i = 0; i < arg.n_ssids; i++) {
4162 arg.ssids[i].len = req->ssids[i].ssid_len;
4163 arg.ssids[i].ssid = req->ssids[i].ssid;
4164 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02004165 } else {
4166 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004167 }
4168
4169 if (req->n_channels) {
4170 arg.n_channels = req->n_channels;
4171 for (i = 0; i < arg.n_channels; i++)
4172 arg.channels[i] = req->channels[i]->center_freq;
4173 }
4174
4175 ret = ath10k_start_scan(ar, &arg);
4176 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004177 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004178 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004179 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004180 spin_unlock_bh(&ar->data_lock);
4181 }
4182
4183exit:
4184 mutex_unlock(&ar->conf_mutex);
4185 return ret;
4186}
4187
4188static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
4189 struct ieee80211_vif *vif)
4190{
4191 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004192
4193 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004194 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004195 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01004196
4197 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004198}
4199
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004200static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
4201 struct ath10k_vif *arvif,
4202 enum set_key_cmd cmd,
4203 struct ieee80211_key_conf *key)
4204{
4205 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
4206 int ret;
4207
4208 /* 10.1 firmware branch requires default key index to be set to group
4209 * key index after installing it. Otherwise FW/HW Txes corrupted
4210 * frames with multi-vif APs. This is not required for main firmware
4211 * branch (e.g. 636).
4212 *
4213 * FIXME: This has been tested only in AP. It remains unknown if this
4214 * is required for multi-vif STA interfaces on 10.1 */
4215
4216 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
4217 return;
4218
4219 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
4220 return;
4221
4222 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
4223 return;
4224
4225 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
4226 return;
4227
4228 if (cmd != SET_KEY)
4229 return;
4230
4231 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4232 key->keyidx);
4233 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004234 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004235 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004236}
4237
Kalle Valo5e3dd152013-06-12 20:52:10 +03004238static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
4239 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
4240 struct ieee80211_key_conf *key)
4241{
4242 struct ath10k *ar = hw->priv;
4243 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4244 struct ath10k_peer *peer;
4245 const u8 *peer_addr;
4246 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
4247 key->cipher == WLAN_CIPHER_SUITE_WEP104;
4248 int ret = 0;
Michal Kazior370e5672015-02-18 14:02:26 +01004249 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004250
Bartosz Markowskid7131c02015-03-10 14:32:19 +01004251 /* this one needs to be done in software */
4252 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
4253 return 1;
4254
Kalle Valo5e3dd152013-06-12 20:52:10 +03004255 if (key->keyidx > WMI_MAX_KEY_INDEX)
4256 return -ENOSPC;
4257
4258 mutex_lock(&ar->conf_mutex);
4259
4260 if (sta)
4261 peer_addr = sta->addr;
4262 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
4263 peer_addr = vif->bss_conf.bssid;
4264 else
4265 peer_addr = vif->addr;
4266
4267 key->hw_key_idx = key->keyidx;
4268
4269 /* the peer should not disappear in mid-way (unless FW goes awry) since
4270 * we already hold conf_mutex. we just make sure its there now. */
4271 spin_lock_bh(&ar->data_lock);
4272 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
4273 spin_unlock_bh(&ar->data_lock);
4274
4275 if (!peer) {
4276 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004277 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03004278 peer_addr);
4279 ret = -EOPNOTSUPP;
4280 goto exit;
4281 } else {
4282 /* if the peer doesn't exist there is no key to disable
4283 * anymore */
4284 goto exit;
4285 }
4286 }
4287
Michal Kazior7cc45732015-03-09 14:24:17 +01004288 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
4289 flags |= WMI_KEY_PAIRWISE;
4290 else
4291 flags |= WMI_KEY_GROUP;
4292
Kalle Valo5e3dd152013-06-12 20:52:10 +03004293 if (is_wep) {
4294 if (cmd == SET_KEY)
4295 arvif->wep_keys[key->keyidx] = key;
4296 else
4297 arvif->wep_keys[key->keyidx] = NULL;
4298
4299 if (cmd == DISABLE_KEY)
4300 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01004301
Michal Kaziorad325cb2015-02-18 14:02:27 +01004302 /* When WEP keys are uploaded it's possible that there are
4303 * stations associated already (e.g. when merging) without any
4304 * keys. Static WEP needs an explicit per-peer key upload.
4305 */
4306 if (vif->type == NL80211_IFTYPE_ADHOC &&
4307 cmd == SET_KEY)
4308 ath10k_mac_vif_update_wep_key(arvif, key);
4309
Michal Kazior370e5672015-02-18 14:02:26 +01004310 /* 802.1x never sets the def_wep_key_idx so each set_key()
4311 * call changes default tx key.
4312 *
4313 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
4314 * after first set_key().
4315 */
4316 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
4317 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004318
Michal Kazior7cc45732015-03-09 14:24:17 +01004319 /* mac80211 uploads static WEP keys as groupwise while fw/hw
4320 * requires pairwise keys for non-self peers, i.e. BSSID in STA
4321 * mode and associated stations in AP/IBSS.
4322 *
4323 * Static WEP keys for peer_addr=vif->addr and 802.1X WEP keys
4324 * work fine when mapped directly from mac80211.
4325 *
4326 * Note: When installing first static WEP groupwise key (which
4327 * should be pairwise) def_wep_key_idx isn't known yet (it's
4328 * equal to -1). Since .set_default_unicast_key is called only
4329 * for static WEP it's used to re-upload the key as pairwise.
4330 */
4331 if (arvif->def_wep_key_idx >= 0 &&
4332 memcmp(peer_addr, arvif->vif->addr, ETH_ALEN)) {
4333 flags &= ~WMI_KEY_GROUP;
4334 flags |= WMI_KEY_PAIRWISE;
4335 }
Michal Kazior370e5672015-02-18 14:02:26 +01004336 }
4337
4338 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004339 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004340 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004341 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004342 goto exit;
4343 }
4344
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004345 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
4346
Kalle Valo5e3dd152013-06-12 20:52:10 +03004347 spin_lock_bh(&ar->data_lock);
4348 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
4349 if (peer && cmd == SET_KEY)
4350 peer->keys[key->keyidx] = key;
4351 else if (peer && cmd == DISABLE_KEY)
4352 peer->keys[key->keyidx] = NULL;
4353 else if (peer == NULL)
4354 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02004355 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004356 spin_unlock_bh(&ar->data_lock);
4357
4358exit:
4359 mutex_unlock(&ar->conf_mutex);
4360 return ret;
4361}
4362
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004363static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
4364 struct ieee80211_vif *vif,
4365 int keyidx)
4366{
4367 struct ath10k *ar = hw->priv;
4368 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4369 int ret;
4370
4371 mutex_lock(&arvif->ar->conf_mutex);
4372
4373 if (arvif->ar->state != ATH10K_STATE_ON)
4374 goto unlock;
4375
4376 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
4377 arvif->vdev_id, keyidx);
4378
4379 ret = ath10k_wmi_vdev_set_param(arvif->ar,
4380 arvif->vdev_id,
4381 arvif->ar->wmi.vdev_param->def_keyid,
4382 keyidx);
4383
4384 if (ret) {
4385 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
4386 arvif->vdev_id,
4387 ret);
4388 goto unlock;
4389 }
4390
4391 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01004392
4393 ret = ath10k_mac_vif_sta_fix_wep_key(arvif);
4394 if (ret) {
4395 ath10k_warn(ar, "failed to fix sta wep key on vdev %i: %d\n",
4396 arvif->vdev_id, ret);
4397 goto unlock;
4398 }
4399
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004400unlock:
4401 mutex_unlock(&arvif->ar->conf_mutex);
4402}
4403
Michal Kazior9797feb2014-02-14 14:49:48 +01004404static void ath10k_sta_rc_update_wk(struct work_struct *wk)
4405{
4406 struct ath10k *ar;
4407 struct ath10k_vif *arvif;
4408 struct ath10k_sta *arsta;
4409 struct ieee80211_sta *sta;
4410 u32 changed, bw, nss, smps;
4411 int err;
4412
4413 arsta = container_of(wk, struct ath10k_sta, update_wk);
4414 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
4415 arvif = arsta->arvif;
4416 ar = arvif->ar;
4417
4418 spin_lock_bh(&ar->data_lock);
4419
4420 changed = arsta->changed;
4421 arsta->changed = 0;
4422
4423 bw = arsta->bw;
4424 nss = arsta->nss;
4425 smps = arsta->smps;
4426
4427 spin_unlock_bh(&ar->data_lock);
4428
4429 mutex_lock(&ar->conf_mutex);
4430
4431 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004432 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004433 sta->addr, bw);
4434
4435 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
4436 WMI_PEER_CHAN_WIDTH, bw);
4437 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004438 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004439 sta->addr, bw, err);
4440 }
4441
4442 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004443 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004444 sta->addr, nss);
4445
4446 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
4447 WMI_PEER_NSS, nss);
4448 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004449 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004450 sta->addr, nss, err);
4451 }
4452
4453 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004454 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004455 sta->addr, smps);
4456
4457 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
4458 WMI_PEER_SMPS_STATE, smps);
4459 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004460 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004461 sta->addr, smps, err);
4462 }
4463
Janusz Dziedzic55884c02014-12-17 12:30:02 +02004464 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
4465 changed & IEEE80211_RC_NSS_CHANGED) {
4466 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02004467 sta->addr);
4468
Michal Kazior590922a2014-10-21 10:10:29 +03004469 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02004470 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004471 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02004472 sta->addr);
4473 }
4474
Michal Kazior9797feb2014-02-14 14:49:48 +01004475 mutex_unlock(&ar->conf_mutex);
4476}
4477
Marek Puzyniak7c354242015-03-30 09:51:52 +03004478static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
4479 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004480{
4481 struct ath10k *ar = arvif->ar;
4482
4483 lockdep_assert_held(&ar->conf_mutex);
4484
Marek Puzyniak7c354242015-03-30 09:51:52 +03004485 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004486 return 0;
4487
4488 if (ar->num_stations >= ar->max_num_stations)
4489 return -ENOBUFS;
4490
4491 ar->num_stations++;
4492
4493 return 0;
4494}
4495
Marek Puzyniak7c354242015-03-30 09:51:52 +03004496static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
4497 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004498{
4499 struct ath10k *ar = arvif->ar;
4500
4501 lockdep_assert_held(&ar->conf_mutex);
4502
Marek Puzyniak7c354242015-03-30 09:51:52 +03004503 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004504 return;
4505
4506 ar->num_stations--;
4507}
4508
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004509struct ath10k_mac_tdls_iter_data {
4510 u32 num_tdls_stations;
4511 struct ieee80211_vif *curr_vif;
4512};
4513
4514static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
4515 struct ieee80211_sta *sta)
4516{
4517 struct ath10k_mac_tdls_iter_data *iter_data = data;
4518 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
4519 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
4520
4521 if (sta->tdls && sta_vif == iter_data->curr_vif)
4522 iter_data->num_tdls_stations++;
4523}
4524
4525static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
4526 struct ieee80211_vif *vif)
4527{
4528 struct ath10k_mac_tdls_iter_data data = {};
4529
4530 data.curr_vif = vif;
4531
4532 ieee80211_iterate_stations_atomic(hw,
4533 ath10k_mac_tdls_vif_stations_count_iter,
4534 &data);
4535 return data.num_tdls_stations;
4536}
4537
4538static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
4539 struct ieee80211_vif *vif)
4540{
4541 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4542 int *num_tdls_vifs = data;
4543
4544 if (vif->type != NL80211_IFTYPE_STATION)
4545 return;
4546
4547 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
4548 (*num_tdls_vifs)++;
4549}
4550
4551static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
4552{
4553 int num_tdls_vifs = 0;
4554
4555 ieee80211_iterate_active_interfaces_atomic(hw,
4556 IEEE80211_IFACE_ITER_NORMAL,
4557 ath10k_mac_tdls_vifs_count_iter,
4558 &num_tdls_vifs);
4559 return num_tdls_vifs;
4560}
4561
Kalle Valo5e3dd152013-06-12 20:52:10 +03004562static int ath10k_sta_state(struct ieee80211_hw *hw,
4563 struct ieee80211_vif *vif,
4564 struct ieee80211_sta *sta,
4565 enum ieee80211_sta_state old_state,
4566 enum ieee80211_sta_state new_state)
4567{
4568 struct ath10k *ar = hw->priv;
4569 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01004570 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004571 int ret = 0;
4572
Michal Kazior76f90022014-02-25 09:29:57 +02004573 if (old_state == IEEE80211_STA_NOTEXIST &&
4574 new_state == IEEE80211_STA_NONE) {
4575 memset(arsta, 0, sizeof(*arsta));
4576 arsta->arvif = arvif;
4577 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
4578 }
4579
Michal Kazior9797feb2014-02-14 14:49:48 +01004580 /* cancel must be done outside the mutex to avoid deadlock */
4581 if ((old_state == IEEE80211_STA_NONE &&
4582 new_state == IEEE80211_STA_NOTEXIST))
4583 cancel_work_sync(&arsta->update_wk);
4584
Kalle Valo5e3dd152013-06-12 20:52:10 +03004585 mutex_lock(&ar->conf_mutex);
4586
4587 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03004588 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004589 /*
4590 * New station addition.
4591 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004592 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
4593 u32 num_tdls_stations;
4594 u32 num_tdls_vifs;
4595
Michal Kaziorcfd10612014-11-25 15:16:05 +01004596 ath10k_dbg(ar, ATH10K_DBG_MAC,
4597 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
4598 arvif->vdev_id, sta->addr,
4599 ar->num_stations + 1, ar->max_num_stations,
4600 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01004601
Marek Puzyniak7c354242015-03-30 09:51:52 +03004602 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01004603 if (ret) {
4604 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
4605 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01004606 goto exit;
4607 }
4608
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004609 if (sta->tdls)
4610 peer_type = WMI_PEER_TYPE_TDLS;
4611
Marek Puzyniak7390ed32015-03-30 09:51:52 +03004612 ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr,
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004613 peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01004614 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004615 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 -08004616 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03004617 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01004618 goto exit;
4619 }
Michal Kazior077efc82014-10-21 10:10:29 +03004620
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004621 if (vif->type == NL80211_IFTYPE_STATION &&
4622 !sta->tdls) {
Michal Kazior077efc82014-10-21 10:10:29 +03004623 WARN_ON(arvif->is_started);
4624
4625 ret = ath10k_vdev_start(arvif);
4626 if (ret) {
4627 ath10k_warn(ar, "failed to start vdev %i: %d\n",
4628 arvif->vdev_id, ret);
4629 WARN_ON(ath10k_peer_delete(ar, arvif->vdev_id,
4630 sta->addr));
Marek Puzyniak7c354242015-03-30 09:51:52 +03004631 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03004632 goto exit;
4633 }
4634
4635 arvif->is_started = true;
4636 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004637
4638 if (!sta->tdls)
4639 goto exit;
4640
4641 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
4642 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
4643
4644 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
4645 num_tdls_stations == 0) {
4646 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
4647 arvif->vdev_id, ar->max_num_tdls_vdevs);
4648 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
4649 ath10k_mac_dec_num_stations(arvif, sta);
4650 ret = -ENOBUFS;
4651 goto exit;
4652 }
4653
4654 if (num_tdls_stations == 0) {
4655 /* This is the first tdls peer in current vif */
4656 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
4657
4658 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
4659 state);
4660 if (ret) {
4661 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
4662 arvif->vdev_id, ret);
4663 ath10k_peer_delete(ar, arvif->vdev_id,
4664 sta->addr);
4665 ath10k_mac_dec_num_stations(arvif, sta);
4666 goto exit;
4667 }
4668 }
4669
4670 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
4671 WMI_TDLS_PEER_STATE_PEERING);
4672 if (ret) {
4673 ath10k_warn(ar,
4674 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
4675 sta->addr, arvif->vdev_id, ret);
4676 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
4677 ath10k_mac_dec_num_stations(arvif, sta);
4678
4679 if (num_tdls_stations != 0)
4680 goto exit;
4681 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
4682 WMI_TDLS_DISABLE);
4683 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004684 } else if ((old_state == IEEE80211_STA_NONE &&
4685 new_state == IEEE80211_STA_NOTEXIST)) {
4686 /*
4687 * Existing station deletion.
4688 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02004689 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004690 "mac vdev %d peer delete %pM (sta gone)\n",
4691 arvif->vdev_id, sta->addr);
Michal Kazior077efc82014-10-21 10:10:29 +03004692
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004693 if (vif->type == NL80211_IFTYPE_STATION &&
4694 !sta->tdls) {
Michal Kazior077efc82014-10-21 10:10:29 +03004695 WARN_ON(!arvif->is_started);
4696
4697 ret = ath10k_vdev_stop(arvif);
4698 if (ret)
4699 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
4700 arvif->vdev_id, ret);
4701
4702 arvif->is_started = false;
4703 }
4704
Kalle Valo5e3dd152013-06-12 20:52:10 +03004705 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
4706 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004707 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004708 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004709
Marek Puzyniak7c354242015-03-30 09:51:52 +03004710 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004711
4712 if (!sta->tdls)
4713 goto exit;
4714
4715 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
4716 goto exit;
4717
4718 /* This was the last tdls peer in current vif */
4719 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
4720 WMI_TDLS_DISABLE);
4721 if (ret) {
4722 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
4723 arvif->vdev_id, ret);
4724 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004725 } else if (old_state == IEEE80211_STA_AUTH &&
4726 new_state == IEEE80211_STA_ASSOC &&
4727 (vif->type == NL80211_IFTYPE_AP ||
4728 vif->type == NL80211_IFTYPE_ADHOC)) {
4729 /*
4730 * New association.
4731 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02004732 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004733 sta->addr);
4734
Michal Kazior590922a2014-10-21 10:10:29 +03004735 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004736 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004737 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004738 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004739 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004740 new_state == IEEE80211_STA_AUTHORIZED &&
4741 sta->tdls) {
4742 /*
4743 * Tdls station authorized.
4744 */
4745 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
4746 sta->addr);
4747
4748 ret = ath10k_station_assoc(ar, vif, sta, false);
4749 if (ret) {
4750 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
4751 sta->addr, arvif->vdev_id, ret);
4752 goto exit;
4753 }
4754
4755 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
4756 WMI_TDLS_PEER_STATE_CONNECTED);
4757 if (ret)
4758 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
4759 sta->addr, arvif->vdev_id, ret);
4760 } else if (old_state == IEEE80211_STA_ASSOC &&
4761 new_state == IEEE80211_STA_AUTH &&
4762 (vif->type == NL80211_IFTYPE_AP ||
4763 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004764 /*
4765 * Disassociation.
4766 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02004767 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004768 sta->addr);
4769
Michal Kazior590922a2014-10-21 10:10:29 +03004770 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004771 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004772 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004773 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004774 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01004775exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03004776 mutex_unlock(&ar->conf_mutex);
4777 return ret;
4778}
4779
4780static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03004781 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004782{
4783 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02004784 struct wmi_sta_uapsd_auto_trig_arg arg = {};
4785 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004786 u32 value = 0;
4787 int ret = 0;
4788
Michal Kazior548db542013-07-05 16:15:15 +03004789 lockdep_assert_held(&ar->conf_mutex);
4790
Kalle Valo5e3dd152013-06-12 20:52:10 +03004791 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
4792 return 0;
4793
4794 switch (ac) {
4795 case IEEE80211_AC_VO:
4796 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
4797 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02004798 prio = 7;
4799 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004800 break;
4801 case IEEE80211_AC_VI:
4802 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
4803 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02004804 prio = 5;
4805 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004806 break;
4807 case IEEE80211_AC_BE:
4808 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
4809 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02004810 prio = 2;
4811 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004812 break;
4813 case IEEE80211_AC_BK:
4814 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
4815 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02004816 prio = 0;
4817 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004818 break;
4819 }
4820
4821 if (enable)
4822 arvif->u.sta.uapsd |= value;
4823 else
4824 arvif->u.sta.uapsd &= ~value;
4825
4826 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
4827 WMI_STA_PS_PARAM_UAPSD,
4828 arvif->u.sta.uapsd);
4829 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004830 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004831 goto exit;
4832 }
4833
4834 if (arvif->u.sta.uapsd)
4835 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
4836 else
4837 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
4838
4839 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
4840 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
4841 value);
4842 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004843 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004844
Michal Kazior9f9b5742014-12-12 12:41:36 +01004845 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
4846 if (ret) {
4847 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
4848 arvif->vdev_id, ret);
4849 return ret;
4850 }
4851
4852 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
4853 if (ret) {
4854 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
4855 arvif->vdev_id, ret);
4856 return ret;
4857 }
4858
Michal Kaziorb0e56152015-01-24 12:14:52 +02004859 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
4860 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
4861 /* Only userspace can make an educated decision when to send
4862 * trigger frame. The following effectively disables u-UAPSD
4863 * autotrigger in firmware (which is enabled by default
4864 * provided the autotrigger service is available).
4865 */
4866
4867 arg.wmm_ac = acc;
4868 arg.user_priority = prio;
4869 arg.service_interval = 0;
4870 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
4871 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
4872
4873 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
4874 arvif->bssid, &arg, 1);
4875 if (ret) {
4876 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
4877 ret);
4878 return ret;
4879 }
4880 }
4881
Kalle Valo5e3dd152013-06-12 20:52:10 +03004882exit:
4883 return ret;
4884}
4885
4886static int ath10k_conf_tx(struct ieee80211_hw *hw,
4887 struct ieee80211_vif *vif, u16 ac,
4888 const struct ieee80211_tx_queue_params *params)
4889{
4890 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01004891 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004892 struct wmi_wmm_params_arg *p = NULL;
4893 int ret;
4894
4895 mutex_lock(&ar->conf_mutex);
4896
4897 switch (ac) {
4898 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01004899 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004900 break;
4901 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01004902 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004903 break;
4904 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01004905 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004906 break;
4907 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01004908 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004909 break;
4910 }
4911
4912 if (WARN_ON(!p)) {
4913 ret = -EINVAL;
4914 goto exit;
4915 }
4916
4917 p->cwmin = params->cw_min;
4918 p->cwmax = params->cw_max;
4919 p->aifs = params->aifs;
4920
4921 /*
4922 * The channel time duration programmed in the HW is in absolute
4923 * microseconds, while mac80211 gives the txop in units of
4924 * 32 microseconds.
4925 */
4926 p->txop = params->txop * 32;
4927
Michal Kazior7fc979a2015-01-28 09:57:28 +02004928 if (ar->wmi.ops->gen_vdev_wmm_conf) {
4929 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
4930 &arvif->wmm_params);
4931 if (ret) {
4932 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
4933 arvif->vdev_id, ret);
4934 goto exit;
4935 }
4936 } else {
4937 /* This won't work well with multi-interface cases but it's
4938 * better than nothing.
4939 */
4940 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
4941 if (ret) {
4942 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
4943 goto exit;
4944 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004945 }
4946
4947 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
4948 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004949 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004950
4951exit:
4952 mutex_unlock(&ar->conf_mutex);
4953 return ret;
4954}
4955
4956#define ATH10K_ROC_TIMEOUT_HZ (2*HZ)
4957
4958static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
4959 struct ieee80211_vif *vif,
4960 struct ieee80211_channel *chan,
4961 int duration,
4962 enum ieee80211_roc_type type)
4963{
4964 struct ath10k *ar = hw->priv;
4965 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4966 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004967 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004968
4969 mutex_lock(&ar->conf_mutex);
4970
4971 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004972 switch (ar->scan.state) {
4973 case ATH10K_SCAN_IDLE:
4974 reinit_completion(&ar->scan.started);
4975 reinit_completion(&ar->scan.completed);
4976 reinit_completion(&ar->scan.on_channel);
4977 ar->scan.state = ATH10K_SCAN_STARTING;
4978 ar->scan.is_roc = true;
4979 ar->scan.vdev_id = arvif->vdev_id;
4980 ar->scan.roc_freq = chan->center_freq;
4981 ret = 0;
4982 break;
4983 case ATH10K_SCAN_STARTING:
4984 case ATH10K_SCAN_RUNNING:
4985 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03004986 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004987 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004988 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004989 spin_unlock_bh(&ar->data_lock);
4990
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004991 if (ret)
4992 goto exit;
4993
Michal Kaziordcca0bd2014-11-24 14:58:32 +01004994 duration = max(duration, WMI_SCAN_CHAN_MIN_TIME_MSEC);
4995
Kalle Valo5e3dd152013-06-12 20:52:10 +03004996 memset(&arg, 0, sizeof(arg));
4997 ath10k_wmi_start_scan_init(ar, &arg);
4998 arg.vdev_id = arvif->vdev_id;
4999 arg.scan_id = ATH10K_SCAN_ID;
5000 arg.n_channels = 1;
5001 arg.channels[0] = chan->center_freq;
5002 arg.dwell_time_active = duration;
5003 arg.dwell_time_passive = duration;
5004 arg.max_scan_time = 2 * duration;
5005 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
5006 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
5007
5008 ret = ath10k_start_scan(ar, &arg);
5009 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005010 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005011 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005012 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005013 spin_unlock_bh(&ar->data_lock);
5014 goto exit;
5015 }
5016
5017 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ);
5018 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005019 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005020
5021 ret = ath10k_scan_stop(ar);
5022 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005023 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005024
Kalle Valo5e3dd152013-06-12 20:52:10 +03005025 ret = -ETIMEDOUT;
5026 goto exit;
5027 }
5028
5029 ret = 0;
5030exit:
5031 mutex_unlock(&ar->conf_mutex);
5032 return ret;
5033}
5034
5035static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
5036{
5037 struct ath10k *ar = hw->priv;
5038
5039 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005040 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005041 mutex_unlock(&ar->conf_mutex);
5042
Michal Kazior4eb2e162014-10-28 10:23:09 +01005043 cancel_delayed_work_sync(&ar->scan.timeout);
5044
Kalle Valo5e3dd152013-06-12 20:52:10 +03005045 return 0;
5046}
5047
5048/*
5049 * Both RTS and Fragmentation threshold are interface-specific
5050 * in ath10k, but device-specific in mac80211.
5051 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03005052
5053static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
5054{
Kalle Valo5e3dd152013-06-12 20:52:10 +03005055 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03005056 struct ath10k_vif *arvif;
5057 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03005058
Michal Kaziorad088bf2013-10-16 15:44:46 +03005059 mutex_lock(&ar->conf_mutex);
5060 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005061 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03005062 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03005063
Michal Kaziorad088bf2013-10-16 15:44:46 +03005064 ret = ath10k_mac_set_rts(arvif, value);
5065 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005066 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03005067 arvif->vdev_id, ret);
5068 break;
5069 }
5070 }
5071 mutex_unlock(&ar->conf_mutex);
5072
5073 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005074}
5075
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02005076static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5077 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005078{
5079 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02005080 bool skip;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005081 int ret;
5082
5083 /* mac80211 doesn't care if we really xmit queued frames or not
5084 * we'll collect those frames either way if we stop/delete vdevs */
5085 if (drop)
5086 return;
5087
Michal Kazior548db542013-07-05 16:15:15 +03005088 mutex_lock(&ar->conf_mutex);
5089
Michal Kazioraffd3212013-07-16 09:54:35 +02005090 if (ar->state == ATH10K_STATE_WEDGED)
5091 goto skip;
5092
Michal Kazioredb82362013-07-05 16:15:14 +03005093 ret = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03005094 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02005095
Michal Kazioredb82362013-07-05 16:15:14 +03005096 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02005097 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03005098 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02005099
Michal Kazior7962b0d2014-10-28 10:34:38 +01005100 skip = (ar->state == ATH10K_STATE_WEDGED) ||
5101 test_bit(ATH10K_FLAG_CRASH_FLUSH,
5102 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02005103
5104 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005105 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02005106
5107 if (ret <= 0 || skip)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005108 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %i\n",
Ben Greear9ba4c782014-02-25 09:29:57 +02005109 skip, ar->state, ret);
Michal Kazior548db542013-07-05 16:15:15 +03005110
Michal Kazioraffd3212013-07-16 09:54:35 +02005111skip:
Michal Kazior548db542013-07-05 16:15:15 +03005112 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005113}
5114
5115/* TODO: Implement this function properly
5116 * For now it is needed to reply to Probe Requests in IBSS mode.
5117 * Propably we need this information from FW.
5118 */
5119static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
5120{
5121 return 1;
5122}
5123
Eliad Pellercf2c92d2014-11-04 11:43:54 +02005124static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
5125 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02005126{
5127 struct ath10k *ar = hw->priv;
5128
Eliad Pellercf2c92d2014-11-04 11:43:54 +02005129 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
5130 return;
5131
Michal Kazioraffd3212013-07-16 09:54:35 +02005132 mutex_lock(&ar->conf_mutex);
5133
5134 /* If device failed to restart it will be in a different state, e.g.
5135 * ATH10K_STATE_WEDGED */
5136 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005137 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02005138 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01005139 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02005140 }
5141
5142 mutex_unlock(&ar->conf_mutex);
5143}
5144
Michal Kazior2e1dea42013-07-31 10:32:40 +02005145static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
5146 struct survey_info *survey)
5147{
5148 struct ath10k *ar = hw->priv;
5149 struct ieee80211_supported_band *sband;
5150 struct survey_info *ar_survey = &ar->survey[idx];
5151 int ret = 0;
5152
5153 mutex_lock(&ar->conf_mutex);
5154
5155 sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
5156 if (sband && idx >= sband->n_channels) {
5157 idx -= sband->n_channels;
5158 sband = NULL;
5159 }
5160
5161 if (!sband)
5162 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
5163
5164 if (!sband || idx >= sband->n_channels) {
5165 ret = -ENOENT;
5166 goto exit;
5167 }
5168
5169 spin_lock_bh(&ar->data_lock);
5170 memcpy(survey, ar_survey, sizeof(*survey));
5171 spin_unlock_bh(&ar->data_lock);
5172
5173 survey->channel = &sband->channels[idx];
5174
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03005175 if (ar->rx_channel == survey->channel)
5176 survey->filled |= SURVEY_INFO_IN_USE;
5177
Michal Kazior2e1dea42013-07-31 10:32:40 +02005178exit:
5179 mutex_unlock(&ar->conf_mutex);
5180 return ret;
5181}
5182
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005183/* Helper table for legacy fixed_rate/bitrate_mask */
5184static const u8 cck_ofdm_rate[] = {
5185 /* CCK */
5186 3, /* 1Mbps */
5187 2, /* 2Mbps */
5188 1, /* 5.5Mbps */
5189 0, /* 11Mbps */
5190 /* OFDM */
5191 3, /* 6Mbps */
5192 7, /* 9Mbps */
5193 2, /* 12Mbps */
5194 6, /* 18Mbps */
5195 1, /* 24Mbps */
5196 5, /* 36Mbps */
5197 0, /* 48Mbps */
5198 4, /* 54Mbps */
5199};
5200
5201/* Check if only one bit set */
5202static int ath10k_check_single_mask(u32 mask)
5203{
5204 int bit;
5205
5206 bit = ffs(mask);
5207 if (!bit)
5208 return 0;
5209
5210 mask &= ~BIT(bit - 1);
5211 if (mask)
5212 return 2;
5213
5214 return 1;
5215}
5216
5217static bool
5218ath10k_default_bitrate_mask(struct ath10k *ar,
5219 enum ieee80211_band band,
5220 const struct cfg80211_bitrate_mask *mask)
5221{
5222 u32 legacy = 0x00ff;
5223 u8 ht = 0xff, i;
5224 u16 vht = 0x3ff;
Ben Greearb116ea12014-11-24 16:22:10 +02005225 u16 nrf = ar->num_rf_chains;
5226
5227 if (ar->cfg_tx_chainmask)
5228 nrf = get_nss_from_chainmask(ar->cfg_tx_chainmask);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005229
5230 switch (band) {
5231 case IEEE80211_BAND_2GHZ:
5232 legacy = 0x00fff;
5233 vht = 0;
5234 break;
5235 case IEEE80211_BAND_5GHZ:
5236 break;
5237 default:
5238 return false;
5239 }
5240
5241 if (mask->control[band].legacy != legacy)
5242 return false;
5243
Ben Greearb116ea12014-11-24 16:22:10 +02005244 for (i = 0; i < nrf; i++)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005245 if (mask->control[band].ht_mcs[i] != ht)
5246 return false;
5247
Ben Greearb116ea12014-11-24 16:22:10 +02005248 for (i = 0; i < nrf; i++)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005249 if (mask->control[band].vht_mcs[i] != vht)
5250 return false;
5251
5252 return true;
5253}
5254
5255static bool
5256ath10k_bitrate_mask_nss(const struct cfg80211_bitrate_mask *mask,
5257 enum ieee80211_band band,
5258 u8 *fixed_nss)
5259{
5260 int ht_nss = 0, vht_nss = 0, i;
5261
5262 /* check legacy */
5263 if (ath10k_check_single_mask(mask->control[band].legacy))
5264 return false;
5265
5266 /* check HT */
5267 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
5268 if (mask->control[band].ht_mcs[i] == 0xff)
5269 continue;
5270 else if (mask->control[band].ht_mcs[i] == 0x00)
5271 break;
Kalle Valod8bb26b2014-09-14 12:50:33 +03005272
5273 return false;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005274 }
5275
5276 ht_nss = i;
5277
5278 /* check VHT */
5279 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
5280 if (mask->control[band].vht_mcs[i] == 0x03ff)
5281 continue;
5282 else if (mask->control[band].vht_mcs[i] == 0x0000)
5283 break;
Kalle Valod8bb26b2014-09-14 12:50:33 +03005284
5285 return false;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005286 }
5287
5288 vht_nss = i;
5289
5290 if (ht_nss > 0 && vht_nss > 0)
5291 return false;
5292
5293 if (ht_nss)
5294 *fixed_nss = ht_nss;
5295 else if (vht_nss)
5296 *fixed_nss = vht_nss;
5297 else
5298 return false;
5299
5300 return true;
5301}
5302
5303static bool
5304ath10k_bitrate_mask_correct(const struct cfg80211_bitrate_mask *mask,
5305 enum ieee80211_band band,
5306 enum wmi_rate_preamble *preamble)
5307{
5308 int legacy = 0, ht = 0, vht = 0, i;
5309
5310 *preamble = WMI_RATE_PREAMBLE_OFDM;
5311
5312 /* check legacy */
5313 legacy = ath10k_check_single_mask(mask->control[band].legacy);
5314 if (legacy > 1)
5315 return false;
5316
5317 /* check HT */
5318 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
5319 ht += ath10k_check_single_mask(mask->control[band].ht_mcs[i]);
5320 if (ht > 1)
5321 return false;
5322
5323 /* check VHT */
5324 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
5325 vht += ath10k_check_single_mask(mask->control[band].vht_mcs[i]);
5326 if (vht > 1)
5327 return false;
5328
5329 /* Currently we support only one fixed_rate */
5330 if ((legacy + ht + vht) != 1)
5331 return false;
5332
5333 if (ht)
5334 *preamble = WMI_RATE_PREAMBLE_HT;
5335 else if (vht)
5336 *preamble = WMI_RATE_PREAMBLE_VHT;
5337
5338 return true;
5339}
5340
5341static bool
Michal Kazior7aa7a722014-08-25 12:09:38 +02005342ath10k_bitrate_mask_rate(struct ath10k *ar,
5343 const struct cfg80211_bitrate_mask *mask,
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005344 enum ieee80211_band band,
5345 u8 *fixed_rate,
5346 u8 *fixed_nss)
5347{
5348 u8 rate = 0, pream = 0, nss = 0, i;
5349 enum wmi_rate_preamble preamble;
5350
5351 /* Check if single rate correct */
5352 if (!ath10k_bitrate_mask_correct(mask, band, &preamble))
5353 return false;
5354
5355 pream = preamble;
5356
5357 switch (preamble) {
5358 case WMI_RATE_PREAMBLE_CCK:
5359 case WMI_RATE_PREAMBLE_OFDM:
5360 i = ffs(mask->control[band].legacy) - 1;
5361
5362 if (band == IEEE80211_BAND_2GHZ && i < 4)
5363 pream = WMI_RATE_PREAMBLE_CCK;
5364
5365 if (band == IEEE80211_BAND_5GHZ)
5366 i += 4;
5367
5368 if (i >= ARRAY_SIZE(cck_ofdm_rate))
5369 return false;
5370
5371 rate = cck_ofdm_rate[i];
5372 break;
5373 case WMI_RATE_PREAMBLE_HT:
5374 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
5375 if (mask->control[band].ht_mcs[i])
5376 break;
5377
5378 if (i == IEEE80211_HT_MCS_MASK_LEN)
5379 return false;
5380
5381 rate = ffs(mask->control[band].ht_mcs[i]) - 1;
5382 nss = i;
5383 break;
5384 case WMI_RATE_PREAMBLE_VHT:
5385 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
5386 if (mask->control[band].vht_mcs[i])
5387 break;
5388
5389 if (i == NL80211_VHT_NSS_MAX)
5390 return false;
5391
5392 rate = ffs(mask->control[band].vht_mcs[i]) - 1;
5393 nss = i;
5394 break;
5395 }
5396
5397 *fixed_nss = nss + 1;
5398 nss <<= 4;
5399 pream <<= 6;
5400
Michal Kazior7aa7a722014-08-25 12:09:38 +02005401 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n",
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005402 pream, nss, rate);
5403
5404 *fixed_rate = pream | nss | rate;
5405
5406 return true;
5407}
5408
Michal Kazior7aa7a722014-08-25 12:09:38 +02005409static bool ath10k_get_fixed_rate_nss(struct ath10k *ar,
5410 const struct cfg80211_bitrate_mask *mask,
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005411 enum ieee80211_band band,
5412 u8 *fixed_rate,
5413 u8 *fixed_nss)
5414{
5415 /* First check full NSS mask, if we can simply limit NSS */
5416 if (ath10k_bitrate_mask_nss(mask, band, fixed_nss))
5417 return true;
5418
5419 /* Next Check single rate is set */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005420 return ath10k_bitrate_mask_rate(ar, mask, band, fixed_rate, fixed_nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005421}
5422
5423static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif,
5424 u8 fixed_rate,
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005425 u8 fixed_nss,
5426 u8 force_sgi)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005427{
5428 struct ath10k *ar = arvif->ar;
5429 u32 vdev_param;
5430 int ret = 0;
5431
5432 mutex_lock(&ar->conf_mutex);
5433
5434 if (arvif->fixed_rate == fixed_rate &&
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005435 arvif->fixed_nss == fixed_nss &&
5436 arvif->force_sgi == force_sgi)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005437 goto exit;
5438
5439 if (fixed_rate == WMI_FIXED_RATE_NONE)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005440 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac disable fixed bitrate mask\n");
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005441
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005442 if (force_sgi)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005443 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac force sgi\n");
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005444
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005445 vdev_param = ar->wmi.vdev_param->fixed_rate;
5446 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
5447 vdev_param, fixed_rate);
5448 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005449 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005450 fixed_rate, ret);
5451 ret = -EINVAL;
5452 goto exit;
5453 }
5454
5455 arvif->fixed_rate = fixed_rate;
5456
5457 vdev_param = ar->wmi.vdev_param->nss;
5458 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
5459 vdev_param, fixed_nss);
5460
5461 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005462 ath10k_warn(ar, "failed to set fixed nss param %d: %d\n",
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005463 fixed_nss, ret);
5464 ret = -EINVAL;
5465 goto exit;
5466 }
5467
5468 arvif->fixed_nss = fixed_nss;
5469
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005470 vdev_param = ar->wmi.vdev_param->sgi;
5471 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5472 force_sgi);
5473
5474 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005475 ath10k_warn(ar, "failed to set sgi param %d: %d\n",
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005476 force_sgi, ret);
5477 ret = -EINVAL;
5478 goto exit;
5479 }
5480
5481 arvif->force_sgi = force_sgi;
5482
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005483exit:
5484 mutex_unlock(&ar->conf_mutex);
5485 return ret;
5486}
5487
5488static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw,
5489 struct ieee80211_vif *vif,
5490 const struct cfg80211_bitrate_mask *mask)
5491{
5492 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5493 struct ath10k *ar = arvif->ar;
5494 enum ieee80211_band band = ar->hw->conf.chandef.chan->band;
5495 u8 fixed_rate = WMI_FIXED_RATE_NONE;
5496 u8 fixed_nss = ar->num_rf_chains;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005497 u8 force_sgi;
5498
Ben Greearb116ea12014-11-24 16:22:10 +02005499 if (ar->cfg_tx_chainmask)
5500 fixed_nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
5501
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005502 force_sgi = mask->control[band].gi;
5503 if (force_sgi == NL80211_TXRATE_FORCE_LGI)
5504 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005505
5506 if (!ath10k_default_bitrate_mask(ar, band, mask)) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005507 if (!ath10k_get_fixed_rate_nss(ar, mask, band,
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005508 &fixed_rate,
5509 &fixed_nss))
5510 return -EINVAL;
5511 }
5512
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005513 if (fixed_rate == WMI_FIXED_RATE_NONE && force_sgi) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005514 ath10k_warn(ar, "failed to force SGI usage for default rate settings\n");
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005515 return -EINVAL;
5516 }
5517
5518 return ath10k_set_fixed_rate_param(arvif, fixed_rate,
5519 fixed_nss, force_sgi);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005520}
5521
Michal Kazior9797feb2014-02-14 14:49:48 +01005522static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
5523 struct ieee80211_vif *vif,
5524 struct ieee80211_sta *sta,
5525 u32 changed)
5526{
5527 struct ath10k *ar = hw->priv;
5528 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5529 u32 bw, smps;
5530
5531 spin_lock_bh(&ar->data_lock);
5532
Michal Kazior7aa7a722014-08-25 12:09:38 +02005533 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01005534 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
5535 sta->addr, changed, sta->bandwidth, sta->rx_nss,
5536 sta->smps_mode);
5537
5538 if (changed & IEEE80211_RC_BW_CHANGED) {
5539 bw = WMI_PEER_CHWIDTH_20MHZ;
5540
5541 switch (sta->bandwidth) {
5542 case IEEE80211_STA_RX_BW_20:
5543 bw = WMI_PEER_CHWIDTH_20MHZ;
5544 break;
5545 case IEEE80211_STA_RX_BW_40:
5546 bw = WMI_PEER_CHWIDTH_40MHZ;
5547 break;
5548 case IEEE80211_STA_RX_BW_80:
5549 bw = WMI_PEER_CHWIDTH_80MHZ;
5550 break;
5551 case IEEE80211_STA_RX_BW_160:
Michal Kazior7aa7a722014-08-25 12:09:38 +02005552 ath10k_warn(ar, "Invalid bandwith %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02005553 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01005554 bw = WMI_PEER_CHWIDTH_20MHZ;
5555 break;
5556 }
5557
5558 arsta->bw = bw;
5559 }
5560
5561 if (changed & IEEE80211_RC_NSS_CHANGED)
5562 arsta->nss = sta->rx_nss;
5563
5564 if (changed & IEEE80211_RC_SMPS_CHANGED) {
5565 smps = WMI_PEER_SMPS_PS_NONE;
5566
5567 switch (sta->smps_mode) {
5568 case IEEE80211_SMPS_AUTOMATIC:
5569 case IEEE80211_SMPS_OFF:
5570 smps = WMI_PEER_SMPS_PS_NONE;
5571 break;
5572 case IEEE80211_SMPS_STATIC:
5573 smps = WMI_PEER_SMPS_STATIC;
5574 break;
5575 case IEEE80211_SMPS_DYNAMIC:
5576 smps = WMI_PEER_SMPS_DYNAMIC;
5577 break;
5578 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02005579 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02005580 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01005581 smps = WMI_PEER_SMPS_PS_NONE;
5582 break;
5583 }
5584
5585 arsta->smps = smps;
5586 }
5587
Michal Kazior9797feb2014-02-14 14:49:48 +01005588 arsta->changed |= changed;
5589
5590 spin_unlock_bh(&ar->data_lock);
5591
5592 ieee80211_queue_work(hw, &arsta->update_wk);
5593}
5594
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02005595static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
5596{
5597 /*
5598 * FIXME: Return 0 for time being. Need to figure out whether FW
5599 * has the API to fetch 64-bit local TSF
5600 */
5601
5602 return 0;
5603}
5604
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02005605static int ath10k_ampdu_action(struct ieee80211_hw *hw,
5606 struct ieee80211_vif *vif,
5607 enum ieee80211_ampdu_mlme_action action,
5608 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
5609 u8 buf_size)
5610{
Michal Kazior7aa7a722014-08-25 12:09:38 +02005611 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02005612 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5613
Michal Kazior7aa7a722014-08-25 12:09:38 +02005614 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 +02005615 arvif->vdev_id, sta->addr, tid, action);
5616
5617 switch (action) {
5618 case IEEE80211_AMPDU_RX_START:
5619 case IEEE80211_AMPDU_RX_STOP:
5620 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
5621 * creation/removal. Do we need to verify this?
5622 */
5623 return 0;
5624 case IEEE80211_AMPDU_TX_START:
5625 case IEEE80211_AMPDU_TX_STOP_CONT:
5626 case IEEE80211_AMPDU_TX_STOP_FLUSH:
5627 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
5628 case IEEE80211_AMPDU_TX_OPERATIONAL:
5629 /* Firmware offloads Tx aggregation entirely so deny mac80211
5630 * Tx aggregation requests.
5631 */
5632 return -EOPNOTSUPP;
5633 }
5634
5635 return -EINVAL;
5636}
5637
Kalle Valo5e3dd152013-06-12 20:52:10 +03005638static const struct ieee80211_ops ath10k_ops = {
5639 .tx = ath10k_tx,
5640 .start = ath10k_start,
5641 .stop = ath10k_stop,
5642 .config = ath10k_config,
5643 .add_interface = ath10k_add_interface,
5644 .remove_interface = ath10k_remove_interface,
5645 .configure_filter = ath10k_configure_filter,
5646 .bss_info_changed = ath10k_bss_info_changed,
5647 .hw_scan = ath10k_hw_scan,
5648 .cancel_hw_scan = ath10k_cancel_hw_scan,
5649 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005650 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005651 .sta_state = ath10k_sta_state,
5652 .conf_tx = ath10k_conf_tx,
5653 .remain_on_channel = ath10k_remain_on_channel,
5654 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
5655 .set_rts_threshold = ath10k_set_rts_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005656 .flush = ath10k_flush,
5657 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03005658 .set_antenna = ath10k_set_antenna,
5659 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02005660 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02005661 .get_survey = ath10k_get_survey,
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005662 .set_bitrate_mask = ath10k_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01005663 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02005664 .get_tsf = ath10k_get_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02005665 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03005666 .get_et_sset_count = ath10k_debug_get_et_sset_count,
5667 .get_et_stats = ath10k_debug_get_et_stats,
5668 .get_et_strings = ath10k_debug_get_et_strings,
Kalle Valo43d2a302014-09-10 18:23:30 +03005669
5670 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
5671
Michal Kazior8cd13ca2013-07-16 09:38:54 +02005672#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02005673 .suspend = ath10k_wow_op_suspend,
5674 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02005675#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02005676#ifdef CONFIG_MAC80211_DEBUGFS
5677 .sta_add_debugfs = ath10k_sta_add_debugfs,
5678#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03005679};
5680
Kalle Valo5e3dd152013-06-12 20:52:10 +03005681#define CHAN2G(_channel, _freq, _flags) { \
5682 .band = IEEE80211_BAND_2GHZ, \
5683 .hw_value = (_channel), \
5684 .center_freq = (_freq), \
5685 .flags = (_flags), \
5686 .max_antenna_gain = 0, \
5687 .max_power = 30, \
5688}
5689
5690#define CHAN5G(_channel, _freq, _flags) { \
5691 .band = IEEE80211_BAND_5GHZ, \
5692 .hw_value = (_channel), \
5693 .center_freq = (_freq), \
5694 .flags = (_flags), \
5695 .max_antenna_gain = 0, \
5696 .max_power = 30, \
5697}
5698
5699static const struct ieee80211_channel ath10k_2ghz_channels[] = {
5700 CHAN2G(1, 2412, 0),
5701 CHAN2G(2, 2417, 0),
5702 CHAN2G(3, 2422, 0),
5703 CHAN2G(4, 2427, 0),
5704 CHAN2G(5, 2432, 0),
5705 CHAN2G(6, 2437, 0),
5706 CHAN2G(7, 2442, 0),
5707 CHAN2G(8, 2447, 0),
5708 CHAN2G(9, 2452, 0),
5709 CHAN2G(10, 2457, 0),
5710 CHAN2G(11, 2462, 0),
5711 CHAN2G(12, 2467, 0),
5712 CHAN2G(13, 2472, 0),
5713 CHAN2G(14, 2484, 0),
5714};
5715
5716static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02005717 CHAN5G(36, 5180, 0),
5718 CHAN5G(40, 5200, 0),
5719 CHAN5G(44, 5220, 0),
5720 CHAN5G(48, 5240, 0),
5721 CHAN5G(52, 5260, 0),
5722 CHAN5G(56, 5280, 0),
5723 CHAN5G(60, 5300, 0),
5724 CHAN5G(64, 5320, 0),
5725 CHAN5G(100, 5500, 0),
5726 CHAN5G(104, 5520, 0),
5727 CHAN5G(108, 5540, 0),
5728 CHAN5G(112, 5560, 0),
5729 CHAN5G(116, 5580, 0),
5730 CHAN5G(120, 5600, 0),
5731 CHAN5G(124, 5620, 0),
5732 CHAN5G(128, 5640, 0),
5733 CHAN5G(132, 5660, 0),
5734 CHAN5G(136, 5680, 0),
5735 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07005736 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02005737 CHAN5G(149, 5745, 0),
5738 CHAN5G(153, 5765, 0),
5739 CHAN5G(157, 5785, 0),
5740 CHAN5G(161, 5805, 0),
5741 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03005742};
5743
Michal Kaziore7b54192014-08-07 11:03:27 +02005744struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005745{
5746 struct ieee80211_hw *hw;
5747 struct ath10k *ar;
5748
Michal Kaziore7b54192014-08-07 11:03:27 +02005749 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005750 if (!hw)
5751 return NULL;
5752
5753 ar = hw->priv;
5754 ar->hw = hw;
5755
5756 return ar;
5757}
5758
5759void ath10k_mac_destroy(struct ath10k *ar)
5760{
5761 ieee80211_free_hw(ar->hw);
5762}
5763
5764static const struct ieee80211_iface_limit ath10k_if_limits[] = {
5765 {
5766 .max = 8,
5767 .types = BIT(NL80211_IFTYPE_STATION)
5768 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02005769 },
5770 {
5771 .max = 3,
5772 .types = BIT(NL80211_IFTYPE_P2P_GO)
5773 },
5774 {
Michal Kazior75d2bd42014-12-12 12:41:39 +01005775 .max = 1,
5776 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
5777 },
5778 {
Michal Kaziord531cb82013-07-31 10:55:13 +02005779 .max = 7,
5780 .types = BIT(NL80211_IFTYPE_AP)
5781 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03005782};
5783
Bartosz Markowskif2595092013-12-10 16:20:39 +01005784static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02005785 {
5786 .max = 8,
5787 .types = BIT(NL80211_IFTYPE_AP)
5788 },
5789};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02005790
5791static const struct ieee80211_iface_combination ath10k_if_comb[] = {
5792 {
5793 .limits = ath10k_if_limits,
5794 .n_limits = ARRAY_SIZE(ath10k_if_limits),
5795 .max_interfaces = 8,
5796 .num_different_channels = 1,
5797 .beacon_int_infra_match = true,
5798 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01005799};
5800
5801static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02005802 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01005803 .limits = ath10k_10x_if_limits,
5804 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02005805 .max_interfaces = 8,
5806 .num_different_channels = 1,
5807 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01005808#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02005809 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
5810 BIT(NL80211_CHAN_WIDTH_20) |
5811 BIT(NL80211_CHAN_WIDTH_40) |
5812 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02005813#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01005814 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03005815};
5816
5817static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
5818{
5819 struct ieee80211_sta_vht_cap vht_cap = {0};
5820 u16 mcs_map;
Michal Kaziorbc657a362015-02-26 11:11:22 +01005821 u32 val;
Michal Kazior8865bee42013-07-24 12:36:46 +02005822 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005823
5824 vht_cap.vht_supported = 1;
5825 vht_cap.cap = ar->vht_cap_info;
5826
Michal Kaziorbc657a362015-02-26 11:11:22 +01005827 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
5828 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
5829 val = ar->num_rf_chains - 1;
5830 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
5831 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
5832
5833 vht_cap.cap |= val;
5834 }
5835
5836 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
5837 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
5838 val = ar->num_rf_chains - 1;
5839 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
5840 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
5841
5842 vht_cap.cap |= val;
5843 }
5844
Michal Kazior8865bee42013-07-24 12:36:46 +02005845 mcs_map = 0;
5846 for (i = 0; i < 8; i++) {
5847 if (i < ar->num_rf_chains)
5848 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i*2);
5849 else
5850 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2);
5851 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005852
5853 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
5854 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
5855
5856 return vht_cap;
5857}
5858
5859static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
5860{
5861 int i;
5862 struct ieee80211_sta_ht_cap ht_cap = {0};
5863
5864 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
5865 return ht_cap;
5866
5867 ht_cap.ht_supported = 1;
5868 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5869 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
5870 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5871 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5872 ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT;
5873
5874 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
5875 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5876
5877 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
5878 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5879
5880 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
5881 u32 smps;
5882
5883 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
5884 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
5885
5886 ht_cap.cap |= smps;
5887 }
5888
5889 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC)
5890 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
5891
5892 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
5893 u32 stbc;
5894
5895 stbc = ar->ht_cap_info;
5896 stbc &= WMI_HT_CAP_RX_STBC;
5897 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
5898 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
5899 stbc &= IEEE80211_HT_CAP_RX_STBC;
5900
5901 ht_cap.cap |= stbc;
5902 }
5903
5904 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
5905 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
5906
5907 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
5908 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
5909
5910 /* max AMSDU is implicitly taken from vht_cap_info */
5911 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
5912 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
5913
Michal Kazior8865bee42013-07-24 12:36:46 +02005914 for (i = 0; i < ar->num_rf_chains; i++)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005915 ht_cap.mcs.rx_mask[i] = 0xFF;
5916
5917 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
5918
5919 return ht_cap;
5920}
5921
Kalle Valo5e3dd152013-06-12 20:52:10 +03005922static void ath10k_get_arvif_iter(void *data, u8 *mac,
5923 struct ieee80211_vif *vif)
5924{
5925 struct ath10k_vif_iter *arvif_iter = data;
5926 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5927
5928 if (arvif->vdev_id == arvif_iter->vdev_id)
5929 arvif_iter->arvif = arvif;
5930}
5931
5932struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
5933{
5934 struct ath10k_vif_iter arvif_iter;
5935 u32 flags;
5936
5937 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
5938 arvif_iter.vdev_id = vdev_id;
5939
5940 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
5941 ieee80211_iterate_active_interfaces_atomic(ar->hw,
5942 flags,
5943 ath10k_get_arvif_iter,
5944 &arvif_iter);
5945 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005946 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005947 return NULL;
5948 }
5949
5950 return arvif_iter.arvif;
5951}
5952
5953int ath10k_mac_register(struct ath10k *ar)
5954{
Johannes Berg3cb10942015-01-22 21:38:45 +01005955 static const u32 cipher_suites[] = {
5956 WLAN_CIPHER_SUITE_WEP40,
5957 WLAN_CIPHER_SUITE_WEP104,
5958 WLAN_CIPHER_SUITE_TKIP,
5959 WLAN_CIPHER_SUITE_CCMP,
5960 WLAN_CIPHER_SUITE_AES_CMAC,
5961 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03005962 struct ieee80211_supported_band *band;
5963 struct ieee80211_sta_vht_cap vht_cap;
5964 struct ieee80211_sta_ht_cap ht_cap;
5965 void *channels;
5966 int ret;
5967
5968 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
5969
5970 SET_IEEE80211_DEV(ar->hw, ar->dev);
5971
5972 ht_cap = ath10k_get_ht_cap(ar);
5973 vht_cap = ath10k_create_vht_cap(ar);
5974
5975 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
5976 channels = kmemdup(ath10k_2ghz_channels,
5977 sizeof(ath10k_2ghz_channels),
5978 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02005979 if (!channels) {
5980 ret = -ENOMEM;
5981 goto err_free;
5982 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005983
5984 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
5985 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
5986 band->channels = channels;
5987 band->n_bitrates = ath10k_g_rates_size;
5988 band->bitrates = ath10k_g_rates;
5989 band->ht_cap = ht_cap;
5990
Yanbo Lid68bb122015-01-23 08:18:20 +08005991 /* Enable the VHT support at 2.4 GHz */
5992 band->vht_cap = vht_cap;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005993
5994 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
5995 }
5996
5997 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
5998 channels = kmemdup(ath10k_5ghz_channels,
5999 sizeof(ath10k_5ghz_channels),
6000 GFP_KERNEL);
6001 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02006002 ret = -ENOMEM;
6003 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006004 }
6005
6006 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
6007 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
6008 band->channels = channels;
6009 band->n_bitrates = ath10k_a_rates_size;
6010 band->bitrates = ath10k_a_rates;
6011 band->ht_cap = ht_cap;
6012 band->vht_cap = vht_cap;
6013 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
6014 }
6015
6016 ar->hw->wiphy->interface_modes =
6017 BIT(NL80211_IFTYPE_STATION) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01006018 BIT(NL80211_IFTYPE_AP);
6019
Ben Greear46acf7b2014-05-16 17:15:38 +03006020 ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask;
6021 ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask;
6022
Bartosz Markowskid3541812013-12-10 16:20:40 +01006023 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
6024 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01006025 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01006026 BIT(NL80211_IFTYPE_P2P_CLIENT) |
6027 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006028
6029 ar->hw->flags = IEEE80211_HW_SIGNAL_DBM |
6030 IEEE80211_HW_SUPPORTS_PS |
6031 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
Kalle Valo5e3dd152013-06-12 20:52:10 +03006032 IEEE80211_HW_MFP_CAPABLE |
6033 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
6034 IEEE80211_HW_HAS_RATE_CONTROL |
Janusz Dziedzic2f0f1122014-02-26 18:42:09 +02006035 IEEE80211_HW_AP_LINK_PS |
Johannes Berg3cb10942015-01-22 21:38:45 +01006036 IEEE80211_HW_SPECTRUM_MGMT |
Michal Kaziorcc9904e2015-03-10 16:22:01 +02006037 IEEE80211_HW_SW_CRYPTO_CONTROL |
6038 IEEE80211_HW_CONNECTION_MONITOR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006039
Eliad Peller0d8614b2014-09-10 14:07:36 +03006040 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
6041
Kalle Valo5e3dd152013-06-12 20:52:10 +03006042 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03006043 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006044
6045 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
6046 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
6047 ar->hw->flags |= IEEE80211_HW_TX_AMPDU_SETUP_IN_HW;
6048 }
6049
6050 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
6051 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
6052
6053 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01006054 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006055
Kalle Valo5e3dd152013-06-12 20:52:10 +03006056 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
6057
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02006058 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
6059 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
6060
6061 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
6062 * that userspace (e.g. wpa_supplicant/hostapd) can generate
6063 * correct Probe Responses. This is more of a hack advert..
6064 */
6065 ar->hw->wiphy->probe_resp_offload |=
6066 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
6067 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
6068 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
6069 }
6070
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006071 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
6072 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
6073
Kalle Valo5e3dd152013-06-12 20:52:10 +03006074 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01006075 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006076 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
6077
6078 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02006079 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
6080
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01006081 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
6082
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02006083 ret = ath10k_wow_init(ar);
6084 if (ret) {
6085 ath10k_warn(ar, "failed to init wow: %d\n", ret);
6086 goto err_free;
6087 }
6088
Kalle Valo5e3dd152013-06-12 20:52:10 +03006089 /*
6090 * on LL hardware queues are managed entirely by the FW
6091 * so we only advertise to mac we can do the queues thing
6092 */
6093 ar->hw->queues = 4;
6094
Kalle Valo5cc7caf2014-12-17 12:20:54 +02006095 switch (ar->wmi.op_version) {
6096 case ATH10K_FW_WMI_OP_VERSION_MAIN:
6097 case ATH10K_FW_WMI_OP_VERSION_TLV:
Bartosz Markowskif2595092013-12-10 16:20:39 +01006098 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
6099 ar->hw->wiphy->n_iface_combinations =
6100 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03006101 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02006102 break;
6103 case ATH10K_FW_WMI_OP_VERSION_10_1:
6104 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02006105 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02006106 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
6107 ar->hw->wiphy->n_iface_combinations =
6108 ARRAY_SIZE(ath10k_10x_if_comb);
6109 break;
6110 case ATH10K_FW_WMI_OP_VERSION_UNSET:
6111 case ATH10K_FW_WMI_OP_VERSION_MAX:
6112 WARN_ON(1);
6113 ret = -EINVAL;
6114 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01006115 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006116
Michal Kazior7c199992013-07-31 10:47:57 +02006117 ar->hw->netdev_features = NETIF_F_HW_CSUM;
6118
Janusz Dziedzic9702c682013-11-20 09:59:41 +02006119 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
6120 /* Init ath dfs pattern detector */
6121 ar->ath_common.debug_mask = ATH_DBG_DFS;
6122 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
6123 NL80211_DFS_UNSET);
6124
6125 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006126 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02006127 }
6128
Kalle Valo5e3dd152013-06-12 20:52:10 +03006129 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
6130 ath10k_reg_notifier);
6131 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006132 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Michal Kaziord6015b22013-07-22 14:13:30 +02006133 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006134 }
6135
Johannes Berg3cb10942015-01-22 21:38:45 +01006136 ar->hw->wiphy->cipher_suites = cipher_suites;
6137 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
6138
Kalle Valo5e3dd152013-06-12 20:52:10 +03006139 ret = ieee80211_register_hw(ar->hw);
6140 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006141 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Michal Kaziord6015b22013-07-22 14:13:30 +02006142 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006143 }
6144
6145 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
6146 ret = regulatory_hint(ar->hw->wiphy,
6147 ar->ath_common.regulatory.alpha2);
6148 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02006149 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006150 }
6151
6152 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02006153
6154err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006155 ieee80211_unregister_hw(ar->hw);
Michal Kaziord6015b22013-07-22 14:13:30 +02006156err_free:
6157 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
6158 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
6159
Kalle Valo5e3dd152013-06-12 20:52:10 +03006160 return ret;
6161}
6162
6163void ath10k_mac_unregister(struct ath10k *ar)
6164{
6165 ieee80211_unregister_hw(ar->hw);
6166
Janusz Dziedzic9702c682013-11-20 09:59:41 +02006167 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
6168 ar->dfs_detector->exit(ar->dfs_detector);
6169
Kalle Valo5e3dd152013-06-12 20:52:10 +03006170 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
6171 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
6172
6173 SET_IEEE80211_DEV(ar->hw, NULL);
6174}