blob: dd0dd6e4bb0a657b337f1f672cf208362f51ea9d [file] [log] [blame]
Kalle Valo5e3dd152013-06-12 20:52:10 +03001/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include "mac.h"
19
20#include <net/mac80211.h>
21#include <linux/etherdevice.h>
22
Michal Kazior8cd13ca2013-07-16 09:38:54 +020023#include "hif.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030024#include "core.h"
25#include "debug.h"
26#include "wmi.h"
27#include "htt.h"
28#include "txrx.h"
Kalle Valo43d2a302014-09-10 18:23:30 +030029#include "testmode.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020030#include "wmi.h"
Michal Kaziorb4aa5392015-03-31 10:26:24 +000031#include "wmi-tlv.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020032#include "wmi-ops.h"
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +020033#include "wow.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030034
Michal Kaziordcc33092015-03-30 09:51:54 +030035/*********/
36/* Rates */
37/*********/
38
Michal Kaziordcc33092015-03-30 09:51:54 +030039static struct ieee80211_rate ath10k_rates[] = {
Michal Kazior5528e032015-03-30 09:51:56 +030040 { .bitrate = 10,
41 .hw_value = ATH10K_HW_RATE_CCK_LP_1M },
42 { .bitrate = 20,
43 .hw_value = ATH10K_HW_RATE_CCK_LP_2M,
44 .hw_value_short = ATH10K_HW_RATE_CCK_SP_2M,
45 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
46 { .bitrate = 55,
47 .hw_value = ATH10K_HW_RATE_CCK_LP_5_5M,
48 .hw_value_short = ATH10K_HW_RATE_CCK_SP_5_5M,
49 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
50 { .bitrate = 110,
51 .hw_value = ATH10K_HW_RATE_CCK_LP_11M,
52 .hw_value_short = ATH10K_HW_RATE_CCK_SP_11M,
53 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
Michal Kazior5653b392015-03-30 09:51:54 +030054
Michal Kazioraf001482015-03-30 09:51:56 +030055 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
56 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
57 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
58 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
59 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
60 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
61 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
62 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
Michal Kaziordcc33092015-03-30 09:51:54 +030063};
64
Michal Kazior8d7aa6b2015-03-30 09:51:57 +030065#define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
66
67#define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
68#define ath10k_a_rates_size (ARRAY_SIZE(ath10k_rates) - \
69 ATH10K_MAC_FIRST_OFDM_RATE_IDX)
Michal Kaziordcc33092015-03-30 09:51:54 +030070#define ath10k_g_rates (ath10k_rates + 0)
71#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
72
Michal Kazior486017c2015-03-30 09:51:54 +030073static bool ath10k_mac_bitrate_is_cck(int bitrate)
74{
75 switch (bitrate) {
76 case 10:
77 case 20:
78 case 55:
79 case 110:
80 return true;
81 }
82
83 return false;
84}
85
86static u8 ath10k_mac_bitrate_to_rate(int bitrate)
87{
88 return DIV_ROUND_UP(bitrate, 5) |
89 (ath10k_mac_bitrate_is_cck(bitrate) ? BIT(7) : 0);
90}
91
Michal Kazior5528e032015-03-30 09:51:56 +030092u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
93 u8 hw_rate)
94{
95 const struct ieee80211_rate *rate;
96 int i;
97
98 for (i = 0; i < sband->n_bitrates; i++) {
99 rate = &sband->bitrates[i];
100
101 if (rate->hw_value == hw_rate)
102 return i;
103 else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
104 rate->hw_value_short == hw_rate)
105 return i;
106 }
107
108 return 0;
109}
110
Michal Kazior01cebe12015-03-30 09:51:56 +0300111u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
112 u32 bitrate)
113{
114 int i;
115
116 for (i = 0; i < sband->n_bitrates; i++)
117 if (sband->bitrates[i].bitrate == bitrate)
118 return i;
119
120 return 0;
121}
122
Michal Kazior3ae54222015-03-31 10:49:20 +0000123static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
124{
125 switch ((mcs_map >> (2 * nss)) & 0x3) {
126 case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;
127 case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;
128 case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;
129 }
130 return 0;
131}
132
Kalle Valo5e3dd152013-06-12 20:52:10 +0300133/**********/
134/* Crypto */
135/**********/
136
137static int ath10k_send_key(struct ath10k_vif *arvif,
138 struct ieee80211_key_conf *key,
139 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100140 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300141{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200142 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300143 struct wmi_vdev_install_key_arg arg = {
144 .vdev_id = arvif->vdev_id,
145 .key_idx = key->keyidx,
146 .key_len = key->keylen,
147 .key_data = key->key,
Michal Kazior370e5672015-02-18 14:02:26 +0100148 .key_flags = flags,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300149 .macaddr = macaddr,
150 };
151
Michal Kazior548db542013-07-05 16:15:15 +0300152 lockdep_assert_held(&arvif->ar->conf_mutex);
153
Kalle Valo5e3dd152013-06-12 20:52:10 +0300154 switch (key->cipher) {
155 case WLAN_CIPHER_SUITE_CCMP:
156 arg.key_cipher = WMI_CIPHER_AES_CCM;
Marek Kwaczynskie4e82e92015-01-24 12:14:53 +0200157 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300158 break;
159 case WLAN_CIPHER_SUITE_TKIP:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300160 arg.key_cipher = WMI_CIPHER_TKIP;
161 arg.key_txmic_len = 8;
162 arg.key_rxmic_len = 8;
163 break;
164 case WLAN_CIPHER_SUITE_WEP40:
165 case WLAN_CIPHER_SUITE_WEP104:
166 arg.key_cipher = WMI_CIPHER_WEP;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300167 break;
Johannes Berg3cb10942015-01-22 21:38:45 +0100168 case WLAN_CIPHER_SUITE_AES_CMAC:
Bartosz Markowskid7131c02015-03-10 14:32:19 +0100169 WARN_ON(1);
170 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300171 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200172 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300173 return -EOPNOTSUPP;
174 }
175
176 if (cmd == DISABLE_KEY) {
177 arg.key_cipher = WMI_CIPHER_NONE;
178 arg.key_data = NULL;
179 }
180
181 return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
182}
183
184static int ath10k_install_key(struct ath10k_vif *arvif,
185 struct ieee80211_key_conf *key,
186 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100187 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300188{
189 struct ath10k *ar = arvif->ar;
190 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300191 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300192
Michal Kazior548db542013-07-05 16:15:15 +0300193 lockdep_assert_held(&ar->conf_mutex);
194
Wolfram Sang16735d02013-11-14 14:32:02 -0800195 reinit_completion(&ar->install_key_done);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300196
Michal Kazior370e5672015-02-18 14:02:26 +0100197 ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300198 if (ret)
199 return ret;
200
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300201 time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);
202 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300203 return -ETIMEDOUT;
204
205 return 0;
206}
207
208static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
209 const u8 *addr)
210{
211 struct ath10k *ar = arvif->ar;
212 struct ath10k_peer *peer;
213 int ret;
214 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100215 u32 flags;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300216
217 lockdep_assert_held(&ar->conf_mutex);
218
219 spin_lock_bh(&ar->data_lock);
220 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
221 spin_unlock_bh(&ar->data_lock);
222
223 if (!peer)
224 return -ENOENT;
225
226 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
227 if (arvif->wep_keys[i] == NULL)
228 continue;
Michal Kazior370e5672015-02-18 14:02:26 +0100229
230 flags = 0;
231 flags |= WMI_KEY_PAIRWISE;
232
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200233 /* set TX_USAGE flag for default key id */
234 if (arvif->def_wep_key_idx == i)
Michal Kazior370e5672015-02-18 14:02:26 +0100235 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300236
237 ret = ath10k_install_key(arvif, arvif->wep_keys[i], SET_KEY,
Michal Kazior370e5672015-02-18 14:02:26 +0100238 addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300239 if (ret)
240 return ret;
241
Sujith Manoharanae167132014-11-25 11:46:59 +0530242 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300243 peer->keys[i] = arvif->wep_keys[i];
Sujith Manoharanae167132014-11-25 11:46:59 +0530244 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300245 }
246
247 return 0;
248}
249
250static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
251 const u8 *addr)
252{
253 struct ath10k *ar = arvif->ar;
254 struct ath10k_peer *peer;
255 int first_errno = 0;
256 int ret;
257 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100258 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300259
260 lockdep_assert_held(&ar->conf_mutex);
261
262 spin_lock_bh(&ar->data_lock);
263 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
264 spin_unlock_bh(&ar->data_lock);
265
266 if (!peer)
267 return -ENOENT;
268
269 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
270 if (peer->keys[i] == NULL)
271 continue;
272
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200273 /* key flags are not required to delete the key */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300274 ret = ath10k_install_key(arvif, peer->keys[i],
Michal Kazior370e5672015-02-18 14:02:26 +0100275 DISABLE_KEY, addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300276 if (ret && first_errno == 0)
277 first_errno = ret;
278
279 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200280 ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300281 i, ret);
282
Sujith Manoharanae167132014-11-25 11:46:59 +0530283 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300284 peer->keys[i] = NULL;
Sujith Manoharanae167132014-11-25 11:46:59 +0530285 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300286 }
287
288 return first_errno;
289}
290
Sujith Manoharan504f6cd2014-11-25 11:46:58 +0530291bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
292 u8 keyidx)
293{
294 struct ath10k_peer *peer;
295 int i;
296
297 lockdep_assert_held(&ar->data_lock);
298
299 /* We don't know which vdev this peer belongs to,
300 * since WMI doesn't give us that information.
301 *
302 * FIXME: multi-bss needs to be handled.
303 */
304 peer = ath10k_peer_find(ar, 0, addr);
305 if (!peer)
306 return false;
307
308 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
309 if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)
310 return true;
311 }
312
313 return false;
314}
315
Kalle Valo5e3dd152013-06-12 20:52:10 +0300316static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
317 struct ieee80211_key_conf *key)
318{
319 struct ath10k *ar = arvif->ar;
320 struct ath10k_peer *peer;
321 u8 addr[ETH_ALEN];
322 int first_errno = 0;
323 int ret;
324 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100325 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300326
327 lockdep_assert_held(&ar->conf_mutex);
328
329 for (;;) {
330 /* since ath10k_install_key we can't hold data_lock all the
331 * time, so we try to remove the keys incrementally */
332 spin_lock_bh(&ar->data_lock);
333 i = 0;
334 list_for_each_entry(peer, &ar->peers, list) {
335 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
336 if (peer->keys[i] == key) {
Kalle Valob25f32c2014-09-14 12:50:49 +0300337 ether_addr_copy(addr, peer->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300338 peer->keys[i] = NULL;
339 break;
340 }
341 }
342
343 if (i < ARRAY_SIZE(peer->keys))
344 break;
345 }
346 spin_unlock_bh(&ar->data_lock);
347
348 if (i == ARRAY_SIZE(peer->keys))
349 break;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200350 /* key flags are not required to delete the key */
Michal Kazior370e5672015-02-18 14:02:26 +0100351 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300352 if (ret && first_errno == 0)
353 first_errno = ret;
354
355 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200356 ath10k_warn(ar, "failed to remove key for %pM: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +0200357 addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300358 }
359
360 return first_errno;
361}
362
Michal Kaziorad325cb2015-02-18 14:02:27 +0100363static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
364 struct ieee80211_key_conf *key)
365{
366 struct ath10k *ar = arvif->ar;
367 struct ath10k_peer *peer;
368 int ret;
369
370 lockdep_assert_held(&ar->conf_mutex);
371
372 list_for_each_entry(peer, &ar->peers, list) {
373 if (!memcmp(peer->addr, arvif->vif->addr, ETH_ALEN))
374 continue;
375
376 if (!memcmp(peer->addr, arvif->bssid, ETH_ALEN))
377 continue;
378
379 if (peer->keys[key->keyidx] == key)
380 continue;
381
382 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
383 arvif->vdev_id, key->keyidx);
384
385 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
386 if (ret) {
387 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
388 arvif->vdev_id, peer->addr, ret);
389 return ret;
390 }
391 }
392
393 return 0;
394}
395
Kalle Valo5e3dd152013-06-12 20:52:10 +0300396/*********************/
397/* General utilities */
398/*********************/
399
400static inline enum wmi_phy_mode
401chan_to_phymode(const struct cfg80211_chan_def *chandef)
402{
403 enum wmi_phy_mode phymode = MODE_UNKNOWN;
404
405 switch (chandef->chan->band) {
406 case IEEE80211_BAND_2GHZ:
407 switch (chandef->width) {
408 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800409 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
410 phymode = MODE_11B;
411 else
412 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300413 break;
414 case NL80211_CHAN_WIDTH_20:
415 phymode = MODE_11NG_HT20;
416 break;
417 case NL80211_CHAN_WIDTH_40:
418 phymode = MODE_11NG_HT40;
419 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400420 case NL80211_CHAN_WIDTH_5:
421 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300422 case NL80211_CHAN_WIDTH_80:
423 case NL80211_CHAN_WIDTH_80P80:
424 case NL80211_CHAN_WIDTH_160:
425 phymode = MODE_UNKNOWN;
426 break;
427 }
428 break;
429 case IEEE80211_BAND_5GHZ:
430 switch (chandef->width) {
431 case NL80211_CHAN_WIDTH_20_NOHT:
432 phymode = MODE_11A;
433 break;
434 case NL80211_CHAN_WIDTH_20:
435 phymode = MODE_11NA_HT20;
436 break;
437 case NL80211_CHAN_WIDTH_40:
438 phymode = MODE_11NA_HT40;
439 break;
440 case NL80211_CHAN_WIDTH_80:
441 phymode = MODE_11AC_VHT80;
442 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400443 case NL80211_CHAN_WIDTH_5:
444 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300445 case NL80211_CHAN_WIDTH_80P80:
446 case NL80211_CHAN_WIDTH_160:
447 phymode = MODE_UNKNOWN;
448 break;
449 }
450 break;
451 default:
452 break;
453 }
454
455 WARN_ON(phymode == MODE_UNKNOWN);
456 return phymode;
457}
458
459static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
460{
461/*
462 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
463 * 0 for no restriction
464 * 1 for 1/4 us
465 * 2 for 1/2 us
466 * 3 for 1 us
467 * 4 for 2 us
468 * 5 for 4 us
469 * 6 for 8 us
470 * 7 for 16 us
471 */
472 switch (mpdudensity) {
473 case 0:
474 return 0;
475 case 1:
476 case 2:
477 case 3:
478 /* Our lower layer calculations limit our precision to
479 1 microsecond */
480 return 1;
481 case 4:
482 return 2;
483 case 5:
484 return 4;
485 case 6:
486 return 8;
487 case 7:
488 return 16;
489 default:
490 return 0;
491 }
492}
493
Michal Kazior500ff9f2015-03-31 10:26:21 +0000494int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
495 struct cfg80211_chan_def *def)
496{
497 struct ieee80211_chanctx_conf *conf;
498
499 rcu_read_lock();
500 conf = rcu_dereference(vif->chanctx_conf);
501 if (!conf) {
502 rcu_read_unlock();
503 return -ENOENT;
504 }
505
506 *def = conf->def;
507 rcu_read_unlock();
508
509 return 0;
510}
511
512static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,
513 struct ieee80211_chanctx_conf *conf,
514 void *data)
515{
516 int *num = data;
517
518 (*num)++;
519}
520
521static int ath10k_mac_num_chanctxs(struct ath10k *ar)
522{
523 int num = 0;
524
525 ieee80211_iter_chan_contexts_atomic(ar->hw,
526 ath10k_mac_num_chanctxs_iter,
527 &num);
528
529 return num;
530}
531
532static void
533ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
534 struct ieee80211_chanctx_conf *conf,
535 void *data)
536{
537 struct cfg80211_chan_def **def = data;
538
539 *def = &conf->def;
540}
541
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300542static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr,
543 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300544{
545 int ret;
546
547 lockdep_assert_held(&ar->conf_mutex);
548
Michal Kaziorcfd10612014-11-25 15:16:05 +0100549 if (ar->num_peers >= ar->max_num_peers)
550 return -ENOBUFS;
551
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300552 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800553 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200554 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200555 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300556 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800557 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300558
559 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800560 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200561 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200562 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300563 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800564 }
Michal Kazior292a7532014-11-25 15:16:04 +0100565
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100566 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300567
568 return 0;
569}
570
Kalle Valo5a13e762014-01-20 11:01:46 +0200571static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
572{
573 struct ath10k *ar = arvif->ar;
574 u32 param;
575 int ret;
576
577 param = ar->wmi.pdev_param->sta_kickout_th;
578 ret = ath10k_wmi_pdev_set_param(ar, param,
579 ATH10K_KICKOUT_THRESHOLD);
580 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200581 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200582 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200583 return ret;
584 }
585
586 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
587 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
588 ATH10K_KEEPALIVE_MIN_IDLE);
589 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200590 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200591 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200592 return ret;
593 }
594
595 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
596 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
597 ATH10K_KEEPALIVE_MAX_IDLE);
598 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200599 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200600 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200601 return ret;
602 }
603
604 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
605 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
606 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
607 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200608 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200609 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200610 return ret;
611 }
612
613 return 0;
614}
615
Vivek Natarajanacab6402014-11-26 09:06:12 +0200616static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200617{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200618 struct ath10k *ar = arvif->ar;
619 u32 vdev_param;
620
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200621 vdev_param = ar->wmi.vdev_param->rts_threshold;
622 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200623}
624
625static int ath10k_mac_set_frag(struct ath10k_vif *arvif, u32 value)
626{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200627 struct ath10k *ar = arvif->ar;
628 u32 vdev_param;
629
Michal Kazior424121c2013-07-22 14:13:31 +0200630 if (value != 0xFFFFFFFF)
631 value = clamp_t(u32, arvif->ar->hw->wiphy->frag_threshold,
632 ATH10K_FRAGMT_THRESHOLD_MIN,
633 ATH10K_FRAGMT_THRESHOLD_MAX);
634
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200635 vdev_param = ar->wmi.vdev_param->fragmentation_threshold;
636 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200637}
638
Kalle Valo5e3dd152013-06-12 20:52:10 +0300639static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
640{
641 int ret;
642
643 lockdep_assert_held(&ar->conf_mutex);
644
645 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
646 if (ret)
647 return ret;
648
649 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
650 if (ret)
651 return ret;
652
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100653 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100654
Kalle Valo5e3dd152013-06-12 20:52:10 +0300655 return 0;
656}
657
658static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
659{
660 struct ath10k_peer *peer, *tmp;
661
662 lockdep_assert_held(&ar->conf_mutex);
663
664 spin_lock_bh(&ar->data_lock);
665 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
666 if (peer->vdev_id != vdev_id)
667 continue;
668
Michal Kazior7aa7a722014-08-25 12:09:38 +0200669 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300670 peer->addr, vdev_id);
671
672 list_del(&peer->list);
673 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100674 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300675 }
676 spin_unlock_bh(&ar->data_lock);
677}
678
Michal Kaziora96d7742013-07-16 09:38:56 +0200679static void ath10k_peer_cleanup_all(struct ath10k *ar)
680{
681 struct ath10k_peer *peer, *tmp;
682
683 lockdep_assert_held(&ar->conf_mutex);
684
685 spin_lock_bh(&ar->data_lock);
686 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
687 list_del(&peer->list);
688 kfree(peer);
689 }
690 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100691
692 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100693 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200694}
695
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300696static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
697 struct ieee80211_sta *sta,
698 enum wmi_tdls_peer_state state)
699{
700 int ret;
701 struct wmi_tdls_peer_update_cmd_arg arg = {};
702 struct wmi_tdls_peer_capab_arg cap = {};
703 struct wmi_channel_arg chan_arg = {};
704
705 lockdep_assert_held(&ar->conf_mutex);
706
707 arg.vdev_id = vdev_id;
708 arg.peer_state = state;
709 ether_addr_copy(arg.addr, sta->addr);
710
711 cap.peer_max_sp = sta->max_sp;
712 cap.peer_uapsd_queues = sta->uapsd_queues;
713
714 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
715 !sta->tdls_initiator)
716 cap.is_peer_responder = 1;
717
718 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
719 if (ret) {
720 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
721 arg.addr, vdev_id, ret);
722 return ret;
723 }
724
725 return 0;
726}
727
Kalle Valo5e3dd152013-06-12 20:52:10 +0300728/************************/
729/* Interface management */
730/************************/
731
Michal Kazior64badcb2014-09-18 11:18:02 +0300732void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
733{
734 struct ath10k *ar = arvif->ar;
735
736 lockdep_assert_held(&ar->data_lock);
737
738 if (!arvif->beacon)
739 return;
740
741 if (!arvif->beacon_buf)
742 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
743 arvif->beacon->len, DMA_TO_DEVICE);
744
Michal Kazioraf213192015-01-29 14:29:52 +0200745 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
746 arvif->beacon_state != ATH10K_BEACON_SENT))
747 return;
748
Michal Kazior64badcb2014-09-18 11:18:02 +0300749 dev_kfree_skb_any(arvif->beacon);
750
751 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200752 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300753}
754
755static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
756{
757 struct ath10k *ar = arvif->ar;
758
759 lockdep_assert_held(&ar->data_lock);
760
761 ath10k_mac_vif_beacon_free(arvif);
762
763 if (arvif->beacon_buf) {
764 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
765 arvif->beacon_buf, arvif->beacon_paddr);
766 arvif->beacon_buf = NULL;
767 }
768}
769
Kalle Valo5e3dd152013-06-12 20:52:10 +0300770static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
771{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300772 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300773
Michal Kazior548db542013-07-05 16:15:15 +0300774 lockdep_assert_held(&ar->conf_mutex);
775
Michal Kazior7962b0d2014-10-28 10:34:38 +0100776 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
777 return -ESHUTDOWN;
778
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300779 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
780 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
781 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300782 return -ETIMEDOUT;
783
784 return 0;
785}
786
Michal Kazior1bbc0972014-04-08 09:45:47 +0300787static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300788{
Michal Kazior500ff9f2015-03-31 10:26:21 +0000789 struct cfg80211_chan_def *chandef = NULL;
Michal Kaziorc930f742014-01-23 11:38:25 +0100790 struct ieee80211_channel *channel = chandef->chan;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300791 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300792 int ret = 0;
793
794 lockdep_assert_held(&ar->conf_mutex);
795
Michal Kazior500ff9f2015-03-31 10:26:21 +0000796 ieee80211_iter_chan_contexts_atomic(ar->hw,
797 ath10k_mac_get_any_chandef_iter,
798 &chandef);
799 if (WARN_ON_ONCE(!chandef))
800 return -ENOENT;
801
802 channel = chandef->chan;
803
Kalle Valo5e3dd152013-06-12 20:52:10 +0300804 arg.vdev_id = vdev_id;
805 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +0100806 arg.channel.band_center_freq1 = chandef->center_freq1;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300807
808 /* TODO setup this dynamically, what in case we
809 don't have any vifs? */
Michal Kaziorc930f742014-01-23 11:38:25 +0100810 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200811 arg.channel.chan_radar =
812 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300813
Michal Kazior89c5c842013-10-23 04:02:13 -0700814 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -0700815 arg.channel.max_power = channel->max_power * 2;
816 arg.channel.max_reg_power = channel->max_reg_power * 2;
817 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300818
Michal Kazior7962b0d2014-10-28 10:34:38 +0100819 reinit_completion(&ar->vdev_setup_done);
820
Kalle Valo5e3dd152013-06-12 20:52:10 +0300821 ret = ath10k_wmi_vdev_start(ar, &arg);
822 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200823 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200824 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300825 return ret;
826 }
827
828 ret = ath10k_vdev_setup_sync(ar);
829 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +0200830 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200831 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300832 return ret;
833 }
834
835 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
836 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200837 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200838 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300839 goto vdev_stop;
840 }
841
842 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300843
Michal Kazior7aa7a722014-08-25 12:09:38 +0200844 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300845 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300846 return 0;
847
848vdev_stop:
849 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
850 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200851 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200852 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300853
854 return ret;
855}
856
Michal Kazior1bbc0972014-04-08 09:45:47 +0300857static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300858{
859 int ret = 0;
860
861 lockdep_assert_held(&ar->conf_mutex);
862
Marek Puzyniak52fa0192013-09-24 14:06:24 +0200863 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
864 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200865 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200866 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300867
Michal Kazior7962b0d2014-10-28 10:34:38 +0100868 reinit_completion(&ar->vdev_setup_done);
869
Kalle Valo5e3dd152013-06-12 20:52:10 +0300870 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
871 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200872 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200873 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300874
875 ret = ath10k_vdev_setup_sync(ar);
876 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +0200877 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200878 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300879
Michal Kazior7aa7a722014-08-25 12:09:38 +0200880 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300881 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300882 return ret;
883}
884
Michal Kazior1bbc0972014-04-08 09:45:47 +0300885static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300886{
887 int bit, ret = 0;
888
889 lockdep_assert_held(&ar->conf_mutex);
890
Ben Greeara9aefb32014-08-12 11:02:19 +0300891 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200892 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300893 return -ENOMEM;
894 }
895
Ben Greear16c11172014-09-23 14:17:16 -0700896 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +0300897
Ben Greear16c11172014-09-23 14:17:16 -0700898 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300899
900 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
901 WMI_VDEV_TYPE_MONITOR,
902 0, ar->mac_addr);
903 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200904 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200905 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +0300906 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300907 }
908
Ben Greear16c11172014-09-23 14:17:16 -0700909 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +0200910 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300911 ar->monitor_vdev_id);
912
Kalle Valo5e3dd152013-06-12 20:52:10 +0300913 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300914}
915
Michal Kazior1bbc0972014-04-08 09:45:47 +0300916static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300917{
918 int ret = 0;
919
920 lockdep_assert_held(&ar->conf_mutex);
921
Kalle Valo5e3dd152013-06-12 20:52:10 +0300922 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
923 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200924 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200925 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300926 return ret;
927 }
928
Ben Greear16c11172014-09-23 14:17:16 -0700929 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300930
Michal Kazior7aa7a722014-08-25 12:09:38 +0200931 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300932 ar->monitor_vdev_id);
933 return ret;
934}
935
Michal Kazior1bbc0972014-04-08 09:45:47 +0300936static int ath10k_monitor_start(struct ath10k *ar)
937{
938 int ret;
939
940 lockdep_assert_held(&ar->conf_mutex);
941
Michal Kazior1bbc0972014-04-08 09:45:47 +0300942 ret = ath10k_monitor_vdev_create(ar);
943 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200944 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +0300945 return ret;
946 }
947
948 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
949 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200950 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +0300951 ath10k_monitor_vdev_delete(ar);
952 return ret;
953 }
954
955 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +0200956 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +0300957
958 return 0;
959}
960
Michal Kazior19337472014-08-28 12:58:16 +0200961static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +0300962{
963 int ret;
964
965 lockdep_assert_held(&ar->conf_mutex);
966
Michal Kazior1bbc0972014-04-08 09:45:47 +0300967 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +0200968 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200969 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +0200970 return ret;
971 }
Michal Kazior1bbc0972014-04-08 09:45:47 +0300972
973 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +0200974 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200975 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +0200976 return ret;
977 }
Michal Kazior1bbc0972014-04-08 09:45:47 +0300978
979 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +0200980 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +0200981
982 return 0;
983}
984
Vasanthakumar Thiagarajan54846212015-03-02 17:45:28 +0530985static bool ath10k_mac_should_disable_promisc(struct ath10k *ar)
986{
987 struct ath10k_vif *arvif;
988
989 if (!(ar->filter_flags & FIF_PROMISC_IN_BSS))
990 return true;
991
992 if (!ar->num_started_vdevs)
993 return false;
994
995 list_for_each_entry(arvif, &ar->arvifs, list)
996 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
997 return false;
998
999 ath10k_dbg(ar, ATH10K_DBG_MAC,
1000 "mac disabling promiscuous mode because vdev is started\n");
1001 return true;
1002}
1003
Michal Kazior500ff9f2015-03-31 10:26:21 +00001004static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1005{
1006 int num_ctx;
1007
1008 /* At least one chanctx is required to derive a channel to start
1009 * monitor vdev on.
1010 */
1011 num_ctx = ath10k_mac_num_chanctxs(ar);
1012 if (num_ctx == 0)
1013 return false;
1014
1015 /* If there's already an existing special monitor interface then don't
1016 * bother creating another monitor vdev.
1017 */
1018 if (ar->monitor_arvif)
1019 return false;
1020
1021 return ar->monitor ||
1022 !ath10k_mac_should_disable_promisc(ar) ||
1023 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1024}
1025
1026static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1027{
1028 int num_ctx;
1029
1030 num_ctx = ath10k_mac_num_chanctxs(ar);
1031
1032 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1033 * shouldn't allow this but make sure to prevent handling the following
1034 * case anyway since multi-channel DFS hasn't been tested at all.
1035 */
1036 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1037 return false;
1038
1039 return true;
1040}
1041
Michal Kazior19337472014-08-28 12:58:16 +02001042static int ath10k_monitor_recalc(struct ath10k *ar)
1043{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001044 bool needed;
1045 bool allowed;
1046 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001047
1048 lockdep_assert_held(&ar->conf_mutex);
1049
Michal Kazior500ff9f2015-03-31 10:26:21 +00001050 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1051 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001052
1053 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001054 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1055 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001056
Michal Kazior500ff9f2015-03-31 10:26:21 +00001057 if (WARN_ON(needed && !allowed)) {
1058 if (ar->monitor_started) {
1059 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1060
1061 ret = ath10k_monitor_stop(ar);
1062 if (ret)
1063 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n", ret);
1064 /* not serious */
1065 }
1066
1067 return -EPERM;
1068 }
1069
1070 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001071 return 0;
1072
Michal Kazior500ff9f2015-03-31 10:26:21 +00001073 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001074 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001075 else
1076 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001077}
1078
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001079static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1080{
1081 struct ath10k *ar = arvif->ar;
1082 u32 vdev_param, rts_cts = 0;
1083
1084 lockdep_assert_held(&ar->conf_mutex);
1085
1086 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1087
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001088 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001089
1090 if (arvif->num_legacy_stations > 0)
1091 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1092 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001093 else
1094 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1095 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001096
1097 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1098 rts_cts);
1099}
1100
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001101static int ath10k_start_cac(struct ath10k *ar)
1102{
1103 int ret;
1104
1105 lockdep_assert_held(&ar->conf_mutex);
1106
1107 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1108
Michal Kazior19337472014-08-28 12:58:16 +02001109 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001110 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001111 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001112 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1113 return ret;
1114 }
1115
Michal Kazior7aa7a722014-08-25 12:09:38 +02001116 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001117 ar->monitor_vdev_id);
1118
1119 return 0;
1120}
1121
1122static int ath10k_stop_cac(struct ath10k *ar)
1123{
1124 lockdep_assert_held(&ar->conf_mutex);
1125
1126 /* CAC is not running - do nothing */
1127 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1128 return 0;
1129
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001130 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001131 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001132
Michal Kazior7aa7a722014-08-25 12:09:38 +02001133 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001134
1135 return 0;
1136}
1137
Michal Kazior500ff9f2015-03-31 10:26:21 +00001138static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1139 struct ieee80211_chanctx_conf *conf,
1140 void *data)
1141{
1142 bool *ret = data;
1143
1144 if (!*ret && conf->radar_enabled)
1145 *ret = true;
1146}
1147
1148static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1149{
1150 bool has_radar = false;
1151
1152 ieee80211_iter_chan_contexts_atomic(ar->hw,
1153 ath10k_mac_has_radar_iter,
1154 &has_radar);
1155
1156 return has_radar;
1157}
1158
Michal Kaziord6500972014-04-08 09:56:09 +03001159static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001160{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001161 int ret;
1162
1163 lockdep_assert_held(&ar->conf_mutex);
1164
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001165 ath10k_stop_cac(ar);
1166
Michal Kazior500ff9f2015-03-31 10:26:21 +00001167 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001168 return;
1169
Michal Kaziord6500972014-04-08 09:56:09 +03001170 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001171 return;
1172
1173 ret = ath10k_start_cac(ar);
1174 if (ret) {
1175 /*
1176 * Not possible to start CAC on current channel so starting
1177 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1178 * by indicating that radar was detected.
1179 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001180 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001181 ieee80211_radar_detected(ar->hw);
1182 }
1183}
1184
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301185static int ath10k_vdev_stop(struct ath10k_vif *arvif)
1186{
1187 struct ath10k *ar = arvif->ar;
1188 int ret;
1189
1190 lockdep_assert_held(&ar->conf_mutex);
1191
1192 reinit_completion(&ar->vdev_setup_done);
1193
1194 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1195 if (ret) {
1196 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1197 arvif->vdev_id, ret);
1198 return ret;
1199 }
1200
1201 ret = ath10k_vdev_setup_sync(ar);
1202 if (ret) {
1203 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
1204 arvif->vdev_id, ret);
1205 return ret;
1206 }
1207
1208 WARN_ON(ar->num_started_vdevs == 0);
1209
1210 if (ar->num_started_vdevs != 0) {
1211 ar->num_started_vdevs--;
1212 ath10k_recalc_radar_detection(ar);
1213 }
1214
1215 return ret;
1216}
1217
Michal Kazior500ff9f2015-03-31 10:26:21 +00001218static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1219 const struct cfg80211_chan_def *chandef,
1220 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001221{
1222 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001223 struct wmi_vdev_start_request_arg arg = {};
Vasanthakumar Thiagarajan54846212015-03-02 17:45:28 +05301224 int ret = 0, ret2;
Michal Kazior72654fa2014-04-08 09:56:09 +03001225
1226 lockdep_assert_held(&ar->conf_mutex);
1227
1228 reinit_completion(&ar->vdev_setup_done);
1229
1230 arg.vdev_id = arvif->vdev_id;
1231 arg.dtim_period = arvif->dtim_period;
1232 arg.bcn_intval = arvif->beacon_interval;
1233
1234 arg.channel.freq = chandef->chan->center_freq;
1235 arg.channel.band_center_freq1 = chandef->center_freq1;
1236 arg.channel.mode = chan_to_phymode(chandef);
1237
1238 arg.channel.min_power = 0;
1239 arg.channel.max_power = chandef->chan->max_power * 2;
1240 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1241 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1242
1243 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1244 arg.ssid = arvif->u.ap.ssid;
1245 arg.ssid_len = arvif->u.ap.ssid_len;
1246 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1247
1248 /* For now allow DFS for AP mode */
1249 arg.channel.chan_radar =
1250 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1251 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1252 arg.ssid = arvif->vif->bss_conf.ssid;
1253 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1254 }
1255
Michal Kazior7aa7a722014-08-25 12:09:38 +02001256 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001257 "mac vdev %d start center_freq %d phymode %s\n",
1258 arg.vdev_id, arg.channel.freq,
1259 ath10k_wmi_phymode_str(arg.channel.mode));
1260
Michal Kaziordc55e302014-07-29 12:53:36 +03001261 if (restart)
1262 ret = ath10k_wmi_vdev_restart(ar, &arg);
1263 else
1264 ret = ath10k_wmi_vdev_start(ar, &arg);
1265
Michal Kazior72654fa2014-04-08 09:56:09 +03001266 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001267 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001268 arg.vdev_id, ret);
1269 return ret;
1270 }
1271
1272 ret = ath10k_vdev_setup_sync(ar);
1273 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001274 ath10k_warn(ar,
1275 "failed to synchronize setup for vdev %i restart %d: %d\n",
1276 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001277 return ret;
1278 }
1279
Michal Kaziord6500972014-04-08 09:56:09 +03001280 ar->num_started_vdevs++;
1281 ath10k_recalc_radar_detection(ar);
1282
Vasanthakumar Thiagarajan54846212015-03-02 17:45:28 +05301283 ret = ath10k_monitor_recalc(ar);
1284 if (ret) {
1285 ath10k_warn(ar, "mac failed to recalc monitor for vdev %i restart %d: %d\n",
1286 arg.vdev_id, restart, ret);
1287 ret2 = ath10k_vdev_stop(arvif);
1288 if (ret2)
1289 ath10k_warn(ar, "mac failed to stop vdev %i restart %d: %d\n",
1290 arg.vdev_id, restart, ret2);
1291 }
1292
Michal Kazior72654fa2014-04-08 09:56:09 +03001293 return ret;
1294}
1295
Michal Kazior500ff9f2015-03-31 10:26:21 +00001296static int ath10k_vdev_start(struct ath10k_vif *arvif,
1297 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001298{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001299 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001300}
1301
Michal Kazior500ff9f2015-03-31 10:26:21 +00001302static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1303 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001304{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001305 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kaziordc55e302014-07-29 12:53:36 +03001306}
1307
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001308static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1309 struct sk_buff *bcn)
1310{
1311 struct ath10k *ar = arvif->ar;
1312 struct ieee80211_mgmt *mgmt;
1313 const u8 *p2p_ie;
1314 int ret;
1315
1316 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1317 return 0;
1318
1319 if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
1320 return 0;
1321
1322 mgmt = (void *)bcn->data;
1323 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1324 mgmt->u.beacon.variable,
1325 bcn->len - (mgmt->u.beacon.variable -
1326 bcn->data));
1327 if (!p2p_ie)
1328 return -ENOENT;
1329
1330 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1331 if (ret) {
1332 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1333 arvif->vdev_id, ret);
1334 return ret;
1335 }
1336
1337 return 0;
1338}
1339
1340static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1341 u8 oui_type, size_t ie_offset)
1342{
1343 size_t len;
1344 const u8 *next;
1345 const u8 *end;
1346 u8 *ie;
1347
1348 if (WARN_ON(skb->len < ie_offset))
1349 return -EINVAL;
1350
1351 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1352 skb->data + ie_offset,
1353 skb->len - ie_offset);
1354 if (!ie)
1355 return -ENOENT;
1356
1357 len = ie[1] + 2;
1358 end = skb->data + skb->len;
1359 next = ie + len;
1360
1361 if (WARN_ON(next > end))
1362 return -EINVAL;
1363
1364 memmove(ie, next, end - next);
1365 skb_trim(skb, skb->len - len);
1366
1367 return 0;
1368}
1369
1370static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1371{
1372 struct ath10k *ar = arvif->ar;
1373 struct ieee80211_hw *hw = ar->hw;
1374 struct ieee80211_vif *vif = arvif->vif;
1375 struct ieee80211_mutable_offsets offs = {};
1376 struct sk_buff *bcn;
1377 int ret;
1378
1379 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1380 return 0;
1381
Michal Kazior81a9a172015-03-05 16:02:17 +02001382 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1383 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1384 return 0;
1385
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001386 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1387 if (!bcn) {
1388 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1389 return -EPERM;
1390 }
1391
1392 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1393 if (ret) {
1394 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1395 kfree_skb(bcn);
1396 return ret;
1397 }
1398
1399 /* P2P IE is inserted by firmware automatically (as configured above)
1400 * so remove it from the base beacon template to avoid duplicate P2P
1401 * IEs in beacon frames.
1402 */
1403 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1404 offsetof(struct ieee80211_mgmt,
1405 u.beacon.variable));
1406
1407 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1408 0, NULL, 0);
1409 kfree_skb(bcn);
1410
1411 if (ret) {
1412 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1413 ret);
1414 return ret;
1415 }
1416
1417 return 0;
1418}
1419
1420static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1421{
1422 struct ath10k *ar = arvif->ar;
1423 struct ieee80211_hw *hw = ar->hw;
1424 struct ieee80211_vif *vif = arvif->vif;
1425 struct sk_buff *prb;
1426 int ret;
1427
1428 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1429 return 0;
1430
Michal Kazior81a9a172015-03-05 16:02:17 +02001431 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1432 return 0;
1433
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001434 prb = ieee80211_proberesp_get(hw, vif);
1435 if (!prb) {
1436 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1437 return -EPERM;
1438 }
1439
1440 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1441 kfree_skb(prb);
1442
1443 if (ret) {
1444 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1445 ret);
1446 return ret;
1447 }
1448
1449 return 0;
1450}
1451
Michal Kazior500ff9f2015-03-31 10:26:21 +00001452static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1453{
1454 struct ath10k *ar = arvif->ar;
1455 struct cfg80211_chan_def def;
1456 int ret;
1457
1458 /* When originally vdev is started during assign_vif_chanctx() some
1459 * information is missing, notably SSID. Firmware revisions with beacon
1460 * offloading require the SSID to be provided during vdev (re)start to
1461 * handle hidden SSID properly.
1462 *
1463 * Vdev restart must be done after vdev has been both started and
1464 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1465 * deliver vdev restart response event causing timeouts during vdev
1466 * syncing in ath10k.
1467 *
1468 * Note: The vdev down/up and template reinstallation could be skipped
1469 * since only wmi-tlv firmware are known to have beacon offload and
1470 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1471 * response delivery. It's probably more robust to keep it as is.
1472 */
1473 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1474 return 0;
1475
1476 if (WARN_ON(!arvif->is_started))
1477 return -EINVAL;
1478
1479 if (WARN_ON(!arvif->is_up))
1480 return -EINVAL;
1481
1482 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1483 return -EINVAL;
1484
1485 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1486 if (ret) {
1487 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1488 arvif->vdev_id, ret);
1489 return ret;
1490 }
1491
1492 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1493 * firmware will crash upon vdev up.
1494 */
1495
1496 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1497 if (ret) {
1498 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1499 return ret;
1500 }
1501
1502 ret = ath10k_mac_setup_prb_tmpl(arvif);
1503 if (ret) {
1504 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1505 return ret;
1506 }
1507
1508 ret = ath10k_vdev_restart(arvif, &def);
1509 if (ret) {
1510 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1511 arvif->vdev_id, ret);
1512 return ret;
1513 }
1514
1515 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1516 arvif->bssid);
1517 if (ret) {
1518 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1519 arvif->vdev_id, ret);
1520 return ret;
1521 }
1522
1523 return 0;
1524}
1525
Kalle Valo5e3dd152013-06-12 20:52:10 +03001526static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001527 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001528{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001529 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001530 int ret = 0;
1531
Michal Kazior548db542013-07-05 16:15:15 +03001532 lockdep_assert_held(&arvif->ar->conf_mutex);
1533
Kalle Valo5e3dd152013-06-12 20:52:10 +03001534 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001535 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1536 if (ret)
1537 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1538 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001539
Michal Kaziorc930f742014-01-23 11:38:25 +01001540 arvif->is_up = false;
Michal Kazior8513d952015-03-09 14:19:24 +01001541
1542 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001543 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001544 spin_unlock_bh(&arvif->ar->data_lock);
1545
Kalle Valo5e3dd152013-06-12 20:52:10 +03001546 return;
1547 }
1548
1549 arvif->tx_seq_no = 0x1000;
1550
Michal Kaziorc930f742014-01-23 11:38:25 +01001551 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001552 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001553
1554 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1555 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001556 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001557 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001558 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001559 return;
1560 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001561
Michal Kaziorc930f742014-01-23 11:38:25 +01001562 arvif->is_up = true;
1563
Michal Kazior500ff9f2015-03-31 10:26:21 +00001564 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1565 if (ret) {
1566 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1567 arvif->vdev_id, ret);
1568 return;
1569 }
1570
Michal Kazior7aa7a722014-08-25 12:09:38 +02001571 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001572}
1573
1574static void ath10k_control_ibss(struct ath10k_vif *arvif,
1575 struct ieee80211_bss_conf *info,
1576 const u8 self_peer[ETH_ALEN])
1577{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001578 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001579 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001580 int ret = 0;
1581
Michal Kazior548db542013-07-05 16:15:15 +03001582 lockdep_assert_held(&arvif->ar->conf_mutex);
1583
Kalle Valo5e3dd152013-06-12 20:52:10 +03001584 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001585 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001586 return;
1587
Michal Kaziorc930f742014-01-23 11:38:25 +01001588 memset(arvif->bssid, 0, ETH_ALEN);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001589
1590 return;
1591 }
1592
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001593 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1594 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001595 ATH10K_DEFAULT_ATIM);
1596 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001597 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001598 arvif->vdev_id, ret);
1599}
1600
Michal Kazior9f9b5742014-12-12 12:41:36 +01001601static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1602{
1603 struct ath10k *ar = arvif->ar;
1604 u32 param;
1605 u32 value;
1606 int ret;
1607
1608 lockdep_assert_held(&arvif->ar->conf_mutex);
1609
1610 if (arvif->u.sta.uapsd)
1611 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1612 else
1613 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1614
1615 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1616 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1617 if (ret) {
1618 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1619 value, arvif->vdev_id, ret);
1620 return ret;
1621 }
1622
1623 return 0;
1624}
1625
1626static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1627{
1628 struct ath10k *ar = arvif->ar;
1629 u32 param;
1630 u32 value;
1631 int ret;
1632
1633 lockdep_assert_held(&arvif->ar->conf_mutex);
1634
1635 if (arvif->u.sta.uapsd)
1636 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1637 else
1638 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1639
1640 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1641 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1642 param, value);
1643 if (ret) {
1644 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1645 value, arvif->vdev_id, ret);
1646 return ret;
1647 }
1648
1649 return 0;
1650}
1651
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001652static int ath10k_mac_ps_vif_count(struct ath10k *ar)
1653{
1654 struct ath10k_vif *arvif;
1655 int num = 0;
1656
1657 lockdep_assert_held(&ar->conf_mutex);
1658
1659 list_for_each_entry(arvif, &ar->arvifs, list)
1660 if (arvif->ps)
1661 num++;
1662
1663 return num;
1664}
1665
Michal Kaziorad088bf2013-10-16 15:44:46 +03001666static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001667{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001668 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001669 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001670 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001671 enum wmi_sta_powersave_param param;
1672 enum wmi_sta_ps_mode psmode;
1673 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001674 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001675 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001676
Michal Kazior548db542013-07-05 16:15:15 +03001677 lockdep_assert_held(&arvif->ar->conf_mutex);
1678
Michal Kaziorad088bf2013-10-16 15:44:46 +03001679 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1680 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001681
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001682 enable_ps = arvif->ps;
1683
1684 if (enable_ps && ath10k_mac_ps_vif_count(ar) > 1 &&
1685 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
1686 ar->fw_features)) {
1687 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1688 arvif->vdev_id);
1689 enable_ps = false;
1690 }
1691
1692 if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001693 psmode = WMI_STA_PS_MODE_ENABLED;
1694 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1695
Michal Kazior526549a2014-12-12 12:41:37 +01001696 ps_timeout = conf->dynamic_ps_timeout;
1697 if (ps_timeout == 0) {
1698 /* Firmware doesn't like 0 */
1699 ps_timeout = ieee80211_tu_to_usec(
1700 vif->bss_conf.beacon_int) / 1000;
1701 }
1702
Michal Kaziorad088bf2013-10-16 15:44:46 +03001703 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001704 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001705 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001706 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001707 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001708 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001709 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001710 } else {
1711 psmode = WMI_STA_PS_MODE_DISABLED;
1712 }
1713
Michal Kazior7aa7a722014-08-25 12:09:38 +02001714 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001715 arvif->vdev_id, psmode ? "enable" : "disable");
1716
Michal Kaziorad088bf2013-10-16 15:44:46 +03001717 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1718 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001719 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001720 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001721 return ret;
1722 }
1723
1724 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001725}
1726
Michal Kazior46725b152015-01-28 09:57:49 +02001727static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1728{
1729 struct ath10k *ar = arvif->ar;
1730 struct wmi_sta_keepalive_arg arg = {};
1731 int ret;
1732
1733 lockdep_assert_held(&arvif->ar->conf_mutex);
1734
1735 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1736 return 0;
1737
1738 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1739 return 0;
1740
1741 /* Some firmware revisions have a bug and ignore the `enabled` field.
1742 * Instead use the interval to disable the keepalive.
1743 */
1744 arg.vdev_id = arvif->vdev_id;
1745 arg.enabled = 1;
1746 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1747 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1748
1749 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1750 if (ret) {
1751 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1752 arvif->vdev_id, ret);
1753 return ret;
1754 }
1755
1756 return 0;
1757}
1758
Michal Kazior81a9a172015-03-05 16:02:17 +02001759static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1760{
1761 struct ath10k *ar = arvif->ar;
1762 struct ieee80211_vif *vif = arvif->vif;
1763 int ret;
1764
Michal Kazior8513d952015-03-09 14:19:24 +01001765 lockdep_assert_held(&arvif->ar->conf_mutex);
1766
1767 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1768 return;
1769
Michal Kazior81a9a172015-03-05 16:02:17 +02001770 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1771 return;
1772
1773 if (!vif->csa_active)
1774 return;
1775
1776 if (!arvif->is_up)
1777 return;
1778
1779 if (!ieee80211_csa_is_complete(vif)) {
1780 ieee80211_csa_update_counter(vif);
1781
1782 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1783 if (ret)
1784 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1785 ret);
1786
1787 ret = ath10k_mac_setup_prb_tmpl(arvif);
1788 if (ret)
1789 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1790 ret);
1791 } else {
1792 ieee80211_csa_finish(vif);
1793 }
1794}
1795
1796static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1797{
1798 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1799 ap_csa_work);
1800 struct ath10k *ar = arvif->ar;
1801
1802 mutex_lock(&ar->conf_mutex);
1803 ath10k_mac_vif_ap_csa_count_down(arvif);
1804 mutex_unlock(&ar->conf_mutex);
1805}
1806
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001807static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1808 struct ieee80211_vif *vif)
1809{
1810 struct sk_buff *skb = data;
1811 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1812 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1813
1814 if (vif->type != NL80211_IFTYPE_STATION)
1815 return;
1816
1817 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1818 return;
1819
1820 cancel_delayed_work(&arvif->connection_loss_work);
1821}
1822
1823void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
1824{
1825 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1826 IEEE80211_IFACE_ITER_NORMAL,
1827 ath10k_mac_handle_beacon_iter,
1828 skb);
1829}
1830
1831static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
1832 struct ieee80211_vif *vif)
1833{
1834 u32 *vdev_id = data;
1835 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1836 struct ath10k *ar = arvif->ar;
1837 struct ieee80211_hw *hw = ar->hw;
1838
1839 if (arvif->vdev_id != *vdev_id)
1840 return;
1841
1842 if (!arvif->is_up)
1843 return;
1844
1845 ieee80211_beacon_loss(vif);
1846
1847 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
1848 * (done by mac80211) succeeds but beacons do not resume then it
1849 * doesn't make sense to continue operation. Queue connection loss work
1850 * which can be cancelled when beacon is received.
1851 */
1852 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
1853 ATH10K_CONNECTION_LOSS_HZ);
1854}
1855
1856void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
1857{
1858 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1859 IEEE80211_IFACE_ITER_NORMAL,
1860 ath10k_mac_handle_beacon_miss_iter,
1861 &vdev_id);
1862}
1863
1864static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
1865{
1866 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1867 connection_loss_work.work);
1868 struct ieee80211_vif *vif = arvif->vif;
1869
1870 if (!arvif->is_up)
1871 return;
1872
1873 ieee80211_connection_loss(vif);
1874}
1875
Kalle Valo5e3dd152013-06-12 20:52:10 +03001876/**********************/
1877/* Station management */
1878/**********************/
1879
Michal Kazior590922a2014-10-21 10:10:29 +03001880static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
1881 struct ieee80211_vif *vif)
1882{
1883 /* Some firmware revisions have unstable STA powersave when listen
1884 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
1885 * generate NullFunc frames properly even if buffered frames have been
1886 * indicated in Beacon TIM. Firmware would seldom wake up to pull
1887 * buffered frames. Often pinging the device from AP would simply fail.
1888 *
1889 * As a workaround set it to 1.
1890 */
1891 if (vif->type == NL80211_IFTYPE_STATION)
1892 return 1;
1893
1894 return ar->hw->conf.listen_interval;
1895}
1896
Kalle Valo5e3dd152013-06-12 20:52:10 +03001897static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001898 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001899 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001900 struct wmi_peer_assoc_complete_arg *arg)
1901{
Michal Kazior590922a2014-10-21 10:10:29 +03001902 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorc51880e2015-03-30 09:51:57 +03001903 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03001904
Michal Kazior548db542013-07-05 16:15:15 +03001905 lockdep_assert_held(&ar->conf_mutex);
1906
Michal Kaziorc51880e2015-03-30 09:51:57 +03001907 if (vif->type == NL80211_IFTYPE_STATION)
1908 aid = vif->bss_conf.aid;
1909 else
1910 aid = sta->aid;
1911
Kalle Valob25f32c2014-09-14 12:50:49 +03001912 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001913 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03001914 arg->peer_aid = aid;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001915 arg->peer_flags |= WMI_PEER_AUTH;
Michal Kazior590922a2014-10-21 10:10:29 +03001916 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001917 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03001918 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001919}
1920
1921static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001922 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001923 struct wmi_peer_assoc_complete_arg *arg)
1924{
Kalle Valo5e3dd152013-06-12 20:52:10 +03001925 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00001926 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001927 struct cfg80211_bss *bss;
1928 const u8 *rsnie = NULL;
1929 const u8 *wpaie = NULL;
1930
Michal Kazior548db542013-07-05 16:15:15 +03001931 lockdep_assert_held(&ar->conf_mutex);
1932
Michal Kazior500ff9f2015-03-31 10:26:21 +00001933 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
1934 return;
1935
1936 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
1937 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001938 if (bss) {
1939 const struct cfg80211_bss_ies *ies;
1940
1941 rcu_read_lock();
1942 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
1943
1944 ies = rcu_dereference(bss->ies);
1945
1946 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03001947 WLAN_OUI_TYPE_MICROSOFT_WPA,
1948 ies->data,
1949 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001950 rcu_read_unlock();
1951 cfg80211_put_bss(ar->hw->wiphy, bss);
1952 }
1953
1954 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
1955 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001956 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001957 arg->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
1958 }
1959
1960 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001961 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001962 arg->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
1963 }
1964}
1965
1966static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001967 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001968 struct ieee80211_sta *sta,
1969 struct wmi_peer_assoc_complete_arg *arg)
1970{
1971 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00001972 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001973 const struct ieee80211_supported_band *sband;
1974 const struct ieee80211_rate *rates;
1975 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03001976 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001977 int i;
1978
Michal Kazior548db542013-07-05 16:15:15 +03001979 lockdep_assert_held(&ar->conf_mutex);
1980
Michal Kazior500ff9f2015-03-31 10:26:21 +00001981 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
1982 return;
1983
1984 sband = ar->hw->wiphy->bands[def.chan->band];
1985 ratemask = sta->supp_rates[def.chan->band];
Kalle Valo5e3dd152013-06-12 20:52:10 +03001986 rates = sband->bitrates;
1987
1988 rateset->num_rates = 0;
1989
1990 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
1991 if (!(ratemask & 1))
1992 continue;
1993
Michal Kazior486017c2015-03-30 09:51:54 +03001994 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
1995 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001996 rateset->num_rates++;
1997 }
1998}
1999
2000static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
2001 struct ieee80211_sta *sta,
2002 struct wmi_peer_assoc_complete_arg *arg)
2003{
2004 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002005 int i, n;
Kalle Valoaf762c02014-09-14 12:50:17 +03002006 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002007
Michal Kazior548db542013-07-05 16:15:15 +03002008 lockdep_assert_held(&ar->conf_mutex);
2009
Kalle Valo5e3dd152013-06-12 20:52:10 +03002010 if (!ht_cap->ht_supported)
2011 return;
2012
2013 arg->peer_flags |= WMI_PEER_HT;
2014 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2015 ht_cap->ampdu_factor)) - 1;
2016
2017 arg->peer_mpdu_density =
2018 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2019
2020 arg->peer_ht_caps = ht_cap->cap;
2021 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2022
2023 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
2024 arg->peer_flags |= WMI_PEER_LDPC;
2025
2026 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
2027 arg->peer_flags |= WMI_PEER_40MHZ;
2028 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2029 }
2030
2031 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2032 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2033
2034 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2035 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2036
2037 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2038 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
2039 arg->peer_flags |= WMI_PEER_STBC;
2040 }
2041
2042 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002043 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2044 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2045 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2046 arg->peer_rate_caps |= stbc;
2047 arg->peer_flags |= WMI_PEER_STBC;
2048 }
2049
Kalle Valo5e3dd152013-06-12 20:52:10 +03002050 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2051 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2052 else if (ht_cap->mcs.rx_mask[1])
2053 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2054
2055 for (i = 0, n = 0; i < IEEE80211_HT_MCS_MASK_LEN*8; i++)
2056 if (ht_cap->mcs.rx_mask[i/8] & (1 << i%8))
2057 arg->peer_ht_rates.rates[n++] = i;
2058
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002059 /*
2060 * This is a workaround for HT-enabled STAs which break the spec
2061 * and have no HT capabilities RX mask (no HT RX MCS map).
2062 *
2063 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2064 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2065 *
2066 * Firmware asserts if such situation occurs.
2067 */
2068 if (n == 0) {
2069 arg->peer_ht_rates.num_rates = 8;
2070 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2071 arg->peer_ht_rates.rates[i] = i;
2072 } else {
2073 arg->peer_ht_rates.num_rates = n;
2074 arg->peer_num_spatial_streams = sta->rx_nss;
2075 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002076
Michal Kazior7aa7a722014-08-25 12:09:38 +02002077 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002078 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002079 arg->peer_ht_rates.num_rates,
2080 arg->peer_num_spatial_streams);
2081}
2082
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002083static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2084 struct ath10k_vif *arvif,
2085 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002086{
2087 u32 uapsd = 0;
2088 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002089 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002090
Michal Kazior548db542013-07-05 16:15:15 +03002091 lockdep_assert_held(&ar->conf_mutex);
2092
Kalle Valo5e3dd152013-06-12 20:52:10 +03002093 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002094 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002095 sta->uapsd_queues, sta->max_sp);
2096
Kalle Valo5e3dd152013-06-12 20:52:10 +03002097 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2098 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2099 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2100 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2101 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2102 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2103 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2104 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2105 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2106 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2107 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2108 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2109
Kalle Valo5e3dd152013-06-12 20:52:10 +03002110 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2111 max_sp = sta->max_sp;
2112
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002113 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2114 sta->addr,
2115 WMI_AP_PS_PEER_PARAM_UAPSD,
2116 uapsd);
2117 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002118 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002119 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002120 return ret;
2121 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002122
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002123 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2124 sta->addr,
2125 WMI_AP_PS_PEER_PARAM_MAX_SP,
2126 max_sp);
2127 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002128 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002129 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002130 return ret;
2131 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002132
2133 /* TODO setup this based on STA listen interval and
2134 beacon interval. Currently we don't know
2135 sta->listen_interval - mac80211 patch required.
2136 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002137 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002138 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2139 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002140 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002141 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002142 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002143 return ret;
2144 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002145 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002146
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002147 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002148}
2149
2150static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002151 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002152 struct ieee80211_sta *sta,
2153 struct wmi_peer_assoc_complete_arg *arg)
2154{
2155 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002156 struct cfg80211_chan_def def;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002157 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002158
Michal Kazior500ff9f2015-03-31 10:26:21 +00002159 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2160 return;
2161
Kalle Valo5e3dd152013-06-12 20:52:10 +03002162 if (!vht_cap->vht_supported)
2163 return;
2164
2165 arg->peer_flags |= WMI_PEER_VHT;
Yanbo Lid68bb122015-01-23 08:18:20 +08002166
Michal Kazior500ff9f2015-03-31 10:26:21 +00002167 if (def.chan->band == IEEE80211_BAND_2GHZ)
Yanbo Lid68bb122015-01-23 08:18:20 +08002168 arg->peer_flags |= WMI_PEER_VHT_2G;
2169
Kalle Valo5e3dd152013-06-12 20:52:10 +03002170 arg->peer_vht_caps = vht_cap->cap;
2171
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002172 ampdu_factor = (vht_cap->cap &
2173 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2174 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2175
2176 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2177 * zero in VHT IE. Using it would result in degraded throughput.
2178 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2179 * it if VHT max_mpdu is smaller. */
2180 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2181 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2182 ampdu_factor)) - 1);
2183
Kalle Valo5e3dd152013-06-12 20:52:10 +03002184 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2185 arg->peer_flags |= WMI_PEER_80MHZ;
2186
2187 arg->peer_vht_rates.rx_max_rate =
2188 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2189 arg->peer_vht_rates.rx_mcs_set =
2190 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2191 arg->peer_vht_rates.tx_max_rate =
2192 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
2193 arg->peer_vht_rates.tx_mcs_set =
2194 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
2195
Michal Kazior7aa7a722014-08-25 12:09:38 +02002196 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002197 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002198}
2199
2200static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002201 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002202 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002203 struct wmi_peer_assoc_complete_arg *arg)
2204{
Michal Kazior590922a2014-10-21 10:10:29 +03002205 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2206
Kalle Valo5e3dd152013-06-12 20:52:10 +03002207 switch (arvif->vdev_type) {
2208 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002209 if (sta->wme)
2210 arg->peer_flags |= WMI_PEER_QOS;
2211
2212 if (sta->wme && sta->uapsd_queues) {
2213 arg->peer_flags |= WMI_PEER_APSD;
2214 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2215 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002216 break;
2217 case WMI_VDEV_TYPE_STA:
Michal Kazior590922a2014-10-21 10:10:29 +03002218 if (vif->bss_conf.qos)
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002219 arg->peer_flags |= WMI_PEER_QOS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002220 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002221 case WMI_VDEV_TYPE_IBSS:
2222 if (sta->wme)
2223 arg->peer_flags |= WMI_PEER_QOS;
2224 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002225 default:
2226 break;
2227 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002228
2229 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
2230 sta->addr, !!(arg->peer_flags & WMI_PEER_QOS));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002231}
2232
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002233static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002234{
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002235 return sta->supp_rates[IEEE80211_BAND_2GHZ] >>
2236 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002237}
2238
Kalle Valo5e3dd152013-06-12 20:52:10 +03002239static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002240 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002241 struct ieee80211_sta *sta,
2242 struct wmi_peer_assoc_complete_arg *arg)
2243{
Michal Kazior500ff9f2015-03-31 10:26:21 +00002244 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002245 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2246
Michal Kazior500ff9f2015-03-31 10:26:21 +00002247 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2248 return;
2249
2250 switch (def.chan->band) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002251 case IEEE80211_BAND_2GHZ:
Yanbo Lid68bb122015-01-23 08:18:20 +08002252 if (sta->vht_cap.vht_supported) {
2253 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2254 phymode = MODE_11AC_VHT40;
2255 else
2256 phymode = MODE_11AC_VHT20;
2257 } else if (sta->ht_cap.ht_supported) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002258 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2259 phymode = MODE_11NG_HT40;
2260 else
2261 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002262 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002263 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002264 } else {
2265 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002266 }
2267
2268 break;
2269 case IEEE80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002270 /*
2271 * Check VHT first.
2272 */
2273 if (sta->vht_cap.vht_supported) {
2274 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2275 phymode = MODE_11AC_VHT80;
2276 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2277 phymode = MODE_11AC_VHT40;
2278 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2279 phymode = MODE_11AC_VHT20;
2280 } else if (sta->ht_cap.ht_supported) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002281 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2282 phymode = MODE_11NA_HT40;
2283 else
2284 phymode = MODE_11NA_HT20;
2285 } else {
2286 phymode = MODE_11A;
2287 }
2288
2289 break;
2290 default:
2291 break;
2292 }
2293
Michal Kazior7aa7a722014-08-25 12:09:38 +02002294 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002295 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002296
Kalle Valo5e3dd152013-06-12 20:52:10 +03002297 arg->peer_phymode = phymode;
2298 WARN_ON(phymode == MODE_UNKNOWN);
2299}
2300
Kalle Valob9ada652013-10-16 15:44:46 +03002301static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002302 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002303 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002304 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002305{
Michal Kazior548db542013-07-05 16:15:15 +03002306 lockdep_assert_held(&ar->conf_mutex);
2307
Kalle Valob9ada652013-10-16 15:44:46 +03002308 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002309
Michal Kazior590922a2014-10-21 10:10:29 +03002310 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
2311 ath10k_peer_assoc_h_crypto(ar, vif, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002312 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Kalle Valob9ada652013-10-16 15:44:46 +03002313 ath10k_peer_assoc_h_ht(ar, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002314 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002315 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2316 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002317
Kalle Valob9ada652013-10-16 15:44:46 +03002318 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002319}
2320
Michal Kazior90046f52014-02-14 14:45:51 +01002321static const u32 ath10k_smps_map[] = {
2322 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2323 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2324 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2325 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2326};
2327
2328static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2329 const u8 *addr,
2330 const struct ieee80211_sta_ht_cap *ht_cap)
2331{
2332 int smps;
2333
2334 if (!ht_cap->ht_supported)
2335 return 0;
2336
2337 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2338 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2339
2340 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2341 return -EINVAL;
2342
2343 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2344 WMI_PEER_SMPS_STATE,
2345 ath10k_smps_map[smps]);
2346}
2347
Michal Kazior139e1702015-02-15 16:50:42 +02002348static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2349 struct ieee80211_vif *vif,
2350 struct ieee80211_sta_vht_cap vht_cap)
2351{
2352 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2353 int ret;
2354 u32 param;
2355 u32 value;
2356
2357 if (!(ar->vht_cap_info &
2358 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2359 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2360 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2361 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2362 return 0;
2363
2364 param = ar->wmi.vdev_param->txbf;
2365 value = 0;
2366
2367 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2368 return 0;
2369
2370 /* The following logic is correct. If a remote STA advertises support
2371 * for being a beamformer then we should enable us being a beamformee.
2372 */
2373
2374 if (ar->vht_cap_info &
2375 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2376 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2377 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2378 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2379
2380 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2381 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2382 }
2383
2384 if (ar->vht_cap_info &
2385 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2386 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2387 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2388 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2389
2390 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2391 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2392 }
2393
2394 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2395 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2396
2397 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2398 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2399
2400 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2401 if (ret) {
2402 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2403 value, ret);
2404 return ret;
2405 }
2406
2407 return 0;
2408}
2409
Kalle Valo5e3dd152013-06-12 20:52:10 +03002410/* can be called only in mac80211 callbacks due to `key_count` usage */
2411static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2412 struct ieee80211_vif *vif,
2413 struct ieee80211_bss_conf *bss_conf)
2414{
2415 struct ath10k *ar = hw->priv;
2416 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002417 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002418 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002419 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002420 struct ieee80211_sta *ap_sta;
2421 int ret;
2422
Michal Kazior548db542013-07-05 16:15:15 +03002423 lockdep_assert_held(&ar->conf_mutex);
2424
Michal Kazior077efc82014-10-21 10:10:29 +03002425 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2426 arvif->vdev_id, arvif->bssid, arvif->aid);
2427
Kalle Valo5e3dd152013-06-12 20:52:10 +03002428 rcu_read_lock();
2429
2430 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2431 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002432 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002433 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002434 rcu_read_unlock();
2435 return;
2436 }
2437
Michal Kazior90046f52014-02-14 14:45:51 +01002438 /* ap_sta must be accessed only within rcu section which must be left
2439 * before calling ath10k_setup_peer_smps() which might sleep. */
2440 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002441 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002442
Michal Kazior590922a2014-10-21 10:10:29 +03002443 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002444 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002445 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002446 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002447 rcu_read_unlock();
2448 return;
2449 }
2450
2451 rcu_read_unlock();
2452
Kalle Valob9ada652013-10-16 15:44:46 +03002453 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2454 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002455 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002456 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002457 return;
2458 }
2459
Michal Kazior90046f52014-02-14 14:45:51 +01002460 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2461 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002462 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002463 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002464 return;
2465 }
2466
Michal Kazior139e1702015-02-15 16:50:42 +02002467 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2468 if (ret) {
2469 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2470 arvif->vdev_id, bss_conf->bssid, ret);
2471 return;
2472 }
2473
Michal Kazior7aa7a722014-08-25 12:09:38 +02002474 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002475 "mac vdev %d up (associated) bssid %pM aid %d\n",
2476 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2477
Michal Kazior077efc82014-10-21 10:10:29 +03002478 WARN_ON(arvif->is_up);
2479
Michal Kaziorc930f742014-01-23 11:38:25 +01002480 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002481 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002482
2483 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2484 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002485 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002486 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002487 return;
2488 }
2489
2490 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002491
2492 /* Workaround: Some firmware revisions (tested with qca6174
2493 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2494 * poked with peer param command.
2495 */
2496 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2497 WMI_PEER_DUMMY_VAR, 1);
2498 if (ret) {
2499 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2500 arvif->bssid, arvif->vdev_id, ret);
2501 return;
2502 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002503}
2504
Kalle Valo5e3dd152013-06-12 20:52:10 +03002505static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2506 struct ieee80211_vif *vif)
2507{
2508 struct ath10k *ar = hw->priv;
2509 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002510 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002511 int ret;
2512
Michal Kazior548db542013-07-05 16:15:15 +03002513 lockdep_assert_held(&ar->conf_mutex);
2514
Michal Kazior077efc82014-10-21 10:10:29 +03002515 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2516 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002517
Kalle Valo5e3dd152013-06-12 20:52:10 +03002518 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002519 if (ret)
2520 ath10k_warn(ar, "faield to down vdev %i: %d\n",
2521 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002522
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002523 arvif->def_wep_key_idx = -1;
2524
Michal Kazior139e1702015-02-15 16:50:42 +02002525 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2526 if (ret) {
2527 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2528 arvif->vdev_id, ret);
2529 return;
2530 }
2531
Michal Kaziorc930f742014-01-23 11:38:25 +01002532 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002533
2534 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002535}
2536
Michal Kazior590922a2014-10-21 10:10:29 +03002537static int ath10k_station_assoc(struct ath10k *ar,
2538 struct ieee80211_vif *vif,
2539 struct ieee80211_sta *sta,
2540 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002541{
Michal Kazior590922a2014-10-21 10:10:29 +03002542 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002543 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002544 int ret = 0;
2545
Michal Kazior548db542013-07-05 16:15:15 +03002546 lockdep_assert_held(&ar->conf_mutex);
2547
Michal Kazior590922a2014-10-21 10:10:29 +03002548 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002549 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002550 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002551 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002552 return ret;
2553 }
2554
2555 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2556 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002557 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002558 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002559 return ret;
2560 }
2561
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002562 /* Re-assoc is run only to update supported rates for given station. It
2563 * doesn't make much sense to reconfigure the peer completely.
2564 */
2565 if (!reassoc) {
2566 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2567 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002568 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002569 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002570 arvif->vdev_id, ret);
2571 return ret;
2572 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002573
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002574 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2575 if (ret) {
2576 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2577 sta->addr, arvif->vdev_id, ret);
2578 return ret;
2579 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002580
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002581 if (!sta->wme) {
2582 arvif->num_legacy_stations++;
2583 ret = ath10k_recalc_rtscts_prot(arvif);
2584 if (ret) {
2585 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2586 arvif->vdev_id, ret);
2587 return ret;
2588 }
2589 }
2590
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002591 /* Plumb cached keys only for static WEP */
2592 if (arvif->def_wep_key_idx != -1) {
2593 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2594 if (ret) {
2595 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2596 arvif->vdev_id, ret);
2597 return ret;
2598 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002599 }
2600 }
2601
Kalle Valo5e3dd152013-06-12 20:52:10 +03002602 return ret;
2603}
2604
Michal Kazior590922a2014-10-21 10:10:29 +03002605static int ath10k_station_disassoc(struct ath10k *ar,
2606 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002607 struct ieee80211_sta *sta)
2608{
Michal Kazior590922a2014-10-21 10:10:29 +03002609 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002610 int ret = 0;
2611
2612 lockdep_assert_held(&ar->conf_mutex);
2613
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002614 if (!sta->wme) {
2615 arvif->num_legacy_stations--;
2616 ret = ath10k_recalc_rtscts_prot(arvif);
2617 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002618 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002619 arvif->vdev_id, ret);
2620 return ret;
2621 }
2622 }
2623
Kalle Valo5e3dd152013-06-12 20:52:10 +03002624 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2625 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002626 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002627 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002628 return ret;
2629 }
2630
2631 return ret;
2632}
2633
2634/**************/
2635/* Regulatory */
2636/**************/
2637
2638static int ath10k_update_channel_list(struct ath10k *ar)
2639{
2640 struct ieee80211_hw *hw = ar->hw;
2641 struct ieee80211_supported_band **bands;
2642 enum ieee80211_band band;
2643 struct ieee80211_channel *channel;
2644 struct wmi_scan_chan_list_arg arg = {0};
2645 struct wmi_channel_arg *ch;
2646 bool passive;
2647 int len;
2648 int ret;
2649 int i;
2650
Michal Kazior548db542013-07-05 16:15:15 +03002651 lockdep_assert_held(&ar->conf_mutex);
2652
Kalle Valo5e3dd152013-06-12 20:52:10 +03002653 bands = hw->wiphy->bands;
2654 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2655 if (!bands[band])
2656 continue;
2657
2658 for (i = 0; i < bands[band]->n_channels; i++) {
2659 if (bands[band]->channels[i].flags &
2660 IEEE80211_CHAN_DISABLED)
2661 continue;
2662
2663 arg.n_channels++;
2664 }
2665 }
2666
2667 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2668 arg.channels = kzalloc(len, GFP_KERNEL);
2669 if (!arg.channels)
2670 return -ENOMEM;
2671
2672 ch = arg.channels;
2673 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2674 if (!bands[band])
2675 continue;
2676
2677 for (i = 0; i < bands[band]->n_channels; i++) {
2678 channel = &bands[band]->channels[i];
2679
2680 if (channel->flags & IEEE80211_CHAN_DISABLED)
2681 continue;
2682
2683 ch->allow_ht = true;
2684
2685 /* FIXME: when should we really allow VHT? */
2686 ch->allow_vht = true;
2687
2688 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002689 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002690
2691 ch->ht40plus =
2692 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2693
Marek Puzyniake8a50f82013-11-20 09:59:47 +02002694 ch->chan_radar =
2695 !!(channel->flags & IEEE80211_CHAN_RADAR);
2696
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002697 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002698 ch->passive = passive;
2699
2700 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02002701 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07002702 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07002703 ch->max_power = channel->max_power * 2;
2704 ch->max_reg_power = channel->max_reg_power * 2;
2705 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002706 ch->reg_class_id = 0; /* FIXME */
2707
2708 /* FIXME: why use only legacy modes, why not any
2709 * HT/VHT modes? Would that even make any
2710 * difference? */
2711 if (channel->band == IEEE80211_BAND_2GHZ)
2712 ch->mode = MODE_11G;
2713 else
2714 ch->mode = MODE_11A;
2715
2716 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
2717 continue;
2718
Michal Kazior7aa7a722014-08-25 12:09:38 +02002719 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002720 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
2721 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002722 ch->freq, ch->max_power, ch->max_reg_power,
2723 ch->max_antenna_gain, ch->mode);
2724
2725 ch++;
2726 }
2727 }
2728
2729 ret = ath10k_wmi_scan_chan_list(ar, &arg);
2730 kfree(arg.channels);
2731
2732 return ret;
2733}
2734
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002735static enum wmi_dfs_region
2736ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
2737{
2738 switch (dfs_region) {
2739 case NL80211_DFS_UNSET:
2740 return WMI_UNINIT_DFS_DOMAIN;
2741 case NL80211_DFS_FCC:
2742 return WMI_FCC_DFS_DOMAIN;
2743 case NL80211_DFS_ETSI:
2744 return WMI_ETSI_DFS_DOMAIN;
2745 case NL80211_DFS_JP:
2746 return WMI_MKK4_DFS_DOMAIN;
2747 }
2748 return WMI_UNINIT_DFS_DOMAIN;
2749}
2750
Michal Kaziorf7843d72013-07-16 09:38:52 +02002751static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002752{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002753 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002754 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002755 enum wmi_dfs_region wmi_dfs_reg;
2756 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002757
Michal Kaziorf7843d72013-07-16 09:38:52 +02002758 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002759
2760 ret = ath10k_update_channel_list(ar);
2761 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002762 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002763
2764 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002765
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002766 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
2767 nl_dfs_reg = ar->dfs_detector->region;
2768 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
2769 } else {
2770 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
2771 }
2772
Kalle Valo5e3dd152013-06-12 20:52:10 +03002773 /* Target allows setting up per-band regdomain but ath_common provides
2774 * a combined one only */
2775 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02002776 regpair->reg_domain,
2777 regpair->reg_domain, /* 2ghz */
2778 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03002779 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002780 regpair->reg_5ghz_ctl,
2781 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002782 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002783 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02002784}
Michal Kazior548db542013-07-05 16:15:15 +03002785
Michal Kaziorf7843d72013-07-16 09:38:52 +02002786static void ath10k_reg_notifier(struct wiphy *wiphy,
2787 struct regulatory_request *request)
2788{
2789 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2790 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002791 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002792
2793 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
2794
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002795 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002796 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002797 request->dfs_region);
2798 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
2799 request->dfs_region);
2800 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002801 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002802 request->dfs_region);
2803 }
2804
Michal Kaziorf7843d72013-07-16 09:38:52 +02002805 mutex_lock(&ar->conf_mutex);
2806 if (ar->state == ATH10K_STATE_ON)
2807 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03002808 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002809}
2810
2811/***************/
2812/* TX handlers */
2813/***************/
2814
Michal Kazior96d828d2015-03-31 10:26:23 +00002815void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
2816{
2817 lockdep_assert_held(&ar->htt.tx_lock);
2818
2819 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
2820 ar->tx_paused |= BIT(reason);
2821 ieee80211_stop_queues(ar->hw);
2822}
2823
2824static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
2825 struct ieee80211_vif *vif)
2826{
2827 struct ath10k *ar = data;
2828 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2829
2830 if (arvif->tx_paused)
2831 return;
2832
2833 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
2834}
2835
2836void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
2837{
2838 lockdep_assert_held(&ar->htt.tx_lock);
2839
2840 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
2841 ar->tx_paused &= ~BIT(reason);
2842
2843 if (ar->tx_paused)
2844 return;
2845
2846 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2847 IEEE80211_IFACE_ITER_RESUME_ALL,
2848 ath10k_mac_tx_unlock_iter,
2849 ar);
2850}
2851
2852void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
2853{
2854 struct ath10k *ar = arvif->ar;
2855
2856 lockdep_assert_held(&ar->htt.tx_lock);
2857
2858 WARN_ON(reason >= BITS_PER_LONG);
2859 arvif->tx_paused |= BIT(reason);
2860 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
2861}
2862
2863void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
2864{
2865 struct ath10k *ar = arvif->ar;
2866
2867 lockdep_assert_held(&ar->htt.tx_lock);
2868
2869 WARN_ON(reason >= BITS_PER_LONG);
2870 arvif->tx_paused &= ~BIT(reason);
2871
2872 if (ar->tx_paused)
2873 return;
2874
2875 if (arvif->tx_paused)
2876 return;
2877
2878 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
2879}
2880
Michal Kaziorb4aa5392015-03-31 10:26:24 +00002881static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
2882 enum wmi_tlv_tx_pause_id pause_id,
2883 enum wmi_tlv_tx_pause_action action)
2884{
2885 struct ath10k *ar = arvif->ar;
2886
2887 lockdep_assert_held(&ar->htt.tx_lock);
2888
2889 switch (pause_id) {
2890 case WMI_TLV_TX_PAUSE_ID_MCC:
2891 case WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA:
2892 case WMI_TLV_TX_PAUSE_ID_P2P_GO_PS:
2893 case WMI_TLV_TX_PAUSE_ID_AP_PS:
2894 case WMI_TLV_TX_PAUSE_ID_IBSS_PS:
2895 switch (action) {
2896 case WMI_TLV_TX_PAUSE_ACTION_STOP:
2897 ath10k_mac_vif_tx_lock(arvif, pause_id);
2898 break;
2899 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
2900 ath10k_mac_vif_tx_unlock(arvif, pause_id);
2901 break;
2902 default:
2903 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
2904 action, arvif->vdev_id);
2905 break;
2906 }
2907 break;
2908 case WMI_TLV_TX_PAUSE_ID_AP_PEER_PS:
2909 case WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD:
2910 case WMI_TLV_TX_PAUSE_ID_STA_ADD_BA:
2911 case WMI_TLV_TX_PAUSE_ID_HOST:
2912 default:
2913 /* FIXME: Some pause_ids aren't vdev specific. Instead they
2914 * target peer_id and tid. Implementing these could improve
2915 * traffic scheduling fairness across multiple connected
2916 * stations in AP/IBSS modes.
2917 */
2918 ath10k_dbg(ar, ATH10K_DBG_MAC,
2919 "mac ignoring unsupported tx pause vdev %i id %d\n",
2920 arvif->vdev_id, pause_id);
2921 break;
2922 }
2923}
2924
2925struct ath10k_mac_tx_pause {
2926 u32 vdev_id;
2927 enum wmi_tlv_tx_pause_id pause_id;
2928 enum wmi_tlv_tx_pause_action action;
2929};
2930
2931static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
2932 struct ieee80211_vif *vif)
2933{
2934 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2935 struct ath10k_mac_tx_pause *arg = data;
2936
2937 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
2938}
2939
2940void ath10k_mac_handle_tx_pause(struct ath10k *ar, u32 vdev_id,
2941 enum wmi_tlv_tx_pause_id pause_id,
2942 enum wmi_tlv_tx_pause_action action)
2943{
2944 struct ath10k_mac_tx_pause arg = {
2945 .vdev_id = vdev_id,
2946 .pause_id = pause_id,
2947 .action = action,
2948 };
2949
2950 spin_lock_bh(&ar->htt.tx_lock);
2951 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2952 IEEE80211_IFACE_ITER_RESUME_ALL,
2953 ath10k_mac_handle_tx_pause_iter,
2954 &arg);
2955 spin_unlock_bh(&ar->htt.tx_lock);
2956}
2957
Michal Kazior42c3aa62013-10-02 11:03:38 +02002958static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
2959{
2960 if (ieee80211_is_mgmt(hdr->frame_control))
2961 return HTT_DATA_TX_EXT_TID_MGMT;
2962
2963 if (!ieee80211_is_data_qos(hdr->frame_control))
2964 return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
2965
2966 if (!is_unicast_ether_addr(ieee80211_get_DA(hdr)))
2967 return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
2968
2969 return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
2970}
2971
Michal Kazior2b37c292014-09-02 11:00:22 +03002972static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
Michal Kaziorddb6ad72013-10-02 11:03:39 +02002973{
Michal Kazior2b37c292014-09-02 11:00:22 +03002974 if (vif)
2975 return ath10k_vif_to_arvif(vif)->vdev_id;
Michal Kaziorddb6ad72013-10-02 11:03:39 +02002976
Michal Kazior1bbc0972014-04-08 09:45:47 +03002977 if (ar->monitor_started)
Michal Kaziorddb6ad72013-10-02 11:03:39 +02002978 return ar->monitor_vdev_id;
2979
Michal Kazior7aa7a722014-08-25 12:09:38 +02002980 ath10k_warn(ar, "failed to resolve vdev id\n");
Michal Kaziorddb6ad72013-10-02 11:03:39 +02002981 return 0;
2982}
2983
Michal Kaziord740d8f2015-03-30 09:51:51 +03002984static enum ath10k_hw_txrx_mode
2985ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03002986 struct ieee80211_sta *sta, struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03002987{
2988 const struct ieee80211_hdr *hdr = (void *)skb->data;
2989 __le16 fc = hdr->frame_control;
2990
2991 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
2992 return ATH10K_HW_TXRX_RAW;
2993
2994 if (ieee80211_is_mgmt(fc))
2995 return ATH10K_HW_TXRX_MGMT;
2996
2997 /* Workaround:
2998 *
2999 * NullFunc frames are mostly used to ping if a client or AP are still
3000 * reachable and responsive. This implies tx status reports must be
3001 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3002 * come to a conclusion that the other end disappeared and tear down
3003 * BSS connection or it can never disconnect from BSS/client (which is
3004 * the case).
3005 *
3006 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3007 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3008 * which seems to deliver correct tx reports for NullFunc frames. The
3009 * downside of using it is it ignores client powersave state so it can
3010 * end up disconnecting sleeping clients in AP mode. It should fix STA
3011 * mode though because AP don't sleep.
3012 */
3013 if (ar->htt.target_version_major < 3 &&
3014 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
3015 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, ar->fw_features))
3016 return ATH10K_HW_TXRX_MGMT;
3017
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003018 /* Workaround:
3019 *
3020 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3021 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3022 * to work with Ethernet txmode so use it.
3023 */
3024 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3025 return ATH10K_HW_TXRX_ETHERNET;
3026
Michal Kaziord740d8f2015-03-30 09:51:51 +03003027 return ATH10K_HW_TXRX_NATIVE_WIFI;
3028}
3029
Michal Kazior4b604552014-07-21 21:03:09 +03003030/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3031 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003032 */
Michal Kazior4b604552014-07-21 21:03:09 +03003033static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003034{
3035 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003036 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003037 u8 *qos_ctl;
3038
3039 if (!ieee80211_is_data_qos(hdr->frame_control))
3040 return;
3041
3042 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003043 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3044 skb->data, (void *)qos_ctl - (void *)skb->data);
3045 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003046
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003047 /* Some firmware revisions don't handle sending QoS NullFunc well.
3048 * These frames are mainly used for CQM purposes so it doesn't really
3049 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003050 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003051 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003052 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003053 cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003054
3055 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003056}
3057
Michal Kaziord740d8f2015-03-30 09:51:51 +03003058static void ath10k_tx_h_8023(struct sk_buff *skb)
3059{
3060 struct ieee80211_hdr *hdr;
3061 struct rfc1042_hdr *rfc1042;
3062 struct ethhdr *eth;
3063 size_t hdrlen;
3064 u8 da[ETH_ALEN];
3065 u8 sa[ETH_ALEN];
3066 __be16 type;
3067
3068 hdr = (void *)skb->data;
3069 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3070 rfc1042 = (void *)skb->data + hdrlen;
3071
3072 ether_addr_copy(da, ieee80211_get_DA(hdr));
3073 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3074 type = rfc1042->snap_type;
3075
3076 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3077 skb_push(skb, sizeof(*eth));
3078
3079 eth = (void *)skb->data;
3080 ether_addr_copy(eth->h_dest, da);
3081 ether_addr_copy(eth->h_source, sa);
3082 eth->h_proto = type;
3083}
3084
Michal Kazior4b604552014-07-21 21:03:09 +03003085static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3086 struct ieee80211_vif *vif,
3087 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003088{
3089 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003090 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3091
3092 /* This is case only for P2P_GO */
3093 if (arvif->vdev_type != WMI_VDEV_TYPE_AP ||
3094 arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
3095 return;
3096
3097 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3098 spin_lock_bh(&ar->data_lock);
3099 if (arvif->u.ap.noa_data)
3100 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3101 GFP_ATOMIC))
3102 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3103 arvif->u.ap.noa_data,
3104 arvif->u.ap.noa_len);
3105 spin_unlock_bh(&ar->data_lock);
3106 }
3107}
3108
Michal Kazior8d6d3622014-11-24 14:58:31 +01003109static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
3110{
3111 /* FIXME: Not really sure since when the behaviour changed. At some
3112 * point new firmware stopped requiring creation of peer entries for
3113 * offchannel tx (and actually creating them causes issues with wmi-htc
3114 * tx credit replenishment and reliability). Assuming it's at least 3.4
3115 * because that's when the `freq` was introduced to TX_FRM HTT command.
3116 */
3117 return !(ar->htt.target_version_major >= 3 &&
3118 ar->htt.target_version_minor >= 4);
3119}
3120
Michal Kaziord740d8f2015-03-30 09:51:51 +03003121static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003122{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003123 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003124 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003125
Michal Kaziord740d8f2015-03-30 09:51:51 +03003126 spin_lock_bh(&ar->data_lock);
3127
3128 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3129 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3130 ret = -ENOSPC;
3131 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003132 }
3133
Michal Kaziord740d8f2015-03-30 09:51:51 +03003134 __skb_queue_tail(q, skb);
3135 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3136
3137unlock:
3138 spin_unlock_bh(&ar->data_lock);
3139
3140 return ret;
3141}
3142
3143static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
3144{
3145 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3146 struct ath10k_htt *htt = &ar->htt;
3147 int ret = 0;
3148
3149 switch (cb->txmode) {
3150 case ATH10K_HW_TXRX_RAW:
3151 case ATH10K_HW_TXRX_NATIVE_WIFI:
3152 case ATH10K_HW_TXRX_ETHERNET:
3153 ret = ath10k_htt_tx(htt, skb);
3154 break;
3155 case ATH10K_HW_TXRX_MGMT:
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003156 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Michal Kaziord740d8f2015-03-30 09:51:51 +03003157 ar->fw_features))
3158 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3159 else if (ar->htt.target_version_major >= 3)
3160 ret = ath10k_htt_tx(htt, skb);
3161 else
3162 ret = ath10k_htt_mgmt_tx(htt, skb);
3163 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003164 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003165
3166 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003167 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3168 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003169 ieee80211_free_txskb(ar->hw, skb);
3170 }
3171}
3172
3173void ath10k_offchan_tx_purge(struct ath10k *ar)
3174{
3175 struct sk_buff *skb;
3176
3177 for (;;) {
3178 skb = skb_dequeue(&ar->offchan_tx_queue);
3179 if (!skb)
3180 break;
3181
3182 ieee80211_free_txskb(ar->hw, skb);
3183 }
3184}
3185
3186void ath10k_offchan_tx_work(struct work_struct *work)
3187{
3188 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3189 struct ath10k_peer *peer;
3190 struct ieee80211_hdr *hdr;
3191 struct sk_buff *skb;
3192 const u8 *peer_addr;
3193 int vdev_id;
3194 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003195 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003196
3197 /* FW requirement: We must create a peer before FW will send out
3198 * an offchannel frame. Otherwise the frame will be stuck and
3199 * never transmitted. We delete the peer upon tx completion.
3200 * It is unlikely that a peer for offchannel tx will already be
3201 * present. However it may be in some rare cases so account for that.
3202 * Otherwise we might remove a legitimate peer and break stuff. */
3203
3204 for (;;) {
3205 skb = skb_dequeue(&ar->offchan_tx_queue);
3206 if (!skb)
3207 break;
3208
3209 mutex_lock(&ar->conf_mutex);
3210
Michal Kazior7aa7a722014-08-25 12:09:38 +02003211 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003212 skb);
3213
3214 hdr = (struct ieee80211_hdr *)skb->data;
3215 peer_addr = ieee80211_get_DA(hdr);
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003216 vdev_id = ATH10K_SKB_CB(skb)->vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003217
3218 spin_lock_bh(&ar->data_lock);
3219 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3220 spin_unlock_bh(&ar->data_lock);
3221
3222 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003223 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003224 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003225 peer_addr, vdev_id);
3226
3227 if (!peer) {
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003228 ret = ath10k_peer_create(ar, vdev_id, peer_addr,
3229 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003230 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003231 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003232 peer_addr, vdev_id, ret);
3233 }
3234
3235 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003236 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003237 ar->offchan_tx_skb = skb;
3238 spin_unlock_bh(&ar->data_lock);
3239
Michal Kaziord740d8f2015-03-30 09:51:51 +03003240 ath10k_mac_tx(ar, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003241
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003242 time_left =
3243 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3244 if (time_left == 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003245 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003246 skb);
3247
3248 if (!peer) {
3249 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3250 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003251 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003252 peer_addr, vdev_id, ret);
3253 }
3254
3255 mutex_unlock(&ar->conf_mutex);
3256 }
3257}
3258
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003259void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3260{
3261 struct sk_buff *skb;
3262
3263 for (;;) {
3264 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3265 if (!skb)
3266 break;
3267
3268 ieee80211_free_txskb(ar->hw, skb);
3269 }
3270}
3271
3272void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3273{
3274 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3275 struct sk_buff *skb;
3276 int ret;
3277
3278 for (;;) {
3279 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3280 if (!skb)
3281 break;
3282
3283 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003284 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003285 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003286 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003287 ieee80211_free_txskb(ar->hw, skb);
3288 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003289 }
3290}
3291
Kalle Valo5e3dd152013-06-12 20:52:10 +03003292/************/
3293/* Scanning */
3294/************/
3295
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003296void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003297{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003298 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003299
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003300 switch (ar->scan.state) {
3301 case ATH10K_SCAN_IDLE:
3302 break;
3303 case ATH10K_SCAN_RUNNING:
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003304 if (ar->scan.is_roc)
3305 ieee80211_remain_on_channel_expired(ar->hw);
John W. Linvillef6eaf1e2015-01-12 16:07:02 -05003306 /* fall through */
Michal Kazior7305d3e2014-11-24 14:58:33 +01003307 case ATH10K_SCAN_ABORTING:
3308 if (!ar->scan.is_roc)
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003309 ieee80211_scan_completed(ar->hw,
3310 (ar->scan.state ==
3311 ATH10K_SCAN_ABORTING));
3312 /* fall through */
3313 case ATH10K_SCAN_STARTING:
3314 ar->scan.state = ATH10K_SCAN_IDLE;
3315 ar->scan_channel = NULL;
3316 ath10k_offchan_tx_purge(ar);
3317 cancel_delayed_work(&ar->scan.timeout);
3318 complete_all(&ar->scan.completed);
3319 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003320 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003321}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003322
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003323void ath10k_scan_finish(struct ath10k *ar)
3324{
3325 spin_lock_bh(&ar->data_lock);
3326 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003327 spin_unlock_bh(&ar->data_lock);
3328}
3329
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003330static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003331{
3332 struct wmi_stop_scan_arg arg = {
3333 .req_id = 1, /* FIXME */
3334 .req_type = WMI_SCAN_STOP_ONE,
3335 .u.scan_id = ATH10K_SCAN_ID,
3336 };
3337 int ret;
3338
3339 lockdep_assert_held(&ar->conf_mutex);
3340
Kalle Valo5e3dd152013-06-12 20:52:10 +03003341 ret = ath10k_wmi_stop_scan(ar, &arg);
3342 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003343 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003344 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003345 }
3346
Kalle Valo5e3dd152013-06-12 20:52:10 +03003347 ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003348 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003349 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003350 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003351 } else if (ret > 0) {
3352 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003353 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003354
3355out:
3356 /* Scan state should be updated upon scan completion but in case
3357 * firmware fails to deliver the event (for whatever reason) it is
3358 * desired to clean up scan state anyway. Firmware may have just
3359 * dropped the scan completion event delivery due to transport pipe
3360 * being overflown with data and/or it can recover on its own before
3361 * next scan request is submitted.
3362 */
3363 spin_lock_bh(&ar->data_lock);
3364 if (ar->scan.state != ATH10K_SCAN_IDLE)
3365 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003366 spin_unlock_bh(&ar->data_lock);
3367
3368 return ret;
3369}
3370
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003371static void ath10k_scan_abort(struct ath10k *ar)
3372{
3373 int ret;
3374
3375 lockdep_assert_held(&ar->conf_mutex);
3376
3377 spin_lock_bh(&ar->data_lock);
3378
3379 switch (ar->scan.state) {
3380 case ATH10K_SCAN_IDLE:
3381 /* This can happen if timeout worker kicked in and called
3382 * abortion while scan completion was being processed.
3383 */
3384 break;
3385 case ATH10K_SCAN_STARTING:
3386 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02003387 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003388 ath10k_scan_state_str(ar->scan.state),
3389 ar->scan.state);
3390 break;
3391 case ATH10K_SCAN_RUNNING:
3392 ar->scan.state = ATH10K_SCAN_ABORTING;
3393 spin_unlock_bh(&ar->data_lock);
3394
3395 ret = ath10k_scan_stop(ar);
3396 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003397 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003398
3399 spin_lock_bh(&ar->data_lock);
3400 break;
3401 }
3402
3403 spin_unlock_bh(&ar->data_lock);
3404}
3405
3406void ath10k_scan_timeout_work(struct work_struct *work)
3407{
3408 struct ath10k *ar = container_of(work, struct ath10k,
3409 scan.timeout.work);
3410
3411 mutex_lock(&ar->conf_mutex);
3412 ath10k_scan_abort(ar);
3413 mutex_unlock(&ar->conf_mutex);
3414}
3415
Kalle Valo5e3dd152013-06-12 20:52:10 +03003416static int ath10k_start_scan(struct ath10k *ar,
3417 const struct wmi_start_scan_arg *arg)
3418{
3419 int ret;
3420
3421 lockdep_assert_held(&ar->conf_mutex);
3422
3423 ret = ath10k_wmi_start_scan(ar, arg);
3424 if (ret)
3425 return ret;
3426
Kalle Valo5e3dd152013-06-12 20:52:10 +03003427 ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ);
3428 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003429 ret = ath10k_scan_stop(ar);
3430 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003431 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003432
3433 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003434 }
3435
Ben Greear2f9eec02015-02-15 16:50:38 +02003436 /* If we failed to start the scan, return error code at
3437 * this point. This is probably due to some issue in the
3438 * firmware, but no need to wedge the driver due to that...
3439 */
3440 spin_lock_bh(&ar->data_lock);
3441 if (ar->scan.state == ATH10K_SCAN_IDLE) {
3442 spin_unlock_bh(&ar->data_lock);
3443 return -EINVAL;
3444 }
3445 spin_unlock_bh(&ar->data_lock);
3446
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003447 /* Add a 200ms margin to account for event/command processing */
3448 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
3449 msecs_to_jiffies(arg->max_scan_time+200));
Kalle Valo5e3dd152013-06-12 20:52:10 +03003450 return 0;
3451}
3452
3453/**********************/
3454/* mac80211 callbacks */
3455/**********************/
3456
3457static void ath10k_tx(struct ieee80211_hw *hw,
3458 struct ieee80211_tx_control *control,
3459 struct sk_buff *skb)
3460{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003461 struct ath10k *ar = hw->priv;
Michal Kazior4b604552014-07-21 21:03:09 +03003462 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3463 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003464 struct ieee80211_sta *sta = control->sta;
Michal Kazior4b604552014-07-21 21:03:09 +03003465 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003466 __le16 fc = hdr->frame_control;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003467
3468 /* We should disable CCK RATE due to P2P */
3469 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003470 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003471
Michal Kazior4b604552014-07-21 21:03:09 +03003472 ATH10K_SKB_CB(skb)->htt.is_offchan = false;
Michal Kazior6fcafef2015-03-30 09:51:51 +03003473 ATH10K_SKB_CB(skb)->htt.freq = 0;
Michal Kazior4b604552014-07-21 21:03:09 +03003474 ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
Michal Kazior2b37c292014-09-02 11:00:22 +03003475 ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003476 ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003477 ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003478
Michal Kaziord740d8f2015-03-30 09:51:51 +03003479 switch (ATH10K_SKB_CB(skb)->txmode) {
3480 case ATH10K_HW_TXRX_MGMT:
3481 case ATH10K_HW_TXRX_NATIVE_WIFI:
Michal Kazior4b604552014-07-21 21:03:09 +03003482 ath10k_tx_h_nwifi(hw, skb);
Michal Kazior4b604552014-07-21 21:03:09 +03003483 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3484 ath10k_tx_h_seq_no(vif, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003485 break;
3486 case ATH10K_HW_TXRX_ETHERNET:
3487 ath10k_tx_h_8023(skb);
3488 break;
3489 case ATH10K_HW_TXRX_RAW:
3490 /* FIXME: Packet injection isn't implemented. It should be
3491 * doable with firmware 10.2 on qca988x.
3492 */
3493 WARN_ON_ONCE(1);
3494 ieee80211_free_txskb(hw, skb);
3495 return;
Michal Kaziorcf84bd42013-07-16 11:04:54 +02003496 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003497
Kalle Valo5e3dd152013-06-12 20:52:10 +03003498 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3499 spin_lock_bh(&ar->data_lock);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003500 ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003501 ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003502 spin_unlock_bh(&ar->data_lock);
3503
Michal Kazior8d6d3622014-11-24 14:58:31 +01003504 if (ath10k_mac_need_offchan_tx_work(ar)) {
3505 ATH10K_SKB_CB(skb)->htt.freq = 0;
3506 ATH10K_SKB_CB(skb)->htt.is_offchan = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003507
Michal Kazior8d6d3622014-11-24 14:58:31 +01003508 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
3509 skb);
3510
3511 skb_queue_tail(&ar->offchan_tx_queue, skb);
3512 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3513 return;
3514 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003515 }
3516
Michal Kaziord740d8f2015-03-30 09:51:51 +03003517 ath10k_mac_tx(ar, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003518}
3519
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003520/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01003521void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003522{
3523 /* make sure rcu-protected mac80211 tx path itself is drained */
3524 synchronize_net();
3525
3526 ath10k_offchan_tx_purge(ar);
3527 ath10k_mgmt_over_wmi_tx_purge(ar);
3528
3529 cancel_work_sync(&ar->offchan_tx_work);
3530 cancel_work_sync(&ar->wmi_mgmt_tx_work);
3531}
3532
Michal Kazioraffd3212013-07-16 09:54:35 +02003533void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02003534{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03003535 struct ath10k_vif *arvif;
3536
Michal Kazior818bdd12013-07-16 09:38:57 +02003537 lockdep_assert_held(&ar->conf_mutex);
3538
Michal Kazior19337472014-08-28 12:58:16 +02003539 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
3540 ar->filter_flags = 0;
3541 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00003542 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02003543
3544 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03003545 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02003546
3547 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00003548 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03003549
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003550 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02003551 ath10k_peer_cleanup_all(ar);
3552 ath10k_core_stop(ar);
3553 ath10k_hif_power_down(ar);
3554
3555 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03003556 list_for_each_entry(arvif, &ar->arvifs, list)
3557 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02003558 spin_unlock_bh(&ar->data_lock);
3559}
3560
Ben Greear46acf7b2014-05-16 17:15:38 +03003561static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
3562{
3563 struct ath10k *ar = hw->priv;
3564
3565 mutex_lock(&ar->conf_mutex);
3566
3567 if (ar->cfg_tx_chainmask) {
3568 *tx_ant = ar->cfg_tx_chainmask;
3569 *rx_ant = ar->cfg_rx_chainmask;
3570 } else {
3571 *tx_ant = ar->supp_tx_chainmask;
3572 *rx_ant = ar->supp_rx_chainmask;
3573 }
3574
3575 mutex_unlock(&ar->conf_mutex);
3576
3577 return 0;
3578}
3579
Ben Greear5572a952014-11-24 16:22:10 +02003580static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
3581{
3582 /* It is not clear that allowing gaps in chainmask
3583 * is helpful. Probably it will not do what user
3584 * is hoping for, so warn in that case.
3585 */
3586 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
3587 return;
3588
3589 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
3590 dbg, cm);
3591}
3592
Ben Greear46acf7b2014-05-16 17:15:38 +03003593static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
3594{
3595 int ret;
3596
3597 lockdep_assert_held(&ar->conf_mutex);
3598
Ben Greear5572a952014-11-24 16:22:10 +02003599 ath10k_check_chain_mask(ar, tx_ant, "tx");
3600 ath10k_check_chain_mask(ar, rx_ant, "rx");
3601
Ben Greear46acf7b2014-05-16 17:15:38 +03003602 ar->cfg_tx_chainmask = tx_ant;
3603 ar->cfg_rx_chainmask = rx_ant;
3604
3605 if ((ar->state != ATH10K_STATE_ON) &&
3606 (ar->state != ATH10K_STATE_RESTARTED))
3607 return 0;
3608
3609 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
3610 tx_ant);
3611 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003612 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03003613 ret, tx_ant);
3614 return ret;
3615 }
3616
3617 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
3618 rx_ant);
3619 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003620 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03003621 ret, rx_ant);
3622 return ret;
3623 }
3624
3625 return 0;
3626}
3627
3628static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
3629{
3630 struct ath10k *ar = hw->priv;
3631 int ret;
3632
3633 mutex_lock(&ar->conf_mutex);
3634 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
3635 mutex_unlock(&ar->conf_mutex);
3636 return ret;
3637}
3638
Kalle Valo5e3dd152013-06-12 20:52:10 +03003639static int ath10k_start(struct ieee80211_hw *hw)
3640{
3641 struct ath10k *ar = hw->priv;
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03003642 u32 burst_enable;
Michal Kazior818bdd12013-07-16 09:38:57 +02003643 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003644
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003645 /*
3646 * This makes sense only when restarting hw. It is harmless to call
3647 * uncoditionally. This is necessary to make sure no HTT/WMI tx
3648 * commands will be submitted while restarting.
3649 */
3650 ath10k_drain_tx(ar);
3651
Michal Kazior548db542013-07-05 16:15:15 +03003652 mutex_lock(&ar->conf_mutex);
3653
Michal Kaziorc5058f52014-05-26 12:46:03 +03003654 switch (ar->state) {
3655 case ATH10K_STATE_OFF:
3656 ar->state = ATH10K_STATE_ON;
3657 break;
3658 case ATH10K_STATE_RESTARTING:
3659 ath10k_halt(ar);
3660 ar->state = ATH10K_STATE_RESTARTED;
3661 break;
3662 case ATH10K_STATE_ON:
3663 case ATH10K_STATE_RESTARTED:
3664 case ATH10K_STATE_WEDGED:
3665 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02003666 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03003667 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03003668 case ATH10K_STATE_UTF:
3669 ret = -EBUSY;
3670 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02003671 }
3672
3673 ret = ath10k_hif_power_up(ar);
3674 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003675 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003676 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02003677 }
3678
Kalle Valo43d2a302014-09-10 18:23:30 +03003679 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02003680 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003681 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003682 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02003683 }
3684
Bartosz Markowski226a3392013-09-26 17:47:16 +02003685 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03003686 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003687 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003688 goto err_core_stop;
3689 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003690
Michal Kaziorc4dd0d02013-11-13 11:05:10 +01003691 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03003692 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003693 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003694 goto err_core_stop;
3695 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003696
Michal Kaziorcf327842015-03-31 10:26:25 +00003697 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
3698 ret = ath10k_wmi_adaptive_qcs(ar, true);
3699 if (ret) {
3700 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
3701 ret);
3702 goto err_core_stop;
3703 }
3704 }
3705
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03003706 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
3707 burst_enable = ar->wmi.pdev_param->burst_enable;
3708 ret = ath10k_wmi_pdev_set_param(ar, burst_enable, 0);
3709 if (ret) {
3710 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
3711 goto err_core_stop;
3712 }
3713 }
3714
Ben Greear46acf7b2014-05-16 17:15:38 +03003715 if (ar->cfg_tx_chainmask)
3716 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask,
3717 ar->cfg_rx_chainmask);
3718
Marek Puzyniakab6258e2014-01-29 15:03:31 +02003719 /*
3720 * By default FW set ARP frames ac to voice (6). In that case ARP
3721 * exchange is not working properly for UAPSD enabled AP. ARP requests
3722 * which arrives with access category 0 are processed by network stack
3723 * and send back with access category 0, but FW changes access category
3724 * to 6. Set ARP frames access category to best effort (0) solves
3725 * this problem.
3726 */
3727
3728 ret = ath10k_wmi_pdev_set_param(ar,
3729 ar->wmi.pdev_param->arp_ac_override, 0);
3730 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003731 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02003732 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003733 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02003734 }
3735
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05303736 ret = ath10k_wmi_pdev_set_param(ar,
3737 ar->wmi.pdev_param->ani_enable, 1);
3738 if (ret) {
3739 ath10k_warn(ar, "failed to enable ani by default: %d\n",
3740 ret);
3741 goto err_core_stop;
3742 }
3743
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05303744 ar->ani_enabled = true;
3745
Michal Kaziord6500972014-04-08 09:56:09 +03003746 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003747 ath10k_regd_update(ar);
3748
Simon Wunderlich855aed12014-08-02 09:12:54 +03003749 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05303750 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03003751
Michal Kaziorae254432014-05-26 12:46:02 +03003752 mutex_unlock(&ar->conf_mutex);
3753 return 0;
3754
3755err_core_stop:
3756 ath10k_core_stop(ar);
3757
3758err_power_down:
3759 ath10k_hif_power_down(ar);
3760
3761err_off:
3762 ar->state = ATH10K_STATE_OFF;
3763
3764err:
Michal Kazior548db542013-07-05 16:15:15 +03003765 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01003766 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003767}
3768
3769static void ath10k_stop(struct ieee80211_hw *hw)
3770{
3771 struct ath10k *ar = hw->priv;
3772
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003773 ath10k_drain_tx(ar);
3774
Michal Kazior548db542013-07-05 16:15:15 +03003775 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03003776 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02003777 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03003778 ar->state = ATH10K_STATE_OFF;
3779 }
Michal Kazior548db542013-07-05 16:15:15 +03003780 mutex_unlock(&ar->conf_mutex);
3781
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003782 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02003783 cancel_work_sync(&ar->restart_work);
3784}
3785
Michal Kaziorad088bf2013-10-16 15:44:46 +03003786static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02003787{
Michal Kaziorad088bf2013-10-16 15:44:46 +03003788 struct ath10k_vif *arvif;
3789 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02003790
3791 lockdep_assert_held(&ar->conf_mutex);
3792
Michal Kaziorad088bf2013-10-16 15:44:46 +03003793 list_for_each_entry(arvif, &ar->arvifs, list) {
3794 ret = ath10k_mac_vif_setup_ps(arvif);
3795 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003796 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03003797 break;
3798 }
3799 }
Michal Kazioraffd3212013-07-16 09:54:35 +02003800
Michal Kaziorad088bf2013-10-16 15:44:46 +03003801 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003802}
3803
Michal Kazior500ff9f2015-03-31 10:26:21 +00003804static void ath10k_mac_chan_reconfigure(struct ath10k *ar)
Michal Kaziorc930f742014-01-23 11:38:25 +01003805{
3806 struct ath10k_vif *arvif;
Michal Kazior500ff9f2015-03-31 10:26:21 +00003807 struct cfg80211_chan_def def;
Michal Kaziorc930f742014-01-23 11:38:25 +01003808 int ret;
3809
3810 lockdep_assert_held(&ar->conf_mutex);
3811
Michal Kazior500ff9f2015-03-31 10:26:21 +00003812 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac chan reconfigure\n");
Michal Kaziorc930f742014-01-23 11:38:25 +01003813
3814 /* First stop monitor interface. Some FW versions crash if there's a
3815 * lone monitor interface. */
Michal Kazior1bbc0972014-04-08 09:45:47 +03003816 if (ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02003817 ath10k_monitor_stop(ar);
Michal Kaziorc930f742014-01-23 11:38:25 +01003818
3819 list_for_each_entry(arvif, &ar->arvifs, list) {
3820 if (!arvif->is_started)
3821 continue;
3822
Michal Kaziordc55e302014-07-29 12:53:36 +03003823 if (!arvif->is_up)
3824 continue;
3825
Michal Kaziorc930f742014-01-23 11:38:25 +01003826 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
3827 continue;
3828
Michal Kaziordc55e302014-07-29 12:53:36 +03003829 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kaziorc930f742014-01-23 11:38:25 +01003830 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003831 ath10k_warn(ar, "failed to down vdev %d: %d\n",
Michal Kaziorc930f742014-01-23 11:38:25 +01003832 arvif->vdev_id, ret);
3833 continue;
3834 }
3835 }
3836
Michal Kaziordc55e302014-07-29 12:53:36 +03003837 /* all vdevs are downed now - attempt to restart and re-up them */
Michal Kaziorc930f742014-01-23 11:38:25 +01003838
3839 list_for_each_entry(arvif, &ar->arvifs, list) {
3840 if (!arvif->is_started)
3841 continue;
3842
3843 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
3844 continue;
3845
Michal Kazior81a9a172015-03-05 16:02:17 +02003846 ret = ath10k_mac_setup_bcn_tmpl(arvif);
3847 if (ret)
3848 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
3849 ret);
3850
3851 ret = ath10k_mac_setup_prb_tmpl(arvif);
3852 if (ret)
3853 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
3854 ret);
3855
Michal Kazior500ff9f2015-03-31 10:26:21 +00003856 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
3857 continue;
3858
3859 ret = ath10k_vdev_restart(arvif, &def);
Michal Kaziorc930f742014-01-23 11:38:25 +01003860 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003861 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
Michal Kaziorc930f742014-01-23 11:38:25 +01003862 arvif->vdev_id, ret);
3863 continue;
3864 }
3865
3866 if (!arvif->is_up)
3867 continue;
3868
3869 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
3870 arvif->bssid);
3871 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003872 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
Michal Kaziorc930f742014-01-23 11:38:25 +01003873 arvif->vdev_id, ret);
3874 continue;
3875 }
3876 }
3877
Michal Kazior19337472014-08-28 12:58:16 +02003878 ath10k_monitor_recalc(ar);
Michal Kaziorc930f742014-01-23 11:38:25 +01003879}
3880
Michal Kazior7d9d5582014-10-21 10:40:15 +03003881static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
3882{
3883 int ret;
3884 u32 param;
3885
3886 lockdep_assert_held(&ar->conf_mutex);
3887
3888 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
3889
3890 param = ar->wmi.pdev_param->txpower_limit2g;
3891 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
3892 if (ret) {
3893 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
3894 txpower, ret);
3895 return ret;
3896 }
3897
3898 param = ar->wmi.pdev_param->txpower_limit5g;
3899 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
3900 if (ret) {
3901 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
3902 txpower, ret);
3903 return ret;
3904 }
3905
3906 return 0;
3907}
3908
3909static int ath10k_mac_txpower_recalc(struct ath10k *ar)
3910{
3911 struct ath10k_vif *arvif;
3912 int ret, txpower = -1;
3913
3914 lockdep_assert_held(&ar->conf_mutex);
3915
3916 list_for_each_entry(arvif, &ar->arvifs, list) {
3917 WARN_ON(arvif->txpower < 0);
3918
3919 if (txpower == -1)
3920 txpower = arvif->txpower;
3921 else
3922 txpower = min(txpower, arvif->txpower);
3923 }
3924
3925 if (WARN_ON(txpower == -1))
3926 return -EINVAL;
3927
3928 ret = ath10k_mac_txpower_setup(ar, txpower);
3929 if (ret) {
3930 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
3931 txpower, ret);
3932 return ret;
3933 }
3934
3935 return 0;
3936}
3937
Kalle Valo5e3dd152013-06-12 20:52:10 +03003938static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
3939{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003940 struct ath10k *ar = hw->priv;
3941 struct ieee80211_conf *conf = &hw->conf;
3942 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003943
3944 mutex_lock(&ar->conf_mutex);
3945
Michal Kazioraffd3212013-07-16 09:54:35 +02003946 if (changed & IEEE80211_CONF_CHANGE_PS)
3947 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003948
3949 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02003950 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
3951 ret = ath10k_monitor_recalc(ar);
3952 if (ret)
3953 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003954 }
3955
3956 mutex_unlock(&ar->conf_mutex);
3957 return ret;
3958}
3959
Ben Greear5572a952014-11-24 16:22:10 +02003960static u32 get_nss_from_chainmask(u16 chain_mask)
3961{
3962 if ((chain_mask & 0x15) == 0x15)
3963 return 4;
3964 else if ((chain_mask & 0x7) == 0x7)
3965 return 3;
3966 else if ((chain_mask & 0x3) == 0x3)
3967 return 2;
3968 return 1;
3969}
3970
Kalle Valo5e3dd152013-06-12 20:52:10 +03003971/*
3972 * TODO:
3973 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
3974 * because we will send mgmt frames without CCK. This requirement
3975 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
3976 * in the TX packet.
3977 */
3978static int ath10k_add_interface(struct ieee80211_hw *hw,
3979 struct ieee80211_vif *vif)
3980{
3981 struct ath10k *ar = hw->priv;
3982 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3983 enum wmi_sta_powersave_param param;
3984 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02003985 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003986 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00003987 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02003988 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003989
Johannes Berg848955c2014-11-11 12:48:42 +01003990 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
3991
Kalle Valo5e3dd152013-06-12 20:52:10 +03003992 mutex_lock(&ar->conf_mutex);
3993
Michal Kazior0dbd09e2013-07-31 10:55:14 +02003994 memset(arvif, 0, sizeof(*arvif));
3995
Kalle Valo5e3dd152013-06-12 20:52:10 +03003996 arvif->ar = ar;
3997 arvif->vif = vif;
3998
Ben Greeare63b33f2013-10-22 14:54:14 -07003999 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004000 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004001 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4002 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004003
Ben Greeara9aefb32014-08-12 11:02:19 +03004004 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004005 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004006 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03004007 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004008 }
Ben Greear16c11172014-09-23 14:17:16 -07004009 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004010
Ben Greear16c11172014-09-23 14:17:16 -07004011 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4012 bit, ar->free_vdev_map);
4013
4014 arvif->vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004015 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004016
Kalle Valo5e3dd152013-06-12 20:52:10 +03004017 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004018 case NL80211_IFTYPE_P2P_DEVICE:
4019 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4020 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
4021 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004022 case NL80211_IFTYPE_UNSPECIFIED:
4023 case NL80211_IFTYPE_STATION:
4024 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4025 if (vif->p2p)
4026 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT;
4027 break;
4028 case NL80211_IFTYPE_ADHOC:
4029 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4030 break;
4031 case NL80211_IFTYPE_AP:
4032 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4033
4034 if (vif->p2p)
4035 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO;
4036 break;
4037 case NL80211_IFTYPE_MONITOR:
4038 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4039 break;
4040 default:
4041 WARN_ON(1);
4042 break;
4043 }
4044
Michal Kazior96d828d2015-03-31 10:26:23 +00004045 /* Using vdev_id as queue number will make it very easy to do per-vif
4046 * tx queue locking. This shouldn't wrap due to interface combinations
4047 * but do a modulo for correctness sake and prevent using offchannel tx
4048 * queues for regular vif tx.
4049 */
4050 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4051 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4052 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4053
Michal Kazior64badcb2014-09-18 11:18:02 +03004054 /* Some firmware revisions don't wait for beacon tx completion before
4055 * sending another SWBA event. This could lead to hardware using old
4056 * (freed) beacon data in some cases, e.g. tx credit starvation
4057 * combined with missed TBTT. This is very very rare.
4058 *
4059 * On non-IOMMU-enabled hosts this could be a possible security issue
4060 * because hw could beacon some random data on the air. On
4061 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4062 * device would crash.
4063 *
4064 * Since there are no beacon tx completions (implicit nor explicit)
4065 * propagated to host the only workaround for this is to allocate a
4066 * DMA-coherent buffer for a lifetime of a vif and use it for all
4067 * beacon tx commands. Worst case for this approach is some beacons may
4068 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4069 */
4070 if (vif->type == NL80211_IFTYPE_ADHOC ||
4071 vif->type == NL80211_IFTYPE_AP) {
4072 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4073 IEEE80211_MAX_FRAME_LEN,
4074 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304075 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004076 if (!arvif->beacon_buf) {
4077 ret = -ENOMEM;
4078 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4079 ret);
4080 goto err;
4081 }
4082 }
4083
4084 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4085 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4086 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004087
4088 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4089 arvif->vdev_subtype, vif->addr);
4090 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004091 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004092 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004093 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004094 }
4095
Ben Greear16c11172014-09-23 14:17:16 -07004096 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Michal Kazior05791192013-10-16 15:44:45 +03004097 list_add(&arvif->list, &ar->arvifs);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004098
Michal Kazior46725b152015-01-28 09:57:49 +02004099 /* It makes no sense to have firmware do keepalives. mac80211 already
4100 * takes care of this with idle connection polling.
4101 */
4102 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004103 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02004104 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004105 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004106 goto err_vdev_delete;
4107 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004108
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004109 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004110
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004111 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4112 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004113 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004114 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03004115 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004116 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004117 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004118 goto err_vdev_delete;
4119 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004120
Ben Greear5572a952014-11-24 16:22:10 +02004121 if (ar->cfg_tx_chainmask) {
4122 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
4123
4124 vdev_param = ar->wmi.vdev_param->nss;
4125 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4126 nss);
4127 if (ret) {
4128 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
4129 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
4130 ret);
4131 goto err_vdev_delete;
4132 }
4133 }
4134
Michal Kaziore57e0572015-03-24 13:14:03 +00004135 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4136 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Marek Puzyniak7390ed32015-03-30 09:51:52 +03004137 ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr,
4138 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004139 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00004140 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004141 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004142 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004143 }
Michal Kaziore57e0572015-03-24 13:14:03 +00004144 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01004145
Michal Kaziore57e0572015-03-24 13:14:03 +00004146 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02004147 ret = ath10k_mac_set_kickout(arvif);
4148 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004149 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004150 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02004151 goto err_peer_delete;
4152 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004153 }
4154
4155 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
4156 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
4157 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
4158 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
4159 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004160 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004161 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004162 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004163 goto err_peer_delete;
4164 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004165
Michal Kazior9f9b5742014-12-12 12:41:36 +01004166 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004167 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004168 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004169 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004170 goto err_peer_delete;
4171 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004172
Michal Kazior9f9b5742014-12-12 12:41:36 +01004173 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004174 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004175 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004176 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004177 goto err_peer_delete;
4178 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004179 }
4180
Michal Kazior424121c2013-07-22 14:13:31 +02004181 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004182 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004183 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03004184 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004185 goto err_peer_delete;
4186 }
Michal Kazior679c54a2013-07-05 16:15:04 +03004187
Michal Kazior424121c2013-07-22 14:13:31 +02004188 ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004189 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004190 ath10k_warn(ar, "failed to set frag threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03004191 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004192 goto err_peer_delete;
4193 }
Michal Kazior679c54a2013-07-05 16:15:04 +03004194
Michal Kazior7d9d5582014-10-21 10:40:15 +03004195 arvif->txpower = vif->bss_conf.txpower;
4196 ret = ath10k_mac_txpower_recalc(ar);
4197 if (ret) {
4198 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4199 goto err_peer_delete;
4200 }
4201
Michal Kazior500ff9f2015-03-31 10:26:21 +00004202 if (vif->type == NL80211_IFTYPE_MONITOR) {
4203 ar->monitor_arvif = arvif;
4204 ret = ath10k_monitor_recalc(ar);
4205 if (ret) {
4206 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
4207 goto err_peer_delete;
4208 }
4209 }
4210
Kalle Valo5e3dd152013-06-12 20:52:10 +03004211 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004212 return 0;
4213
4214err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00004215 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4216 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14a2013-10-16 15:44:45 +03004217 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
4218
4219err_vdev_delete:
4220 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07004221 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004222 list_del(&arvif->list);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004223
4224err:
Michal Kazior64badcb2014-09-18 11:18:02 +03004225 if (arvif->beacon_buf) {
4226 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
4227 arvif->beacon_buf, arvif->beacon_paddr);
4228 arvif->beacon_buf = NULL;
4229 }
4230
Michal Kazior9dad14a2013-10-16 15:44:45 +03004231 mutex_unlock(&ar->conf_mutex);
4232
Kalle Valo5e3dd152013-06-12 20:52:10 +03004233 return ret;
4234}
4235
Michal Kaziorb4aa5392015-03-31 10:26:24 +00004236static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
4237{
4238 int i;
4239
4240 for (i = 0; i < BITS_PER_LONG; i++)
4241 ath10k_mac_vif_tx_unlock(arvif, i);
4242}
4243
Kalle Valo5e3dd152013-06-12 20:52:10 +03004244static void ath10k_remove_interface(struct ieee80211_hw *hw,
4245 struct ieee80211_vif *vif)
4246{
4247 struct ath10k *ar = hw->priv;
4248 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4249 int ret;
4250
Michal Kazior81a9a172015-03-05 16:02:17 +02004251 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004252 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02004253
Sujith Manoharan5d011f52014-11-25 11:47:00 +05304254 mutex_lock(&ar->conf_mutex);
4255
Michal Kaziored543882013-09-13 14:16:56 +02004256 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004257 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02004258 spin_unlock_bh(&ar->data_lock);
4259
Simon Wunderlich855aed12014-08-02 09:12:54 +03004260 ret = ath10k_spectral_vif_stop(arvif);
4261 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004262 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03004263 arvif->vdev_id, ret);
4264
Ben Greear16c11172014-09-23 14:17:16 -07004265 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004266 list_del(&arvif->list);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004267
Michal Kaziore57e0572015-03-24 13:14:03 +00004268 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4269 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02004270 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
4271 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004272 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00004273 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004274 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004275
4276 kfree(arvif->u.ap.noa_data);
4277 }
4278
Michal Kazior7aa7a722014-08-25 12:09:38 +02004279 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004280 arvif->vdev_id);
4281
Kalle Valo5e3dd152013-06-12 20:52:10 +03004282 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
4283 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004284 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004285 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004286
Michal Kazior2c512052015-02-15 16:50:40 +02004287 /* Some firmware revisions don't notify host about self-peer removal
4288 * until after associated vdev is deleted.
4289 */
Michal Kaziore57e0572015-03-24 13:14:03 +00004290 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4291 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02004292 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
4293 vif->addr);
4294 if (ret)
4295 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
4296 arvif->vdev_id, ret);
4297
4298 spin_lock_bh(&ar->data_lock);
4299 ar->num_peers--;
4300 spin_unlock_bh(&ar->data_lock);
4301 }
4302
Kalle Valo5e3dd152013-06-12 20:52:10 +03004303 ath10k_peer_cleanup(ar, arvif->vdev_id);
4304
Michal Kazior500ff9f2015-03-31 10:26:21 +00004305 if (vif->type == NL80211_IFTYPE_MONITOR) {
4306 ar->monitor_arvif = NULL;
4307 ret = ath10k_monitor_recalc(ar);
4308 if (ret)
4309 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
4310 }
4311
Michal Kaziorb4aa5392015-03-31 10:26:24 +00004312 spin_lock_bh(&ar->htt.tx_lock);
4313 ath10k_mac_vif_tx_unlock_all(arvif);
4314 spin_unlock_bh(&ar->htt.tx_lock);
4315
Kalle Valo5e3dd152013-06-12 20:52:10 +03004316 mutex_unlock(&ar->conf_mutex);
4317}
4318
4319/*
4320 * FIXME: Has to be verified.
4321 */
4322#define SUPPORTED_FILTERS \
4323 (FIF_PROMISC_IN_BSS | \
4324 FIF_ALLMULTI | \
4325 FIF_CONTROL | \
4326 FIF_PSPOLL | \
4327 FIF_OTHER_BSS | \
4328 FIF_BCN_PRBRESP_PROMISC | \
4329 FIF_PROBE_REQ | \
4330 FIF_FCSFAIL)
4331
4332static void ath10k_configure_filter(struct ieee80211_hw *hw,
4333 unsigned int changed_flags,
4334 unsigned int *total_flags,
4335 u64 multicast)
4336{
4337 struct ath10k *ar = hw->priv;
4338 int ret;
4339
4340 mutex_lock(&ar->conf_mutex);
4341
4342 changed_flags &= SUPPORTED_FILTERS;
4343 *total_flags &= SUPPORTED_FILTERS;
4344 ar->filter_flags = *total_flags;
4345
Michal Kazior19337472014-08-28 12:58:16 +02004346 ret = ath10k_monitor_recalc(ar);
4347 if (ret)
4348 ath10k_warn(ar, "failed to recalc montior: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004349
4350 mutex_unlock(&ar->conf_mutex);
4351}
4352
4353static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
4354 struct ieee80211_vif *vif,
4355 struct ieee80211_bss_conf *info,
4356 u32 changed)
4357{
4358 struct ath10k *ar = hw->priv;
4359 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4360 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03004361 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004362
4363 mutex_lock(&ar->conf_mutex);
4364
4365 if (changed & BSS_CHANGED_IBSS)
4366 ath10k_control_ibss(arvif, info, vif->addr);
4367
4368 if (changed & BSS_CHANGED_BEACON_INT) {
4369 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004370 vdev_param = ar->wmi.vdev_param->beacon_interval;
4371 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004372 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02004373 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004374 "mac vdev %d beacon_interval %d\n",
4375 arvif->vdev_id, arvif->beacon_interval);
4376
Kalle Valo5e3dd152013-06-12 20:52:10 +03004377 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004378 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004379 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004380 }
4381
4382 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004383 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004384 "vdev %d set beacon tx mode to staggered\n",
4385 arvif->vdev_id);
4386
Bartosz Markowski226a3392013-09-26 17:47:16 +02004387 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
4388 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004389 WMI_BEACON_STAGGERED_MODE);
4390 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004391 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004392 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02004393
4394 ret = ath10k_mac_setup_bcn_tmpl(arvif);
4395 if (ret)
4396 ath10k_warn(ar, "failed to update beacon template: %d\n",
4397 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004398 }
4399
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02004400 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
4401 ret = ath10k_mac_setup_prb_tmpl(arvif);
4402 if (ret)
4403 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
4404 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004405 }
4406
Michal Kaziorba2479f2015-01-24 12:14:51 +02004407 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004408 arvif->dtim_period = info->dtim_period;
4409
Michal Kazior7aa7a722014-08-25 12:09:38 +02004410 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004411 "mac vdev %d dtim_period %d\n",
4412 arvif->vdev_id, arvif->dtim_period);
4413
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004414 vdev_param = ar->wmi.vdev_param->dtim_period;
4415 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004416 arvif->dtim_period);
4417 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004418 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004419 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004420 }
4421
4422 if (changed & BSS_CHANGED_SSID &&
4423 vif->type == NL80211_IFTYPE_AP) {
4424 arvif->u.ap.ssid_len = info->ssid_len;
4425 if (info->ssid_len)
4426 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
4427 arvif->u.ap.hidden_ssid = info->hidden_ssid;
4428 }
4429
Michal Kazior077efc82014-10-21 10:10:29 +03004430 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
4431 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004432
4433 if (changed & BSS_CHANGED_BEACON_ENABLED)
4434 ath10k_control_beaconing(arvif, info);
4435
4436 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004437 arvif->use_cts_prot = info->use_cts_prot;
Michal Kazior7aa7a722014-08-25 12:09:38 +02004438 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004439 arvif->vdev_id, info->use_cts_prot);
Kalle Valo60c3daa2013-09-08 17:56:07 +03004440
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004441 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004442 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004443 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004444 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01004445
4446 vdev_param = ar->wmi.vdev_param->protection_mode;
4447 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4448 info->use_cts_prot ? 1 : 0);
4449 if (ret)
4450 ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
4451 info->use_cts_prot, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004452 }
4453
4454 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004455 if (info->use_short_slot)
4456 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
4457
4458 else
4459 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
4460
Michal Kazior7aa7a722014-08-25 12:09:38 +02004461 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004462 arvif->vdev_id, slottime);
4463
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004464 vdev_param = ar->wmi.vdev_param->slot_time;
4465 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004466 slottime);
4467 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004468 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004469 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004470 }
4471
4472 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004473 if (info->use_short_preamble)
4474 preamble = WMI_VDEV_PREAMBLE_SHORT;
4475 else
4476 preamble = WMI_VDEV_PREAMBLE_LONG;
4477
Michal Kazior7aa7a722014-08-25 12:09:38 +02004478 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004479 "mac vdev %d preamble %dn",
4480 arvif->vdev_id, preamble);
4481
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004482 vdev_param = ar->wmi.vdev_param->preamble;
4483 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004484 preamble);
4485 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004486 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004487 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004488 }
4489
4490 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02004491 if (info->assoc) {
4492 /* Workaround: Make sure monitor vdev is not running
4493 * when associating to prevent some firmware revisions
4494 * (e.g. 10.1 and 10.2) from crashing.
4495 */
4496 if (ar->monitor_started)
4497 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004498 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02004499 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03004500 } else {
4501 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02004502 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004503 }
4504
Michal Kazior7d9d5582014-10-21 10:40:15 +03004505 if (changed & BSS_CHANGED_TXPOWER) {
4506 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
4507 arvif->vdev_id, info->txpower);
4508
4509 arvif->txpower = info->txpower;
4510 ret = ath10k_mac_txpower_recalc(ar);
4511 if (ret)
4512 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4513 }
4514
Michal Kaziorbf14e652014-12-12 12:41:38 +01004515 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01004516 arvif->ps = vif->bss_conf.ps;
4517
4518 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01004519 if (ret)
4520 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
4521 arvif->vdev_id, ret);
4522 }
4523
Kalle Valo5e3dd152013-06-12 20:52:10 +03004524 mutex_unlock(&ar->conf_mutex);
4525}
4526
4527static int ath10k_hw_scan(struct ieee80211_hw *hw,
4528 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02004529 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004530{
4531 struct ath10k *ar = hw->priv;
4532 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02004533 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004534 struct wmi_start_scan_arg arg;
4535 int ret = 0;
4536 int i;
4537
4538 mutex_lock(&ar->conf_mutex);
4539
4540 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004541 switch (ar->scan.state) {
4542 case ATH10K_SCAN_IDLE:
4543 reinit_completion(&ar->scan.started);
4544 reinit_completion(&ar->scan.completed);
4545 ar->scan.state = ATH10K_SCAN_STARTING;
4546 ar->scan.is_roc = false;
4547 ar->scan.vdev_id = arvif->vdev_id;
4548 ret = 0;
4549 break;
4550 case ATH10K_SCAN_STARTING:
4551 case ATH10K_SCAN_RUNNING:
4552 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03004553 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004554 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004555 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004556 spin_unlock_bh(&ar->data_lock);
4557
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004558 if (ret)
4559 goto exit;
4560
Kalle Valo5e3dd152013-06-12 20:52:10 +03004561 memset(&arg, 0, sizeof(arg));
4562 ath10k_wmi_start_scan_init(ar, &arg);
4563 arg.vdev_id = arvif->vdev_id;
4564 arg.scan_id = ATH10K_SCAN_ID;
4565
4566 if (!req->no_cck)
4567 arg.scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES;
4568
4569 if (req->ie_len) {
4570 arg.ie_len = req->ie_len;
4571 memcpy(arg.ie, req->ie, arg.ie_len);
4572 }
4573
4574 if (req->n_ssids) {
4575 arg.n_ssids = req->n_ssids;
4576 for (i = 0; i < arg.n_ssids; i++) {
4577 arg.ssids[i].len = req->ssids[i].ssid_len;
4578 arg.ssids[i].ssid = req->ssids[i].ssid;
4579 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02004580 } else {
4581 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004582 }
4583
4584 if (req->n_channels) {
4585 arg.n_channels = req->n_channels;
4586 for (i = 0; i < arg.n_channels; i++)
4587 arg.channels[i] = req->channels[i]->center_freq;
4588 }
4589
4590 ret = ath10k_start_scan(ar, &arg);
4591 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004592 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004593 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004594 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004595 spin_unlock_bh(&ar->data_lock);
4596 }
4597
4598exit:
4599 mutex_unlock(&ar->conf_mutex);
4600 return ret;
4601}
4602
4603static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
4604 struct ieee80211_vif *vif)
4605{
4606 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004607
4608 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004609 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004610 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01004611
4612 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004613}
4614
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004615static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
4616 struct ath10k_vif *arvif,
4617 enum set_key_cmd cmd,
4618 struct ieee80211_key_conf *key)
4619{
4620 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
4621 int ret;
4622
4623 /* 10.1 firmware branch requires default key index to be set to group
4624 * key index after installing it. Otherwise FW/HW Txes corrupted
4625 * frames with multi-vif APs. This is not required for main firmware
4626 * branch (e.g. 636).
4627 *
4628 * FIXME: This has been tested only in AP. It remains unknown if this
4629 * is required for multi-vif STA interfaces on 10.1 */
4630
4631 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
4632 return;
4633
4634 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
4635 return;
4636
4637 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
4638 return;
4639
4640 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
4641 return;
4642
4643 if (cmd != SET_KEY)
4644 return;
4645
4646 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4647 key->keyidx);
4648 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004649 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004650 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004651}
4652
Kalle Valo5e3dd152013-06-12 20:52:10 +03004653static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
4654 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
4655 struct ieee80211_key_conf *key)
4656{
4657 struct ath10k *ar = hw->priv;
4658 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4659 struct ath10k_peer *peer;
4660 const u8 *peer_addr;
4661 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
4662 key->cipher == WLAN_CIPHER_SUITE_WEP104;
4663 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00004664 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01004665 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00004666 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004667
Bartosz Markowskid7131c02015-03-10 14:32:19 +01004668 /* this one needs to be done in software */
4669 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
4670 return 1;
4671
Kalle Valo5e3dd152013-06-12 20:52:10 +03004672 if (key->keyidx > WMI_MAX_KEY_INDEX)
4673 return -ENOSPC;
4674
4675 mutex_lock(&ar->conf_mutex);
4676
4677 if (sta)
4678 peer_addr = sta->addr;
4679 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
4680 peer_addr = vif->bss_conf.bssid;
4681 else
4682 peer_addr = vif->addr;
4683
4684 key->hw_key_idx = key->keyidx;
4685
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03004686 if (is_wep) {
4687 if (cmd == SET_KEY)
4688 arvif->wep_keys[key->keyidx] = key;
4689 else
4690 arvif->wep_keys[key->keyidx] = NULL;
4691 }
4692
Kalle Valo5e3dd152013-06-12 20:52:10 +03004693 /* the peer should not disappear in mid-way (unless FW goes awry) since
4694 * we already hold conf_mutex. we just make sure its there now. */
4695 spin_lock_bh(&ar->data_lock);
4696 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
4697 spin_unlock_bh(&ar->data_lock);
4698
4699 if (!peer) {
4700 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004701 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03004702 peer_addr);
4703 ret = -EOPNOTSUPP;
4704 goto exit;
4705 } else {
4706 /* if the peer doesn't exist there is no key to disable
4707 * anymore */
4708 goto exit;
4709 }
4710 }
4711
Michal Kazior7cc45732015-03-09 14:24:17 +01004712 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
4713 flags |= WMI_KEY_PAIRWISE;
4714 else
4715 flags |= WMI_KEY_GROUP;
4716
Kalle Valo5e3dd152013-06-12 20:52:10 +03004717 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004718 if (cmd == DISABLE_KEY)
4719 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01004720
Michal Kaziorad325cb2015-02-18 14:02:27 +01004721 /* When WEP keys are uploaded it's possible that there are
4722 * stations associated already (e.g. when merging) without any
4723 * keys. Static WEP needs an explicit per-peer key upload.
4724 */
4725 if (vif->type == NL80211_IFTYPE_ADHOC &&
4726 cmd == SET_KEY)
4727 ath10k_mac_vif_update_wep_key(arvif, key);
4728
Michal Kazior370e5672015-02-18 14:02:26 +01004729 /* 802.1x never sets the def_wep_key_idx so each set_key()
4730 * call changes default tx key.
4731 *
4732 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
4733 * after first set_key().
4734 */
4735 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
4736 flags |= WMI_KEY_TX_USAGE;
Michal Kazior370e5672015-02-18 14:02:26 +01004737 }
4738
4739 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004740 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004741 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004742 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004743 goto exit;
4744 }
4745
Michal Kazior29a10002015-04-10 13:05:58 +00004746 /* mac80211 sets static WEP keys as groupwise while firmware requires
4747 * them to be installed twice as both pairwise and groupwise.
4748 */
4749 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
4750 flags2 = flags;
4751 flags2 &= ~WMI_KEY_GROUP;
4752 flags2 |= WMI_KEY_PAIRWISE;
4753
4754 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
4755 if (ret) {
4756 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
4757 arvif->vdev_id, peer_addr, ret);
4758 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
4759 peer_addr, flags);
4760 if (ret2)
4761 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
4762 arvif->vdev_id, peer_addr, ret2);
4763 goto exit;
4764 }
4765 }
4766
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004767 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
4768
Kalle Valo5e3dd152013-06-12 20:52:10 +03004769 spin_lock_bh(&ar->data_lock);
4770 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
4771 if (peer && cmd == SET_KEY)
4772 peer->keys[key->keyidx] = key;
4773 else if (peer && cmd == DISABLE_KEY)
4774 peer->keys[key->keyidx] = NULL;
4775 else if (peer == NULL)
4776 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02004777 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004778 spin_unlock_bh(&ar->data_lock);
4779
4780exit:
4781 mutex_unlock(&ar->conf_mutex);
4782 return ret;
4783}
4784
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004785static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
4786 struct ieee80211_vif *vif,
4787 int keyidx)
4788{
4789 struct ath10k *ar = hw->priv;
4790 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4791 int ret;
4792
4793 mutex_lock(&arvif->ar->conf_mutex);
4794
4795 if (arvif->ar->state != ATH10K_STATE_ON)
4796 goto unlock;
4797
4798 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
4799 arvif->vdev_id, keyidx);
4800
4801 ret = ath10k_wmi_vdev_set_param(arvif->ar,
4802 arvif->vdev_id,
4803 arvif->ar->wmi.vdev_param->def_keyid,
4804 keyidx);
4805
4806 if (ret) {
4807 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
4808 arvif->vdev_id,
4809 ret);
4810 goto unlock;
4811 }
4812
4813 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01004814
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004815unlock:
4816 mutex_unlock(&arvif->ar->conf_mutex);
4817}
4818
Michal Kazior9797feb2014-02-14 14:49:48 +01004819static void ath10k_sta_rc_update_wk(struct work_struct *wk)
4820{
4821 struct ath10k *ar;
4822 struct ath10k_vif *arvif;
4823 struct ath10k_sta *arsta;
4824 struct ieee80211_sta *sta;
4825 u32 changed, bw, nss, smps;
4826 int err;
4827
4828 arsta = container_of(wk, struct ath10k_sta, update_wk);
4829 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
4830 arvif = arsta->arvif;
4831 ar = arvif->ar;
4832
4833 spin_lock_bh(&ar->data_lock);
4834
4835 changed = arsta->changed;
4836 arsta->changed = 0;
4837
4838 bw = arsta->bw;
4839 nss = arsta->nss;
4840 smps = arsta->smps;
4841
4842 spin_unlock_bh(&ar->data_lock);
4843
4844 mutex_lock(&ar->conf_mutex);
4845
4846 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004847 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004848 sta->addr, bw);
4849
4850 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
4851 WMI_PEER_CHAN_WIDTH, bw);
4852 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004853 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004854 sta->addr, bw, err);
4855 }
4856
4857 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004858 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004859 sta->addr, nss);
4860
4861 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
4862 WMI_PEER_NSS, nss);
4863 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004864 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004865 sta->addr, nss, err);
4866 }
4867
4868 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004869 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004870 sta->addr, smps);
4871
4872 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
4873 WMI_PEER_SMPS_STATE, smps);
4874 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004875 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004876 sta->addr, smps, err);
4877 }
4878
Janusz Dziedzic55884c02014-12-17 12:30:02 +02004879 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
4880 changed & IEEE80211_RC_NSS_CHANGED) {
4881 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02004882 sta->addr);
4883
Michal Kazior590922a2014-10-21 10:10:29 +03004884 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02004885 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004886 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02004887 sta->addr);
4888 }
4889
Michal Kazior9797feb2014-02-14 14:49:48 +01004890 mutex_unlock(&ar->conf_mutex);
4891}
4892
Marek Puzyniak7c354242015-03-30 09:51:52 +03004893static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
4894 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004895{
4896 struct ath10k *ar = arvif->ar;
4897
4898 lockdep_assert_held(&ar->conf_mutex);
4899
Marek Puzyniak7c354242015-03-30 09:51:52 +03004900 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004901 return 0;
4902
4903 if (ar->num_stations >= ar->max_num_stations)
4904 return -ENOBUFS;
4905
4906 ar->num_stations++;
4907
4908 return 0;
4909}
4910
Marek Puzyniak7c354242015-03-30 09:51:52 +03004911static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
4912 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004913{
4914 struct ath10k *ar = arvif->ar;
4915
4916 lockdep_assert_held(&ar->conf_mutex);
4917
Marek Puzyniak7c354242015-03-30 09:51:52 +03004918 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004919 return;
4920
4921 ar->num_stations--;
4922}
4923
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004924struct ath10k_mac_tdls_iter_data {
4925 u32 num_tdls_stations;
4926 struct ieee80211_vif *curr_vif;
4927};
4928
4929static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
4930 struct ieee80211_sta *sta)
4931{
4932 struct ath10k_mac_tdls_iter_data *iter_data = data;
4933 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
4934 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
4935
4936 if (sta->tdls && sta_vif == iter_data->curr_vif)
4937 iter_data->num_tdls_stations++;
4938}
4939
4940static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
4941 struct ieee80211_vif *vif)
4942{
4943 struct ath10k_mac_tdls_iter_data data = {};
4944
4945 data.curr_vif = vif;
4946
4947 ieee80211_iterate_stations_atomic(hw,
4948 ath10k_mac_tdls_vif_stations_count_iter,
4949 &data);
4950 return data.num_tdls_stations;
4951}
4952
4953static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
4954 struct ieee80211_vif *vif)
4955{
4956 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4957 int *num_tdls_vifs = data;
4958
4959 if (vif->type != NL80211_IFTYPE_STATION)
4960 return;
4961
4962 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
4963 (*num_tdls_vifs)++;
4964}
4965
4966static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
4967{
4968 int num_tdls_vifs = 0;
4969
4970 ieee80211_iterate_active_interfaces_atomic(hw,
4971 IEEE80211_IFACE_ITER_NORMAL,
4972 ath10k_mac_tdls_vifs_count_iter,
4973 &num_tdls_vifs);
4974 return num_tdls_vifs;
4975}
4976
Kalle Valo5e3dd152013-06-12 20:52:10 +03004977static int ath10k_sta_state(struct ieee80211_hw *hw,
4978 struct ieee80211_vif *vif,
4979 struct ieee80211_sta *sta,
4980 enum ieee80211_sta_state old_state,
4981 enum ieee80211_sta_state new_state)
4982{
4983 struct ath10k *ar = hw->priv;
4984 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01004985 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004986 int ret = 0;
4987
Michal Kazior76f90022014-02-25 09:29:57 +02004988 if (old_state == IEEE80211_STA_NOTEXIST &&
4989 new_state == IEEE80211_STA_NONE) {
4990 memset(arsta, 0, sizeof(*arsta));
4991 arsta->arvif = arvif;
4992 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
4993 }
4994
Michal Kazior9797feb2014-02-14 14:49:48 +01004995 /* cancel must be done outside the mutex to avoid deadlock */
4996 if ((old_state == IEEE80211_STA_NONE &&
4997 new_state == IEEE80211_STA_NOTEXIST))
4998 cancel_work_sync(&arsta->update_wk);
4999
Kalle Valo5e3dd152013-06-12 20:52:10 +03005000 mutex_lock(&ar->conf_mutex);
5001
5002 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005003 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005004 /*
5005 * New station addition.
5006 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005007 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5008 u32 num_tdls_stations;
5009 u32 num_tdls_vifs;
5010
Michal Kaziorcfd10612014-11-25 15:16:05 +01005011 ath10k_dbg(ar, ATH10K_DBG_MAC,
5012 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5013 arvif->vdev_id, sta->addr,
5014 ar->num_stations + 1, ar->max_num_stations,
5015 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005016
Marek Puzyniak7c354242015-03-30 09:51:52 +03005017 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005018 if (ret) {
5019 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5020 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005021 goto exit;
5022 }
5023
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005024 if (sta->tdls)
5025 peer_type = WMI_PEER_TYPE_TDLS;
5026
Marek Puzyniak7390ed32015-03-30 09:51:52 +03005027 ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr,
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005028 peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005029 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005030 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 -08005031 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005032 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005033 goto exit;
5034 }
Michal Kazior077efc82014-10-21 10:10:29 +03005035
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005036 if (!sta->tdls)
5037 goto exit;
5038
5039 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
5040 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
5041
5042 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
5043 num_tdls_stations == 0) {
5044 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
5045 arvif->vdev_id, ar->max_num_tdls_vdevs);
5046 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5047 ath10k_mac_dec_num_stations(arvif, sta);
5048 ret = -ENOBUFS;
5049 goto exit;
5050 }
5051
5052 if (num_tdls_stations == 0) {
5053 /* This is the first tdls peer in current vif */
5054 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
5055
5056 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5057 state);
5058 if (ret) {
5059 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
5060 arvif->vdev_id, ret);
5061 ath10k_peer_delete(ar, arvif->vdev_id,
5062 sta->addr);
5063 ath10k_mac_dec_num_stations(arvif, sta);
5064 goto exit;
5065 }
5066 }
5067
5068 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5069 WMI_TDLS_PEER_STATE_PEERING);
5070 if (ret) {
5071 ath10k_warn(ar,
5072 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
5073 sta->addr, arvif->vdev_id, ret);
5074 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5075 ath10k_mac_dec_num_stations(arvif, sta);
5076
5077 if (num_tdls_stations != 0)
5078 goto exit;
5079 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5080 WMI_TDLS_DISABLE);
5081 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005082 } else if ((old_state == IEEE80211_STA_NONE &&
5083 new_state == IEEE80211_STA_NOTEXIST)) {
5084 /*
5085 * Existing station deletion.
5086 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005087 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005088 "mac vdev %d peer delete %pM (sta gone)\n",
5089 arvif->vdev_id, sta->addr);
Michal Kazior077efc82014-10-21 10:10:29 +03005090
Kalle Valo5e3dd152013-06-12 20:52:10 +03005091 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5092 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005093 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005094 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005095
Marek Puzyniak7c354242015-03-30 09:51:52 +03005096 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005097
5098 if (!sta->tdls)
5099 goto exit;
5100
5101 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
5102 goto exit;
5103
5104 /* This was the last tdls peer in current vif */
5105 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5106 WMI_TDLS_DISABLE);
5107 if (ret) {
5108 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
5109 arvif->vdev_id, ret);
5110 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005111 } else if (old_state == IEEE80211_STA_AUTH &&
5112 new_state == IEEE80211_STA_ASSOC &&
5113 (vif->type == NL80211_IFTYPE_AP ||
5114 vif->type == NL80211_IFTYPE_ADHOC)) {
5115 /*
5116 * New association.
5117 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005118 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005119 sta->addr);
5120
Michal Kazior590922a2014-10-21 10:10:29 +03005121 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005122 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005123 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005124 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005125 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005126 new_state == IEEE80211_STA_AUTHORIZED &&
5127 sta->tdls) {
5128 /*
5129 * Tdls station authorized.
5130 */
5131 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
5132 sta->addr);
5133
5134 ret = ath10k_station_assoc(ar, vif, sta, false);
5135 if (ret) {
5136 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
5137 sta->addr, arvif->vdev_id, ret);
5138 goto exit;
5139 }
5140
5141 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5142 WMI_TDLS_PEER_STATE_CONNECTED);
5143 if (ret)
5144 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
5145 sta->addr, arvif->vdev_id, ret);
5146 } else if (old_state == IEEE80211_STA_ASSOC &&
5147 new_state == IEEE80211_STA_AUTH &&
5148 (vif->type == NL80211_IFTYPE_AP ||
5149 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005150 /*
5151 * Disassociation.
5152 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005153 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005154 sta->addr);
5155
Michal Kazior590922a2014-10-21 10:10:29 +03005156 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005157 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005158 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005159 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005160 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005161exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005162 mutex_unlock(&ar->conf_mutex);
5163 return ret;
5164}
5165
5166static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03005167 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005168{
5169 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02005170 struct wmi_sta_uapsd_auto_trig_arg arg = {};
5171 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005172 u32 value = 0;
5173 int ret = 0;
5174
Michal Kazior548db542013-07-05 16:15:15 +03005175 lockdep_assert_held(&ar->conf_mutex);
5176
Kalle Valo5e3dd152013-06-12 20:52:10 +03005177 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
5178 return 0;
5179
5180 switch (ac) {
5181 case IEEE80211_AC_VO:
5182 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
5183 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005184 prio = 7;
5185 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005186 break;
5187 case IEEE80211_AC_VI:
5188 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
5189 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005190 prio = 5;
5191 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005192 break;
5193 case IEEE80211_AC_BE:
5194 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
5195 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005196 prio = 2;
5197 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005198 break;
5199 case IEEE80211_AC_BK:
5200 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
5201 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005202 prio = 0;
5203 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005204 break;
5205 }
5206
5207 if (enable)
5208 arvif->u.sta.uapsd |= value;
5209 else
5210 arvif->u.sta.uapsd &= ~value;
5211
5212 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5213 WMI_STA_PS_PARAM_UAPSD,
5214 arvif->u.sta.uapsd);
5215 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005216 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005217 goto exit;
5218 }
5219
5220 if (arvif->u.sta.uapsd)
5221 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
5222 else
5223 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5224
5225 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5226 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
5227 value);
5228 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005229 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005230
Michal Kazior9f9b5742014-12-12 12:41:36 +01005231 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
5232 if (ret) {
5233 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
5234 arvif->vdev_id, ret);
5235 return ret;
5236 }
5237
5238 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
5239 if (ret) {
5240 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
5241 arvif->vdev_id, ret);
5242 return ret;
5243 }
5244
Michal Kaziorb0e56152015-01-24 12:14:52 +02005245 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
5246 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
5247 /* Only userspace can make an educated decision when to send
5248 * trigger frame. The following effectively disables u-UAPSD
5249 * autotrigger in firmware (which is enabled by default
5250 * provided the autotrigger service is available).
5251 */
5252
5253 arg.wmm_ac = acc;
5254 arg.user_priority = prio;
5255 arg.service_interval = 0;
5256 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
5257 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
5258
5259 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
5260 arvif->bssid, &arg, 1);
5261 if (ret) {
5262 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
5263 ret);
5264 return ret;
5265 }
5266 }
5267
Kalle Valo5e3dd152013-06-12 20:52:10 +03005268exit:
5269 return ret;
5270}
5271
5272static int ath10k_conf_tx(struct ieee80211_hw *hw,
5273 struct ieee80211_vif *vif, u16 ac,
5274 const struct ieee80211_tx_queue_params *params)
5275{
5276 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01005277 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005278 struct wmi_wmm_params_arg *p = NULL;
5279 int ret;
5280
5281 mutex_lock(&ar->conf_mutex);
5282
5283 switch (ac) {
5284 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01005285 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005286 break;
5287 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01005288 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005289 break;
5290 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01005291 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005292 break;
5293 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01005294 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005295 break;
5296 }
5297
5298 if (WARN_ON(!p)) {
5299 ret = -EINVAL;
5300 goto exit;
5301 }
5302
5303 p->cwmin = params->cw_min;
5304 p->cwmax = params->cw_max;
5305 p->aifs = params->aifs;
5306
5307 /*
5308 * The channel time duration programmed in the HW is in absolute
5309 * microseconds, while mac80211 gives the txop in units of
5310 * 32 microseconds.
5311 */
5312 p->txop = params->txop * 32;
5313
Michal Kazior7fc979a2015-01-28 09:57:28 +02005314 if (ar->wmi.ops->gen_vdev_wmm_conf) {
5315 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
5316 &arvif->wmm_params);
5317 if (ret) {
5318 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
5319 arvif->vdev_id, ret);
5320 goto exit;
5321 }
5322 } else {
5323 /* This won't work well with multi-interface cases but it's
5324 * better than nothing.
5325 */
5326 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
5327 if (ret) {
5328 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
5329 goto exit;
5330 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005331 }
5332
5333 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
5334 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005335 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005336
5337exit:
5338 mutex_unlock(&ar->conf_mutex);
5339 return ret;
5340}
5341
5342#define ATH10K_ROC_TIMEOUT_HZ (2*HZ)
5343
5344static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
5345 struct ieee80211_vif *vif,
5346 struct ieee80211_channel *chan,
5347 int duration,
5348 enum ieee80211_roc_type type)
5349{
5350 struct ath10k *ar = hw->priv;
5351 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5352 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005353 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00005354 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005355
5356 mutex_lock(&ar->conf_mutex);
5357
5358 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005359 switch (ar->scan.state) {
5360 case ATH10K_SCAN_IDLE:
5361 reinit_completion(&ar->scan.started);
5362 reinit_completion(&ar->scan.completed);
5363 reinit_completion(&ar->scan.on_channel);
5364 ar->scan.state = ATH10K_SCAN_STARTING;
5365 ar->scan.is_roc = true;
5366 ar->scan.vdev_id = arvif->vdev_id;
5367 ar->scan.roc_freq = chan->center_freq;
5368 ret = 0;
5369 break;
5370 case ATH10K_SCAN_STARTING:
5371 case ATH10K_SCAN_RUNNING:
5372 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005373 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005374 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005375 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005376 spin_unlock_bh(&ar->data_lock);
5377
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005378 if (ret)
5379 goto exit;
5380
Michal Kaziorfcf98442015-03-31 11:03:47 +00005381 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01005382
Kalle Valo5e3dd152013-06-12 20:52:10 +03005383 memset(&arg, 0, sizeof(arg));
5384 ath10k_wmi_start_scan_init(ar, &arg);
5385 arg.vdev_id = arvif->vdev_id;
5386 arg.scan_id = ATH10K_SCAN_ID;
5387 arg.n_channels = 1;
5388 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00005389 arg.dwell_time_active = scan_time_msec;
5390 arg.dwell_time_passive = scan_time_msec;
5391 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005392 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
5393 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00005394 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005395
5396 ret = ath10k_start_scan(ar, &arg);
5397 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005398 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005399 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005400 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005401 spin_unlock_bh(&ar->data_lock);
5402 goto exit;
5403 }
5404
5405 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ);
5406 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005407 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005408
5409 ret = ath10k_scan_stop(ar);
5410 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005411 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005412
Kalle Valo5e3dd152013-06-12 20:52:10 +03005413 ret = -ETIMEDOUT;
5414 goto exit;
5415 }
5416
Michal Kaziorfcf98442015-03-31 11:03:47 +00005417 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5418 msecs_to_jiffies(duration));
5419
Kalle Valo5e3dd152013-06-12 20:52:10 +03005420 ret = 0;
5421exit:
5422 mutex_unlock(&ar->conf_mutex);
5423 return ret;
5424}
5425
5426static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
5427{
5428 struct ath10k *ar = hw->priv;
5429
5430 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005431 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005432 mutex_unlock(&ar->conf_mutex);
5433
Michal Kazior4eb2e162014-10-28 10:23:09 +01005434 cancel_delayed_work_sync(&ar->scan.timeout);
5435
Kalle Valo5e3dd152013-06-12 20:52:10 +03005436 return 0;
5437}
5438
5439/*
5440 * Both RTS and Fragmentation threshold are interface-specific
5441 * in ath10k, but device-specific in mac80211.
5442 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03005443
5444static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
5445{
Kalle Valo5e3dd152013-06-12 20:52:10 +03005446 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03005447 struct ath10k_vif *arvif;
5448 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03005449
Michal Kaziorad088bf2013-10-16 15:44:46 +03005450 mutex_lock(&ar->conf_mutex);
5451 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005452 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03005453 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03005454
Michal Kaziorad088bf2013-10-16 15:44:46 +03005455 ret = ath10k_mac_set_rts(arvif, value);
5456 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005457 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03005458 arvif->vdev_id, ret);
5459 break;
5460 }
5461 }
5462 mutex_unlock(&ar->conf_mutex);
5463
5464 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005465}
5466
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02005467static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5468 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005469{
5470 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02005471 bool skip;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005472 int ret;
5473
5474 /* mac80211 doesn't care if we really xmit queued frames or not
5475 * we'll collect those frames either way if we stop/delete vdevs */
5476 if (drop)
5477 return;
5478
Michal Kazior548db542013-07-05 16:15:15 +03005479 mutex_lock(&ar->conf_mutex);
5480
Michal Kazioraffd3212013-07-16 09:54:35 +02005481 if (ar->state == ATH10K_STATE_WEDGED)
5482 goto skip;
5483
Michal Kazioredb82362013-07-05 16:15:14 +03005484 ret = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03005485 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02005486
Michal Kazioredb82362013-07-05 16:15:14 +03005487 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02005488 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03005489 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02005490
Michal Kazior7962b0d2014-10-28 10:34:38 +01005491 skip = (ar->state == ATH10K_STATE_WEDGED) ||
5492 test_bit(ATH10K_FLAG_CRASH_FLUSH,
5493 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02005494
5495 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005496 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02005497
5498 if (ret <= 0 || skip)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005499 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %i\n",
Ben Greear9ba4c782014-02-25 09:29:57 +02005500 skip, ar->state, ret);
Michal Kazior548db542013-07-05 16:15:15 +03005501
Michal Kazioraffd3212013-07-16 09:54:35 +02005502skip:
Michal Kazior548db542013-07-05 16:15:15 +03005503 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005504}
5505
5506/* TODO: Implement this function properly
5507 * For now it is needed to reply to Probe Requests in IBSS mode.
5508 * Propably we need this information from FW.
5509 */
5510static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
5511{
5512 return 1;
5513}
5514
Eliad Pellercf2c92d2014-11-04 11:43:54 +02005515static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
5516 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02005517{
5518 struct ath10k *ar = hw->priv;
5519
Eliad Pellercf2c92d2014-11-04 11:43:54 +02005520 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
5521 return;
5522
Michal Kazioraffd3212013-07-16 09:54:35 +02005523 mutex_lock(&ar->conf_mutex);
5524
5525 /* If device failed to restart it will be in a different state, e.g.
5526 * ATH10K_STATE_WEDGED */
5527 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005528 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02005529 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01005530 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02005531 }
5532
5533 mutex_unlock(&ar->conf_mutex);
5534}
5535
Michal Kazior2e1dea42013-07-31 10:32:40 +02005536static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
5537 struct survey_info *survey)
5538{
5539 struct ath10k *ar = hw->priv;
5540 struct ieee80211_supported_band *sband;
5541 struct survey_info *ar_survey = &ar->survey[idx];
5542 int ret = 0;
5543
5544 mutex_lock(&ar->conf_mutex);
5545
5546 sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
5547 if (sband && idx >= sband->n_channels) {
5548 idx -= sband->n_channels;
5549 sband = NULL;
5550 }
5551
5552 if (!sband)
5553 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
5554
5555 if (!sband || idx >= sband->n_channels) {
5556 ret = -ENOENT;
5557 goto exit;
5558 }
5559
5560 spin_lock_bh(&ar->data_lock);
5561 memcpy(survey, ar_survey, sizeof(*survey));
5562 spin_unlock_bh(&ar->data_lock);
5563
5564 survey->channel = &sband->channels[idx];
5565
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03005566 if (ar->rx_channel == survey->channel)
5567 survey->filled |= SURVEY_INFO_IN_USE;
5568
Michal Kazior2e1dea42013-07-31 10:32:40 +02005569exit:
5570 mutex_unlock(&ar->conf_mutex);
5571 return ret;
5572}
5573
Michal Kazior3ae54222015-03-31 10:49:20 +00005574static bool
5575ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
5576 enum ieee80211_band band,
5577 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005578{
Michal Kazior3ae54222015-03-31 10:49:20 +00005579 int num_rates = 0;
5580 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005581
Michal Kazior3ae54222015-03-31 10:49:20 +00005582 num_rates += hweight32(mask->control[band].legacy);
5583
5584 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
5585 num_rates += hweight8(mask->control[band].ht_mcs[i]);
5586
5587 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
5588 num_rates += hweight16(mask->control[band].vht_mcs[i]);
5589
5590 return num_rates == 1;
5591}
5592
5593static bool
5594ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
5595 enum ieee80211_band band,
5596 const struct cfg80211_bitrate_mask *mask,
5597 int *nss)
5598{
5599 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
5600 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
5601 u8 ht_nss_mask = 0;
5602 u8 vht_nss_mask = 0;
5603 int i;
5604
5605 if (mask->control[band].legacy)
5606 return false;
5607
5608 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
5609 if (mask->control[band].ht_mcs[i] == 0)
5610 continue;
5611 else if (mask->control[band].ht_mcs[i] ==
5612 sband->ht_cap.mcs.rx_mask[i])
5613 ht_nss_mask |= BIT(i);
5614 else
5615 return false;
5616 }
5617
5618 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
5619 if (mask->control[band].vht_mcs[i] == 0)
5620 continue;
5621 else if (mask->control[band].vht_mcs[i] ==
5622 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
5623 vht_nss_mask |= BIT(i);
5624 else
5625 return false;
5626 }
5627
5628 if (ht_nss_mask != vht_nss_mask)
5629 return false;
5630
5631 if (ht_nss_mask == 0)
5632 return false;
5633
5634 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
5635 return false;
5636
5637 *nss = fls(ht_nss_mask);
5638
5639 return true;
5640}
5641
5642static int
5643ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
5644 enum ieee80211_band band,
5645 const struct cfg80211_bitrate_mask *mask,
5646 u8 *rate, u8 *nss)
5647{
5648 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
5649 int rate_idx;
5650 int i;
5651 u16 bitrate;
5652 u8 preamble;
5653 u8 hw_rate;
5654
5655 if (hweight32(mask->control[band].legacy) == 1) {
5656 rate_idx = ffs(mask->control[band].legacy) - 1;
5657
5658 hw_rate = sband->bitrates[rate_idx].hw_value;
5659 bitrate = sband->bitrates[rate_idx].bitrate;
5660
5661 if (ath10k_mac_bitrate_is_cck(bitrate))
5662 preamble = WMI_RATE_PREAMBLE_CCK;
5663 else
5664 preamble = WMI_RATE_PREAMBLE_OFDM;
5665
5666 *nss = 1;
5667 *rate = preamble << 6 |
5668 (*nss - 1) << 4 |
5669 hw_rate << 0;
5670
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005671 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005672 }
5673
Michal Kazior3ae54222015-03-31 10:49:20 +00005674 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
5675 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
5676 *nss = i + 1;
5677 *rate = WMI_RATE_PREAMBLE_HT << 6 |
5678 (*nss - 1) << 4 |
5679 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005680
Michal Kazior3ae54222015-03-31 10:49:20 +00005681 return 0;
5682 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005683 }
5684
Michal Kazior3ae54222015-03-31 10:49:20 +00005685 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
5686 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
5687 *nss = i + 1;
5688 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
5689 (*nss - 1) << 4 |
5690 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005691
Michal Kazior3ae54222015-03-31 10:49:20 +00005692 return 0;
5693 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005694 }
5695
Michal Kazior3ae54222015-03-31 10:49:20 +00005696 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005697}
5698
Michal Kazior3ae54222015-03-31 10:49:20 +00005699static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
5700 u8 rate, u8 nss, u8 sgi)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005701{
5702 struct ath10k *ar = arvif->ar;
5703 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00005704 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005705
Michal Kazior3ae54222015-03-31 10:49:20 +00005706 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005707
Michal Kazior3ae54222015-03-31 10:49:20 +00005708 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
5709 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005710
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005711 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00005712 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005713 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005714 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00005715 rate, ret);
5716 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005717 }
5718
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005719 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00005720 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005721 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00005722 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
5723 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005724 }
5725
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005726 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00005727 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005728 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00005729 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
5730 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005731 }
5732
Michal Kazior3ae54222015-03-31 10:49:20 +00005733 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005734}
5735
Michal Kazior3ae54222015-03-31 10:49:20 +00005736static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
5737 struct ieee80211_vif *vif,
5738 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005739{
5740 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00005741 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005742 struct ath10k *ar = arvif->ar;
Michal Kazior500ff9f2015-03-31 10:26:21 +00005743 enum ieee80211_band band;
Michal Kazior3ae54222015-03-31 10:49:20 +00005744 u8 rate;
5745 u8 nss;
5746 u8 sgi;
5747 int single_nss;
5748 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005749
Michal Kazior500ff9f2015-03-31 10:26:21 +00005750 if (ath10k_mac_vif_chan(vif, &def))
5751 return -EPERM;
5752
Michal Kazior500ff9f2015-03-31 10:26:21 +00005753 band = def.chan->band;
5754
Michal Kazior3ae54222015-03-31 10:49:20 +00005755 sgi = mask->control[band].gi;
5756 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005757 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005758
Michal Kazior3ae54222015-03-31 10:49:20 +00005759 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
5760 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
5761 &rate, &nss);
5762 if (ret) {
5763 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
5764 arvif->vdev_id, ret);
5765 return ret;
5766 }
5767 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
5768 &single_nss)) {
5769 rate = WMI_FIXED_RATE_NONE;
5770 nss = single_nss;
5771 } else {
5772 rate = WMI_FIXED_RATE_NONE;
5773 nss = ar->num_rf_chains;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005774 }
5775
Michal Kazior3ae54222015-03-31 10:49:20 +00005776 mutex_lock(&ar->conf_mutex);
5777
5778 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi);
5779 if (ret) {
5780 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
5781 arvif->vdev_id, ret);
5782 goto exit;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005783 }
5784
Michal Kazior3ae54222015-03-31 10:49:20 +00005785exit:
5786 mutex_unlock(&ar->conf_mutex);
5787
5788 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005789}
5790
Michal Kazior9797feb2014-02-14 14:49:48 +01005791static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
5792 struct ieee80211_vif *vif,
5793 struct ieee80211_sta *sta,
5794 u32 changed)
5795{
5796 struct ath10k *ar = hw->priv;
5797 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5798 u32 bw, smps;
5799
5800 spin_lock_bh(&ar->data_lock);
5801
Michal Kazior7aa7a722014-08-25 12:09:38 +02005802 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01005803 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
5804 sta->addr, changed, sta->bandwidth, sta->rx_nss,
5805 sta->smps_mode);
5806
5807 if (changed & IEEE80211_RC_BW_CHANGED) {
5808 bw = WMI_PEER_CHWIDTH_20MHZ;
5809
5810 switch (sta->bandwidth) {
5811 case IEEE80211_STA_RX_BW_20:
5812 bw = WMI_PEER_CHWIDTH_20MHZ;
5813 break;
5814 case IEEE80211_STA_RX_BW_40:
5815 bw = WMI_PEER_CHWIDTH_40MHZ;
5816 break;
5817 case IEEE80211_STA_RX_BW_80:
5818 bw = WMI_PEER_CHWIDTH_80MHZ;
5819 break;
5820 case IEEE80211_STA_RX_BW_160:
Michal Kazior7aa7a722014-08-25 12:09:38 +02005821 ath10k_warn(ar, "Invalid bandwith %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02005822 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01005823 bw = WMI_PEER_CHWIDTH_20MHZ;
5824 break;
5825 }
5826
5827 arsta->bw = bw;
5828 }
5829
5830 if (changed & IEEE80211_RC_NSS_CHANGED)
5831 arsta->nss = sta->rx_nss;
5832
5833 if (changed & IEEE80211_RC_SMPS_CHANGED) {
5834 smps = WMI_PEER_SMPS_PS_NONE;
5835
5836 switch (sta->smps_mode) {
5837 case IEEE80211_SMPS_AUTOMATIC:
5838 case IEEE80211_SMPS_OFF:
5839 smps = WMI_PEER_SMPS_PS_NONE;
5840 break;
5841 case IEEE80211_SMPS_STATIC:
5842 smps = WMI_PEER_SMPS_STATIC;
5843 break;
5844 case IEEE80211_SMPS_DYNAMIC:
5845 smps = WMI_PEER_SMPS_DYNAMIC;
5846 break;
5847 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02005848 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02005849 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01005850 smps = WMI_PEER_SMPS_PS_NONE;
5851 break;
5852 }
5853
5854 arsta->smps = smps;
5855 }
5856
Michal Kazior9797feb2014-02-14 14:49:48 +01005857 arsta->changed |= changed;
5858
5859 spin_unlock_bh(&ar->data_lock);
5860
5861 ieee80211_queue_work(hw, &arsta->update_wk);
5862}
5863
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02005864static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
5865{
5866 /*
5867 * FIXME: Return 0 for time being. Need to figure out whether FW
5868 * has the API to fetch 64-bit local TSF
5869 */
5870
5871 return 0;
5872}
5873
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02005874static int ath10k_ampdu_action(struct ieee80211_hw *hw,
5875 struct ieee80211_vif *vif,
5876 enum ieee80211_ampdu_mlme_action action,
5877 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
5878 u8 buf_size)
5879{
Michal Kazior7aa7a722014-08-25 12:09:38 +02005880 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02005881 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5882
Michal Kazior7aa7a722014-08-25 12:09:38 +02005883 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 +02005884 arvif->vdev_id, sta->addr, tid, action);
5885
5886 switch (action) {
5887 case IEEE80211_AMPDU_RX_START:
5888 case IEEE80211_AMPDU_RX_STOP:
5889 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
5890 * creation/removal. Do we need to verify this?
5891 */
5892 return 0;
5893 case IEEE80211_AMPDU_TX_START:
5894 case IEEE80211_AMPDU_TX_STOP_CONT:
5895 case IEEE80211_AMPDU_TX_STOP_FLUSH:
5896 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
5897 case IEEE80211_AMPDU_TX_OPERATIONAL:
5898 /* Firmware offloads Tx aggregation entirely so deny mac80211
5899 * Tx aggregation requests.
5900 */
5901 return -EOPNOTSUPP;
5902 }
5903
5904 return -EINVAL;
5905}
5906
Michal Kazior500ff9f2015-03-31 10:26:21 +00005907static void
5908ath10k_mac_update_rx_channel(struct ath10k *ar)
5909{
5910 struct cfg80211_chan_def *def = NULL;
5911
5912 /* Both locks are required because ar->rx_channel is modified. This
5913 * allows readers to hold either lock.
5914 */
5915 lockdep_assert_held(&ar->conf_mutex);
5916 lockdep_assert_held(&ar->data_lock);
5917
5918 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
5919 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
5920 * ppdu on Rx may reduce performance on low-end systems. It should be
5921 * possible to make tables/hashmaps to speed the lookup up (be vary of
5922 * cpu data cache lines though regarding sizes) but to keep the initial
5923 * implementation simple and less intrusive fallback to the slow lookup
5924 * only for multi-channel cases. Single-channel cases will remain to
5925 * use the old channel derival and thus performance should not be
5926 * affected much.
5927 */
5928 rcu_read_lock();
5929 if (ath10k_mac_num_chanctxs(ar) == 1) {
5930 ieee80211_iter_chan_contexts_atomic(ar->hw,
5931 ath10k_mac_get_any_chandef_iter,
5932 &def);
5933 ar->rx_channel = def->chan;
5934 } else {
5935 ar->rx_channel = NULL;
5936 }
5937 rcu_read_unlock();
5938}
5939
5940static void
5941ath10k_mac_chan_ctx_init(struct ath10k *ar,
5942 struct ath10k_chanctx *arctx,
5943 struct ieee80211_chanctx_conf *conf)
5944{
5945 lockdep_assert_held(&ar->conf_mutex);
5946 lockdep_assert_held(&ar->data_lock);
5947
5948 memset(arctx, 0, sizeof(*arctx));
5949
5950 arctx->conf = *conf;
5951}
5952
5953static int
5954ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
5955 struct ieee80211_chanctx_conf *ctx)
5956{
5957 struct ath10k *ar = hw->priv;
5958 struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
5959
5960 ath10k_dbg(ar, ATH10K_DBG_MAC,
5961 "mac chanctx add freq %hu width %d ptr %p\n",
5962 ctx->def.chan->center_freq, ctx->def.width, ctx);
5963
5964 mutex_lock(&ar->conf_mutex);
5965
5966 spin_lock_bh(&ar->data_lock);
5967 ath10k_mac_chan_ctx_init(ar, arctx, ctx);
5968 ath10k_mac_update_rx_channel(ar);
5969 spin_unlock_bh(&ar->data_lock);
5970
5971 ath10k_recalc_radar_detection(ar);
5972 ath10k_monitor_recalc(ar);
5973
5974 mutex_unlock(&ar->conf_mutex);
5975
5976 return 0;
5977}
5978
5979static void
5980ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
5981 struct ieee80211_chanctx_conf *ctx)
5982{
5983 struct ath10k *ar = hw->priv;
5984
5985 ath10k_dbg(ar, ATH10K_DBG_MAC,
5986 "mac chanctx remove freq %hu width %d ptr %p\n",
5987 ctx->def.chan->center_freq, ctx->def.width, ctx);
5988
5989 mutex_lock(&ar->conf_mutex);
5990
5991 spin_lock_bh(&ar->data_lock);
5992 ath10k_mac_update_rx_channel(ar);
5993 spin_unlock_bh(&ar->data_lock);
5994
5995 ath10k_recalc_radar_detection(ar);
5996 ath10k_monitor_recalc(ar);
5997
5998 mutex_unlock(&ar->conf_mutex);
5999}
6000
6001static void
6002ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
6003 struct ieee80211_chanctx_conf *ctx,
6004 u32 changed)
6005{
6006 struct ath10k *ar = hw->priv;
6007 struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
6008
6009 mutex_lock(&ar->conf_mutex);
6010
6011 ath10k_dbg(ar, ATH10K_DBG_MAC,
6012 "mac chanctx change freq %hu->%hu width %d->%d ptr %p changed %x\n",
6013 arctx->conf.def.chan->center_freq,
6014 ctx->def.chan->center_freq,
6015 arctx->conf.def.width, ctx->def.width,
6016 ctx, changed);
6017
6018 /* This shouldn't really happen because channel switching should use
6019 * switch_vif_chanctx().
6020 */
6021 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
6022 goto unlock;
6023
6024 spin_lock_bh(&ar->data_lock);
6025 arctx->conf = *ctx;
6026 spin_unlock_bh(&ar->data_lock);
6027
6028 ath10k_recalc_radar_detection(ar);
6029
6030 /* FIXME: How to configure Rx chains properly? */
6031
6032 /* No other actions are actually necessary. Firmware maintains channel
6033 * definitions per vdev internally and there's no host-side channel
6034 * context abstraction to configure, e.g. channel width.
6035 */
6036
6037unlock:
6038 mutex_unlock(&ar->conf_mutex);
6039}
6040
6041static int
6042ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
6043 struct ieee80211_vif *vif,
6044 struct ieee80211_chanctx_conf *ctx)
6045{
6046 struct ath10k *ar = hw->priv;
6047 struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
6048 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6049 int ret;
6050
6051 mutex_lock(&ar->conf_mutex);
6052
6053 ath10k_dbg(ar, ATH10K_DBG_MAC,
6054 "mac chanctx assign ptr %p vdev_id %i\n",
6055 ctx, arvif->vdev_id);
6056
6057 if (WARN_ON(arvif->is_started)) {
6058 mutex_unlock(&ar->conf_mutex);
6059 return -EBUSY;
6060 }
6061
6062 ret = ath10k_vdev_start(arvif, &arctx->conf.def);
6063 if (ret) {
6064 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
6065 arvif->vdev_id, vif->addr,
6066 arctx->conf.def.chan->center_freq, ret);
6067 goto err;
6068 }
6069
6070 arvif->is_started = true;
6071
6072 if (vif->type == NL80211_IFTYPE_MONITOR) {
6073 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
6074 if (ret) {
6075 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
6076 arvif->vdev_id, ret);
6077 goto err_stop;
6078 }
6079
6080 arvif->is_up = true;
6081 }
6082
6083 mutex_unlock(&ar->conf_mutex);
6084 return 0;
6085
6086err_stop:
6087 ath10k_vdev_stop(arvif);
6088 arvif->is_started = false;
6089
6090err:
6091 mutex_unlock(&ar->conf_mutex);
6092 return ret;
6093}
6094
6095static void
6096ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
6097 struct ieee80211_vif *vif,
6098 struct ieee80211_chanctx_conf *ctx)
6099{
6100 struct ath10k *ar = hw->priv;
6101 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6102 int ret;
6103
6104 mutex_lock(&ar->conf_mutex);
6105
6106 ath10k_dbg(ar, ATH10K_DBG_MAC,
6107 "mac chanctx unassign ptr %p vdev_id %i\n",
6108 ctx, arvif->vdev_id);
6109
6110 WARN_ON(!arvif->is_started);
6111
6112 if (vif->type == NL80211_IFTYPE_MONITOR) {
6113 WARN_ON(!arvif->is_up);
6114
6115 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
6116 if (ret)
6117 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
6118 arvif->vdev_id, ret);
6119
6120 arvif->is_up = false;
6121 }
6122
6123 ret = ath10k_vdev_stop(arvif);
6124 if (ret)
6125 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
6126 arvif->vdev_id, ret);
6127
6128 arvif->is_started = false;
6129
6130 mutex_unlock(&ar->conf_mutex);
6131}
6132
6133static int
6134ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
6135 struct ieee80211_vif_chanctx_switch *vifs,
6136 int n_vifs,
6137 enum ieee80211_chanctx_switch_mode mode)
6138{
6139 struct ath10k *ar = hw->priv;
6140 struct ath10k_vif *arvif;
6141 struct ath10k_chanctx *arctx_new, *arctx_old;
6142 int i;
6143
6144 mutex_lock(&ar->conf_mutex);
6145
6146 ath10k_dbg(ar, ATH10K_DBG_MAC,
6147 "mac chanctx switch n_vifs %d mode %d\n",
6148 n_vifs, mode);
6149
6150 spin_lock_bh(&ar->data_lock);
6151 for (i = 0; i < n_vifs; i++) {
6152 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6153 arctx_new = (void *)vifs[i].new_ctx->drv_priv;
6154 arctx_old = (void *)vifs[i].old_ctx->drv_priv;
6155
6156 ath10k_dbg(ar, ATH10K_DBG_MAC,
6157 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d ptr %p->%p\n",
6158 arvif->vdev_id,
6159 vifs[i].old_ctx->def.chan->center_freq,
6160 vifs[i].new_ctx->def.chan->center_freq,
6161 vifs[i].old_ctx->def.width,
6162 vifs[i].new_ctx->def.width,
6163 arctx_old, arctx_new);
6164
6165 if (mode == CHANCTX_SWMODE_SWAP_CONTEXTS) {
6166 ath10k_mac_chan_ctx_init(ar, arctx_new,
6167 vifs[i].new_ctx);
6168 }
6169
6170 arctx_new->conf = *vifs[i].new_ctx;
6171
6172 /* FIXME: ath10k_mac_chan_reconfigure() uses current, i.e. not
6173 * yet updated chanctx_conf pointer.
6174 */
6175 arctx_old->conf = *vifs[i].new_ctx;
6176 }
6177 ath10k_mac_update_rx_channel(ar);
6178 spin_unlock_bh(&ar->data_lock);
6179
6180 /* FIXME: Reconfigure only affected vifs */
6181 ath10k_mac_chan_reconfigure(ar);
6182
6183 mutex_unlock(&ar->conf_mutex);
6184 return 0;
6185}
6186
Kalle Valo5e3dd152013-06-12 20:52:10 +03006187static const struct ieee80211_ops ath10k_ops = {
6188 .tx = ath10k_tx,
6189 .start = ath10k_start,
6190 .stop = ath10k_stop,
6191 .config = ath10k_config,
6192 .add_interface = ath10k_add_interface,
6193 .remove_interface = ath10k_remove_interface,
6194 .configure_filter = ath10k_configure_filter,
6195 .bss_info_changed = ath10k_bss_info_changed,
6196 .hw_scan = ath10k_hw_scan,
6197 .cancel_hw_scan = ath10k_cancel_hw_scan,
6198 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006199 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03006200 .sta_state = ath10k_sta_state,
6201 .conf_tx = ath10k_conf_tx,
6202 .remain_on_channel = ath10k_remain_on_channel,
6203 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
6204 .set_rts_threshold = ath10k_set_rts_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03006205 .flush = ath10k_flush,
6206 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03006207 .set_antenna = ath10k_set_antenna,
6208 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006209 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02006210 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00006211 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01006212 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006213 .get_tsf = ath10k_get_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006214 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03006215 .get_et_sset_count = ath10k_debug_get_et_sset_count,
6216 .get_et_stats = ath10k_debug_get_et_stats,
6217 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00006218 .add_chanctx = ath10k_mac_op_add_chanctx,
6219 .remove_chanctx = ath10k_mac_op_remove_chanctx,
6220 .change_chanctx = ath10k_mac_op_change_chanctx,
6221 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
6222 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
6223 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Kalle Valo43d2a302014-09-10 18:23:30 +03006224
6225 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
6226
Michal Kazior8cd13ca2013-07-16 09:38:54 +02006227#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02006228 .suspend = ath10k_wow_op_suspend,
6229 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02006230#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02006231#ifdef CONFIG_MAC80211_DEBUGFS
6232 .sta_add_debugfs = ath10k_sta_add_debugfs,
6233#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03006234};
6235
Kalle Valo5e3dd152013-06-12 20:52:10 +03006236#define CHAN2G(_channel, _freq, _flags) { \
6237 .band = IEEE80211_BAND_2GHZ, \
6238 .hw_value = (_channel), \
6239 .center_freq = (_freq), \
6240 .flags = (_flags), \
6241 .max_antenna_gain = 0, \
6242 .max_power = 30, \
6243}
6244
6245#define CHAN5G(_channel, _freq, _flags) { \
6246 .band = IEEE80211_BAND_5GHZ, \
6247 .hw_value = (_channel), \
6248 .center_freq = (_freq), \
6249 .flags = (_flags), \
6250 .max_antenna_gain = 0, \
6251 .max_power = 30, \
6252}
6253
6254static const struct ieee80211_channel ath10k_2ghz_channels[] = {
6255 CHAN2G(1, 2412, 0),
6256 CHAN2G(2, 2417, 0),
6257 CHAN2G(3, 2422, 0),
6258 CHAN2G(4, 2427, 0),
6259 CHAN2G(5, 2432, 0),
6260 CHAN2G(6, 2437, 0),
6261 CHAN2G(7, 2442, 0),
6262 CHAN2G(8, 2447, 0),
6263 CHAN2G(9, 2452, 0),
6264 CHAN2G(10, 2457, 0),
6265 CHAN2G(11, 2462, 0),
6266 CHAN2G(12, 2467, 0),
6267 CHAN2G(13, 2472, 0),
6268 CHAN2G(14, 2484, 0),
6269};
6270
6271static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02006272 CHAN5G(36, 5180, 0),
6273 CHAN5G(40, 5200, 0),
6274 CHAN5G(44, 5220, 0),
6275 CHAN5G(48, 5240, 0),
6276 CHAN5G(52, 5260, 0),
6277 CHAN5G(56, 5280, 0),
6278 CHAN5G(60, 5300, 0),
6279 CHAN5G(64, 5320, 0),
6280 CHAN5G(100, 5500, 0),
6281 CHAN5G(104, 5520, 0),
6282 CHAN5G(108, 5540, 0),
6283 CHAN5G(112, 5560, 0),
6284 CHAN5G(116, 5580, 0),
6285 CHAN5G(120, 5600, 0),
6286 CHAN5G(124, 5620, 0),
6287 CHAN5G(128, 5640, 0),
6288 CHAN5G(132, 5660, 0),
6289 CHAN5G(136, 5680, 0),
6290 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07006291 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02006292 CHAN5G(149, 5745, 0),
6293 CHAN5G(153, 5765, 0),
6294 CHAN5G(157, 5785, 0),
6295 CHAN5G(161, 5805, 0),
6296 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03006297};
6298
Michal Kaziore7b54192014-08-07 11:03:27 +02006299struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006300{
6301 struct ieee80211_hw *hw;
6302 struct ath10k *ar;
6303
Michal Kaziore7b54192014-08-07 11:03:27 +02006304 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006305 if (!hw)
6306 return NULL;
6307
6308 ar = hw->priv;
6309 ar->hw = hw;
6310
6311 return ar;
6312}
6313
6314void ath10k_mac_destroy(struct ath10k *ar)
6315{
6316 ieee80211_free_hw(ar->hw);
6317}
6318
6319static const struct ieee80211_iface_limit ath10k_if_limits[] = {
6320 {
6321 .max = 8,
6322 .types = BIT(NL80211_IFTYPE_STATION)
6323 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02006324 },
6325 {
6326 .max = 3,
6327 .types = BIT(NL80211_IFTYPE_P2P_GO)
6328 },
6329 {
Michal Kazior75d2bd42014-12-12 12:41:39 +01006330 .max = 1,
6331 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
6332 },
6333 {
Michal Kaziord531cb82013-07-31 10:55:13 +02006334 .max = 7,
6335 .types = BIT(NL80211_IFTYPE_AP)
6336 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03006337};
6338
Bartosz Markowskif2595092013-12-10 16:20:39 +01006339static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006340 {
6341 .max = 8,
6342 .types = BIT(NL80211_IFTYPE_AP)
6343 },
6344};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006345
6346static const struct ieee80211_iface_combination ath10k_if_comb[] = {
6347 {
6348 .limits = ath10k_if_limits,
6349 .n_limits = ARRAY_SIZE(ath10k_if_limits),
6350 .max_interfaces = 8,
6351 .num_different_channels = 1,
6352 .beacon_int_infra_match = true,
6353 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01006354};
6355
6356static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006357 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01006358 .limits = ath10k_10x_if_limits,
6359 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006360 .max_interfaces = 8,
6361 .num_different_channels = 1,
6362 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01006363#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006364 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
6365 BIT(NL80211_CHAN_WIDTH_20) |
6366 BIT(NL80211_CHAN_WIDTH_40) |
6367 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006368#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01006369 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03006370};
6371
Michal Kaziorcf327842015-03-31 10:26:25 +00006372static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
6373 {
6374 .max = 2,
6375 .types = BIT(NL80211_IFTYPE_STATION) |
6376 BIT(NL80211_IFTYPE_AP) |
6377 BIT(NL80211_IFTYPE_P2P_CLIENT) |
6378 BIT(NL80211_IFTYPE_P2P_GO),
6379 },
6380 {
6381 .max = 1,
6382 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
6383 },
6384};
6385
6386static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
6387 {
6388 .max = 1,
6389 .types = BIT(NL80211_IFTYPE_STATION),
6390 },
6391 {
6392 .max = 1,
6393 .types = BIT(NL80211_IFTYPE_ADHOC),
6394 },
6395};
6396
6397/* FIXME: This is not thouroughly tested. These combinations may over- or
6398 * underestimate hw/fw capabilities.
6399 */
6400static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
6401 {
6402 .limits = ath10k_tlv_if_limit,
6403 .num_different_channels = 1,
6404 .max_interfaces = 3,
6405 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
6406 },
6407 {
6408 .limits = ath10k_tlv_if_limit_ibss,
6409 .num_different_channels = 1,
6410 .max_interfaces = 2,
6411 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
6412 },
6413};
6414
6415static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
6416 {
6417 .limits = ath10k_tlv_if_limit,
6418 .num_different_channels = 2,
6419 .max_interfaces = 3,
6420 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
6421 },
6422 {
6423 .limits = ath10k_tlv_if_limit_ibss,
6424 .num_different_channels = 1,
6425 .max_interfaces = 2,
6426 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
6427 },
6428};
6429
Kalle Valo5e3dd152013-06-12 20:52:10 +03006430static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
6431{
6432 struct ieee80211_sta_vht_cap vht_cap = {0};
6433 u16 mcs_map;
Michal Kaziorbc657a362015-02-26 11:11:22 +01006434 u32 val;
Michal Kazior8865bee42013-07-24 12:36:46 +02006435 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006436
6437 vht_cap.vht_supported = 1;
6438 vht_cap.cap = ar->vht_cap_info;
6439
Michal Kaziorbc657a362015-02-26 11:11:22 +01006440 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
6441 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
6442 val = ar->num_rf_chains - 1;
6443 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
6444 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
6445
6446 vht_cap.cap |= val;
6447 }
6448
6449 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
6450 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
6451 val = ar->num_rf_chains - 1;
6452 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
6453 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
6454
6455 vht_cap.cap |= val;
6456 }
6457
Michal Kazior8865bee42013-07-24 12:36:46 +02006458 mcs_map = 0;
6459 for (i = 0; i < 8; i++) {
6460 if (i < ar->num_rf_chains)
6461 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i*2);
6462 else
6463 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2);
6464 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006465
6466 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
6467 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
6468
6469 return vht_cap;
6470}
6471
6472static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
6473{
6474 int i;
6475 struct ieee80211_sta_ht_cap ht_cap = {0};
6476
6477 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
6478 return ht_cap;
6479
6480 ht_cap.ht_supported = 1;
6481 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
6482 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
6483 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6484 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
6485 ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT;
6486
6487 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
6488 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
6489
6490 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
6491 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
6492
6493 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
6494 u32 smps;
6495
6496 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
6497 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
6498
6499 ht_cap.cap |= smps;
6500 }
6501
6502 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC)
6503 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
6504
6505 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
6506 u32 stbc;
6507
6508 stbc = ar->ht_cap_info;
6509 stbc &= WMI_HT_CAP_RX_STBC;
6510 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
6511 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
6512 stbc &= IEEE80211_HT_CAP_RX_STBC;
6513
6514 ht_cap.cap |= stbc;
6515 }
6516
6517 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
6518 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
6519
6520 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
6521 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
6522
6523 /* max AMSDU is implicitly taken from vht_cap_info */
6524 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
6525 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
6526
Michal Kazior8865bee42013-07-24 12:36:46 +02006527 for (i = 0; i < ar->num_rf_chains; i++)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006528 ht_cap.mcs.rx_mask[i] = 0xFF;
6529
6530 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
6531
6532 return ht_cap;
6533}
6534
Kalle Valo5e3dd152013-06-12 20:52:10 +03006535static void ath10k_get_arvif_iter(void *data, u8 *mac,
6536 struct ieee80211_vif *vif)
6537{
6538 struct ath10k_vif_iter *arvif_iter = data;
6539 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6540
6541 if (arvif->vdev_id == arvif_iter->vdev_id)
6542 arvif_iter->arvif = arvif;
6543}
6544
6545struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
6546{
6547 struct ath10k_vif_iter arvif_iter;
6548 u32 flags;
6549
6550 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
6551 arvif_iter.vdev_id = vdev_id;
6552
6553 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
6554 ieee80211_iterate_active_interfaces_atomic(ar->hw,
6555 flags,
6556 ath10k_get_arvif_iter,
6557 &arvif_iter);
6558 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006559 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006560 return NULL;
6561 }
6562
6563 return arvif_iter.arvif;
6564}
6565
6566int ath10k_mac_register(struct ath10k *ar)
6567{
Johannes Berg3cb10942015-01-22 21:38:45 +01006568 static const u32 cipher_suites[] = {
6569 WLAN_CIPHER_SUITE_WEP40,
6570 WLAN_CIPHER_SUITE_WEP104,
6571 WLAN_CIPHER_SUITE_TKIP,
6572 WLAN_CIPHER_SUITE_CCMP,
6573 WLAN_CIPHER_SUITE_AES_CMAC,
6574 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03006575 struct ieee80211_supported_band *band;
6576 struct ieee80211_sta_vht_cap vht_cap;
6577 struct ieee80211_sta_ht_cap ht_cap;
6578 void *channels;
6579 int ret;
6580
6581 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
6582
6583 SET_IEEE80211_DEV(ar->hw, ar->dev);
6584
6585 ht_cap = ath10k_get_ht_cap(ar);
6586 vht_cap = ath10k_create_vht_cap(ar);
6587
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00006588 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
6589 ARRAY_SIZE(ath10k_5ghz_channels)) !=
6590 ATH10K_NUM_CHANS);
6591
Kalle Valo5e3dd152013-06-12 20:52:10 +03006592 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
6593 channels = kmemdup(ath10k_2ghz_channels,
6594 sizeof(ath10k_2ghz_channels),
6595 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02006596 if (!channels) {
6597 ret = -ENOMEM;
6598 goto err_free;
6599 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006600
6601 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
6602 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
6603 band->channels = channels;
6604 band->n_bitrates = ath10k_g_rates_size;
6605 band->bitrates = ath10k_g_rates;
6606 band->ht_cap = ht_cap;
6607
Yanbo Lid68bb122015-01-23 08:18:20 +08006608 /* Enable the VHT support at 2.4 GHz */
6609 band->vht_cap = vht_cap;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006610
6611 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
6612 }
6613
6614 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
6615 channels = kmemdup(ath10k_5ghz_channels,
6616 sizeof(ath10k_5ghz_channels),
6617 GFP_KERNEL);
6618 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02006619 ret = -ENOMEM;
6620 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006621 }
6622
6623 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
6624 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
6625 band->channels = channels;
6626 band->n_bitrates = ath10k_a_rates_size;
6627 band->bitrates = ath10k_a_rates;
6628 band->ht_cap = ht_cap;
6629 band->vht_cap = vht_cap;
6630 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
6631 }
6632
6633 ar->hw->wiphy->interface_modes =
6634 BIT(NL80211_IFTYPE_STATION) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01006635 BIT(NL80211_IFTYPE_AP);
6636
Ben Greear46acf7b2014-05-16 17:15:38 +03006637 ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask;
6638 ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask;
6639
Bartosz Markowskid3541812013-12-10 16:20:40 +01006640 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
6641 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01006642 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01006643 BIT(NL80211_IFTYPE_P2P_CLIENT) |
6644 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006645
6646 ar->hw->flags = IEEE80211_HW_SIGNAL_DBM |
6647 IEEE80211_HW_SUPPORTS_PS |
6648 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
Kalle Valo5e3dd152013-06-12 20:52:10 +03006649 IEEE80211_HW_MFP_CAPABLE |
6650 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
6651 IEEE80211_HW_HAS_RATE_CONTROL |
Janusz Dziedzic2f0f1122014-02-26 18:42:09 +02006652 IEEE80211_HW_AP_LINK_PS |
Johannes Berg3cb10942015-01-22 21:38:45 +01006653 IEEE80211_HW_SPECTRUM_MGMT |
Michal Kaziorcc9904e2015-03-10 16:22:01 +02006654 IEEE80211_HW_SW_CRYPTO_CONTROL |
Michal Kazior500ff9f2015-03-31 10:26:21 +00006655 IEEE80211_HW_CONNECTION_MONITOR |
6656 IEEE80211_HW_WANT_MONITOR_VIF |
Michal Kazior96d828d2015-03-31 10:26:23 +00006657 IEEE80211_HW_CHANCTX_STA_CSA |
6658 IEEE80211_HW_QUEUE_CONTROL;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006659
Eliad Peller0d8614b2014-09-10 14:07:36 +03006660 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
6661
Kalle Valo5e3dd152013-06-12 20:52:10 +03006662 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03006663 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006664
6665 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
6666 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
6667 ar->hw->flags |= IEEE80211_HW_TX_AMPDU_SETUP_IN_HW;
6668 }
6669
6670 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
6671 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
6672
6673 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01006674 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006675 ar->hw->chanctx_data_size = sizeof(struct ath10k_chanctx);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006676
Kalle Valo5e3dd152013-06-12 20:52:10 +03006677 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
6678
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02006679 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
6680 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
6681
6682 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
6683 * that userspace (e.g. wpa_supplicant/hostapd) can generate
6684 * correct Probe Responses. This is more of a hack advert..
6685 */
6686 ar->hw->wiphy->probe_resp_offload |=
6687 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
6688 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
6689 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
6690 }
6691
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006692 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
6693 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
6694
Kalle Valo5e3dd152013-06-12 20:52:10 +03006695 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01006696 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006697 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
6698
6699 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02006700 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
6701
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01006702 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
6703
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02006704 ret = ath10k_wow_init(ar);
6705 if (ret) {
6706 ath10k_warn(ar, "failed to init wow: %d\n", ret);
6707 goto err_free;
6708 }
6709
Kalle Valo5e3dd152013-06-12 20:52:10 +03006710 /*
6711 * on LL hardware queues are managed entirely by the FW
6712 * so we only advertise to mac we can do the queues thing
6713 */
Michal Kazior96d828d2015-03-31 10:26:23 +00006714 ar->hw->queues = IEEE80211_MAX_QUEUES;
6715
6716 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
6717 * something that vdev_ids can't reach so that we don't stop the queue
6718 * accidentally.
6719 */
6720 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006721
Kalle Valo5cc7caf2014-12-17 12:20:54 +02006722 switch (ar->wmi.op_version) {
6723 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01006724 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
6725 ar->hw->wiphy->n_iface_combinations =
6726 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03006727 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02006728 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00006729 case ATH10K_FW_WMI_OP_VERSION_TLV:
6730 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
6731 ar->hw->wiphy->iface_combinations =
6732 ath10k_tlv_qcs_if_comb;
6733 ar->hw->wiphy->n_iface_combinations =
6734 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
6735 } else {
6736 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
6737 ar->hw->wiphy->n_iface_combinations =
6738 ARRAY_SIZE(ath10k_tlv_if_comb);
6739 }
6740 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
6741 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02006742 case ATH10K_FW_WMI_OP_VERSION_10_1:
6743 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02006744 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02006745 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
6746 ar->hw->wiphy->n_iface_combinations =
6747 ARRAY_SIZE(ath10k_10x_if_comb);
6748 break;
6749 case ATH10K_FW_WMI_OP_VERSION_UNSET:
6750 case ATH10K_FW_WMI_OP_VERSION_MAX:
6751 WARN_ON(1);
6752 ret = -EINVAL;
6753 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01006754 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006755
Michal Kazior7c199992013-07-31 10:47:57 +02006756 ar->hw->netdev_features = NETIF_F_HW_CSUM;
6757
Janusz Dziedzic9702c682013-11-20 09:59:41 +02006758 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
6759 /* Init ath dfs pattern detector */
6760 ar->ath_common.debug_mask = ATH_DBG_DFS;
6761 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
6762 NL80211_DFS_UNSET);
6763
6764 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006765 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02006766 }
6767
Kalle Valo5e3dd152013-06-12 20:52:10 +03006768 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
6769 ath10k_reg_notifier);
6770 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006771 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Michal Kaziord6015b22013-07-22 14:13:30 +02006772 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006773 }
6774
Johannes Berg3cb10942015-01-22 21:38:45 +01006775 ar->hw->wiphy->cipher_suites = cipher_suites;
6776 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
6777
Kalle Valo5e3dd152013-06-12 20:52:10 +03006778 ret = ieee80211_register_hw(ar->hw);
6779 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006780 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Michal Kaziord6015b22013-07-22 14:13:30 +02006781 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006782 }
6783
6784 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
6785 ret = regulatory_hint(ar->hw->wiphy,
6786 ar->ath_common.regulatory.alpha2);
6787 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02006788 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006789 }
6790
6791 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02006792
6793err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006794 ieee80211_unregister_hw(ar->hw);
Michal Kaziord6015b22013-07-22 14:13:30 +02006795err_free:
6796 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
6797 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
6798
Kalle Valo5e3dd152013-06-12 20:52:10 +03006799 return ret;
6800}
6801
6802void ath10k_mac_unregister(struct ath10k *ar)
6803{
6804 ieee80211_unregister_hw(ar->hw);
6805
Janusz Dziedzic9702c682013-11-20 09:59:41 +02006806 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
6807 ar->dfs_detector->exit(ar->dfs_detector);
6808
Kalle Valo5e3dd152013-06-12 20:52:10 +03006809 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
6810 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
6811
6812 SET_IEEE80211_DEV(ar->hw, NULL);
6813}