blob: 339cb9addfb21b8312850c03403cf6b90147eb9c [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 Kazior370e5672015-02-18 14:02:26 +0100363static int ath10k_mac_vif_sta_fix_wep_key(struct ath10k_vif *arvif)
364{
365 struct ath10k *ar = arvif->ar;
366 enum nl80211_iftype iftype = arvif->vif->type;
367 struct ieee80211_key_conf *key;
368 u32 flags = 0;
369 int num = 0;
370 int i;
371 int ret;
372
373 lockdep_assert_held(&ar->conf_mutex);
374
375 if (iftype != NL80211_IFTYPE_STATION)
376 return 0;
377
378 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
379 if (arvif->wep_keys[i]) {
380 key = arvif->wep_keys[i];
381 ++num;
382 }
383 }
384
385 if (num != 1)
386 return 0;
387
388 flags |= WMI_KEY_PAIRWISE;
389 flags |= WMI_KEY_TX_USAGE;
390
391 ret = ath10k_install_key(arvif, key, SET_KEY, arvif->bssid, flags);
392 if (ret) {
393 ath10k_warn(ar, "failed to install key %i on vdev %i: %d\n",
394 key->keyidx, arvif->vdev_id, ret);
395 return ret;
396 }
397
398 return 0;
399}
400
Michal Kaziorad325cb2015-02-18 14:02:27 +0100401static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
402 struct ieee80211_key_conf *key)
403{
404 struct ath10k *ar = arvif->ar;
405 struct ath10k_peer *peer;
406 int ret;
407
408 lockdep_assert_held(&ar->conf_mutex);
409
410 list_for_each_entry(peer, &ar->peers, list) {
411 if (!memcmp(peer->addr, arvif->vif->addr, ETH_ALEN))
412 continue;
413
414 if (!memcmp(peer->addr, arvif->bssid, ETH_ALEN))
415 continue;
416
417 if (peer->keys[key->keyidx] == key)
418 continue;
419
420 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
421 arvif->vdev_id, key->keyidx);
422
423 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
424 if (ret) {
425 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
426 arvif->vdev_id, peer->addr, ret);
427 return ret;
428 }
429 }
430
431 return 0;
432}
433
Kalle Valo5e3dd152013-06-12 20:52:10 +0300434/*********************/
435/* General utilities */
436/*********************/
437
438static inline enum wmi_phy_mode
439chan_to_phymode(const struct cfg80211_chan_def *chandef)
440{
441 enum wmi_phy_mode phymode = MODE_UNKNOWN;
442
443 switch (chandef->chan->band) {
444 case IEEE80211_BAND_2GHZ:
445 switch (chandef->width) {
446 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800447 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
448 phymode = MODE_11B;
449 else
450 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300451 break;
452 case NL80211_CHAN_WIDTH_20:
453 phymode = MODE_11NG_HT20;
454 break;
455 case NL80211_CHAN_WIDTH_40:
456 phymode = MODE_11NG_HT40;
457 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400458 case NL80211_CHAN_WIDTH_5:
459 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300460 case NL80211_CHAN_WIDTH_80:
461 case NL80211_CHAN_WIDTH_80P80:
462 case NL80211_CHAN_WIDTH_160:
463 phymode = MODE_UNKNOWN;
464 break;
465 }
466 break;
467 case IEEE80211_BAND_5GHZ:
468 switch (chandef->width) {
469 case NL80211_CHAN_WIDTH_20_NOHT:
470 phymode = MODE_11A;
471 break;
472 case NL80211_CHAN_WIDTH_20:
473 phymode = MODE_11NA_HT20;
474 break;
475 case NL80211_CHAN_WIDTH_40:
476 phymode = MODE_11NA_HT40;
477 break;
478 case NL80211_CHAN_WIDTH_80:
479 phymode = MODE_11AC_VHT80;
480 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400481 case NL80211_CHAN_WIDTH_5:
482 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300483 case NL80211_CHAN_WIDTH_80P80:
484 case NL80211_CHAN_WIDTH_160:
485 phymode = MODE_UNKNOWN;
486 break;
487 }
488 break;
489 default:
490 break;
491 }
492
493 WARN_ON(phymode == MODE_UNKNOWN);
494 return phymode;
495}
496
497static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
498{
499/*
500 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
501 * 0 for no restriction
502 * 1 for 1/4 us
503 * 2 for 1/2 us
504 * 3 for 1 us
505 * 4 for 2 us
506 * 5 for 4 us
507 * 6 for 8 us
508 * 7 for 16 us
509 */
510 switch (mpdudensity) {
511 case 0:
512 return 0;
513 case 1:
514 case 2:
515 case 3:
516 /* Our lower layer calculations limit our precision to
517 1 microsecond */
518 return 1;
519 case 4:
520 return 2;
521 case 5:
522 return 4;
523 case 6:
524 return 8;
525 case 7:
526 return 16;
527 default:
528 return 0;
529 }
530}
531
Michal Kazior500ff9f2015-03-31 10:26:21 +0000532int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
533 struct cfg80211_chan_def *def)
534{
535 struct ieee80211_chanctx_conf *conf;
536
537 rcu_read_lock();
538 conf = rcu_dereference(vif->chanctx_conf);
539 if (!conf) {
540 rcu_read_unlock();
541 return -ENOENT;
542 }
543
544 *def = conf->def;
545 rcu_read_unlock();
546
547 return 0;
548}
549
550static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,
551 struct ieee80211_chanctx_conf *conf,
552 void *data)
553{
554 int *num = data;
555
556 (*num)++;
557}
558
559static int ath10k_mac_num_chanctxs(struct ath10k *ar)
560{
561 int num = 0;
562
563 ieee80211_iter_chan_contexts_atomic(ar->hw,
564 ath10k_mac_num_chanctxs_iter,
565 &num);
566
567 return num;
568}
569
570static void
571ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
572 struct ieee80211_chanctx_conf *conf,
573 void *data)
574{
575 struct cfg80211_chan_def **def = data;
576
577 *def = &conf->def;
578}
579
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300580static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr,
581 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300582{
583 int ret;
584
585 lockdep_assert_held(&ar->conf_mutex);
586
Michal Kaziorcfd10612014-11-25 15:16:05 +0100587 if (ar->num_peers >= ar->max_num_peers)
588 return -ENOBUFS;
589
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300590 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800591 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200592 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200593 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300594 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800595 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300596
597 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800598 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200599 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200600 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300601 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800602 }
Michal Kazior292a7532014-11-25 15:16:04 +0100603
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100604 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300605
606 return 0;
607}
608
Kalle Valo5a13e762014-01-20 11:01:46 +0200609static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
610{
611 struct ath10k *ar = arvif->ar;
612 u32 param;
613 int ret;
614
615 param = ar->wmi.pdev_param->sta_kickout_th;
616 ret = ath10k_wmi_pdev_set_param(ar, param,
617 ATH10K_KICKOUT_THRESHOLD);
618 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200619 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200620 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200621 return ret;
622 }
623
624 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
625 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
626 ATH10K_KEEPALIVE_MIN_IDLE);
627 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200628 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200629 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200630 return ret;
631 }
632
633 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
634 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
635 ATH10K_KEEPALIVE_MAX_IDLE);
636 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200637 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200638 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200639 return ret;
640 }
641
642 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
643 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
644 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
645 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200646 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200647 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200648 return ret;
649 }
650
651 return 0;
652}
653
Vivek Natarajanacab6402014-11-26 09:06:12 +0200654static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200655{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200656 struct ath10k *ar = arvif->ar;
657 u32 vdev_param;
658
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200659 vdev_param = ar->wmi.vdev_param->rts_threshold;
660 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200661}
662
663static int ath10k_mac_set_frag(struct ath10k_vif *arvif, u32 value)
664{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200665 struct ath10k *ar = arvif->ar;
666 u32 vdev_param;
667
Michal Kazior424121c2013-07-22 14:13:31 +0200668 if (value != 0xFFFFFFFF)
669 value = clamp_t(u32, arvif->ar->hw->wiphy->frag_threshold,
670 ATH10K_FRAGMT_THRESHOLD_MIN,
671 ATH10K_FRAGMT_THRESHOLD_MAX);
672
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200673 vdev_param = ar->wmi.vdev_param->fragmentation_threshold;
674 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200675}
676
Kalle Valo5e3dd152013-06-12 20:52:10 +0300677static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
678{
679 int ret;
680
681 lockdep_assert_held(&ar->conf_mutex);
682
683 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
684 if (ret)
685 return ret;
686
687 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
688 if (ret)
689 return ret;
690
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100691 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100692
Kalle Valo5e3dd152013-06-12 20:52:10 +0300693 return 0;
694}
695
696static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
697{
698 struct ath10k_peer *peer, *tmp;
699
700 lockdep_assert_held(&ar->conf_mutex);
701
702 spin_lock_bh(&ar->data_lock);
703 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
704 if (peer->vdev_id != vdev_id)
705 continue;
706
Michal Kazior7aa7a722014-08-25 12:09:38 +0200707 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300708 peer->addr, vdev_id);
709
710 list_del(&peer->list);
711 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100712 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300713 }
714 spin_unlock_bh(&ar->data_lock);
715}
716
Michal Kaziora96d7742013-07-16 09:38:56 +0200717static void ath10k_peer_cleanup_all(struct ath10k *ar)
718{
719 struct ath10k_peer *peer, *tmp;
720
721 lockdep_assert_held(&ar->conf_mutex);
722
723 spin_lock_bh(&ar->data_lock);
724 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
725 list_del(&peer->list);
726 kfree(peer);
727 }
728 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100729
730 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100731 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200732}
733
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300734static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
735 struct ieee80211_sta *sta,
736 enum wmi_tdls_peer_state state)
737{
738 int ret;
739 struct wmi_tdls_peer_update_cmd_arg arg = {};
740 struct wmi_tdls_peer_capab_arg cap = {};
741 struct wmi_channel_arg chan_arg = {};
742
743 lockdep_assert_held(&ar->conf_mutex);
744
745 arg.vdev_id = vdev_id;
746 arg.peer_state = state;
747 ether_addr_copy(arg.addr, sta->addr);
748
749 cap.peer_max_sp = sta->max_sp;
750 cap.peer_uapsd_queues = sta->uapsd_queues;
751
752 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
753 !sta->tdls_initiator)
754 cap.is_peer_responder = 1;
755
756 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
757 if (ret) {
758 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
759 arg.addr, vdev_id, ret);
760 return ret;
761 }
762
763 return 0;
764}
765
Kalle Valo5e3dd152013-06-12 20:52:10 +0300766/************************/
767/* Interface management */
768/************************/
769
Michal Kazior64badcb2014-09-18 11:18:02 +0300770void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
771{
772 struct ath10k *ar = arvif->ar;
773
774 lockdep_assert_held(&ar->data_lock);
775
776 if (!arvif->beacon)
777 return;
778
779 if (!arvif->beacon_buf)
780 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
781 arvif->beacon->len, DMA_TO_DEVICE);
782
Michal Kazioraf213192015-01-29 14:29:52 +0200783 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
784 arvif->beacon_state != ATH10K_BEACON_SENT))
785 return;
786
Michal Kazior64badcb2014-09-18 11:18:02 +0300787 dev_kfree_skb_any(arvif->beacon);
788
789 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200790 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300791}
792
793static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
794{
795 struct ath10k *ar = arvif->ar;
796
797 lockdep_assert_held(&ar->data_lock);
798
799 ath10k_mac_vif_beacon_free(arvif);
800
801 if (arvif->beacon_buf) {
802 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
803 arvif->beacon_buf, arvif->beacon_paddr);
804 arvif->beacon_buf = NULL;
805 }
806}
807
Kalle Valo5e3dd152013-06-12 20:52:10 +0300808static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
809{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300810 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300811
Michal Kazior548db542013-07-05 16:15:15 +0300812 lockdep_assert_held(&ar->conf_mutex);
813
Michal Kazior7962b0d2014-10-28 10:34:38 +0100814 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
815 return -ESHUTDOWN;
816
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300817 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
818 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
819 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300820 return -ETIMEDOUT;
821
822 return 0;
823}
824
Michal Kazior1bbc0972014-04-08 09:45:47 +0300825static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300826{
Michal Kazior500ff9f2015-03-31 10:26:21 +0000827 struct cfg80211_chan_def *chandef = NULL;
Michal Kaziorc930f742014-01-23 11:38:25 +0100828 struct ieee80211_channel *channel = chandef->chan;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300829 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300830 int ret = 0;
831
832 lockdep_assert_held(&ar->conf_mutex);
833
Michal Kazior500ff9f2015-03-31 10:26:21 +0000834 ieee80211_iter_chan_contexts_atomic(ar->hw,
835 ath10k_mac_get_any_chandef_iter,
836 &chandef);
837 if (WARN_ON_ONCE(!chandef))
838 return -ENOENT;
839
840 channel = chandef->chan;
841
Kalle Valo5e3dd152013-06-12 20:52:10 +0300842 arg.vdev_id = vdev_id;
843 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +0100844 arg.channel.band_center_freq1 = chandef->center_freq1;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300845
846 /* TODO setup this dynamically, what in case we
847 don't have any vifs? */
Michal Kaziorc930f742014-01-23 11:38:25 +0100848 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200849 arg.channel.chan_radar =
850 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300851
Michal Kazior89c5c842013-10-23 04:02:13 -0700852 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -0700853 arg.channel.max_power = channel->max_power * 2;
854 arg.channel.max_reg_power = channel->max_reg_power * 2;
855 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300856
Michal Kazior7962b0d2014-10-28 10:34:38 +0100857 reinit_completion(&ar->vdev_setup_done);
858
Kalle Valo5e3dd152013-06-12 20:52:10 +0300859 ret = ath10k_wmi_vdev_start(ar, &arg);
860 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200861 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200862 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300863 return ret;
864 }
865
866 ret = ath10k_vdev_setup_sync(ar);
867 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +0200868 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200869 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300870 return ret;
871 }
872
873 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
874 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200875 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200876 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300877 goto vdev_stop;
878 }
879
880 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300881
Michal Kazior7aa7a722014-08-25 12:09:38 +0200882 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300883 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300884 return 0;
885
886vdev_stop:
887 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
888 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200889 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200890 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300891
892 return ret;
893}
894
Michal Kazior1bbc0972014-04-08 09:45:47 +0300895static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300896{
897 int ret = 0;
898
899 lockdep_assert_held(&ar->conf_mutex);
900
Marek Puzyniak52fa0192013-09-24 14:06:24 +0200901 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
902 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200903 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200904 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300905
Michal Kazior7962b0d2014-10-28 10:34:38 +0100906 reinit_completion(&ar->vdev_setup_done);
907
Kalle Valo5e3dd152013-06-12 20:52:10 +0300908 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
909 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200910 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200911 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300912
913 ret = ath10k_vdev_setup_sync(ar);
914 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +0200915 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200916 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300917
Michal Kazior7aa7a722014-08-25 12:09:38 +0200918 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300919 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300920 return ret;
921}
922
Michal Kazior1bbc0972014-04-08 09:45:47 +0300923static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300924{
925 int bit, ret = 0;
926
927 lockdep_assert_held(&ar->conf_mutex);
928
Ben Greeara9aefb32014-08-12 11:02:19 +0300929 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200930 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +0300931 return -ENOMEM;
932 }
933
Ben Greear16c11172014-09-23 14:17:16 -0700934 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +0300935
Ben Greear16c11172014-09-23 14:17:16 -0700936 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300937
938 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
939 WMI_VDEV_TYPE_MONITOR,
940 0, ar->mac_addr);
941 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200942 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200943 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +0300944 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300945 }
946
Ben Greear16c11172014-09-23 14:17:16 -0700947 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +0200948 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300949 ar->monitor_vdev_id);
950
Kalle Valo5e3dd152013-06-12 20:52:10 +0300951 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300952}
953
Michal Kazior1bbc0972014-04-08 09:45:47 +0300954static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300955{
956 int ret = 0;
957
958 lockdep_assert_held(&ar->conf_mutex);
959
Kalle Valo5e3dd152013-06-12 20:52:10 +0300960 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
961 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200962 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200963 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300964 return ret;
965 }
966
Ben Greear16c11172014-09-23 14:17:16 -0700967 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300968
Michal Kazior7aa7a722014-08-25 12:09:38 +0200969 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300970 ar->monitor_vdev_id);
971 return ret;
972}
973
Michal Kazior1bbc0972014-04-08 09:45:47 +0300974static int ath10k_monitor_start(struct ath10k *ar)
975{
976 int ret;
977
978 lockdep_assert_held(&ar->conf_mutex);
979
Michal Kazior1bbc0972014-04-08 09:45:47 +0300980 ret = ath10k_monitor_vdev_create(ar);
981 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200982 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +0300983 return ret;
984 }
985
986 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
987 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200988 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +0300989 ath10k_monitor_vdev_delete(ar);
990 return ret;
991 }
992
993 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +0200994 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +0300995
996 return 0;
997}
998
Michal Kazior19337472014-08-28 12:58:16 +0200999static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +03001000{
1001 int ret;
1002
1003 lockdep_assert_held(&ar->conf_mutex);
1004
Michal Kazior1bbc0972014-04-08 09:45:47 +03001005 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001006 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001007 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001008 return ret;
1009 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001010
1011 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001012 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001013 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001014 return ret;
1015 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001016
1017 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001018 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +02001019
1020 return 0;
1021}
1022
Vasanthakumar Thiagarajan54846212015-03-02 17:45:28 +05301023static bool ath10k_mac_should_disable_promisc(struct ath10k *ar)
1024{
1025 struct ath10k_vif *arvif;
1026
1027 if (!(ar->filter_flags & FIF_PROMISC_IN_BSS))
1028 return true;
1029
1030 if (!ar->num_started_vdevs)
1031 return false;
1032
1033 list_for_each_entry(arvif, &ar->arvifs, list)
1034 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1035 return false;
1036
1037 ath10k_dbg(ar, ATH10K_DBG_MAC,
1038 "mac disabling promiscuous mode because vdev is started\n");
1039 return true;
1040}
1041
Michal Kazior500ff9f2015-03-31 10:26:21 +00001042static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1043{
1044 int num_ctx;
1045
1046 /* At least one chanctx is required to derive a channel to start
1047 * monitor vdev on.
1048 */
1049 num_ctx = ath10k_mac_num_chanctxs(ar);
1050 if (num_ctx == 0)
1051 return false;
1052
1053 /* If there's already an existing special monitor interface then don't
1054 * bother creating another monitor vdev.
1055 */
1056 if (ar->monitor_arvif)
1057 return false;
1058
1059 return ar->monitor ||
1060 !ath10k_mac_should_disable_promisc(ar) ||
1061 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1062}
1063
1064static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1065{
1066 int num_ctx;
1067
1068 num_ctx = ath10k_mac_num_chanctxs(ar);
1069
1070 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1071 * shouldn't allow this but make sure to prevent handling the following
1072 * case anyway since multi-channel DFS hasn't been tested at all.
1073 */
1074 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1075 return false;
1076
1077 return true;
1078}
1079
Michal Kazior19337472014-08-28 12:58:16 +02001080static int ath10k_monitor_recalc(struct ath10k *ar)
1081{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001082 bool needed;
1083 bool allowed;
1084 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001085
1086 lockdep_assert_held(&ar->conf_mutex);
1087
Michal Kazior500ff9f2015-03-31 10:26:21 +00001088 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1089 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001090
1091 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001092 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1093 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001094
Michal Kazior500ff9f2015-03-31 10:26:21 +00001095 if (WARN_ON(needed && !allowed)) {
1096 if (ar->monitor_started) {
1097 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1098
1099 ret = ath10k_monitor_stop(ar);
1100 if (ret)
1101 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n", ret);
1102 /* not serious */
1103 }
1104
1105 return -EPERM;
1106 }
1107
1108 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001109 return 0;
1110
Michal Kazior500ff9f2015-03-31 10:26:21 +00001111 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001112 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001113 else
1114 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001115}
1116
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001117static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1118{
1119 struct ath10k *ar = arvif->ar;
1120 u32 vdev_param, rts_cts = 0;
1121
1122 lockdep_assert_held(&ar->conf_mutex);
1123
1124 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1125
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001126 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001127
1128 if (arvif->num_legacy_stations > 0)
1129 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1130 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001131 else
1132 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1133 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001134
1135 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1136 rts_cts);
1137}
1138
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001139static int ath10k_start_cac(struct ath10k *ar)
1140{
1141 int ret;
1142
1143 lockdep_assert_held(&ar->conf_mutex);
1144
1145 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1146
Michal Kazior19337472014-08-28 12:58:16 +02001147 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001148 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001149 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001150 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1151 return ret;
1152 }
1153
Michal Kazior7aa7a722014-08-25 12:09:38 +02001154 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001155 ar->monitor_vdev_id);
1156
1157 return 0;
1158}
1159
1160static int ath10k_stop_cac(struct ath10k *ar)
1161{
1162 lockdep_assert_held(&ar->conf_mutex);
1163
1164 /* CAC is not running - do nothing */
1165 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1166 return 0;
1167
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001168 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001169 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001170
Michal Kazior7aa7a722014-08-25 12:09:38 +02001171 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001172
1173 return 0;
1174}
1175
Michal Kazior500ff9f2015-03-31 10:26:21 +00001176static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1177 struct ieee80211_chanctx_conf *conf,
1178 void *data)
1179{
1180 bool *ret = data;
1181
1182 if (!*ret && conf->radar_enabled)
1183 *ret = true;
1184}
1185
1186static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1187{
1188 bool has_radar = false;
1189
1190 ieee80211_iter_chan_contexts_atomic(ar->hw,
1191 ath10k_mac_has_radar_iter,
1192 &has_radar);
1193
1194 return has_radar;
1195}
1196
Michal Kaziord6500972014-04-08 09:56:09 +03001197static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001198{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001199 int ret;
1200
1201 lockdep_assert_held(&ar->conf_mutex);
1202
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001203 ath10k_stop_cac(ar);
1204
Michal Kazior500ff9f2015-03-31 10:26:21 +00001205 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001206 return;
1207
Michal Kaziord6500972014-04-08 09:56:09 +03001208 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001209 return;
1210
1211 ret = ath10k_start_cac(ar);
1212 if (ret) {
1213 /*
1214 * Not possible to start CAC on current channel so starting
1215 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1216 * by indicating that radar was detected.
1217 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001218 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001219 ieee80211_radar_detected(ar->hw);
1220 }
1221}
1222
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301223static int ath10k_vdev_stop(struct ath10k_vif *arvif)
1224{
1225 struct ath10k *ar = arvif->ar;
1226 int ret;
1227
1228 lockdep_assert_held(&ar->conf_mutex);
1229
1230 reinit_completion(&ar->vdev_setup_done);
1231
1232 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1233 if (ret) {
1234 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1235 arvif->vdev_id, ret);
1236 return ret;
1237 }
1238
1239 ret = ath10k_vdev_setup_sync(ar);
1240 if (ret) {
1241 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
1242 arvif->vdev_id, ret);
1243 return ret;
1244 }
1245
1246 WARN_ON(ar->num_started_vdevs == 0);
1247
1248 if (ar->num_started_vdevs != 0) {
1249 ar->num_started_vdevs--;
1250 ath10k_recalc_radar_detection(ar);
1251 }
1252
1253 return ret;
1254}
1255
Michal Kazior500ff9f2015-03-31 10:26:21 +00001256static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1257 const struct cfg80211_chan_def *chandef,
1258 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001259{
1260 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001261 struct wmi_vdev_start_request_arg arg = {};
Vasanthakumar Thiagarajan54846212015-03-02 17:45:28 +05301262 int ret = 0, ret2;
Michal Kazior72654fa2014-04-08 09:56:09 +03001263
1264 lockdep_assert_held(&ar->conf_mutex);
1265
1266 reinit_completion(&ar->vdev_setup_done);
1267
1268 arg.vdev_id = arvif->vdev_id;
1269 arg.dtim_period = arvif->dtim_period;
1270 arg.bcn_intval = arvif->beacon_interval;
1271
1272 arg.channel.freq = chandef->chan->center_freq;
1273 arg.channel.band_center_freq1 = chandef->center_freq1;
1274 arg.channel.mode = chan_to_phymode(chandef);
1275
1276 arg.channel.min_power = 0;
1277 arg.channel.max_power = chandef->chan->max_power * 2;
1278 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1279 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1280
1281 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1282 arg.ssid = arvif->u.ap.ssid;
1283 arg.ssid_len = arvif->u.ap.ssid_len;
1284 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1285
1286 /* For now allow DFS for AP mode */
1287 arg.channel.chan_radar =
1288 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1289 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1290 arg.ssid = arvif->vif->bss_conf.ssid;
1291 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1292 }
1293
Michal Kazior7aa7a722014-08-25 12:09:38 +02001294 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001295 "mac vdev %d start center_freq %d phymode %s\n",
1296 arg.vdev_id, arg.channel.freq,
1297 ath10k_wmi_phymode_str(arg.channel.mode));
1298
Michal Kaziordc55e302014-07-29 12:53:36 +03001299 if (restart)
1300 ret = ath10k_wmi_vdev_restart(ar, &arg);
1301 else
1302 ret = ath10k_wmi_vdev_start(ar, &arg);
1303
Michal Kazior72654fa2014-04-08 09:56:09 +03001304 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001305 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001306 arg.vdev_id, ret);
1307 return ret;
1308 }
1309
1310 ret = ath10k_vdev_setup_sync(ar);
1311 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001312 ath10k_warn(ar,
1313 "failed to synchronize setup for vdev %i restart %d: %d\n",
1314 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001315 return ret;
1316 }
1317
Michal Kaziord6500972014-04-08 09:56:09 +03001318 ar->num_started_vdevs++;
1319 ath10k_recalc_radar_detection(ar);
1320
Vasanthakumar Thiagarajan54846212015-03-02 17:45:28 +05301321 ret = ath10k_monitor_recalc(ar);
1322 if (ret) {
1323 ath10k_warn(ar, "mac failed to recalc monitor for vdev %i restart %d: %d\n",
1324 arg.vdev_id, restart, ret);
1325 ret2 = ath10k_vdev_stop(arvif);
1326 if (ret2)
1327 ath10k_warn(ar, "mac failed to stop vdev %i restart %d: %d\n",
1328 arg.vdev_id, restart, ret2);
1329 }
1330
Michal Kazior72654fa2014-04-08 09:56:09 +03001331 return ret;
1332}
1333
Michal Kazior500ff9f2015-03-31 10:26:21 +00001334static int ath10k_vdev_start(struct ath10k_vif *arvif,
1335 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001336{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001337 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001338}
1339
Michal Kazior500ff9f2015-03-31 10:26:21 +00001340static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1341 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001342{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001343 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kaziordc55e302014-07-29 12:53:36 +03001344}
1345
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001346static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1347 struct sk_buff *bcn)
1348{
1349 struct ath10k *ar = arvif->ar;
1350 struct ieee80211_mgmt *mgmt;
1351 const u8 *p2p_ie;
1352 int ret;
1353
1354 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1355 return 0;
1356
1357 if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
1358 return 0;
1359
1360 mgmt = (void *)bcn->data;
1361 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1362 mgmt->u.beacon.variable,
1363 bcn->len - (mgmt->u.beacon.variable -
1364 bcn->data));
1365 if (!p2p_ie)
1366 return -ENOENT;
1367
1368 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1369 if (ret) {
1370 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1371 arvif->vdev_id, ret);
1372 return ret;
1373 }
1374
1375 return 0;
1376}
1377
1378static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1379 u8 oui_type, size_t ie_offset)
1380{
1381 size_t len;
1382 const u8 *next;
1383 const u8 *end;
1384 u8 *ie;
1385
1386 if (WARN_ON(skb->len < ie_offset))
1387 return -EINVAL;
1388
1389 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1390 skb->data + ie_offset,
1391 skb->len - ie_offset);
1392 if (!ie)
1393 return -ENOENT;
1394
1395 len = ie[1] + 2;
1396 end = skb->data + skb->len;
1397 next = ie + len;
1398
1399 if (WARN_ON(next > end))
1400 return -EINVAL;
1401
1402 memmove(ie, next, end - next);
1403 skb_trim(skb, skb->len - len);
1404
1405 return 0;
1406}
1407
1408static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1409{
1410 struct ath10k *ar = arvif->ar;
1411 struct ieee80211_hw *hw = ar->hw;
1412 struct ieee80211_vif *vif = arvif->vif;
1413 struct ieee80211_mutable_offsets offs = {};
1414 struct sk_buff *bcn;
1415 int ret;
1416
1417 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1418 return 0;
1419
Michal Kazior81a9a172015-03-05 16:02:17 +02001420 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1421 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1422 return 0;
1423
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001424 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1425 if (!bcn) {
1426 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1427 return -EPERM;
1428 }
1429
1430 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1431 if (ret) {
1432 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1433 kfree_skb(bcn);
1434 return ret;
1435 }
1436
1437 /* P2P IE is inserted by firmware automatically (as configured above)
1438 * so remove it from the base beacon template to avoid duplicate P2P
1439 * IEs in beacon frames.
1440 */
1441 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1442 offsetof(struct ieee80211_mgmt,
1443 u.beacon.variable));
1444
1445 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1446 0, NULL, 0);
1447 kfree_skb(bcn);
1448
1449 if (ret) {
1450 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1451 ret);
1452 return ret;
1453 }
1454
1455 return 0;
1456}
1457
1458static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1459{
1460 struct ath10k *ar = arvif->ar;
1461 struct ieee80211_hw *hw = ar->hw;
1462 struct ieee80211_vif *vif = arvif->vif;
1463 struct sk_buff *prb;
1464 int ret;
1465
1466 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1467 return 0;
1468
Michal Kazior81a9a172015-03-05 16:02:17 +02001469 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1470 return 0;
1471
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001472 prb = ieee80211_proberesp_get(hw, vif);
1473 if (!prb) {
1474 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1475 return -EPERM;
1476 }
1477
1478 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1479 kfree_skb(prb);
1480
1481 if (ret) {
1482 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1483 ret);
1484 return ret;
1485 }
1486
1487 return 0;
1488}
1489
Michal Kazior500ff9f2015-03-31 10:26:21 +00001490static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1491{
1492 struct ath10k *ar = arvif->ar;
1493 struct cfg80211_chan_def def;
1494 int ret;
1495
1496 /* When originally vdev is started during assign_vif_chanctx() some
1497 * information is missing, notably SSID. Firmware revisions with beacon
1498 * offloading require the SSID to be provided during vdev (re)start to
1499 * handle hidden SSID properly.
1500 *
1501 * Vdev restart must be done after vdev has been both started and
1502 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1503 * deliver vdev restart response event causing timeouts during vdev
1504 * syncing in ath10k.
1505 *
1506 * Note: The vdev down/up and template reinstallation could be skipped
1507 * since only wmi-tlv firmware are known to have beacon offload and
1508 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1509 * response delivery. It's probably more robust to keep it as is.
1510 */
1511 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1512 return 0;
1513
1514 if (WARN_ON(!arvif->is_started))
1515 return -EINVAL;
1516
1517 if (WARN_ON(!arvif->is_up))
1518 return -EINVAL;
1519
1520 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1521 return -EINVAL;
1522
1523 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1524 if (ret) {
1525 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1526 arvif->vdev_id, ret);
1527 return ret;
1528 }
1529
1530 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1531 * firmware will crash upon vdev up.
1532 */
1533
1534 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1535 if (ret) {
1536 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1537 return ret;
1538 }
1539
1540 ret = ath10k_mac_setup_prb_tmpl(arvif);
1541 if (ret) {
1542 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1543 return ret;
1544 }
1545
1546 ret = ath10k_vdev_restart(arvif, &def);
1547 if (ret) {
1548 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1549 arvif->vdev_id, ret);
1550 return ret;
1551 }
1552
1553 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1554 arvif->bssid);
1555 if (ret) {
1556 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1557 arvif->vdev_id, ret);
1558 return ret;
1559 }
1560
1561 return 0;
1562}
1563
Kalle Valo5e3dd152013-06-12 20:52:10 +03001564static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001565 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001566{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001567 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001568 int ret = 0;
1569
Michal Kazior548db542013-07-05 16:15:15 +03001570 lockdep_assert_held(&arvif->ar->conf_mutex);
1571
Kalle Valo5e3dd152013-06-12 20:52:10 +03001572 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001573 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1574 if (ret)
1575 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1576 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001577
Michal Kaziorc930f742014-01-23 11:38:25 +01001578 arvif->is_up = false;
Michal Kazior8513d952015-03-09 14:19:24 +01001579
1580 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001581 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001582 spin_unlock_bh(&arvif->ar->data_lock);
1583
Kalle Valo5e3dd152013-06-12 20:52:10 +03001584 return;
1585 }
1586
1587 arvif->tx_seq_no = 0x1000;
1588
Michal Kaziorc930f742014-01-23 11:38:25 +01001589 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001590 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001591
1592 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1593 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001594 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001595 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001596 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001597 return;
1598 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001599
Michal Kaziorc930f742014-01-23 11:38:25 +01001600 arvif->is_up = true;
1601
Michal Kazior500ff9f2015-03-31 10:26:21 +00001602 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1603 if (ret) {
1604 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1605 arvif->vdev_id, ret);
1606 return;
1607 }
1608
Michal Kazior7aa7a722014-08-25 12:09:38 +02001609 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001610}
1611
1612static void ath10k_control_ibss(struct ath10k_vif *arvif,
1613 struct ieee80211_bss_conf *info,
1614 const u8 self_peer[ETH_ALEN])
1615{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001616 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001617 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001618 int ret = 0;
1619
Michal Kazior548db542013-07-05 16:15:15 +03001620 lockdep_assert_held(&arvif->ar->conf_mutex);
1621
Kalle Valo5e3dd152013-06-12 20:52:10 +03001622 if (!info->ibss_joined) {
1623 ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer);
1624 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001625 ath10k_warn(ar, "failed to delete IBSS self peer %pM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001626 self_peer, arvif->vdev_id, ret);
1627
Michal Kaziorc930f742014-01-23 11:38:25 +01001628 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001629 return;
1630
Michal Kaziorc930f742014-01-23 11:38:25 +01001631 memset(arvif->bssid, 0, ETH_ALEN);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001632
1633 return;
1634 }
1635
Marek Puzyniak7390ed32015-03-30 09:51:52 +03001636 ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer,
1637 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001638 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001639 ath10k_warn(ar, "failed to create IBSS self peer %pM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001640 self_peer, arvif->vdev_id, ret);
1641 return;
1642 }
1643
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001644 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1645 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001646 ATH10K_DEFAULT_ATIM);
1647 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001648 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001649 arvif->vdev_id, ret);
1650}
1651
Michal Kazior9f9b5742014-12-12 12:41:36 +01001652static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1653{
1654 struct ath10k *ar = arvif->ar;
1655 u32 param;
1656 u32 value;
1657 int ret;
1658
1659 lockdep_assert_held(&arvif->ar->conf_mutex);
1660
1661 if (arvif->u.sta.uapsd)
1662 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1663 else
1664 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1665
1666 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1667 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1668 if (ret) {
1669 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1670 value, arvif->vdev_id, ret);
1671 return ret;
1672 }
1673
1674 return 0;
1675}
1676
1677static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1678{
1679 struct ath10k *ar = arvif->ar;
1680 u32 param;
1681 u32 value;
1682 int ret;
1683
1684 lockdep_assert_held(&arvif->ar->conf_mutex);
1685
1686 if (arvif->u.sta.uapsd)
1687 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1688 else
1689 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1690
1691 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1692 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1693 param, value);
1694 if (ret) {
1695 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1696 value, arvif->vdev_id, ret);
1697 return ret;
1698 }
1699
1700 return 0;
1701}
1702
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001703static int ath10k_mac_ps_vif_count(struct ath10k *ar)
1704{
1705 struct ath10k_vif *arvif;
1706 int num = 0;
1707
1708 lockdep_assert_held(&ar->conf_mutex);
1709
1710 list_for_each_entry(arvif, &ar->arvifs, list)
1711 if (arvif->ps)
1712 num++;
1713
1714 return num;
1715}
1716
Michal Kaziorad088bf2013-10-16 15:44:46 +03001717static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001718{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001719 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001720 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001721 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001722 enum wmi_sta_powersave_param param;
1723 enum wmi_sta_ps_mode psmode;
1724 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001725 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001726 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001727
Michal Kazior548db542013-07-05 16:15:15 +03001728 lockdep_assert_held(&arvif->ar->conf_mutex);
1729
Michal Kaziorad088bf2013-10-16 15:44:46 +03001730 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1731 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001732
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001733 enable_ps = arvif->ps;
1734
1735 if (enable_ps && ath10k_mac_ps_vif_count(ar) > 1 &&
1736 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
1737 ar->fw_features)) {
1738 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1739 arvif->vdev_id);
1740 enable_ps = false;
1741 }
1742
1743 if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001744 psmode = WMI_STA_PS_MODE_ENABLED;
1745 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1746
Michal Kazior526549a2014-12-12 12:41:37 +01001747 ps_timeout = conf->dynamic_ps_timeout;
1748 if (ps_timeout == 0) {
1749 /* Firmware doesn't like 0 */
1750 ps_timeout = ieee80211_tu_to_usec(
1751 vif->bss_conf.beacon_int) / 1000;
1752 }
1753
Michal Kaziorad088bf2013-10-16 15:44:46 +03001754 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001755 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001756 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001757 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001758 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001759 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001760 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001761 } else {
1762 psmode = WMI_STA_PS_MODE_DISABLED;
1763 }
1764
Michal Kazior7aa7a722014-08-25 12:09:38 +02001765 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001766 arvif->vdev_id, psmode ? "enable" : "disable");
1767
Michal Kaziorad088bf2013-10-16 15:44:46 +03001768 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1769 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001770 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001771 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001772 return ret;
1773 }
1774
1775 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001776}
1777
Michal Kazior46725b152015-01-28 09:57:49 +02001778static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1779{
1780 struct ath10k *ar = arvif->ar;
1781 struct wmi_sta_keepalive_arg arg = {};
1782 int ret;
1783
1784 lockdep_assert_held(&arvif->ar->conf_mutex);
1785
1786 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1787 return 0;
1788
1789 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1790 return 0;
1791
1792 /* Some firmware revisions have a bug and ignore the `enabled` field.
1793 * Instead use the interval to disable the keepalive.
1794 */
1795 arg.vdev_id = arvif->vdev_id;
1796 arg.enabled = 1;
1797 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1798 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1799
1800 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1801 if (ret) {
1802 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1803 arvif->vdev_id, ret);
1804 return ret;
1805 }
1806
1807 return 0;
1808}
1809
Michal Kazior81a9a172015-03-05 16:02:17 +02001810static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1811{
1812 struct ath10k *ar = arvif->ar;
1813 struct ieee80211_vif *vif = arvif->vif;
1814 int ret;
1815
Michal Kazior8513d952015-03-09 14:19:24 +01001816 lockdep_assert_held(&arvif->ar->conf_mutex);
1817
1818 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1819 return;
1820
Michal Kazior81a9a172015-03-05 16:02:17 +02001821 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1822 return;
1823
1824 if (!vif->csa_active)
1825 return;
1826
1827 if (!arvif->is_up)
1828 return;
1829
1830 if (!ieee80211_csa_is_complete(vif)) {
1831 ieee80211_csa_update_counter(vif);
1832
1833 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1834 if (ret)
1835 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1836 ret);
1837
1838 ret = ath10k_mac_setup_prb_tmpl(arvif);
1839 if (ret)
1840 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1841 ret);
1842 } else {
1843 ieee80211_csa_finish(vif);
1844 }
1845}
1846
1847static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1848{
1849 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1850 ap_csa_work);
1851 struct ath10k *ar = arvif->ar;
1852
1853 mutex_lock(&ar->conf_mutex);
1854 ath10k_mac_vif_ap_csa_count_down(arvif);
1855 mutex_unlock(&ar->conf_mutex);
1856}
1857
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001858static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1859 struct ieee80211_vif *vif)
1860{
1861 struct sk_buff *skb = data;
1862 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1863 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1864
1865 if (vif->type != NL80211_IFTYPE_STATION)
1866 return;
1867
1868 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1869 return;
1870
1871 cancel_delayed_work(&arvif->connection_loss_work);
1872}
1873
1874void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
1875{
1876 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1877 IEEE80211_IFACE_ITER_NORMAL,
1878 ath10k_mac_handle_beacon_iter,
1879 skb);
1880}
1881
1882static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
1883 struct ieee80211_vif *vif)
1884{
1885 u32 *vdev_id = data;
1886 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1887 struct ath10k *ar = arvif->ar;
1888 struct ieee80211_hw *hw = ar->hw;
1889
1890 if (arvif->vdev_id != *vdev_id)
1891 return;
1892
1893 if (!arvif->is_up)
1894 return;
1895
1896 ieee80211_beacon_loss(vif);
1897
1898 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
1899 * (done by mac80211) succeeds but beacons do not resume then it
1900 * doesn't make sense to continue operation. Queue connection loss work
1901 * which can be cancelled when beacon is received.
1902 */
1903 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
1904 ATH10K_CONNECTION_LOSS_HZ);
1905}
1906
1907void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
1908{
1909 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1910 IEEE80211_IFACE_ITER_NORMAL,
1911 ath10k_mac_handle_beacon_miss_iter,
1912 &vdev_id);
1913}
1914
1915static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
1916{
1917 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1918 connection_loss_work.work);
1919 struct ieee80211_vif *vif = arvif->vif;
1920
1921 if (!arvif->is_up)
1922 return;
1923
1924 ieee80211_connection_loss(vif);
1925}
1926
Kalle Valo5e3dd152013-06-12 20:52:10 +03001927/**********************/
1928/* Station management */
1929/**********************/
1930
Michal Kazior590922a2014-10-21 10:10:29 +03001931static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
1932 struct ieee80211_vif *vif)
1933{
1934 /* Some firmware revisions have unstable STA powersave when listen
1935 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
1936 * generate NullFunc frames properly even if buffered frames have been
1937 * indicated in Beacon TIM. Firmware would seldom wake up to pull
1938 * buffered frames. Often pinging the device from AP would simply fail.
1939 *
1940 * As a workaround set it to 1.
1941 */
1942 if (vif->type == NL80211_IFTYPE_STATION)
1943 return 1;
1944
1945 return ar->hw->conf.listen_interval;
1946}
1947
Kalle Valo5e3dd152013-06-12 20:52:10 +03001948static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001949 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001950 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001951 struct wmi_peer_assoc_complete_arg *arg)
1952{
Michal Kazior590922a2014-10-21 10:10:29 +03001953 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorc51880e2015-03-30 09:51:57 +03001954 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03001955
Michal Kazior548db542013-07-05 16:15:15 +03001956 lockdep_assert_held(&ar->conf_mutex);
1957
Michal Kaziorc51880e2015-03-30 09:51:57 +03001958 if (vif->type == NL80211_IFTYPE_STATION)
1959 aid = vif->bss_conf.aid;
1960 else
1961 aid = sta->aid;
1962
Kalle Valob25f32c2014-09-14 12:50:49 +03001963 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001964 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03001965 arg->peer_aid = aid;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001966 arg->peer_flags |= WMI_PEER_AUTH;
Michal Kazior590922a2014-10-21 10:10:29 +03001967 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001968 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03001969 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001970}
1971
1972static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001973 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001974 struct wmi_peer_assoc_complete_arg *arg)
1975{
Kalle Valo5e3dd152013-06-12 20:52:10 +03001976 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00001977 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001978 struct cfg80211_bss *bss;
1979 const u8 *rsnie = NULL;
1980 const u8 *wpaie = NULL;
1981
Michal Kazior548db542013-07-05 16:15:15 +03001982 lockdep_assert_held(&ar->conf_mutex);
1983
Michal Kazior500ff9f2015-03-31 10:26:21 +00001984 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
1985 return;
1986
1987 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
1988 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001989 if (bss) {
1990 const struct cfg80211_bss_ies *ies;
1991
1992 rcu_read_lock();
1993 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
1994
1995 ies = rcu_dereference(bss->ies);
1996
1997 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03001998 WLAN_OUI_TYPE_MICROSOFT_WPA,
1999 ies->data,
2000 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002001 rcu_read_unlock();
2002 cfg80211_put_bss(ar->hw->wiphy, bss);
2003 }
2004
2005 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2006 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002007 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002008 arg->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
2009 }
2010
2011 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002012 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002013 arg->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
2014 }
2015}
2016
2017static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002018 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002019 struct ieee80211_sta *sta,
2020 struct wmi_peer_assoc_complete_arg *arg)
2021{
2022 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002023 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002024 const struct ieee80211_supported_band *sband;
2025 const struct ieee80211_rate *rates;
2026 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002027 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002028 int i;
2029
Michal Kazior548db542013-07-05 16:15:15 +03002030 lockdep_assert_held(&ar->conf_mutex);
2031
Michal Kazior500ff9f2015-03-31 10:26:21 +00002032 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2033 return;
2034
2035 sband = ar->hw->wiphy->bands[def.chan->band];
2036 ratemask = sta->supp_rates[def.chan->band];
Kalle Valo5e3dd152013-06-12 20:52:10 +03002037 rates = sband->bitrates;
2038
2039 rateset->num_rates = 0;
2040
2041 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2042 if (!(ratemask & 1))
2043 continue;
2044
Michal Kazior486017c2015-03-30 09:51:54 +03002045 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2046 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002047 rateset->num_rates++;
2048 }
2049}
2050
2051static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
2052 struct ieee80211_sta *sta,
2053 struct wmi_peer_assoc_complete_arg *arg)
2054{
2055 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002056 int i, n;
Kalle Valoaf762c02014-09-14 12:50:17 +03002057 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002058
Michal Kazior548db542013-07-05 16:15:15 +03002059 lockdep_assert_held(&ar->conf_mutex);
2060
Kalle Valo5e3dd152013-06-12 20:52:10 +03002061 if (!ht_cap->ht_supported)
2062 return;
2063
2064 arg->peer_flags |= WMI_PEER_HT;
2065 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2066 ht_cap->ampdu_factor)) - 1;
2067
2068 arg->peer_mpdu_density =
2069 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2070
2071 arg->peer_ht_caps = ht_cap->cap;
2072 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2073
2074 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
2075 arg->peer_flags |= WMI_PEER_LDPC;
2076
2077 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
2078 arg->peer_flags |= WMI_PEER_40MHZ;
2079 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2080 }
2081
2082 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2083 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2084
2085 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2086 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2087
2088 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2089 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
2090 arg->peer_flags |= WMI_PEER_STBC;
2091 }
2092
2093 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002094 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2095 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2096 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2097 arg->peer_rate_caps |= stbc;
2098 arg->peer_flags |= WMI_PEER_STBC;
2099 }
2100
Kalle Valo5e3dd152013-06-12 20:52:10 +03002101 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2102 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2103 else if (ht_cap->mcs.rx_mask[1])
2104 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2105
2106 for (i = 0, n = 0; i < IEEE80211_HT_MCS_MASK_LEN*8; i++)
2107 if (ht_cap->mcs.rx_mask[i/8] & (1 << i%8))
2108 arg->peer_ht_rates.rates[n++] = i;
2109
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002110 /*
2111 * This is a workaround for HT-enabled STAs which break the spec
2112 * and have no HT capabilities RX mask (no HT RX MCS map).
2113 *
2114 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2115 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2116 *
2117 * Firmware asserts if such situation occurs.
2118 */
2119 if (n == 0) {
2120 arg->peer_ht_rates.num_rates = 8;
2121 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2122 arg->peer_ht_rates.rates[i] = i;
2123 } else {
2124 arg->peer_ht_rates.num_rates = n;
2125 arg->peer_num_spatial_streams = sta->rx_nss;
2126 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002127
Michal Kazior7aa7a722014-08-25 12:09:38 +02002128 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002129 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002130 arg->peer_ht_rates.num_rates,
2131 arg->peer_num_spatial_streams);
2132}
2133
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002134static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2135 struct ath10k_vif *arvif,
2136 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002137{
2138 u32 uapsd = 0;
2139 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002140 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002141
Michal Kazior548db542013-07-05 16:15:15 +03002142 lockdep_assert_held(&ar->conf_mutex);
2143
Kalle Valo5e3dd152013-06-12 20:52:10 +03002144 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002145 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002146 sta->uapsd_queues, sta->max_sp);
2147
Kalle Valo5e3dd152013-06-12 20:52:10 +03002148 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2149 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2150 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2151 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2152 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2153 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2154 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2155 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2156 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2157 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2158 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2159 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2160
Kalle Valo5e3dd152013-06-12 20:52:10 +03002161 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2162 max_sp = sta->max_sp;
2163
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002164 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2165 sta->addr,
2166 WMI_AP_PS_PEER_PARAM_UAPSD,
2167 uapsd);
2168 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002169 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002170 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002171 return ret;
2172 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002173
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002174 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2175 sta->addr,
2176 WMI_AP_PS_PEER_PARAM_MAX_SP,
2177 max_sp);
2178 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002179 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002180 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002181 return ret;
2182 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002183
2184 /* TODO setup this based on STA listen interval and
2185 beacon interval. Currently we don't know
2186 sta->listen_interval - mac80211 patch required.
2187 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002188 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002189 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2190 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002191 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002192 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002193 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002194 return ret;
2195 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002196 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002197
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002198 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002199}
2200
2201static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002202 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002203 struct ieee80211_sta *sta,
2204 struct wmi_peer_assoc_complete_arg *arg)
2205{
2206 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002207 struct cfg80211_chan_def def;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002208 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002209
Michal Kazior500ff9f2015-03-31 10:26:21 +00002210 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2211 return;
2212
Kalle Valo5e3dd152013-06-12 20:52:10 +03002213 if (!vht_cap->vht_supported)
2214 return;
2215
2216 arg->peer_flags |= WMI_PEER_VHT;
Yanbo Lid68bb122015-01-23 08:18:20 +08002217
Michal Kazior500ff9f2015-03-31 10:26:21 +00002218 if (def.chan->band == IEEE80211_BAND_2GHZ)
Yanbo Lid68bb122015-01-23 08:18:20 +08002219 arg->peer_flags |= WMI_PEER_VHT_2G;
2220
Kalle Valo5e3dd152013-06-12 20:52:10 +03002221 arg->peer_vht_caps = vht_cap->cap;
2222
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002223 ampdu_factor = (vht_cap->cap &
2224 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2225 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2226
2227 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2228 * zero in VHT IE. Using it would result in degraded throughput.
2229 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2230 * it if VHT max_mpdu is smaller. */
2231 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2232 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2233 ampdu_factor)) - 1);
2234
Kalle Valo5e3dd152013-06-12 20:52:10 +03002235 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2236 arg->peer_flags |= WMI_PEER_80MHZ;
2237
2238 arg->peer_vht_rates.rx_max_rate =
2239 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2240 arg->peer_vht_rates.rx_mcs_set =
2241 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2242 arg->peer_vht_rates.tx_max_rate =
2243 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
2244 arg->peer_vht_rates.tx_mcs_set =
2245 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
2246
Michal Kazior7aa7a722014-08-25 12:09:38 +02002247 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002248 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002249}
2250
2251static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002252 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002253 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002254 struct wmi_peer_assoc_complete_arg *arg)
2255{
Michal Kazior590922a2014-10-21 10:10:29 +03002256 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2257
Kalle Valo5e3dd152013-06-12 20:52:10 +03002258 switch (arvif->vdev_type) {
2259 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002260 if (sta->wme)
2261 arg->peer_flags |= WMI_PEER_QOS;
2262
2263 if (sta->wme && sta->uapsd_queues) {
2264 arg->peer_flags |= WMI_PEER_APSD;
2265 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2266 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002267 break;
2268 case WMI_VDEV_TYPE_STA:
Michal Kazior590922a2014-10-21 10:10:29 +03002269 if (vif->bss_conf.qos)
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002270 arg->peer_flags |= WMI_PEER_QOS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002271 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002272 case WMI_VDEV_TYPE_IBSS:
2273 if (sta->wme)
2274 arg->peer_flags |= WMI_PEER_QOS;
2275 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002276 default:
2277 break;
2278 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002279
2280 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
2281 sta->addr, !!(arg->peer_flags & WMI_PEER_QOS));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002282}
2283
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002284static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002285{
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002286 return sta->supp_rates[IEEE80211_BAND_2GHZ] >>
2287 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002288}
2289
Kalle Valo5e3dd152013-06-12 20:52:10 +03002290static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002291 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002292 struct ieee80211_sta *sta,
2293 struct wmi_peer_assoc_complete_arg *arg)
2294{
Michal Kazior500ff9f2015-03-31 10:26:21 +00002295 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002296 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2297
Michal Kazior500ff9f2015-03-31 10:26:21 +00002298 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2299 return;
2300
2301 switch (def.chan->band) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002302 case IEEE80211_BAND_2GHZ:
Yanbo Lid68bb122015-01-23 08:18:20 +08002303 if (sta->vht_cap.vht_supported) {
2304 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2305 phymode = MODE_11AC_VHT40;
2306 else
2307 phymode = MODE_11AC_VHT20;
2308 } else if (sta->ht_cap.ht_supported) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002309 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2310 phymode = MODE_11NG_HT40;
2311 else
2312 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002313 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002314 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002315 } else {
2316 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002317 }
2318
2319 break;
2320 case IEEE80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002321 /*
2322 * Check VHT first.
2323 */
2324 if (sta->vht_cap.vht_supported) {
2325 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2326 phymode = MODE_11AC_VHT80;
2327 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2328 phymode = MODE_11AC_VHT40;
2329 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2330 phymode = MODE_11AC_VHT20;
2331 } else if (sta->ht_cap.ht_supported) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002332 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2333 phymode = MODE_11NA_HT40;
2334 else
2335 phymode = MODE_11NA_HT20;
2336 } else {
2337 phymode = MODE_11A;
2338 }
2339
2340 break;
2341 default:
2342 break;
2343 }
2344
Michal Kazior7aa7a722014-08-25 12:09:38 +02002345 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002346 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002347
Kalle Valo5e3dd152013-06-12 20:52:10 +03002348 arg->peer_phymode = phymode;
2349 WARN_ON(phymode == MODE_UNKNOWN);
2350}
2351
Kalle Valob9ada652013-10-16 15:44:46 +03002352static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002353 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002354 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002355 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002356{
Michal Kazior548db542013-07-05 16:15:15 +03002357 lockdep_assert_held(&ar->conf_mutex);
2358
Kalle Valob9ada652013-10-16 15:44:46 +03002359 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002360
Michal Kazior590922a2014-10-21 10:10:29 +03002361 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
2362 ath10k_peer_assoc_h_crypto(ar, vif, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002363 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Kalle Valob9ada652013-10-16 15:44:46 +03002364 ath10k_peer_assoc_h_ht(ar, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002365 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002366 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2367 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002368
Kalle Valob9ada652013-10-16 15:44:46 +03002369 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002370}
2371
Michal Kazior90046f52014-02-14 14:45:51 +01002372static const u32 ath10k_smps_map[] = {
2373 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2374 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2375 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2376 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2377};
2378
2379static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2380 const u8 *addr,
2381 const struct ieee80211_sta_ht_cap *ht_cap)
2382{
2383 int smps;
2384
2385 if (!ht_cap->ht_supported)
2386 return 0;
2387
2388 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2389 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2390
2391 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2392 return -EINVAL;
2393
2394 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2395 WMI_PEER_SMPS_STATE,
2396 ath10k_smps_map[smps]);
2397}
2398
Michal Kazior139e1702015-02-15 16:50:42 +02002399static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2400 struct ieee80211_vif *vif,
2401 struct ieee80211_sta_vht_cap vht_cap)
2402{
2403 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2404 int ret;
2405 u32 param;
2406 u32 value;
2407
2408 if (!(ar->vht_cap_info &
2409 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2410 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2411 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2412 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2413 return 0;
2414
2415 param = ar->wmi.vdev_param->txbf;
2416 value = 0;
2417
2418 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2419 return 0;
2420
2421 /* The following logic is correct. If a remote STA advertises support
2422 * for being a beamformer then we should enable us being a beamformee.
2423 */
2424
2425 if (ar->vht_cap_info &
2426 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2427 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2428 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2429 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2430
2431 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2432 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2433 }
2434
2435 if (ar->vht_cap_info &
2436 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2437 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2438 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2439 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2440
2441 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2442 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2443 }
2444
2445 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2446 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2447
2448 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2449 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2450
2451 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2452 if (ret) {
2453 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2454 value, ret);
2455 return ret;
2456 }
2457
2458 return 0;
2459}
2460
Kalle Valo5e3dd152013-06-12 20:52:10 +03002461/* can be called only in mac80211 callbacks due to `key_count` usage */
2462static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2463 struct ieee80211_vif *vif,
2464 struct ieee80211_bss_conf *bss_conf)
2465{
2466 struct ath10k *ar = hw->priv;
2467 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002468 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002469 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002470 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002471 struct ieee80211_sta *ap_sta;
2472 int ret;
2473
Michal Kazior548db542013-07-05 16:15:15 +03002474 lockdep_assert_held(&ar->conf_mutex);
2475
Michal Kazior077efc82014-10-21 10:10:29 +03002476 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2477 arvif->vdev_id, arvif->bssid, arvif->aid);
2478
Kalle Valo5e3dd152013-06-12 20:52:10 +03002479 rcu_read_lock();
2480
2481 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2482 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002483 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002484 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002485 rcu_read_unlock();
2486 return;
2487 }
2488
Michal Kazior90046f52014-02-14 14:45:51 +01002489 /* ap_sta must be accessed only within rcu section which must be left
2490 * before calling ath10k_setup_peer_smps() which might sleep. */
2491 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002492 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002493
Michal Kazior590922a2014-10-21 10:10:29 +03002494 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002495 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002496 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002497 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002498 rcu_read_unlock();
2499 return;
2500 }
2501
2502 rcu_read_unlock();
2503
Kalle Valob9ada652013-10-16 15:44:46 +03002504 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2505 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002506 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002507 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002508 return;
2509 }
2510
Michal Kazior90046f52014-02-14 14:45:51 +01002511 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2512 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002513 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002514 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002515 return;
2516 }
2517
Michal Kazior139e1702015-02-15 16:50:42 +02002518 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2519 if (ret) {
2520 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2521 arvif->vdev_id, bss_conf->bssid, ret);
2522 return;
2523 }
2524
Michal Kazior7aa7a722014-08-25 12:09:38 +02002525 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002526 "mac vdev %d up (associated) bssid %pM aid %d\n",
2527 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2528
Michal Kazior077efc82014-10-21 10:10:29 +03002529 WARN_ON(arvif->is_up);
2530
Michal Kaziorc930f742014-01-23 11:38:25 +01002531 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002532 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002533
2534 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2535 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002536 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002537 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002538 return;
2539 }
2540
2541 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002542
2543 /* Workaround: Some firmware revisions (tested with qca6174
2544 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2545 * poked with peer param command.
2546 */
2547 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2548 WMI_PEER_DUMMY_VAR, 1);
2549 if (ret) {
2550 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2551 arvif->bssid, arvif->vdev_id, ret);
2552 return;
2553 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002554}
2555
Kalle Valo5e3dd152013-06-12 20:52:10 +03002556static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2557 struct ieee80211_vif *vif)
2558{
2559 struct ath10k *ar = hw->priv;
2560 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002561 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002562 int ret;
2563
Michal Kazior548db542013-07-05 16:15:15 +03002564 lockdep_assert_held(&ar->conf_mutex);
2565
Michal Kazior077efc82014-10-21 10:10:29 +03002566 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2567 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002568
Kalle Valo5e3dd152013-06-12 20:52:10 +03002569 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002570 if (ret)
2571 ath10k_warn(ar, "faield to down vdev %i: %d\n",
2572 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002573
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002574 arvif->def_wep_key_idx = -1;
2575
Michal Kazior139e1702015-02-15 16:50:42 +02002576 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2577 if (ret) {
2578 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2579 arvif->vdev_id, ret);
2580 return;
2581 }
2582
Michal Kaziorc930f742014-01-23 11:38:25 +01002583 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002584
2585 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002586}
2587
Michal Kazior590922a2014-10-21 10:10:29 +03002588static int ath10k_station_assoc(struct ath10k *ar,
2589 struct ieee80211_vif *vif,
2590 struct ieee80211_sta *sta,
2591 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002592{
Michal Kazior590922a2014-10-21 10:10:29 +03002593 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002594 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002595 int ret = 0;
2596
Michal Kazior548db542013-07-05 16:15:15 +03002597 lockdep_assert_held(&ar->conf_mutex);
2598
Michal Kazior590922a2014-10-21 10:10:29 +03002599 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002600 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002601 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002602 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002603 return ret;
2604 }
2605
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02002606 peer_arg.peer_reassoc = reassoc;
Kalle Valob9ada652013-10-16 15:44:46 +03002607 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2608 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002609 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002610 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002611 return ret;
2612 }
2613
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002614 /* Re-assoc is run only to update supported rates for given station. It
2615 * doesn't make much sense to reconfigure the peer completely.
2616 */
2617 if (!reassoc) {
2618 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2619 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002620 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002621 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002622 arvif->vdev_id, ret);
2623 return ret;
2624 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002625
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002626 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2627 if (ret) {
2628 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2629 sta->addr, arvif->vdev_id, ret);
2630 return ret;
2631 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002632
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002633 if (!sta->wme) {
2634 arvif->num_legacy_stations++;
2635 ret = ath10k_recalc_rtscts_prot(arvif);
2636 if (ret) {
2637 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2638 arvif->vdev_id, ret);
2639 return ret;
2640 }
2641 }
2642
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002643 /* Plumb cached keys only for static WEP */
2644 if (arvif->def_wep_key_idx != -1) {
2645 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2646 if (ret) {
2647 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2648 arvif->vdev_id, ret);
2649 return ret;
2650 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002651 }
2652 }
2653
Kalle Valo5e3dd152013-06-12 20:52:10 +03002654 return ret;
2655}
2656
Michal Kazior590922a2014-10-21 10:10:29 +03002657static int ath10k_station_disassoc(struct ath10k *ar,
2658 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002659 struct ieee80211_sta *sta)
2660{
Michal Kazior590922a2014-10-21 10:10:29 +03002661 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002662 int ret = 0;
2663
2664 lockdep_assert_held(&ar->conf_mutex);
2665
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002666 if (!sta->wme) {
2667 arvif->num_legacy_stations--;
2668 ret = ath10k_recalc_rtscts_prot(arvif);
2669 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002670 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002671 arvif->vdev_id, ret);
2672 return ret;
2673 }
2674 }
2675
Kalle Valo5e3dd152013-06-12 20:52:10 +03002676 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2677 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002678 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002679 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002680 return ret;
2681 }
2682
2683 return ret;
2684}
2685
2686/**************/
2687/* Regulatory */
2688/**************/
2689
2690static int ath10k_update_channel_list(struct ath10k *ar)
2691{
2692 struct ieee80211_hw *hw = ar->hw;
2693 struct ieee80211_supported_band **bands;
2694 enum ieee80211_band band;
2695 struct ieee80211_channel *channel;
2696 struct wmi_scan_chan_list_arg arg = {0};
2697 struct wmi_channel_arg *ch;
2698 bool passive;
2699 int len;
2700 int ret;
2701 int i;
2702
Michal Kazior548db542013-07-05 16:15:15 +03002703 lockdep_assert_held(&ar->conf_mutex);
2704
Kalle Valo5e3dd152013-06-12 20:52:10 +03002705 bands = hw->wiphy->bands;
2706 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2707 if (!bands[band])
2708 continue;
2709
2710 for (i = 0; i < bands[band]->n_channels; i++) {
2711 if (bands[band]->channels[i].flags &
2712 IEEE80211_CHAN_DISABLED)
2713 continue;
2714
2715 arg.n_channels++;
2716 }
2717 }
2718
2719 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2720 arg.channels = kzalloc(len, GFP_KERNEL);
2721 if (!arg.channels)
2722 return -ENOMEM;
2723
2724 ch = arg.channels;
2725 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2726 if (!bands[band])
2727 continue;
2728
2729 for (i = 0; i < bands[band]->n_channels; i++) {
2730 channel = &bands[band]->channels[i];
2731
2732 if (channel->flags & IEEE80211_CHAN_DISABLED)
2733 continue;
2734
2735 ch->allow_ht = true;
2736
2737 /* FIXME: when should we really allow VHT? */
2738 ch->allow_vht = true;
2739
2740 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002741 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002742
2743 ch->ht40plus =
2744 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2745
Marek Puzyniake8a50f82013-11-20 09:59:47 +02002746 ch->chan_radar =
2747 !!(channel->flags & IEEE80211_CHAN_RADAR);
2748
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002749 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002750 ch->passive = passive;
2751
2752 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02002753 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07002754 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07002755 ch->max_power = channel->max_power * 2;
2756 ch->max_reg_power = channel->max_reg_power * 2;
2757 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002758 ch->reg_class_id = 0; /* FIXME */
2759
2760 /* FIXME: why use only legacy modes, why not any
2761 * HT/VHT modes? Would that even make any
2762 * difference? */
2763 if (channel->band == IEEE80211_BAND_2GHZ)
2764 ch->mode = MODE_11G;
2765 else
2766 ch->mode = MODE_11A;
2767
2768 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
2769 continue;
2770
Michal Kazior7aa7a722014-08-25 12:09:38 +02002771 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002772 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
2773 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002774 ch->freq, ch->max_power, ch->max_reg_power,
2775 ch->max_antenna_gain, ch->mode);
2776
2777 ch++;
2778 }
2779 }
2780
2781 ret = ath10k_wmi_scan_chan_list(ar, &arg);
2782 kfree(arg.channels);
2783
2784 return ret;
2785}
2786
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002787static enum wmi_dfs_region
2788ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
2789{
2790 switch (dfs_region) {
2791 case NL80211_DFS_UNSET:
2792 return WMI_UNINIT_DFS_DOMAIN;
2793 case NL80211_DFS_FCC:
2794 return WMI_FCC_DFS_DOMAIN;
2795 case NL80211_DFS_ETSI:
2796 return WMI_ETSI_DFS_DOMAIN;
2797 case NL80211_DFS_JP:
2798 return WMI_MKK4_DFS_DOMAIN;
2799 }
2800 return WMI_UNINIT_DFS_DOMAIN;
2801}
2802
Michal Kaziorf7843d72013-07-16 09:38:52 +02002803static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002804{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002805 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002806 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002807 enum wmi_dfs_region wmi_dfs_reg;
2808 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002809
Michal Kaziorf7843d72013-07-16 09:38:52 +02002810 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002811
2812 ret = ath10k_update_channel_list(ar);
2813 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002814 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002815
2816 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002817
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002818 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
2819 nl_dfs_reg = ar->dfs_detector->region;
2820 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
2821 } else {
2822 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
2823 }
2824
Kalle Valo5e3dd152013-06-12 20:52:10 +03002825 /* Target allows setting up per-band regdomain but ath_common provides
2826 * a combined one only */
2827 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02002828 regpair->reg_domain,
2829 regpair->reg_domain, /* 2ghz */
2830 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03002831 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002832 regpair->reg_5ghz_ctl,
2833 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002834 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002835 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02002836}
Michal Kazior548db542013-07-05 16:15:15 +03002837
Michal Kaziorf7843d72013-07-16 09:38:52 +02002838static void ath10k_reg_notifier(struct wiphy *wiphy,
2839 struct regulatory_request *request)
2840{
2841 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2842 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002843 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002844
2845 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
2846
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002847 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002848 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002849 request->dfs_region);
2850 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
2851 request->dfs_region);
2852 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002853 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02002854 request->dfs_region);
2855 }
2856
Michal Kaziorf7843d72013-07-16 09:38:52 +02002857 mutex_lock(&ar->conf_mutex);
2858 if (ar->state == ATH10K_STATE_ON)
2859 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03002860 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002861}
2862
2863/***************/
2864/* TX handlers */
2865/***************/
2866
Michal Kazior96d828d2015-03-31 10:26:23 +00002867void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
2868{
2869 lockdep_assert_held(&ar->htt.tx_lock);
2870
2871 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
2872 ar->tx_paused |= BIT(reason);
2873 ieee80211_stop_queues(ar->hw);
2874}
2875
2876static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
2877 struct ieee80211_vif *vif)
2878{
2879 struct ath10k *ar = data;
2880 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2881
2882 if (arvif->tx_paused)
2883 return;
2884
2885 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
2886}
2887
2888void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
2889{
2890 lockdep_assert_held(&ar->htt.tx_lock);
2891
2892 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
2893 ar->tx_paused &= ~BIT(reason);
2894
2895 if (ar->tx_paused)
2896 return;
2897
2898 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2899 IEEE80211_IFACE_ITER_RESUME_ALL,
2900 ath10k_mac_tx_unlock_iter,
2901 ar);
2902}
2903
2904void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
2905{
2906 struct ath10k *ar = arvif->ar;
2907
2908 lockdep_assert_held(&ar->htt.tx_lock);
2909
2910 WARN_ON(reason >= BITS_PER_LONG);
2911 arvif->tx_paused |= BIT(reason);
2912 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
2913}
2914
2915void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
2916{
2917 struct ath10k *ar = arvif->ar;
2918
2919 lockdep_assert_held(&ar->htt.tx_lock);
2920
2921 WARN_ON(reason >= BITS_PER_LONG);
2922 arvif->tx_paused &= ~BIT(reason);
2923
2924 if (ar->tx_paused)
2925 return;
2926
2927 if (arvif->tx_paused)
2928 return;
2929
2930 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
2931}
2932
Michal Kaziorb4aa5392015-03-31 10:26:24 +00002933static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
2934 enum wmi_tlv_tx_pause_id pause_id,
2935 enum wmi_tlv_tx_pause_action action)
2936{
2937 struct ath10k *ar = arvif->ar;
2938
2939 lockdep_assert_held(&ar->htt.tx_lock);
2940
2941 switch (pause_id) {
2942 case WMI_TLV_TX_PAUSE_ID_MCC:
2943 case WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA:
2944 case WMI_TLV_TX_PAUSE_ID_P2P_GO_PS:
2945 case WMI_TLV_TX_PAUSE_ID_AP_PS:
2946 case WMI_TLV_TX_PAUSE_ID_IBSS_PS:
2947 switch (action) {
2948 case WMI_TLV_TX_PAUSE_ACTION_STOP:
2949 ath10k_mac_vif_tx_lock(arvif, pause_id);
2950 break;
2951 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
2952 ath10k_mac_vif_tx_unlock(arvif, pause_id);
2953 break;
2954 default:
2955 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
2956 action, arvif->vdev_id);
2957 break;
2958 }
2959 break;
2960 case WMI_TLV_TX_PAUSE_ID_AP_PEER_PS:
2961 case WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD:
2962 case WMI_TLV_TX_PAUSE_ID_STA_ADD_BA:
2963 case WMI_TLV_TX_PAUSE_ID_HOST:
2964 default:
2965 /* FIXME: Some pause_ids aren't vdev specific. Instead they
2966 * target peer_id and tid. Implementing these could improve
2967 * traffic scheduling fairness across multiple connected
2968 * stations in AP/IBSS modes.
2969 */
2970 ath10k_dbg(ar, ATH10K_DBG_MAC,
2971 "mac ignoring unsupported tx pause vdev %i id %d\n",
2972 arvif->vdev_id, pause_id);
2973 break;
2974 }
2975}
2976
2977struct ath10k_mac_tx_pause {
2978 u32 vdev_id;
2979 enum wmi_tlv_tx_pause_id pause_id;
2980 enum wmi_tlv_tx_pause_action action;
2981};
2982
2983static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
2984 struct ieee80211_vif *vif)
2985{
2986 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2987 struct ath10k_mac_tx_pause *arg = data;
2988
2989 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
2990}
2991
2992void ath10k_mac_handle_tx_pause(struct ath10k *ar, u32 vdev_id,
2993 enum wmi_tlv_tx_pause_id pause_id,
2994 enum wmi_tlv_tx_pause_action action)
2995{
2996 struct ath10k_mac_tx_pause arg = {
2997 .vdev_id = vdev_id,
2998 .pause_id = pause_id,
2999 .action = action,
3000 };
3001
3002 spin_lock_bh(&ar->htt.tx_lock);
3003 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3004 IEEE80211_IFACE_ITER_RESUME_ALL,
3005 ath10k_mac_handle_tx_pause_iter,
3006 &arg);
3007 spin_unlock_bh(&ar->htt.tx_lock);
3008}
3009
Michal Kazior42c3aa62013-10-02 11:03:38 +02003010static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
3011{
3012 if (ieee80211_is_mgmt(hdr->frame_control))
3013 return HTT_DATA_TX_EXT_TID_MGMT;
3014
3015 if (!ieee80211_is_data_qos(hdr->frame_control))
3016 return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
3017
3018 if (!is_unicast_ether_addr(ieee80211_get_DA(hdr)))
3019 return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
3020
3021 return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
3022}
3023
Michal Kazior2b37c292014-09-02 11:00:22 +03003024static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003025{
Michal Kazior2b37c292014-09-02 11:00:22 +03003026 if (vif)
3027 return ath10k_vif_to_arvif(vif)->vdev_id;
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003028
Michal Kazior1bbc0972014-04-08 09:45:47 +03003029 if (ar->monitor_started)
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003030 return ar->monitor_vdev_id;
3031
Michal Kazior7aa7a722014-08-25 12:09:38 +02003032 ath10k_warn(ar, "failed to resolve vdev id\n");
Michal Kaziorddb6ad72013-10-02 11:03:39 +02003033 return 0;
3034}
3035
Michal Kaziord740d8f2015-03-30 09:51:51 +03003036static enum ath10k_hw_txrx_mode
3037ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003038 struct ieee80211_sta *sta, struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003039{
3040 const struct ieee80211_hdr *hdr = (void *)skb->data;
3041 __le16 fc = hdr->frame_control;
3042
3043 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3044 return ATH10K_HW_TXRX_RAW;
3045
3046 if (ieee80211_is_mgmt(fc))
3047 return ATH10K_HW_TXRX_MGMT;
3048
3049 /* Workaround:
3050 *
3051 * NullFunc frames are mostly used to ping if a client or AP are still
3052 * reachable and responsive. This implies tx status reports must be
3053 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3054 * come to a conclusion that the other end disappeared and tear down
3055 * BSS connection or it can never disconnect from BSS/client (which is
3056 * the case).
3057 *
3058 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3059 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3060 * which seems to deliver correct tx reports for NullFunc frames. The
3061 * downside of using it is it ignores client powersave state so it can
3062 * end up disconnecting sleeping clients in AP mode. It should fix STA
3063 * mode though because AP don't sleep.
3064 */
3065 if (ar->htt.target_version_major < 3 &&
3066 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
3067 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, ar->fw_features))
3068 return ATH10K_HW_TXRX_MGMT;
3069
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003070 /* Workaround:
3071 *
3072 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3073 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3074 * to work with Ethernet txmode so use it.
3075 */
3076 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3077 return ATH10K_HW_TXRX_ETHERNET;
3078
Michal Kaziord740d8f2015-03-30 09:51:51 +03003079 return ATH10K_HW_TXRX_NATIVE_WIFI;
3080}
3081
Michal Kazior4b604552014-07-21 21:03:09 +03003082/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3083 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003084 */
Michal Kazior4b604552014-07-21 21:03:09 +03003085static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003086{
3087 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003088 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003089 u8 *qos_ctl;
3090
3091 if (!ieee80211_is_data_qos(hdr->frame_control))
3092 return;
3093
3094 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003095 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3096 skb->data, (void *)qos_ctl - (void *)skb->data);
3097 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003098
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003099 /* Some firmware revisions don't handle sending QoS NullFunc well.
3100 * These frames are mainly used for CQM purposes so it doesn't really
3101 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003102 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003103 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003104 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003105 cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003106
3107 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003108}
3109
Michal Kaziord740d8f2015-03-30 09:51:51 +03003110static void ath10k_tx_h_8023(struct sk_buff *skb)
3111{
3112 struct ieee80211_hdr *hdr;
3113 struct rfc1042_hdr *rfc1042;
3114 struct ethhdr *eth;
3115 size_t hdrlen;
3116 u8 da[ETH_ALEN];
3117 u8 sa[ETH_ALEN];
3118 __be16 type;
3119
3120 hdr = (void *)skb->data;
3121 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3122 rfc1042 = (void *)skb->data + hdrlen;
3123
3124 ether_addr_copy(da, ieee80211_get_DA(hdr));
3125 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3126 type = rfc1042->snap_type;
3127
3128 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3129 skb_push(skb, sizeof(*eth));
3130
3131 eth = (void *)skb->data;
3132 ether_addr_copy(eth->h_dest, da);
3133 ether_addr_copy(eth->h_source, sa);
3134 eth->h_proto = type;
3135}
3136
Michal Kazior4b604552014-07-21 21:03:09 +03003137static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3138 struct ieee80211_vif *vif,
3139 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003140{
3141 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003142 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3143
3144 /* This is case only for P2P_GO */
3145 if (arvif->vdev_type != WMI_VDEV_TYPE_AP ||
3146 arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
3147 return;
3148
3149 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3150 spin_lock_bh(&ar->data_lock);
3151 if (arvif->u.ap.noa_data)
3152 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3153 GFP_ATOMIC))
3154 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3155 arvif->u.ap.noa_data,
3156 arvif->u.ap.noa_len);
3157 spin_unlock_bh(&ar->data_lock);
3158 }
3159}
3160
Michal Kazior8d6d3622014-11-24 14:58:31 +01003161static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
3162{
3163 /* FIXME: Not really sure since when the behaviour changed. At some
3164 * point new firmware stopped requiring creation of peer entries for
3165 * offchannel tx (and actually creating them causes issues with wmi-htc
3166 * tx credit replenishment and reliability). Assuming it's at least 3.4
3167 * because that's when the `freq` was introduced to TX_FRM HTT command.
3168 */
3169 return !(ar->htt.target_version_major >= 3 &&
3170 ar->htt.target_version_minor >= 4);
3171}
3172
Michal Kaziord740d8f2015-03-30 09:51:51 +03003173static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003174{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003175 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003176 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003177
Michal Kaziord740d8f2015-03-30 09:51:51 +03003178 spin_lock_bh(&ar->data_lock);
3179
3180 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3181 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3182 ret = -ENOSPC;
3183 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003184 }
3185
Michal Kaziord740d8f2015-03-30 09:51:51 +03003186 __skb_queue_tail(q, skb);
3187 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3188
3189unlock:
3190 spin_unlock_bh(&ar->data_lock);
3191
3192 return ret;
3193}
3194
3195static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
3196{
3197 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3198 struct ath10k_htt *htt = &ar->htt;
3199 int ret = 0;
3200
3201 switch (cb->txmode) {
3202 case ATH10K_HW_TXRX_RAW:
3203 case ATH10K_HW_TXRX_NATIVE_WIFI:
3204 case ATH10K_HW_TXRX_ETHERNET:
3205 ret = ath10k_htt_tx(htt, skb);
3206 break;
3207 case ATH10K_HW_TXRX_MGMT:
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003208 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Michal Kaziord740d8f2015-03-30 09:51:51 +03003209 ar->fw_features))
3210 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3211 else if (ar->htt.target_version_major >= 3)
3212 ret = ath10k_htt_tx(htt, skb);
3213 else
3214 ret = ath10k_htt_mgmt_tx(htt, skb);
3215 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003216 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003217
3218 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003219 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3220 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003221 ieee80211_free_txskb(ar->hw, skb);
3222 }
3223}
3224
3225void ath10k_offchan_tx_purge(struct ath10k *ar)
3226{
3227 struct sk_buff *skb;
3228
3229 for (;;) {
3230 skb = skb_dequeue(&ar->offchan_tx_queue);
3231 if (!skb)
3232 break;
3233
3234 ieee80211_free_txskb(ar->hw, skb);
3235 }
3236}
3237
3238void ath10k_offchan_tx_work(struct work_struct *work)
3239{
3240 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3241 struct ath10k_peer *peer;
3242 struct ieee80211_hdr *hdr;
3243 struct sk_buff *skb;
3244 const u8 *peer_addr;
3245 int vdev_id;
3246 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003247 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003248
3249 /* FW requirement: We must create a peer before FW will send out
3250 * an offchannel frame. Otherwise the frame will be stuck and
3251 * never transmitted. We delete the peer upon tx completion.
3252 * It is unlikely that a peer for offchannel tx will already be
3253 * present. However it may be in some rare cases so account for that.
3254 * Otherwise we might remove a legitimate peer and break stuff. */
3255
3256 for (;;) {
3257 skb = skb_dequeue(&ar->offchan_tx_queue);
3258 if (!skb)
3259 break;
3260
3261 mutex_lock(&ar->conf_mutex);
3262
Michal Kazior7aa7a722014-08-25 12:09:38 +02003263 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003264 skb);
3265
3266 hdr = (struct ieee80211_hdr *)skb->data;
3267 peer_addr = ieee80211_get_DA(hdr);
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003268 vdev_id = ATH10K_SKB_CB(skb)->vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003269
3270 spin_lock_bh(&ar->data_lock);
3271 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3272 spin_unlock_bh(&ar->data_lock);
3273
3274 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003275 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003276 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003277 peer_addr, vdev_id);
3278
3279 if (!peer) {
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003280 ret = ath10k_peer_create(ar, vdev_id, peer_addr,
3281 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003282 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003283 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003284 peer_addr, vdev_id, ret);
3285 }
3286
3287 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003288 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003289 ar->offchan_tx_skb = skb;
3290 spin_unlock_bh(&ar->data_lock);
3291
Michal Kaziord740d8f2015-03-30 09:51:51 +03003292 ath10k_mac_tx(ar, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003293
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003294 time_left =
3295 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3296 if (time_left == 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003297 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003298 skb);
3299
3300 if (!peer) {
3301 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3302 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003303 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003304 peer_addr, vdev_id, ret);
3305 }
3306
3307 mutex_unlock(&ar->conf_mutex);
3308 }
3309}
3310
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003311void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3312{
3313 struct sk_buff *skb;
3314
3315 for (;;) {
3316 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3317 if (!skb)
3318 break;
3319
3320 ieee80211_free_txskb(ar->hw, skb);
3321 }
3322}
3323
3324void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3325{
3326 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3327 struct sk_buff *skb;
3328 int ret;
3329
3330 for (;;) {
3331 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3332 if (!skb)
3333 break;
3334
3335 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003336 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003337 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003338 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003339 ieee80211_free_txskb(ar->hw, skb);
3340 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003341 }
3342}
3343
Kalle Valo5e3dd152013-06-12 20:52:10 +03003344/************/
3345/* Scanning */
3346/************/
3347
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003348void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003349{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003350 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003351
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003352 switch (ar->scan.state) {
3353 case ATH10K_SCAN_IDLE:
3354 break;
3355 case ATH10K_SCAN_RUNNING:
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003356 if (ar->scan.is_roc)
3357 ieee80211_remain_on_channel_expired(ar->hw);
John W. Linvillef6eaf1e2015-01-12 16:07:02 -05003358 /* fall through */
Michal Kazior7305d3e2014-11-24 14:58:33 +01003359 case ATH10K_SCAN_ABORTING:
3360 if (!ar->scan.is_roc)
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003361 ieee80211_scan_completed(ar->hw,
3362 (ar->scan.state ==
3363 ATH10K_SCAN_ABORTING));
3364 /* fall through */
3365 case ATH10K_SCAN_STARTING:
3366 ar->scan.state = ATH10K_SCAN_IDLE;
3367 ar->scan_channel = NULL;
3368 ath10k_offchan_tx_purge(ar);
3369 cancel_delayed_work(&ar->scan.timeout);
3370 complete_all(&ar->scan.completed);
3371 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003372 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003373}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003374
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003375void ath10k_scan_finish(struct ath10k *ar)
3376{
3377 spin_lock_bh(&ar->data_lock);
3378 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003379 spin_unlock_bh(&ar->data_lock);
3380}
3381
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003382static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003383{
3384 struct wmi_stop_scan_arg arg = {
3385 .req_id = 1, /* FIXME */
3386 .req_type = WMI_SCAN_STOP_ONE,
3387 .u.scan_id = ATH10K_SCAN_ID,
3388 };
3389 int ret;
3390
3391 lockdep_assert_held(&ar->conf_mutex);
3392
Kalle Valo5e3dd152013-06-12 20:52:10 +03003393 ret = ath10k_wmi_stop_scan(ar, &arg);
3394 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003395 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003396 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003397 }
3398
Kalle Valo5e3dd152013-06-12 20:52:10 +03003399 ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003400 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003401 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003402 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003403 } else if (ret > 0) {
3404 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003405 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003406
3407out:
3408 /* Scan state should be updated upon scan completion but in case
3409 * firmware fails to deliver the event (for whatever reason) it is
3410 * desired to clean up scan state anyway. Firmware may have just
3411 * dropped the scan completion event delivery due to transport pipe
3412 * being overflown with data and/or it can recover on its own before
3413 * next scan request is submitted.
3414 */
3415 spin_lock_bh(&ar->data_lock);
3416 if (ar->scan.state != ATH10K_SCAN_IDLE)
3417 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003418 spin_unlock_bh(&ar->data_lock);
3419
3420 return ret;
3421}
3422
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003423static void ath10k_scan_abort(struct ath10k *ar)
3424{
3425 int ret;
3426
3427 lockdep_assert_held(&ar->conf_mutex);
3428
3429 spin_lock_bh(&ar->data_lock);
3430
3431 switch (ar->scan.state) {
3432 case ATH10K_SCAN_IDLE:
3433 /* This can happen if timeout worker kicked in and called
3434 * abortion while scan completion was being processed.
3435 */
3436 break;
3437 case ATH10K_SCAN_STARTING:
3438 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02003439 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003440 ath10k_scan_state_str(ar->scan.state),
3441 ar->scan.state);
3442 break;
3443 case ATH10K_SCAN_RUNNING:
3444 ar->scan.state = ATH10K_SCAN_ABORTING;
3445 spin_unlock_bh(&ar->data_lock);
3446
3447 ret = ath10k_scan_stop(ar);
3448 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003449 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003450
3451 spin_lock_bh(&ar->data_lock);
3452 break;
3453 }
3454
3455 spin_unlock_bh(&ar->data_lock);
3456}
3457
3458void ath10k_scan_timeout_work(struct work_struct *work)
3459{
3460 struct ath10k *ar = container_of(work, struct ath10k,
3461 scan.timeout.work);
3462
3463 mutex_lock(&ar->conf_mutex);
3464 ath10k_scan_abort(ar);
3465 mutex_unlock(&ar->conf_mutex);
3466}
3467
Kalle Valo5e3dd152013-06-12 20:52:10 +03003468static int ath10k_start_scan(struct ath10k *ar,
3469 const struct wmi_start_scan_arg *arg)
3470{
3471 int ret;
3472
3473 lockdep_assert_held(&ar->conf_mutex);
3474
3475 ret = ath10k_wmi_start_scan(ar, arg);
3476 if (ret)
3477 return ret;
3478
Kalle Valo5e3dd152013-06-12 20:52:10 +03003479 ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ);
3480 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003481 ret = ath10k_scan_stop(ar);
3482 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003483 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003484
3485 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003486 }
3487
Ben Greear2f9eec02015-02-15 16:50:38 +02003488 /* If we failed to start the scan, return error code at
3489 * this point. This is probably due to some issue in the
3490 * firmware, but no need to wedge the driver due to that...
3491 */
3492 spin_lock_bh(&ar->data_lock);
3493 if (ar->scan.state == ATH10K_SCAN_IDLE) {
3494 spin_unlock_bh(&ar->data_lock);
3495 return -EINVAL;
3496 }
3497 spin_unlock_bh(&ar->data_lock);
3498
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003499 /* Add a 200ms margin to account for event/command processing */
3500 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
3501 msecs_to_jiffies(arg->max_scan_time+200));
Kalle Valo5e3dd152013-06-12 20:52:10 +03003502 return 0;
3503}
3504
3505/**********************/
3506/* mac80211 callbacks */
3507/**********************/
3508
3509static void ath10k_tx(struct ieee80211_hw *hw,
3510 struct ieee80211_tx_control *control,
3511 struct sk_buff *skb)
3512{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003513 struct ath10k *ar = hw->priv;
Michal Kazior4b604552014-07-21 21:03:09 +03003514 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3515 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003516 struct ieee80211_sta *sta = control->sta;
Michal Kazior4b604552014-07-21 21:03:09 +03003517 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003518 __le16 fc = hdr->frame_control;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003519
3520 /* We should disable CCK RATE due to P2P */
3521 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003522 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003523
Michal Kazior4b604552014-07-21 21:03:09 +03003524 ATH10K_SKB_CB(skb)->htt.is_offchan = false;
Michal Kazior6fcafef2015-03-30 09:51:51 +03003525 ATH10K_SKB_CB(skb)->htt.freq = 0;
Michal Kazior4b604552014-07-21 21:03:09 +03003526 ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
Michal Kazior2b37c292014-09-02 11:00:22 +03003527 ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003528 ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003529 ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003530
Michal Kaziord740d8f2015-03-30 09:51:51 +03003531 switch (ATH10K_SKB_CB(skb)->txmode) {
3532 case ATH10K_HW_TXRX_MGMT:
3533 case ATH10K_HW_TXRX_NATIVE_WIFI:
Michal Kazior4b604552014-07-21 21:03:09 +03003534 ath10k_tx_h_nwifi(hw, skb);
Michal Kazior4b604552014-07-21 21:03:09 +03003535 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3536 ath10k_tx_h_seq_no(vif, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003537 break;
3538 case ATH10K_HW_TXRX_ETHERNET:
3539 ath10k_tx_h_8023(skb);
3540 break;
3541 case ATH10K_HW_TXRX_RAW:
3542 /* FIXME: Packet injection isn't implemented. It should be
3543 * doable with firmware 10.2 on qca988x.
3544 */
3545 WARN_ON_ONCE(1);
3546 ieee80211_free_txskb(hw, skb);
3547 return;
Michal Kaziorcf84bd42013-07-16 11:04:54 +02003548 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003549
Kalle Valo5e3dd152013-06-12 20:52:10 +03003550 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3551 spin_lock_bh(&ar->data_lock);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003552 ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003553 ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003554 spin_unlock_bh(&ar->data_lock);
3555
Michal Kazior8d6d3622014-11-24 14:58:31 +01003556 if (ath10k_mac_need_offchan_tx_work(ar)) {
3557 ATH10K_SKB_CB(skb)->htt.freq = 0;
3558 ATH10K_SKB_CB(skb)->htt.is_offchan = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003559
Michal Kazior8d6d3622014-11-24 14:58:31 +01003560 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
3561 skb);
3562
3563 skb_queue_tail(&ar->offchan_tx_queue, skb);
3564 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3565 return;
3566 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003567 }
3568
Michal Kaziord740d8f2015-03-30 09:51:51 +03003569 ath10k_mac_tx(ar, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003570}
3571
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003572/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01003573void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003574{
3575 /* make sure rcu-protected mac80211 tx path itself is drained */
3576 synchronize_net();
3577
3578 ath10k_offchan_tx_purge(ar);
3579 ath10k_mgmt_over_wmi_tx_purge(ar);
3580
3581 cancel_work_sync(&ar->offchan_tx_work);
3582 cancel_work_sync(&ar->wmi_mgmt_tx_work);
3583}
3584
Michal Kazioraffd3212013-07-16 09:54:35 +02003585void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02003586{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03003587 struct ath10k_vif *arvif;
3588
Michal Kazior818bdd12013-07-16 09:38:57 +02003589 lockdep_assert_held(&ar->conf_mutex);
3590
Michal Kazior19337472014-08-28 12:58:16 +02003591 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
3592 ar->filter_flags = 0;
3593 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00003594 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02003595
3596 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03003597 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02003598
3599 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00003600 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03003601
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003602 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02003603 ath10k_peer_cleanup_all(ar);
3604 ath10k_core_stop(ar);
3605 ath10k_hif_power_down(ar);
3606
3607 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03003608 list_for_each_entry(arvif, &ar->arvifs, list)
3609 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02003610 spin_unlock_bh(&ar->data_lock);
3611}
3612
Ben Greear46acf7b2014-05-16 17:15:38 +03003613static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
3614{
3615 struct ath10k *ar = hw->priv;
3616
3617 mutex_lock(&ar->conf_mutex);
3618
3619 if (ar->cfg_tx_chainmask) {
3620 *tx_ant = ar->cfg_tx_chainmask;
3621 *rx_ant = ar->cfg_rx_chainmask;
3622 } else {
3623 *tx_ant = ar->supp_tx_chainmask;
3624 *rx_ant = ar->supp_rx_chainmask;
3625 }
3626
3627 mutex_unlock(&ar->conf_mutex);
3628
3629 return 0;
3630}
3631
Ben Greear5572a952014-11-24 16:22:10 +02003632static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
3633{
3634 /* It is not clear that allowing gaps in chainmask
3635 * is helpful. Probably it will not do what user
3636 * is hoping for, so warn in that case.
3637 */
3638 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
3639 return;
3640
3641 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
3642 dbg, cm);
3643}
3644
Ben Greear46acf7b2014-05-16 17:15:38 +03003645static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
3646{
3647 int ret;
3648
3649 lockdep_assert_held(&ar->conf_mutex);
3650
Ben Greear5572a952014-11-24 16:22:10 +02003651 ath10k_check_chain_mask(ar, tx_ant, "tx");
3652 ath10k_check_chain_mask(ar, rx_ant, "rx");
3653
Ben Greear46acf7b2014-05-16 17:15:38 +03003654 ar->cfg_tx_chainmask = tx_ant;
3655 ar->cfg_rx_chainmask = rx_ant;
3656
3657 if ((ar->state != ATH10K_STATE_ON) &&
3658 (ar->state != ATH10K_STATE_RESTARTED))
3659 return 0;
3660
3661 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
3662 tx_ant);
3663 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003664 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03003665 ret, tx_ant);
3666 return ret;
3667 }
3668
3669 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
3670 rx_ant);
3671 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003672 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03003673 ret, rx_ant);
3674 return ret;
3675 }
3676
3677 return 0;
3678}
3679
3680static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
3681{
3682 struct ath10k *ar = hw->priv;
3683 int ret;
3684
3685 mutex_lock(&ar->conf_mutex);
3686 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
3687 mutex_unlock(&ar->conf_mutex);
3688 return ret;
3689}
3690
Kalle Valo5e3dd152013-06-12 20:52:10 +03003691static int ath10k_start(struct ieee80211_hw *hw)
3692{
3693 struct ath10k *ar = hw->priv;
Michal Kazior818bdd12013-07-16 09:38:57 +02003694 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003695
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003696 /*
3697 * This makes sense only when restarting hw. It is harmless to call
3698 * uncoditionally. This is necessary to make sure no HTT/WMI tx
3699 * commands will be submitted while restarting.
3700 */
3701 ath10k_drain_tx(ar);
3702
Michal Kazior548db542013-07-05 16:15:15 +03003703 mutex_lock(&ar->conf_mutex);
3704
Michal Kaziorc5058f52014-05-26 12:46:03 +03003705 switch (ar->state) {
3706 case ATH10K_STATE_OFF:
3707 ar->state = ATH10K_STATE_ON;
3708 break;
3709 case ATH10K_STATE_RESTARTING:
3710 ath10k_halt(ar);
3711 ar->state = ATH10K_STATE_RESTARTED;
3712 break;
3713 case ATH10K_STATE_ON:
3714 case ATH10K_STATE_RESTARTED:
3715 case ATH10K_STATE_WEDGED:
3716 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02003717 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03003718 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03003719 case ATH10K_STATE_UTF:
3720 ret = -EBUSY;
3721 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02003722 }
3723
3724 ret = ath10k_hif_power_up(ar);
3725 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003726 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003727 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02003728 }
3729
Kalle Valo43d2a302014-09-10 18:23:30 +03003730 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02003731 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003732 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003733 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02003734 }
3735
Bartosz Markowski226a3392013-09-26 17:47:16 +02003736 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03003737 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003738 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003739 goto err_core_stop;
3740 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003741
Michal Kaziorc4dd0d02013-11-13 11:05:10 +01003742 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03003743 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003744 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003745 goto err_core_stop;
3746 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003747
Michal Kaziorcf327842015-03-31 10:26:25 +00003748 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
3749 ret = ath10k_wmi_adaptive_qcs(ar, true);
3750 if (ret) {
3751 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
3752 ret);
3753 goto err_core_stop;
3754 }
3755 }
3756
Ben Greear46acf7b2014-05-16 17:15:38 +03003757 if (ar->cfg_tx_chainmask)
3758 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask,
3759 ar->cfg_rx_chainmask);
3760
Marek Puzyniakab6258e2014-01-29 15:03:31 +02003761 /*
3762 * By default FW set ARP frames ac to voice (6). In that case ARP
3763 * exchange is not working properly for UAPSD enabled AP. ARP requests
3764 * which arrives with access category 0 are processed by network stack
3765 * and send back with access category 0, but FW changes access category
3766 * to 6. Set ARP frames access category to best effort (0) solves
3767 * this problem.
3768 */
3769
3770 ret = ath10k_wmi_pdev_set_param(ar,
3771 ar->wmi.pdev_param->arp_ac_override, 0);
3772 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003773 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02003774 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03003775 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02003776 }
3777
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05303778 ret = ath10k_wmi_pdev_set_param(ar,
3779 ar->wmi.pdev_param->ani_enable, 1);
3780 if (ret) {
3781 ath10k_warn(ar, "failed to enable ani by default: %d\n",
3782 ret);
3783 goto err_core_stop;
3784 }
3785
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05303786 ar->ani_enabled = true;
3787
Michal Kaziord6500972014-04-08 09:56:09 +03003788 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003789 ath10k_regd_update(ar);
3790
Simon Wunderlich855aed12014-08-02 09:12:54 +03003791 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05303792 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03003793
Michal Kaziorae254432014-05-26 12:46:02 +03003794 mutex_unlock(&ar->conf_mutex);
3795 return 0;
3796
3797err_core_stop:
3798 ath10k_core_stop(ar);
3799
3800err_power_down:
3801 ath10k_hif_power_down(ar);
3802
3803err_off:
3804 ar->state = ATH10K_STATE_OFF;
3805
3806err:
Michal Kazior548db542013-07-05 16:15:15 +03003807 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01003808 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003809}
3810
3811static void ath10k_stop(struct ieee80211_hw *hw)
3812{
3813 struct ath10k *ar = hw->priv;
3814
Michal Kaziorbca7baf2014-05-26 12:46:03 +03003815 ath10k_drain_tx(ar);
3816
Michal Kazior548db542013-07-05 16:15:15 +03003817 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03003818 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02003819 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03003820 ar->state = ATH10K_STATE_OFF;
3821 }
Michal Kazior548db542013-07-05 16:15:15 +03003822 mutex_unlock(&ar->conf_mutex);
3823
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003824 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02003825 cancel_work_sync(&ar->restart_work);
3826}
3827
Michal Kaziorad088bf2013-10-16 15:44:46 +03003828static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02003829{
Michal Kaziorad088bf2013-10-16 15:44:46 +03003830 struct ath10k_vif *arvif;
3831 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02003832
3833 lockdep_assert_held(&ar->conf_mutex);
3834
Michal Kaziorad088bf2013-10-16 15:44:46 +03003835 list_for_each_entry(arvif, &ar->arvifs, list) {
3836 ret = ath10k_mac_vif_setup_ps(arvif);
3837 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003838 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03003839 break;
3840 }
3841 }
Michal Kazioraffd3212013-07-16 09:54:35 +02003842
Michal Kaziorad088bf2013-10-16 15:44:46 +03003843 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003844}
3845
Michal Kazior500ff9f2015-03-31 10:26:21 +00003846static void ath10k_mac_chan_reconfigure(struct ath10k *ar)
Michal Kaziorc930f742014-01-23 11:38:25 +01003847{
3848 struct ath10k_vif *arvif;
Michal Kazior500ff9f2015-03-31 10:26:21 +00003849 struct cfg80211_chan_def def;
Michal Kaziorc930f742014-01-23 11:38:25 +01003850 int ret;
3851
3852 lockdep_assert_held(&ar->conf_mutex);
3853
Michal Kazior500ff9f2015-03-31 10:26:21 +00003854 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac chan reconfigure\n");
Michal Kaziorc930f742014-01-23 11:38:25 +01003855
3856 /* First stop monitor interface. Some FW versions crash if there's a
3857 * lone monitor interface. */
Michal Kazior1bbc0972014-04-08 09:45:47 +03003858 if (ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02003859 ath10k_monitor_stop(ar);
Michal Kaziorc930f742014-01-23 11:38:25 +01003860
3861 list_for_each_entry(arvif, &ar->arvifs, list) {
3862 if (!arvif->is_started)
3863 continue;
3864
Michal Kaziordc55e302014-07-29 12:53:36 +03003865 if (!arvif->is_up)
3866 continue;
3867
Michal Kaziorc930f742014-01-23 11:38:25 +01003868 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
3869 continue;
3870
Michal Kaziordc55e302014-07-29 12:53:36 +03003871 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kaziorc930f742014-01-23 11:38:25 +01003872 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003873 ath10k_warn(ar, "failed to down vdev %d: %d\n",
Michal Kaziorc930f742014-01-23 11:38:25 +01003874 arvif->vdev_id, ret);
3875 continue;
3876 }
3877 }
3878
Michal Kaziordc55e302014-07-29 12:53:36 +03003879 /* all vdevs are downed now - attempt to restart and re-up them */
Michal Kaziorc930f742014-01-23 11:38:25 +01003880
3881 list_for_each_entry(arvif, &ar->arvifs, list) {
3882 if (!arvif->is_started)
3883 continue;
3884
3885 if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
3886 continue;
3887
Michal Kazior81a9a172015-03-05 16:02:17 +02003888 ret = ath10k_mac_setup_bcn_tmpl(arvif);
3889 if (ret)
3890 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
3891 ret);
3892
3893 ret = ath10k_mac_setup_prb_tmpl(arvif);
3894 if (ret)
3895 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
3896 ret);
3897
Michal Kazior500ff9f2015-03-31 10:26:21 +00003898 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
3899 continue;
3900
3901 ret = ath10k_vdev_restart(arvif, &def);
Michal Kaziorc930f742014-01-23 11:38:25 +01003902 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003903 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
Michal Kaziorc930f742014-01-23 11:38:25 +01003904 arvif->vdev_id, ret);
3905 continue;
3906 }
3907
3908 if (!arvif->is_up)
3909 continue;
3910
3911 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
3912 arvif->bssid);
3913 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003914 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
Michal Kaziorc930f742014-01-23 11:38:25 +01003915 arvif->vdev_id, ret);
3916 continue;
3917 }
3918 }
3919
Michal Kazior19337472014-08-28 12:58:16 +02003920 ath10k_monitor_recalc(ar);
Michal Kaziorc930f742014-01-23 11:38:25 +01003921}
3922
Michal Kazior7d9d5582014-10-21 10:40:15 +03003923static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
3924{
3925 int ret;
3926 u32 param;
3927
3928 lockdep_assert_held(&ar->conf_mutex);
3929
3930 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
3931
3932 param = ar->wmi.pdev_param->txpower_limit2g;
3933 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
3934 if (ret) {
3935 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
3936 txpower, ret);
3937 return ret;
3938 }
3939
3940 param = ar->wmi.pdev_param->txpower_limit5g;
3941 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
3942 if (ret) {
3943 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
3944 txpower, ret);
3945 return ret;
3946 }
3947
3948 return 0;
3949}
3950
3951static int ath10k_mac_txpower_recalc(struct ath10k *ar)
3952{
3953 struct ath10k_vif *arvif;
3954 int ret, txpower = -1;
3955
3956 lockdep_assert_held(&ar->conf_mutex);
3957
3958 list_for_each_entry(arvif, &ar->arvifs, list) {
3959 WARN_ON(arvif->txpower < 0);
3960
3961 if (txpower == -1)
3962 txpower = arvif->txpower;
3963 else
3964 txpower = min(txpower, arvif->txpower);
3965 }
3966
3967 if (WARN_ON(txpower == -1))
3968 return -EINVAL;
3969
3970 ret = ath10k_mac_txpower_setup(ar, txpower);
3971 if (ret) {
3972 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
3973 txpower, ret);
3974 return ret;
3975 }
3976
3977 return 0;
3978}
3979
Kalle Valo5e3dd152013-06-12 20:52:10 +03003980static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
3981{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003982 struct ath10k *ar = hw->priv;
3983 struct ieee80211_conf *conf = &hw->conf;
3984 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003985
3986 mutex_lock(&ar->conf_mutex);
3987
Michal Kazioraffd3212013-07-16 09:54:35 +02003988 if (changed & IEEE80211_CONF_CHANGE_PS)
3989 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003990
3991 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02003992 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
3993 ret = ath10k_monitor_recalc(ar);
3994 if (ret)
3995 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003996 }
3997
3998 mutex_unlock(&ar->conf_mutex);
3999 return ret;
4000}
4001
Ben Greear5572a952014-11-24 16:22:10 +02004002static u32 get_nss_from_chainmask(u16 chain_mask)
4003{
4004 if ((chain_mask & 0x15) == 0x15)
4005 return 4;
4006 else if ((chain_mask & 0x7) == 0x7)
4007 return 3;
4008 else if ((chain_mask & 0x3) == 0x3)
4009 return 2;
4010 return 1;
4011}
4012
Kalle Valo5e3dd152013-06-12 20:52:10 +03004013/*
4014 * TODO:
4015 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4016 * because we will send mgmt frames without CCK. This requirement
4017 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4018 * in the TX packet.
4019 */
4020static int ath10k_add_interface(struct ieee80211_hw *hw,
4021 struct ieee80211_vif *vif)
4022{
4023 struct ath10k *ar = hw->priv;
4024 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4025 enum wmi_sta_powersave_param param;
4026 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004027 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004028 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004029 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004030 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004031
Johannes Berg848955c2014-11-11 12:48:42 +01004032 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4033
Kalle Valo5e3dd152013-06-12 20:52:10 +03004034 mutex_lock(&ar->conf_mutex);
4035
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004036 memset(arvif, 0, sizeof(*arvif));
4037
Kalle Valo5e3dd152013-06-12 20:52:10 +03004038 arvif->ar = ar;
4039 arvif->vif = vif;
4040
Ben Greeare63b33f2013-10-22 14:54:14 -07004041 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004042 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004043 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4044 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004045
Ben Greeara9aefb32014-08-12 11:02:19 +03004046 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004047 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004048 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03004049 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004050 }
Ben Greear16c11172014-09-23 14:17:16 -07004051 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004052
Ben Greear16c11172014-09-23 14:17:16 -07004053 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4054 bit, ar->free_vdev_map);
4055
4056 arvif->vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004057 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004058
Kalle Valo5e3dd152013-06-12 20:52:10 +03004059 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004060 case NL80211_IFTYPE_P2P_DEVICE:
4061 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4062 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
4063 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004064 case NL80211_IFTYPE_UNSPECIFIED:
4065 case NL80211_IFTYPE_STATION:
4066 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4067 if (vif->p2p)
4068 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT;
4069 break;
4070 case NL80211_IFTYPE_ADHOC:
4071 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4072 break;
4073 case NL80211_IFTYPE_AP:
4074 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4075
4076 if (vif->p2p)
4077 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO;
4078 break;
4079 case NL80211_IFTYPE_MONITOR:
4080 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4081 break;
4082 default:
4083 WARN_ON(1);
4084 break;
4085 }
4086
Michal Kazior96d828d2015-03-31 10:26:23 +00004087 /* Using vdev_id as queue number will make it very easy to do per-vif
4088 * tx queue locking. This shouldn't wrap due to interface combinations
4089 * but do a modulo for correctness sake and prevent using offchannel tx
4090 * queues for regular vif tx.
4091 */
4092 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4093 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4094 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4095
Michal Kazior64badcb2014-09-18 11:18:02 +03004096 /* Some firmware revisions don't wait for beacon tx completion before
4097 * sending another SWBA event. This could lead to hardware using old
4098 * (freed) beacon data in some cases, e.g. tx credit starvation
4099 * combined with missed TBTT. This is very very rare.
4100 *
4101 * On non-IOMMU-enabled hosts this could be a possible security issue
4102 * because hw could beacon some random data on the air. On
4103 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4104 * device would crash.
4105 *
4106 * Since there are no beacon tx completions (implicit nor explicit)
4107 * propagated to host the only workaround for this is to allocate a
4108 * DMA-coherent buffer for a lifetime of a vif and use it for all
4109 * beacon tx commands. Worst case for this approach is some beacons may
4110 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4111 */
4112 if (vif->type == NL80211_IFTYPE_ADHOC ||
4113 vif->type == NL80211_IFTYPE_AP) {
4114 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4115 IEEE80211_MAX_FRAME_LEN,
4116 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304117 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004118 if (!arvif->beacon_buf) {
4119 ret = -ENOMEM;
4120 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4121 ret);
4122 goto err;
4123 }
4124 }
4125
4126 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4127 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4128 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004129
4130 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4131 arvif->vdev_subtype, vif->addr);
4132 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004133 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004134 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004135 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004136 }
4137
Ben Greear16c11172014-09-23 14:17:16 -07004138 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Michal Kazior05791192013-10-16 15:44:45 +03004139 list_add(&arvif->list, &ar->arvifs);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004140
Michal Kazior46725b152015-01-28 09:57:49 +02004141 /* It makes no sense to have firmware do keepalives. mac80211 already
4142 * takes care of this with idle connection polling.
4143 */
4144 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004145 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02004146 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004147 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004148 goto err_vdev_delete;
4149 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004150
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004151 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004152
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004153 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4154 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004155 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004156 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03004157 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004158 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004159 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004160 goto err_vdev_delete;
4161 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004162
Ben Greear5572a952014-11-24 16:22:10 +02004163 if (ar->cfg_tx_chainmask) {
4164 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
4165
4166 vdev_param = ar->wmi.vdev_param->nss;
4167 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4168 nss);
4169 if (ret) {
4170 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
4171 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
4172 ret);
4173 goto err_vdev_delete;
4174 }
4175 }
4176
Kalle Valo5e3dd152013-06-12 20:52:10 +03004177 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Marek Puzyniak7390ed32015-03-30 09:51:52 +03004178 ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr,
4179 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004180 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004181 ath10k_warn(ar, "failed to create vdev %i peer for AP: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004182 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004183 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004184 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01004185
Kalle Valo5a13e762014-01-20 11:01:46 +02004186 ret = ath10k_mac_set_kickout(arvif);
4187 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004188 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004189 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02004190 goto err_peer_delete;
4191 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004192 }
4193
4194 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
4195 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
4196 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
4197 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
4198 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004199 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004200 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004201 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004202 goto err_peer_delete;
4203 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004204
Michal Kazior9f9b5742014-12-12 12:41:36 +01004205 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004206 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004207 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004208 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004209 goto err_peer_delete;
4210 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004211
Michal Kazior9f9b5742014-12-12 12:41:36 +01004212 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004213 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004214 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004215 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004216 goto err_peer_delete;
4217 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004218 }
4219
Michal Kazior424121c2013-07-22 14:13:31 +02004220 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004221 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004222 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03004223 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004224 goto err_peer_delete;
4225 }
Michal Kazior679c54a2013-07-05 16:15:04 +03004226
Michal Kazior424121c2013-07-22 14:13:31 +02004227 ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004228 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004229 ath10k_warn(ar, "failed to set frag threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03004230 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004231 goto err_peer_delete;
4232 }
Michal Kazior679c54a2013-07-05 16:15:04 +03004233
Michal Kazior7d9d5582014-10-21 10:40:15 +03004234 arvif->txpower = vif->bss_conf.txpower;
4235 ret = ath10k_mac_txpower_recalc(ar);
4236 if (ret) {
4237 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4238 goto err_peer_delete;
4239 }
4240
Michal Kazior500ff9f2015-03-31 10:26:21 +00004241 if (vif->type == NL80211_IFTYPE_MONITOR) {
4242 ar->monitor_arvif = arvif;
4243 ret = ath10k_monitor_recalc(ar);
4244 if (ret) {
4245 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
4246 goto err_peer_delete;
4247 }
4248 }
4249
Kalle Valo5e3dd152013-06-12 20:52:10 +03004250 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004251 return 0;
4252
4253err_peer_delete:
4254 if (arvif->vdev_type == WMI_VDEV_TYPE_AP)
4255 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
4256
4257err_vdev_delete:
4258 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07004259 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004260 list_del(&arvif->list);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004261
4262err:
Michal Kazior64badcb2014-09-18 11:18:02 +03004263 if (arvif->beacon_buf) {
4264 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
4265 arvif->beacon_buf, arvif->beacon_paddr);
4266 arvif->beacon_buf = NULL;
4267 }
4268
Michal Kazior9dad14a2013-10-16 15:44:45 +03004269 mutex_unlock(&ar->conf_mutex);
4270
Kalle Valo5e3dd152013-06-12 20:52:10 +03004271 return ret;
4272}
4273
Michal Kaziorb4aa5392015-03-31 10:26:24 +00004274static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
4275{
4276 int i;
4277
4278 for (i = 0; i < BITS_PER_LONG; i++)
4279 ath10k_mac_vif_tx_unlock(arvif, i);
4280}
4281
Kalle Valo5e3dd152013-06-12 20:52:10 +03004282static void ath10k_remove_interface(struct ieee80211_hw *hw,
4283 struct ieee80211_vif *vif)
4284{
4285 struct ath10k *ar = hw->priv;
4286 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4287 int ret;
4288
Michal Kazior81a9a172015-03-05 16:02:17 +02004289 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004290 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02004291
Sujith Manoharan5d011f52014-11-25 11:47:00 +05304292 mutex_lock(&ar->conf_mutex);
4293
Michal Kaziored543882013-09-13 14:16:56 +02004294 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004295 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02004296 spin_unlock_bh(&ar->data_lock);
4297
Simon Wunderlich855aed12014-08-02 09:12:54 +03004298 ret = ath10k_spectral_vif_stop(arvif);
4299 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004300 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03004301 arvif->vdev_id, ret);
4302
Ben Greear16c11172014-09-23 14:17:16 -07004303 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004304 list_del(&arvif->list);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004305
4306 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Michal Kazior2c512052015-02-15 16:50:40 +02004307 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
4308 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004309 if (ret)
Michal Kazior2c512052015-02-15 16:50:40 +02004310 ath10k_warn(ar, "failed to submit AP self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004311 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004312
4313 kfree(arvif->u.ap.noa_data);
4314 }
4315
Michal Kazior7aa7a722014-08-25 12:09:38 +02004316 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004317 arvif->vdev_id);
4318
Kalle Valo5e3dd152013-06-12 20:52:10 +03004319 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
4320 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004321 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004322 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004323
Michal Kazior2c512052015-02-15 16:50:40 +02004324 /* Some firmware revisions don't notify host about self-peer removal
4325 * until after associated vdev is deleted.
4326 */
4327 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
4328 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
4329 vif->addr);
4330 if (ret)
4331 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
4332 arvif->vdev_id, ret);
4333
4334 spin_lock_bh(&ar->data_lock);
4335 ar->num_peers--;
4336 spin_unlock_bh(&ar->data_lock);
4337 }
4338
Kalle Valo5e3dd152013-06-12 20:52:10 +03004339 ath10k_peer_cleanup(ar, arvif->vdev_id);
4340
Michal Kazior500ff9f2015-03-31 10:26:21 +00004341 if (vif->type == NL80211_IFTYPE_MONITOR) {
4342 ar->monitor_arvif = NULL;
4343 ret = ath10k_monitor_recalc(ar);
4344 if (ret)
4345 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
4346 }
4347
Michal Kaziorb4aa5392015-03-31 10:26:24 +00004348 spin_lock_bh(&ar->htt.tx_lock);
4349 ath10k_mac_vif_tx_unlock_all(arvif);
4350 spin_unlock_bh(&ar->htt.tx_lock);
4351
Kalle Valo5e3dd152013-06-12 20:52:10 +03004352 mutex_unlock(&ar->conf_mutex);
4353}
4354
4355/*
4356 * FIXME: Has to be verified.
4357 */
4358#define SUPPORTED_FILTERS \
4359 (FIF_PROMISC_IN_BSS | \
4360 FIF_ALLMULTI | \
4361 FIF_CONTROL | \
4362 FIF_PSPOLL | \
4363 FIF_OTHER_BSS | \
4364 FIF_BCN_PRBRESP_PROMISC | \
4365 FIF_PROBE_REQ | \
4366 FIF_FCSFAIL)
4367
4368static void ath10k_configure_filter(struct ieee80211_hw *hw,
4369 unsigned int changed_flags,
4370 unsigned int *total_flags,
4371 u64 multicast)
4372{
4373 struct ath10k *ar = hw->priv;
4374 int ret;
4375
4376 mutex_lock(&ar->conf_mutex);
4377
4378 changed_flags &= SUPPORTED_FILTERS;
4379 *total_flags &= SUPPORTED_FILTERS;
4380 ar->filter_flags = *total_flags;
4381
Michal Kazior19337472014-08-28 12:58:16 +02004382 ret = ath10k_monitor_recalc(ar);
4383 if (ret)
4384 ath10k_warn(ar, "failed to recalc montior: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004385
4386 mutex_unlock(&ar->conf_mutex);
4387}
4388
4389static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
4390 struct ieee80211_vif *vif,
4391 struct ieee80211_bss_conf *info,
4392 u32 changed)
4393{
4394 struct ath10k *ar = hw->priv;
4395 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4396 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03004397 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004398
4399 mutex_lock(&ar->conf_mutex);
4400
4401 if (changed & BSS_CHANGED_IBSS)
4402 ath10k_control_ibss(arvif, info, vif->addr);
4403
4404 if (changed & BSS_CHANGED_BEACON_INT) {
4405 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004406 vdev_param = ar->wmi.vdev_param->beacon_interval;
4407 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004408 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02004409 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004410 "mac vdev %d beacon_interval %d\n",
4411 arvif->vdev_id, arvif->beacon_interval);
4412
Kalle Valo5e3dd152013-06-12 20:52:10 +03004413 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004414 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004415 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004416 }
4417
4418 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004419 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004420 "vdev %d set beacon tx mode to staggered\n",
4421 arvif->vdev_id);
4422
Bartosz Markowski226a3392013-09-26 17:47:16 +02004423 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
4424 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004425 WMI_BEACON_STAGGERED_MODE);
4426 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004427 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004428 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02004429
4430 ret = ath10k_mac_setup_bcn_tmpl(arvif);
4431 if (ret)
4432 ath10k_warn(ar, "failed to update beacon template: %d\n",
4433 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004434 }
4435
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02004436 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
4437 ret = ath10k_mac_setup_prb_tmpl(arvif);
4438 if (ret)
4439 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
4440 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004441 }
4442
Michal Kaziorba2479f2015-01-24 12:14:51 +02004443 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004444 arvif->dtim_period = info->dtim_period;
4445
Michal Kazior7aa7a722014-08-25 12:09:38 +02004446 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004447 "mac vdev %d dtim_period %d\n",
4448 arvif->vdev_id, arvif->dtim_period);
4449
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004450 vdev_param = ar->wmi.vdev_param->dtim_period;
4451 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004452 arvif->dtim_period);
4453 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004454 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004455 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004456 }
4457
4458 if (changed & BSS_CHANGED_SSID &&
4459 vif->type == NL80211_IFTYPE_AP) {
4460 arvif->u.ap.ssid_len = info->ssid_len;
4461 if (info->ssid_len)
4462 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
4463 arvif->u.ap.hidden_ssid = info->hidden_ssid;
4464 }
4465
Michal Kazior077efc82014-10-21 10:10:29 +03004466 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
4467 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004468
4469 if (changed & BSS_CHANGED_BEACON_ENABLED)
4470 ath10k_control_beaconing(arvif, info);
4471
4472 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004473 arvif->use_cts_prot = info->use_cts_prot;
Michal Kazior7aa7a722014-08-25 12:09:38 +02004474 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004475 arvif->vdev_id, info->use_cts_prot);
Kalle Valo60c3daa2013-09-08 17:56:07 +03004476
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02004477 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004478 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004479 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004480 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01004481
4482 vdev_param = ar->wmi.vdev_param->protection_mode;
4483 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4484 info->use_cts_prot ? 1 : 0);
4485 if (ret)
4486 ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
4487 info->use_cts_prot, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004488 }
4489
4490 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004491 if (info->use_short_slot)
4492 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
4493
4494 else
4495 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
4496
Michal Kazior7aa7a722014-08-25 12:09:38 +02004497 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03004498 arvif->vdev_id, slottime);
4499
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004500 vdev_param = ar->wmi.vdev_param->slot_time;
4501 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004502 slottime);
4503 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004504 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004505 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004506 }
4507
4508 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03004509 if (info->use_short_preamble)
4510 preamble = WMI_VDEV_PREAMBLE_SHORT;
4511 else
4512 preamble = WMI_VDEV_PREAMBLE_LONG;
4513
Michal Kazior7aa7a722014-08-25 12:09:38 +02004514 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03004515 "mac vdev %d preamble %dn",
4516 arvif->vdev_id, preamble);
4517
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004518 vdev_param = ar->wmi.vdev_param->preamble;
4519 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004520 preamble);
4521 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004522 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02004523 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004524 }
4525
4526 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02004527 if (info->assoc) {
4528 /* Workaround: Make sure monitor vdev is not running
4529 * when associating to prevent some firmware revisions
4530 * (e.g. 10.1 and 10.2) from crashing.
4531 */
4532 if (ar->monitor_started)
4533 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004534 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02004535 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03004536 } else {
4537 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02004538 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004539 }
4540
Michal Kazior7d9d5582014-10-21 10:40:15 +03004541 if (changed & BSS_CHANGED_TXPOWER) {
4542 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
4543 arvif->vdev_id, info->txpower);
4544
4545 arvif->txpower = info->txpower;
4546 ret = ath10k_mac_txpower_recalc(ar);
4547 if (ret)
4548 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4549 }
4550
Michal Kaziorbf14e652014-12-12 12:41:38 +01004551 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01004552 arvif->ps = vif->bss_conf.ps;
4553
4554 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01004555 if (ret)
4556 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
4557 arvif->vdev_id, ret);
4558 }
4559
Kalle Valo5e3dd152013-06-12 20:52:10 +03004560 mutex_unlock(&ar->conf_mutex);
4561}
4562
4563static int ath10k_hw_scan(struct ieee80211_hw *hw,
4564 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02004565 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004566{
4567 struct ath10k *ar = hw->priv;
4568 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02004569 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004570 struct wmi_start_scan_arg arg;
4571 int ret = 0;
4572 int i;
4573
4574 mutex_lock(&ar->conf_mutex);
4575
4576 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004577 switch (ar->scan.state) {
4578 case ATH10K_SCAN_IDLE:
4579 reinit_completion(&ar->scan.started);
4580 reinit_completion(&ar->scan.completed);
4581 ar->scan.state = ATH10K_SCAN_STARTING;
4582 ar->scan.is_roc = false;
4583 ar->scan.vdev_id = arvif->vdev_id;
4584 ret = 0;
4585 break;
4586 case ATH10K_SCAN_STARTING:
4587 case ATH10K_SCAN_RUNNING:
4588 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03004589 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004590 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004591 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004592 spin_unlock_bh(&ar->data_lock);
4593
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004594 if (ret)
4595 goto exit;
4596
Kalle Valo5e3dd152013-06-12 20:52:10 +03004597 memset(&arg, 0, sizeof(arg));
4598 ath10k_wmi_start_scan_init(ar, &arg);
4599 arg.vdev_id = arvif->vdev_id;
4600 arg.scan_id = ATH10K_SCAN_ID;
4601
4602 if (!req->no_cck)
4603 arg.scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES;
4604
4605 if (req->ie_len) {
4606 arg.ie_len = req->ie_len;
4607 memcpy(arg.ie, req->ie, arg.ie_len);
4608 }
4609
4610 if (req->n_ssids) {
4611 arg.n_ssids = req->n_ssids;
4612 for (i = 0; i < arg.n_ssids; i++) {
4613 arg.ssids[i].len = req->ssids[i].ssid_len;
4614 arg.ssids[i].ssid = req->ssids[i].ssid;
4615 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02004616 } else {
4617 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004618 }
4619
4620 if (req->n_channels) {
4621 arg.n_channels = req->n_channels;
4622 for (i = 0; i < arg.n_channels; i++)
4623 arg.channels[i] = req->channels[i]->center_freq;
4624 }
4625
4626 ret = ath10k_start_scan(ar, &arg);
4627 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004628 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004629 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004630 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004631 spin_unlock_bh(&ar->data_lock);
4632 }
4633
4634exit:
4635 mutex_unlock(&ar->conf_mutex);
4636 return ret;
4637}
4638
4639static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
4640 struct ieee80211_vif *vif)
4641{
4642 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004643
4644 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004645 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004646 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01004647
4648 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004649}
4650
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004651static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
4652 struct ath10k_vif *arvif,
4653 enum set_key_cmd cmd,
4654 struct ieee80211_key_conf *key)
4655{
4656 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
4657 int ret;
4658
4659 /* 10.1 firmware branch requires default key index to be set to group
4660 * key index after installing it. Otherwise FW/HW Txes corrupted
4661 * frames with multi-vif APs. This is not required for main firmware
4662 * branch (e.g. 636).
4663 *
4664 * FIXME: This has been tested only in AP. It remains unknown if this
4665 * is required for multi-vif STA interfaces on 10.1 */
4666
4667 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
4668 return;
4669
4670 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
4671 return;
4672
4673 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
4674 return;
4675
4676 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
4677 return;
4678
4679 if (cmd != SET_KEY)
4680 return;
4681
4682 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4683 key->keyidx);
4684 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004685 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004686 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004687}
4688
Kalle Valo5e3dd152013-06-12 20:52:10 +03004689static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
4690 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
4691 struct ieee80211_key_conf *key)
4692{
4693 struct ath10k *ar = hw->priv;
4694 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4695 struct ath10k_peer *peer;
4696 const u8 *peer_addr;
4697 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
4698 key->cipher == WLAN_CIPHER_SUITE_WEP104;
4699 int ret = 0;
Michal Kazior370e5672015-02-18 14:02:26 +01004700 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004701
Bartosz Markowskid7131c02015-03-10 14:32:19 +01004702 /* this one needs to be done in software */
4703 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
4704 return 1;
4705
Kalle Valo5e3dd152013-06-12 20:52:10 +03004706 if (key->keyidx > WMI_MAX_KEY_INDEX)
4707 return -ENOSPC;
4708
4709 mutex_lock(&ar->conf_mutex);
4710
4711 if (sta)
4712 peer_addr = sta->addr;
4713 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
4714 peer_addr = vif->bss_conf.bssid;
4715 else
4716 peer_addr = vif->addr;
4717
4718 key->hw_key_idx = key->keyidx;
4719
4720 /* the peer should not disappear in mid-way (unless FW goes awry) since
4721 * we already hold conf_mutex. we just make sure its there now. */
4722 spin_lock_bh(&ar->data_lock);
4723 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
4724 spin_unlock_bh(&ar->data_lock);
4725
4726 if (!peer) {
4727 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004728 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03004729 peer_addr);
4730 ret = -EOPNOTSUPP;
4731 goto exit;
4732 } else {
4733 /* if the peer doesn't exist there is no key to disable
4734 * anymore */
4735 goto exit;
4736 }
4737 }
4738
Michal Kazior7cc45732015-03-09 14:24:17 +01004739 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
4740 flags |= WMI_KEY_PAIRWISE;
4741 else
4742 flags |= WMI_KEY_GROUP;
4743
Kalle Valo5e3dd152013-06-12 20:52:10 +03004744 if (is_wep) {
4745 if (cmd == SET_KEY)
4746 arvif->wep_keys[key->keyidx] = key;
4747 else
4748 arvif->wep_keys[key->keyidx] = NULL;
4749
4750 if (cmd == DISABLE_KEY)
4751 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01004752
Michal Kaziorad325cb2015-02-18 14:02:27 +01004753 /* When WEP keys are uploaded it's possible that there are
4754 * stations associated already (e.g. when merging) without any
4755 * keys. Static WEP needs an explicit per-peer key upload.
4756 */
4757 if (vif->type == NL80211_IFTYPE_ADHOC &&
4758 cmd == SET_KEY)
4759 ath10k_mac_vif_update_wep_key(arvif, key);
4760
Michal Kazior370e5672015-02-18 14:02:26 +01004761 /* 802.1x never sets the def_wep_key_idx so each set_key()
4762 * call changes default tx key.
4763 *
4764 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
4765 * after first set_key().
4766 */
4767 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
4768 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004769
Michal Kazior7cc45732015-03-09 14:24:17 +01004770 /* mac80211 uploads static WEP keys as groupwise while fw/hw
4771 * requires pairwise keys for non-self peers, i.e. BSSID in STA
4772 * mode and associated stations in AP/IBSS.
4773 *
4774 * Static WEP keys for peer_addr=vif->addr and 802.1X WEP keys
4775 * work fine when mapped directly from mac80211.
4776 *
4777 * Note: When installing first static WEP groupwise key (which
4778 * should be pairwise) def_wep_key_idx isn't known yet (it's
4779 * equal to -1). Since .set_default_unicast_key is called only
4780 * for static WEP it's used to re-upload the key as pairwise.
4781 */
4782 if (arvif->def_wep_key_idx >= 0 &&
4783 memcmp(peer_addr, arvif->vif->addr, ETH_ALEN)) {
4784 flags &= ~WMI_KEY_GROUP;
4785 flags |= WMI_KEY_PAIRWISE;
4786 }
Michal Kazior370e5672015-02-18 14:02:26 +01004787 }
4788
4789 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004790 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004791 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004792 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004793 goto exit;
4794 }
4795
Michal Kaziorcfb27d22013-12-02 09:06:36 +01004796 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
4797
Kalle Valo5e3dd152013-06-12 20:52:10 +03004798 spin_lock_bh(&ar->data_lock);
4799 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
4800 if (peer && cmd == SET_KEY)
4801 peer->keys[key->keyidx] = key;
4802 else if (peer && cmd == DISABLE_KEY)
4803 peer->keys[key->keyidx] = NULL;
4804 else if (peer == NULL)
4805 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02004806 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004807 spin_unlock_bh(&ar->data_lock);
4808
4809exit:
4810 mutex_unlock(&ar->conf_mutex);
4811 return ret;
4812}
4813
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004814static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
4815 struct ieee80211_vif *vif,
4816 int keyidx)
4817{
4818 struct ath10k *ar = hw->priv;
4819 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4820 int ret;
4821
4822 mutex_lock(&arvif->ar->conf_mutex);
4823
4824 if (arvif->ar->state != ATH10K_STATE_ON)
4825 goto unlock;
4826
4827 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
4828 arvif->vdev_id, keyidx);
4829
4830 ret = ath10k_wmi_vdev_set_param(arvif->ar,
4831 arvif->vdev_id,
4832 arvif->ar->wmi.vdev_param->def_keyid,
4833 keyidx);
4834
4835 if (ret) {
4836 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
4837 arvif->vdev_id,
4838 ret);
4839 goto unlock;
4840 }
4841
4842 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01004843
4844 ret = ath10k_mac_vif_sta_fix_wep_key(arvif);
4845 if (ret) {
4846 ath10k_warn(ar, "failed to fix sta wep key on vdev %i: %d\n",
4847 arvif->vdev_id, ret);
4848 goto unlock;
4849 }
4850
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004851unlock:
4852 mutex_unlock(&arvif->ar->conf_mutex);
4853}
4854
Michal Kazior9797feb2014-02-14 14:49:48 +01004855static void ath10k_sta_rc_update_wk(struct work_struct *wk)
4856{
4857 struct ath10k *ar;
4858 struct ath10k_vif *arvif;
4859 struct ath10k_sta *arsta;
4860 struct ieee80211_sta *sta;
4861 u32 changed, bw, nss, smps;
4862 int err;
4863
4864 arsta = container_of(wk, struct ath10k_sta, update_wk);
4865 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
4866 arvif = arsta->arvif;
4867 ar = arvif->ar;
4868
4869 spin_lock_bh(&ar->data_lock);
4870
4871 changed = arsta->changed;
4872 arsta->changed = 0;
4873
4874 bw = arsta->bw;
4875 nss = arsta->nss;
4876 smps = arsta->smps;
4877
4878 spin_unlock_bh(&ar->data_lock);
4879
4880 mutex_lock(&ar->conf_mutex);
4881
4882 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004883 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004884 sta->addr, bw);
4885
4886 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
4887 WMI_PEER_CHAN_WIDTH, bw);
4888 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004889 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004890 sta->addr, bw, err);
4891 }
4892
4893 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004894 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004895 sta->addr, nss);
4896
4897 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
4898 WMI_PEER_NSS, nss);
4899 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004900 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004901 sta->addr, nss, err);
4902 }
4903
4904 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004905 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004906 sta->addr, smps);
4907
4908 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
4909 WMI_PEER_SMPS_STATE, smps);
4910 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004911 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01004912 sta->addr, smps, err);
4913 }
4914
Janusz Dziedzic55884c02014-12-17 12:30:02 +02004915 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
4916 changed & IEEE80211_RC_NSS_CHANGED) {
4917 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02004918 sta->addr);
4919
Michal Kazior590922a2014-10-21 10:10:29 +03004920 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02004921 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004922 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02004923 sta->addr);
4924 }
4925
Michal Kazior9797feb2014-02-14 14:49:48 +01004926 mutex_unlock(&ar->conf_mutex);
4927}
4928
Marek Puzyniak7c354242015-03-30 09:51:52 +03004929static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
4930 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004931{
4932 struct ath10k *ar = arvif->ar;
4933
4934 lockdep_assert_held(&ar->conf_mutex);
4935
Marek Puzyniak7c354242015-03-30 09:51:52 +03004936 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004937 return 0;
4938
4939 if (ar->num_stations >= ar->max_num_stations)
4940 return -ENOBUFS;
4941
4942 ar->num_stations++;
4943
4944 return 0;
4945}
4946
Marek Puzyniak7c354242015-03-30 09:51:52 +03004947static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
4948 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004949{
4950 struct ath10k *ar = arvif->ar;
4951
4952 lockdep_assert_held(&ar->conf_mutex);
4953
Marek Puzyniak7c354242015-03-30 09:51:52 +03004954 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01004955 return;
4956
4957 ar->num_stations--;
4958}
4959
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004960struct ath10k_mac_tdls_iter_data {
4961 u32 num_tdls_stations;
4962 struct ieee80211_vif *curr_vif;
4963};
4964
4965static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
4966 struct ieee80211_sta *sta)
4967{
4968 struct ath10k_mac_tdls_iter_data *iter_data = data;
4969 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
4970 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
4971
4972 if (sta->tdls && sta_vif == iter_data->curr_vif)
4973 iter_data->num_tdls_stations++;
4974}
4975
4976static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
4977 struct ieee80211_vif *vif)
4978{
4979 struct ath10k_mac_tdls_iter_data data = {};
4980
4981 data.curr_vif = vif;
4982
4983 ieee80211_iterate_stations_atomic(hw,
4984 ath10k_mac_tdls_vif_stations_count_iter,
4985 &data);
4986 return data.num_tdls_stations;
4987}
4988
4989static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
4990 struct ieee80211_vif *vif)
4991{
4992 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4993 int *num_tdls_vifs = data;
4994
4995 if (vif->type != NL80211_IFTYPE_STATION)
4996 return;
4997
4998 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
4999 (*num_tdls_vifs)++;
5000}
5001
5002static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5003{
5004 int num_tdls_vifs = 0;
5005
5006 ieee80211_iterate_active_interfaces_atomic(hw,
5007 IEEE80211_IFACE_ITER_NORMAL,
5008 ath10k_mac_tdls_vifs_count_iter,
5009 &num_tdls_vifs);
5010 return num_tdls_vifs;
5011}
5012
Kalle Valo5e3dd152013-06-12 20:52:10 +03005013static int ath10k_sta_state(struct ieee80211_hw *hw,
5014 struct ieee80211_vif *vif,
5015 struct ieee80211_sta *sta,
5016 enum ieee80211_sta_state old_state,
5017 enum ieee80211_sta_state new_state)
5018{
5019 struct ath10k *ar = hw->priv;
5020 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005021 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005022 int ret = 0;
5023
Michal Kazior76f90022014-02-25 09:29:57 +02005024 if (old_state == IEEE80211_STA_NOTEXIST &&
5025 new_state == IEEE80211_STA_NONE) {
5026 memset(arsta, 0, sizeof(*arsta));
5027 arsta->arvif = arvif;
5028 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
5029 }
5030
Michal Kazior9797feb2014-02-14 14:49:48 +01005031 /* cancel must be done outside the mutex to avoid deadlock */
5032 if ((old_state == IEEE80211_STA_NONE &&
5033 new_state == IEEE80211_STA_NOTEXIST))
5034 cancel_work_sync(&arsta->update_wk);
5035
Kalle Valo5e3dd152013-06-12 20:52:10 +03005036 mutex_lock(&ar->conf_mutex);
5037
5038 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005039 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005040 /*
5041 * New station addition.
5042 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005043 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5044 u32 num_tdls_stations;
5045 u32 num_tdls_vifs;
5046
Michal Kaziorcfd10612014-11-25 15:16:05 +01005047 ath10k_dbg(ar, ATH10K_DBG_MAC,
5048 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5049 arvif->vdev_id, sta->addr,
5050 ar->num_stations + 1, ar->max_num_stations,
5051 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005052
Marek Puzyniak7c354242015-03-30 09:51:52 +03005053 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005054 if (ret) {
5055 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5056 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005057 goto exit;
5058 }
5059
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005060 if (sta->tdls)
5061 peer_type = WMI_PEER_TYPE_TDLS;
5062
Marek Puzyniak7390ed32015-03-30 09:51:52 +03005063 ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr,
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005064 peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005065 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005066 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 -08005067 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005068 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005069 goto exit;
5070 }
Michal Kazior077efc82014-10-21 10:10:29 +03005071
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005072 if (!sta->tdls)
5073 goto exit;
5074
5075 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
5076 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
5077
5078 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
5079 num_tdls_stations == 0) {
5080 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
5081 arvif->vdev_id, ar->max_num_tdls_vdevs);
5082 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5083 ath10k_mac_dec_num_stations(arvif, sta);
5084 ret = -ENOBUFS;
5085 goto exit;
5086 }
5087
5088 if (num_tdls_stations == 0) {
5089 /* This is the first tdls peer in current vif */
5090 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
5091
5092 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5093 state);
5094 if (ret) {
5095 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
5096 arvif->vdev_id, ret);
5097 ath10k_peer_delete(ar, arvif->vdev_id,
5098 sta->addr);
5099 ath10k_mac_dec_num_stations(arvif, sta);
5100 goto exit;
5101 }
5102 }
5103
5104 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5105 WMI_TDLS_PEER_STATE_PEERING);
5106 if (ret) {
5107 ath10k_warn(ar,
5108 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
5109 sta->addr, arvif->vdev_id, ret);
5110 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5111 ath10k_mac_dec_num_stations(arvif, sta);
5112
5113 if (num_tdls_stations != 0)
5114 goto exit;
5115 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5116 WMI_TDLS_DISABLE);
5117 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005118 } else if ((old_state == IEEE80211_STA_NONE &&
5119 new_state == IEEE80211_STA_NOTEXIST)) {
5120 /*
5121 * Existing station deletion.
5122 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005123 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005124 "mac vdev %d peer delete %pM (sta gone)\n",
5125 arvif->vdev_id, sta->addr);
Michal Kazior077efc82014-10-21 10:10:29 +03005126
Kalle Valo5e3dd152013-06-12 20:52:10 +03005127 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5128 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005129 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005130 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005131
Marek Puzyniak7c354242015-03-30 09:51:52 +03005132 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005133
5134 if (!sta->tdls)
5135 goto exit;
5136
5137 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
5138 goto exit;
5139
5140 /* This was the last tdls peer in current vif */
5141 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5142 WMI_TDLS_DISABLE);
5143 if (ret) {
5144 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
5145 arvif->vdev_id, ret);
5146 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005147 } else if (old_state == IEEE80211_STA_AUTH &&
5148 new_state == IEEE80211_STA_ASSOC &&
5149 (vif->type == NL80211_IFTYPE_AP ||
5150 vif->type == NL80211_IFTYPE_ADHOC)) {
5151 /*
5152 * New association.
5153 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005154 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005155 sta->addr);
5156
Michal Kazior590922a2014-10-21 10:10:29 +03005157 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005158 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005159 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005160 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005161 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005162 new_state == IEEE80211_STA_AUTHORIZED &&
5163 sta->tdls) {
5164 /*
5165 * Tdls station authorized.
5166 */
5167 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
5168 sta->addr);
5169
5170 ret = ath10k_station_assoc(ar, vif, sta, false);
5171 if (ret) {
5172 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
5173 sta->addr, arvif->vdev_id, ret);
5174 goto exit;
5175 }
5176
5177 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5178 WMI_TDLS_PEER_STATE_CONNECTED);
5179 if (ret)
5180 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
5181 sta->addr, arvif->vdev_id, ret);
5182 } else if (old_state == IEEE80211_STA_ASSOC &&
5183 new_state == IEEE80211_STA_AUTH &&
5184 (vif->type == NL80211_IFTYPE_AP ||
5185 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005186 /*
5187 * Disassociation.
5188 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005189 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005190 sta->addr);
5191
Michal Kazior590922a2014-10-21 10:10:29 +03005192 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005193 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005194 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005195 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005196 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005197exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005198 mutex_unlock(&ar->conf_mutex);
5199 return ret;
5200}
5201
5202static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03005203 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005204{
5205 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02005206 struct wmi_sta_uapsd_auto_trig_arg arg = {};
5207 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005208 u32 value = 0;
5209 int ret = 0;
5210
Michal Kazior548db542013-07-05 16:15:15 +03005211 lockdep_assert_held(&ar->conf_mutex);
5212
Kalle Valo5e3dd152013-06-12 20:52:10 +03005213 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
5214 return 0;
5215
5216 switch (ac) {
5217 case IEEE80211_AC_VO:
5218 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
5219 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005220 prio = 7;
5221 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005222 break;
5223 case IEEE80211_AC_VI:
5224 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
5225 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005226 prio = 5;
5227 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005228 break;
5229 case IEEE80211_AC_BE:
5230 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
5231 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005232 prio = 2;
5233 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005234 break;
5235 case IEEE80211_AC_BK:
5236 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
5237 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02005238 prio = 0;
5239 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005240 break;
5241 }
5242
5243 if (enable)
5244 arvif->u.sta.uapsd |= value;
5245 else
5246 arvif->u.sta.uapsd &= ~value;
5247
5248 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5249 WMI_STA_PS_PARAM_UAPSD,
5250 arvif->u.sta.uapsd);
5251 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005252 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005253 goto exit;
5254 }
5255
5256 if (arvif->u.sta.uapsd)
5257 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
5258 else
5259 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5260
5261 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5262 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
5263 value);
5264 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005265 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005266
Michal Kazior9f9b5742014-12-12 12:41:36 +01005267 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
5268 if (ret) {
5269 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
5270 arvif->vdev_id, ret);
5271 return ret;
5272 }
5273
5274 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
5275 if (ret) {
5276 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
5277 arvif->vdev_id, ret);
5278 return ret;
5279 }
5280
Michal Kaziorb0e56152015-01-24 12:14:52 +02005281 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
5282 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
5283 /* Only userspace can make an educated decision when to send
5284 * trigger frame. The following effectively disables u-UAPSD
5285 * autotrigger in firmware (which is enabled by default
5286 * provided the autotrigger service is available).
5287 */
5288
5289 arg.wmm_ac = acc;
5290 arg.user_priority = prio;
5291 arg.service_interval = 0;
5292 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
5293 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
5294
5295 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
5296 arvif->bssid, &arg, 1);
5297 if (ret) {
5298 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
5299 ret);
5300 return ret;
5301 }
5302 }
5303
Kalle Valo5e3dd152013-06-12 20:52:10 +03005304exit:
5305 return ret;
5306}
5307
5308static int ath10k_conf_tx(struct ieee80211_hw *hw,
5309 struct ieee80211_vif *vif, u16 ac,
5310 const struct ieee80211_tx_queue_params *params)
5311{
5312 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01005313 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005314 struct wmi_wmm_params_arg *p = NULL;
5315 int ret;
5316
5317 mutex_lock(&ar->conf_mutex);
5318
5319 switch (ac) {
5320 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01005321 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005322 break;
5323 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01005324 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005325 break;
5326 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01005327 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005328 break;
5329 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01005330 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005331 break;
5332 }
5333
5334 if (WARN_ON(!p)) {
5335 ret = -EINVAL;
5336 goto exit;
5337 }
5338
5339 p->cwmin = params->cw_min;
5340 p->cwmax = params->cw_max;
5341 p->aifs = params->aifs;
5342
5343 /*
5344 * The channel time duration programmed in the HW is in absolute
5345 * microseconds, while mac80211 gives the txop in units of
5346 * 32 microseconds.
5347 */
5348 p->txop = params->txop * 32;
5349
Michal Kazior7fc979a2015-01-28 09:57:28 +02005350 if (ar->wmi.ops->gen_vdev_wmm_conf) {
5351 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
5352 &arvif->wmm_params);
5353 if (ret) {
5354 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
5355 arvif->vdev_id, ret);
5356 goto exit;
5357 }
5358 } else {
5359 /* This won't work well with multi-interface cases but it's
5360 * better than nothing.
5361 */
5362 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
5363 if (ret) {
5364 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
5365 goto exit;
5366 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005367 }
5368
5369 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
5370 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005371 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005372
5373exit:
5374 mutex_unlock(&ar->conf_mutex);
5375 return ret;
5376}
5377
5378#define ATH10K_ROC_TIMEOUT_HZ (2*HZ)
5379
5380static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
5381 struct ieee80211_vif *vif,
5382 struct ieee80211_channel *chan,
5383 int duration,
5384 enum ieee80211_roc_type type)
5385{
5386 struct ath10k *ar = hw->priv;
5387 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5388 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005389 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005390
5391 mutex_lock(&ar->conf_mutex);
5392
5393 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005394 switch (ar->scan.state) {
5395 case ATH10K_SCAN_IDLE:
5396 reinit_completion(&ar->scan.started);
5397 reinit_completion(&ar->scan.completed);
5398 reinit_completion(&ar->scan.on_channel);
5399 ar->scan.state = ATH10K_SCAN_STARTING;
5400 ar->scan.is_roc = true;
5401 ar->scan.vdev_id = arvif->vdev_id;
5402 ar->scan.roc_freq = chan->center_freq;
5403 ret = 0;
5404 break;
5405 case ATH10K_SCAN_STARTING:
5406 case ATH10K_SCAN_RUNNING:
5407 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005408 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005409 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005410 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005411 spin_unlock_bh(&ar->data_lock);
5412
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005413 if (ret)
5414 goto exit;
5415
Michal Kaziordcca0bd2014-11-24 14:58:32 +01005416 duration = max(duration, WMI_SCAN_CHAN_MIN_TIME_MSEC);
5417
Kalle Valo5e3dd152013-06-12 20:52:10 +03005418 memset(&arg, 0, sizeof(arg));
5419 ath10k_wmi_start_scan_init(ar, &arg);
5420 arg.vdev_id = arvif->vdev_id;
5421 arg.scan_id = ATH10K_SCAN_ID;
5422 arg.n_channels = 1;
5423 arg.channels[0] = chan->center_freq;
5424 arg.dwell_time_active = duration;
5425 arg.dwell_time_passive = duration;
5426 arg.max_scan_time = 2 * duration;
5427 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
5428 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
5429
5430 ret = ath10k_start_scan(ar, &arg);
5431 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005432 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005433 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005434 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005435 spin_unlock_bh(&ar->data_lock);
5436 goto exit;
5437 }
5438
5439 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ);
5440 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005441 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005442
5443 ret = ath10k_scan_stop(ar);
5444 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005445 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005446
Kalle Valo5e3dd152013-06-12 20:52:10 +03005447 ret = -ETIMEDOUT;
5448 goto exit;
5449 }
5450
5451 ret = 0;
5452exit:
5453 mutex_unlock(&ar->conf_mutex);
5454 return ret;
5455}
5456
5457static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
5458{
5459 struct ath10k *ar = hw->priv;
5460
5461 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005462 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005463 mutex_unlock(&ar->conf_mutex);
5464
Michal Kazior4eb2e162014-10-28 10:23:09 +01005465 cancel_delayed_work_sync(&ar->scan.timeout);
5466
Kalle Valo5e3dd152013-06-12 20:52:10 +03005467 return 0;
5468}
5469
5470/*
5471 * Both RTS and Fragmentation threshold are interface-specific
5472 * in ath10k, but device-specific in mac80211.
5473 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03005474
5475static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
5476{
Kalle Valo5e3dd152013-06-12 20:52:10 +03005477 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03005478 struct ath10k_vif *arvif;
5479 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03005480
Michal Kaziorad088bf2013-10-16 15:44:46 +03005481 mutex_lock(&ar->conf_mutex);
5482 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005483 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03005484 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03005485
Michal Kaziorad088bf2013-10-16 15:44:46 +03005486 ret = ath10k_mac_set_rts(arvif, value);
5487 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005488 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03005489 arvif->vdev_id, ret);
5490 break;
5491 }
5492 }
5493 mutex_unlock(&ar->conf_mutex);
5494
5495 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005496}
5497
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02005498static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5499 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005500{
5501 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02005502 bool skip;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005503 int ret;
5504
5505 /* mac80211 doesn't care if we really xmit queued frames or not
5506 * we'll collect those frames either way if we stop/delete vdevs */
5507 if (drop)
5508 return;
5509
Michal Kazior548db542013-07-05 16:15:15 +03005510 mutex_lock(&ar->conf_mutex);
5511
Michal Kazioraffd3212013-07-16 09:54:35 +02005512 if (ar->state == ATH10K_STATE_WEDGED)
5513 goto skip;
5514
Michal Kazioredb82362013-07-05 16:15:14 +03005515 ret = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03005516 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02005517
Michal Kazioredb82362013-07-05 16:15:14 +03005518 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02005519 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03005520 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02005521
Michal Kazior7962b0d2014-10-28 10:34:38 +01005522 skip = (ar->state == ATH10K_STATE_WEDGED) ||
5523 test_bit(ATH10K_FLAG_CRASH_FLUSH,
5524 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02005525
5526 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005527 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02005528
5529 if (ret <= 0 || skip)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005530 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %i\n",
Ben Greear9ba4c782014-02-25 09:29:57 +02005531 skip, ar->state, ret);
Michal Kazior548db542013-07-05 16:15:15 +03005532
Michal Kazioraffd3212013-07-16 09:54:35 +02005533skip:
Michal Kazior548db542013-07-05 16:15:15 +03005534 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005535}
5536
5537/* TODO: Implement this function properly
5538 * For now it is needed to reply to Probe Requests in IBSS mode.
5539 * Propably we need this information from FW.
5540 */
5541static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
5542{
5543 return 1;
5544}
5545
Eliad Pellercf2c92d2014-11-04 11:43:54 +02005546static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
5547 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02005548{
5549 struct ath10k *ar = hw->priv;
5550
Eliad Pellercf2c92d2014-11-04 11:43:54 +02005551 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
5552 return;
5553
Michal Kazioraffd3212013-07-16 09:54:35 +02005554 mutex_lock(&ar->conf_mutex);
5555
5556 /* If device failed to restart it will be in a different state, e.g.
5557 * ATH10K_STATE_WEDGED */
5558 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005559 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02005560 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01005561 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02005562 }
5563
5564 mutex_unlock(&ar->conf_mutex);
5565}
5566
Michal Kazior2e1dea42013-07-31 10:32:40 +02005567static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
5568 struct survey_info *survey)
5569{
5570 struct ath10k *ar = hw->priv;
5571 struct ieee80211_supported_band *sband;
5572 struct survey_info *ar_survey = &ar->survey[idx];
5573 int ret = 0;
5574
5575 mutex_lock(&ar->conf_mutex);
5576
5577 sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
5578 if (sband && idx >= sband->n_channels) {
5579 idx -= sband->n_channels;
5580 sband = NULL;
5581 }
5582
5583 if (!sband)
5584 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
5585
5586 if (!sband || idx >= sband->n_channels) {
5587 ret = -ENOENT;
5588 goto exit;
5589 }
5590
5591 spin_lock_bh(&ar->data_lock);
5592 memcpy(survey, ar_survey, sizeof(*survey));
5593 spin_unlock_bh(&ar->data_lock);
5594
5595 survey->channel = &sband->channels[idx];
5596
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03005597 if (ar->rx_channel == survey->channel)
5598 survey->filled |= SURVEY_INFO_IN_USE;
5599
Michal Kazior2e1dea42013-07-31 10:32:40 +02005600exit:
5601 mutex_unlock(&ar->conf_mutex);
5602 return ret;
5603}
5604
Michal Kazior3ae54222015-03-31 10:49:20 +00005605static bool
5606ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
5607 enum ieee80211_band band,
5608 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005609{
Michal Kazior3ae54222015-03-31 10:49:20 +00005610 int num_rates = 0;
5611 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005612
Michal Kazior3ae54222015-03-31 10:49:20 +00005613 num_rates += hweight32(mask->control[band].legacy);
5614
5615 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
5616 num_rates += hweight8(mask->control[band].ht_mcs[i]);
5617
5618 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
5619 num_rates += hweight16(mask->control[band].vht_mcs[i]);
5620
5621 return num_rates == 1;
5622}
5623
5624static bool
5625ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
5626 enum ieee80211_band band,
5627 const struct cfg80211_bitrate_mask *mask,
5628 int *nss)
5629{
5630 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
5631 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
5632 u8 ht_nss_mask = 0;
5633 u8 vht_nss_mask = 0;
5634 int i;
5635
5636 if (mask->control[band].legacy)
5637 return false;
5638
5639 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
5640 if (mask->control[band].ht_mcs[i] == 0)
5641 continue;
5642 else if (mask->control[band].ht_mcs[i] ==
5643 sband->ht_cap.mcs.rx_mask[i])
5644 ht_nss_mask |= BIT(i);
5645 else
5646 return false;
5647 }
5648
5649 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
5650 if (mask->control[band].vht_mcs[i] == 0)
5651 continue;
5652 else if (mask->control[band].vht_mcs[i] ==
5653 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
5654 vht_nss_mask |= BIT(i);
5655 else
5656 return false;
5657 }
5658
5659 if (ht_nss_mask != vht_nss_mask)
5660 return false;
5661
5662 if (ht_nss_mask == 0)
5663 return false;
5664
5665 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
5666 return false;
5667
5668 *nss = fls(ht_nss_mask);
5669
5670 return true;
5671}
5672
5673static int
5674ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
5675 enum ieee80211_band band,
5676 const struct cfg80211_bitrate_mask *mask,
5677 u8 *rate, u8 *nss)
5678{
5679 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
5680 int rate_idx;
5681 int i;
5682 u16 bitrate;
5683 u8 preamble;
5684 u8 hw_rate;
5685
5686 if (hweight32(mask->control[band].legacy) == 1) {
5687 rate_idx = ffs(mask->control[band].legacy) - 1;
5688
5689 hw_rate = sband->bitrates[rate_idx].hw_value;
5690 bitrate = sband->bitrates[rate_idx].bitrate;
5691
5692 if (ath10k_mac_bitrate_is_cck(bitrate))
5693 preamble = WMI_RATE_PREAMBLE_CCK;
5694 else
5695 preamble = WMI_RATE_PREAMBLE_OFDM;
5696
5697 *nss = 1;
5698 *rate = preamble << 6 |
5699 (*nss - 1) << 4 |
5700 hw_rate << 0;
5701
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005702 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005703 }
5704
Michal Kazior3ae54222015-03-31 10:49:20 +00005705 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
5706 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
5707 *nss = i + 1;
5708 *rate = WMI_RATE_PREAMBLE_HT << 6 |
5709 (*nss - 1) << 4 |
5710 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005711
Michal Kazior3ae54222015-03-31 10:49:20 +00005712 return 0;
5713 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005714 }
5715
Michal Kazior3ae54222015-03-31 10:49:20 +00005716 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
5717 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
5718 *nss = i + 1;
5719 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
5720 (*nss - 1) << 4 |
5721 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005722
Michal Kazior3ae54222015-03-31 10:49:20 +00005723 return 0;
5724 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005725 }
5726
Michal Kazior3ae54222015-03-31 10:49:20 +00005727 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005728}
5729
Michal Kazior3ae54222015-03-31 10:49:20 +00005730static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
5731 u8 rate, u8 nss, u8 sgi)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005732{
5733 struct ath10k *ar = arvif->ar;
5734 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00005735 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005736
Michal Kazior3ae54222015-03-31 10:49:20 +00005737 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005738
Michal Kazior3ae54222015-03-31 10:49:20 +00005739 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
5740 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005741
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005742 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00005743 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005744 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005745 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00005746 rate, ret);
5747 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005748 }
5749
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005750 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00005751 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005752 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00005753 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
5754 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005755 }
5756
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005757 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00005758 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005759 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00005760 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
5761 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005762 }
5763
Michal Kazior3ae54222015-03-31 10:49:20 +00005764 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005765}
5766
Michal Kazior3ae54222015-03-31 10:49:20 +00005767static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
5768 struct ieee80211_vif *vif,
5769 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005770{
5771 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00005772 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005773 struct ath10k *ar = arvif->ar;
Michal Kazior500ff9f2015-03-31 10:26:21 +00005774 enum ieee80211_band band;
Michal Kazior3ae54222015-03-31 10:49:20 +00005775 u8 rate;
5776 u8 nss;
5777 u8 sgi;
5778 int single_nss;
5779 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005780
Michal Kazior500ff9f2015-03-31 10:26:21 +00005781 if (ath10k_mac_vif_chan(vif, &def))
5782 return -EPERM;
5783
Michal Kazior500ff9f2015-03-31 10:26:21 +00005784 band = def.chan->band;
5785
Michal Kazior3ae54222015-03-31 10:49:20 +00005786 sgi = mask->control[band].gi;
5787 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005788 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005789
Michal Kazior3ae54222015-03-31 10:49:20 +00005790 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
5791 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
5792 &rate, &nss);
5793 if (ret) {
5794 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
5795 arvif->vdev_id, ret);
5796 return ret;
5797 }
5798 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
5799 &single_nss)) {
5800 rate = WMI_FIXED_RATE_NONE;
5801 nss = single_nss;
5802 } else {
5803 rate = WMI_FIXED_RATE_NONE;
5804 nss = ar->num_rf_chains;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005805 }
5806
Michal Kazior3ae54222015-03-31 10:49:20 +00005807 mutex_lock(&ar->conf_mutex);
5808
5809 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi);
5810 if (ret) {
5811 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
5812 arvif->vdev_id, ret);
5813 goto exit;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01005814 }
5815
Michal Kazior3ae54222015-03-31 10:49:20 +00005816exit:
5817 mutex_unlock(&ar->conf_mutex);
5818
5819 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01005820}
5821
Michal Kazior9797feb2014-02-14 14:49:48 +01005822static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
5823 struct ieee80211_vif *vif,
5824 struct ieee80211_sta *sta,
5825 u32 changed)
5826{
5827 struct ath10k *ar = hw->priv;
5828 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5829 u32 bw, smps;
5830
5831 spin_lock_bh(&ar->data_lock);
5832
Michal Kazior7aa7a722014-08-25 12:09:38 +02005833 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01005834 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
5835 sta->addr, changed, sta->bandwidth, sta->rx_nss,
5836 sta->smps_mode);
5837
5838 if (changed & IEEE80211_RC_BW_CHANGED) {
5839 bw = WMI_PEER_CHWIDTH_20MHZ;
5840
5841 switch (sta->bandwidth) {
5842 case IEEE80211_STA_RX_BW_20:
5843 bw = WMI_PEER_CHWIDTH_20MHZ;
5844 break;
5845 case IEEE80211_STA_RX_BW_40:
5846 bw = WMI_PEER_CHWIDTH_40MHZ;
5847 break;
5848 case IEEE80211_STA_RX_BW_80:
5849 bw = WMI_PEER_CHWIDTH_80MHZ;
5850 break;
5851 case IEEE80211_STA_RX_BW_160:
Michal Kazior7aa7a722014-08-25 12:09:38 +02005852 ath10k_warn(ar, "Invalid bandwith %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02005853 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01005854 bw = WMI_PEER_CHWIDTH_20MHZ;
5855 break;
5856 }
5857
5858 arsta->bw = bw;
5859 }
5860
5861 if (changed & IEEE80211_RC_NSS_CHANGED)
5862 arsta->nss = sta->rx_nss;
5863
5864 if (changed & IEEE80211_RC_SMPS_CHANGED) {
5865 smps = WMI_PEER_SMPS_PS_NONE;
5866
5867 switch (sta->smps_mode) {
5868 case IEEE80211_SMPS_AUTOMATIC:
5869 case IEEE80211_SMPS_OFF:
5870 smps = WMI_PEER_SMPS_PS_NONE;
5871 break;
5872 case IEEE80211_SMPS_STATIC:
5873 smps = WMI_PEER_SMPS_STATIC;
5874 break;
5875 case IEEE80211_SMPS_DYNAMIC:
5876 smps = WMI_PEER_SMPS_DYNAMIC;
5877 break;
5878 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02005879 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02005880 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01005881 smps = WMI_PEER_SMPS_PS_NONE;
5882 break;
5883 }
5884
5885 arsta->smps = smps;
5886 }
5887
Michal Kazior9797feb2014-02-14 14:49:48 +01005888 arsta->changed |= changed;
5889
5890 spin_unlock_bh(&ar->data_lock);
5891
5892 ieee80211_queue_work(hw, &arsta->update_wk);
5893}
5894
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02005895static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
5896{
5897 /*
5898 * FIXME: Return 0 for time being. Need to figure out whether FW
5899 * has the API to fetch 64-bit local TSF
5900 */
5901
5902 return 0;
5903}
5904
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02005905static int ath10k_ampdu_action(struct ieee80211_hw *hw,
5906 struct ieee80211_vif *vif,
5907 enum ieee80211_ampdu_mlme_action action,
5908 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
5909 u8 buf_size)
5910{
Michal Kazior7aa7a722014-08-25 12:09:38 +02005911 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02005912 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5913
Michal Kazior7aa7a722014-08-25 12:09:38 +02005914 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 +02005915 arvif->vdev_id, sta->addr, tid, action);
5916
5917 switch (action) {
5918 case IEEE80211_AMPDU_RX_START:
5919 case IEEE80211_AMPDU_RX_STOP:
5920 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
5921 * creation/removal. Do we need to verify this?
5922 */
5923 return 0;
5924 case IEEE80211_AMPDU_TX_START:
5925 case IEEE80211_AMPDU_TX_STOP_CONT:
5926 case IEEE80211_AMPDU_TX_STOP_FLUSH:
5927 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
5928 case IEEE80211_AMPDU_TX_OPERATIONAL:
5929 /* Firmware offloads Tx aggregation entirely so deny mac80211
5930 * Tx aggregation requests.
5931 */
5932 return -EOPNOTSUPP;
5933 }
5934
5935 return -EINVAL;
5936}
5937
Michal Kazior500ff9f2015-03-31 10:26:21 +00005938static void
5939ath10k_mac_update_rx_channel(struct ath10k *ar)
5940{
5941 struct cfg80211_chan_def *def = NULL;
5942
5943 /* Both locks are required because ar->rx_channel is modified. This
5944 * allows readers to hold either lock.
5945 */
5946 lockdep_assert_held(&ar->conf_mutex);
5947 lockdep_assert_held(&ar->data_lock);
5948
5949 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
5950 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
5951 * ppdu on Rx may reduce performance on low-end systems. It should be
5952 * possible to make tables/hashmaps to speed the lookup up (be vary of
5953 * cpu data cache lines though regarding sizes) but to keep the initial
5954 * implementation simple and less intrusive fallback to the slow lookup
5955 * only for multi-channel cases. Single-channel cases will remain to
5956 * use the old channel derival and thus performance should not be
5957 * affected much.
5958 */
5959 rcu_read_lock();
5960 if (ath10k_mac_num_chanctxs(ar) == 1) {
5961 ieee80211_iter_chan_contexts_atomic(ar->hw,
5962 ath10k_mac_get_any_chandef_iter,
5963 &def);
5964 ar->rx_channel = def->chan;
5965 } else {
5966 ar->rx_channel = NULL;
5967 }
5968 rcu_read_unlock();
5969}
5970
5971static void
5972ath10k_mac_chan_ctx_init(struct ath10k *ar,
5973 struct ath10k_chanctx *arctx,
5974 struct ieee80211_chanctx_conf *conf)
5975{
5976 lockdep_assert_held(&ar->conf_mutex);
5977 lockdep_assert_held(&ar->data_lock);
5978
5979 memset(arctx, 0, sizeof(*arctx));
5980
5981 arctx->conf = *conf;
5982}
5983
5984static int
5985ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
5986 struct ieee80211_chanctx_conf *ctx)
5987{
5988 struct ath10k *ar = hw->priv;
5989 struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
5990
5991 ath10k_dbg(ar, ATH10K_DBG_MAC,
5992 "mac chanctx add freq %hu width %d ptr %p\n",
5993 ctx->def.chan->center_freq, ctx->def.width, ctx);
5994
5995 mutex_lock(&ar->conf_mutex);
5996
5997 spin_lock_bh(&ar->data_lock);
5998 ath10k_mac_chan_ctx_init(ar, arctx, ctx);
5999 ath10k_mac_update_rx_channel(ar);
6000 spin_unlock_bh(&ar->data_lock);
6001
6002 ath10k_recalc_radar_detection(ar);
6003 ath10k_monitor_recalc(ar);
6004
6005 mutex_unlock(&ar->conf_mutex);
6006
6007 return 0;
6008}
6009
6010static void
6011ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
6012 struct ieee80211_chanctx_conf *ctx)
6013{
6014 struct ath10k *ar = hw->priv;
6015
6016 ath10k_dbg(ar, ATH10K_DBG_MAC,
6017 "mac chanctx remove freq %hu width %d ptr %p\n",
6018 ctx->def.chan->center_freq, ctx->def.width, ctx);
6019
6020 mutex_lock(&ar->conf_mutex);
6021
6022 spin_lock_bh(&ar->data_lock);
6023 ath10k_mac_update_rx_channel(ar);
6024 spin_unlock_bh(&ar->data_lock);
6025
6026 ath10k_recalc_radar_detection(ar);
6027 ath10k_monitor_recalc(ar);
6028
6029 mutex_unlock(&ar->conf_mutex);
6030}
6031
6032static void
6033ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
6034 struct ieee80211_chanctx_conf *ctx,
6035 u32 changed)
6036{
6037 struct ath10k *ar = hw->priv;
6038 struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
6039
6040 mutex_lock(&ar->conf_mutex);
6041
6042 ath10k_dbg(ar, ATH10K_DBG_MAC,
6043 "mac chanctx change freq %hu->%hu width %d->%d ptr %p changed %x\n",
6044 arctx->conf.def.chan->center_freq,
6045 ctx->def.chan->center_freq,
6046 arctx->conf.def.width, ctx->def.width,
6047 ctx, changed);
6048
6049 /* This shouldn't really happen because channel switching should use
6050 * switch_vif_chanctx().
6051 */
6052 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
6053 goto unlock;
6054
6055 spin_lock_bh(&ar->data_lock);
6056 arctx->conf = *ctx;
6057 spin_unlock_bh(&ar->data_lock);
6058
6059 ath10k_recalc_radar_detection(ar);
6060
6061 /* FIXME: How to configure Rx chains properly? */
6062
6063 /* No other actions are actually necessary. Firmware maintains channel
6064 * definitions per vdev internally and there's no host-side channel
6065 * context abstraction to configure, e.g. channel width.
6066 */
6067
6068unlock:
6069 mutex_unlock(&ar->conf_mutex);
6070}
6071
6072static int
6073ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
6074 struct ieee80211_vif *vif,
6075 struct ieee80211_chanctx_conf *ctx)
6076{
6077 struct ath10k *ar = hw->priv;
6078 struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
6079 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6080 int ret;
6081
6082 mutex_lock(&ar->conf_mutex);
6083
6084 ath10k_dbg(ar, ATH10K_DBG_MAC,
6085 "mac chanctx assign ptr %p vdev_id %i\n",
6086 ctx, arvif->vdev_id);
6087
6088 if (WARN_ON(arvif->is_started)) {
6089 mutex_unlock(&ar->conf_mutex);
6090 return -EBUSY;
6091 }
6092
6093 ret = ath10k_vdev_start(arvif, &arctx->conf.def);
6094 if (ret) {
6095 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
6096 arvif->vdev_id, vif->addr,
6097 arctx->conf.def.chan->center_freq, ret);
6098 goto err;
6099 }
6100
6101 arvif->is_started = true;
6102
6103 if (vif->type == NL80211_IFTYPE_MONITOR) {
6104 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
6105 if (ret) {
6106 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
6107 arvif->vdev_id, ret);
6108 goto err_stop;
6109 }
6110
6111 arvif->is_up = true;
6112 }
6113
6114 mutex_unlock(&ar->conf_mutex);
6115 return 0;
6116
6117err_stop:
6118 ath10k_vdev_stop(arvif);
6119 arvif->is_started = false;
6120
6121err:
6122 mutex_unlock(&ar->conf_mutex);
6123 return ret;
6124}
6125
6126static void
6127ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
6128 struct ieee80211_vif *vif,
6129 struct ieee80211_chanctx_conf *ctx)
6130{
6131 struct ath10k *ar = hw->priv;
6132 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6133 int ret;
6134
6135 mutex_lock(&ar->conf_mutex);
6136
6137 ath10k_dbg(ar, ATH10K_DBG_MAC,
6138 "mac chanctx unassign ptr %p vdev_id %i\n",
6139 ctx, arvif->vdev_id);
6140
6141 WARN_ON(!arvif->is_started);
6142
6143 if (vif->type == NL80211_IFTYPE_MONITOR) {
6144 WARN_ON(!arvif->is_up);
6145
6146 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
6147 if (ret)
6148 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
6149 arvif->vdev_id, ret);
6150
6151 arvif->is_up = false;
6152 }
6153
6154 ret = ath10k_vdev_stop(arvif);
6155 if (ret)
6156 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
6157 arvif->vdev_id, ret);
6158
6159 arvif->is_started = false;
6160
6161 mutex_unlock(&ar->conf_mutex);
6162}
6163
6164static int
6165ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
6166 struct ieee80211_vif_chanctx_switch *vifs,
6167 int n_vifs,
6168 enum ieee80211_chanctx_switch_mode mode)
6169{
6170 struct ath10k *ar = hw->priv;
6171 struct ath10k_vif *arvif;
6172 struct ath10k_chanctx *arctx_new, *arctx_old;
6173 int i;
6174
6175 mutex_lock(&ar->conf_mutex);
6176
6177 ath10k_dbg(ar, ATH10K_DBG_MAC,
6178 "mac chanctx switch n_vifs %d mode %d\n",
6179 n_vifs, mode);
6180
6181 spin_lock_bh(&ar->data_lock);
6182 for (i = 0; i < n_vifs; i++) {
6183 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6184 arctx_new = (void *)vifs[i].new_ctx->drv_priv;
6185 arctx_old = (void *)vifs[i].old_ctx->drv_priv;
6186
6187 ath10k_dbg(ar, ATH10K_DBG_MAC,
6188 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d ptr %p->%p\n",
6189 arvif->vdev_id,
6190 vifs[i].old_ctx->def.chan->center_freq,
6191 vifs[i].new_ctx->def.chan->center_freq,
6192 vifs[i].old_ctx->def.width,
6193 vifs[i].new_ctx->def.width,
6194 arctx_old, arctx_new);
6195
6196 if (mode == CHANCTX_SWMODE_SWAP_CONTEXTS) {
6197 ath10k_mac_chan_ctx_init(ar, arctx_new,
6198 vifs[i].new_ctx);
6199 }
6200
6201 arctx_new->conf = *vifs[i].new_ctx;
6202
6203 /* FIXME: ath10k_mac_chan_reconfigure() uses current, i.e. not
6204 * yet updated chanctx_conf pointer.
6205 */
6206 arctx_old->conf = *vifs[i].new_ctx;
6207 }
6208 ath10k_mac_update_rx_channel(ar);
6209 spin_unlock_bh(&ar->data_lock);
6210
6211 /* FIXME: Reconfigure only affected vifs */
6212 ath10k_mac_chan_reconfigure(ar);
6213
6214 mutex_unlock(&ar->conf_mutex);
6215 return 0;
6216}
6217
Kalle Valo5e3dd152013-06-12 20:52:10 +03006218static const struct ieee80211_ops ath10k_ops = {
6219 .tx = ath10k_tx,
6220 .start = ath10k_start,
6221 .stop = ath10k_stop,
6222 .config = ath10k_config,
6223 .add_interface = ath10k_add_interface,
6224 .remove_interface = ath10k_remove_interface,
6225 .configure_filter = ath10k_configure_filter,
6226 .bss_info_changed = ath10k_bss_info_changed,
6227 .hw_scan = ath10k_hw_scan,
6228 .cancel_hw_scan = ath10k_cancel_hw_scan,
6229 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02006230 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03006231 .sta_state = ath10k_sta_state,
6232 .conf_tx = ath10k_conf_tx,
6233 .remain_on_channel = ath10k_remain_on_channel,
6234 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
6235 .set_rts_threshold = ath10k_set_rts_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03006236 .flush = ath10k_flush,
6237 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03006238 .set_antenna = ath10k_set_antenna,
6239 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006240 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02006241 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00006242 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01006243 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006244 .get_tsf = ath10k_get_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006245 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03006246 .get_et_sset_count = ath10k_debug_get_et_sset_count,
6247 .get_et_stats = ath10k_debug_get_et_stats,
6248 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00006249 .add_chanctx = ath10k_mac_op_add_chanctx,
6250 .remove_chanctx = ath10k_mac_op_remove_chanctx,
6251 .change_chanctx = ath10k_mac_op_change_chanctx,
6252 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
6253 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
6254 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Kalle Valo43d2a302014-09-10 18:23:30 +03006255
6256 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
6257
Michal Kazior8cd13ca2013-07-16 09:38:54 +02006258#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02006259 .suspend = ath10k_wow_op_suspend,
6260 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02006261#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02006262#ifdef CONFIG_MAC80211_DEBUGFS
6263 .sta_add_debugfs = ath10k_sta_add_debugfs,
6264#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03006265};
6266
Kalle Valo5e3dd152013-06-12 20:52:10 +03006267#define CHAN2G(_channel, _freq, _flags) { \
6268 .band = IEEE80211_BAND_2GHZ, \
6269 .hw_value = (_channel), \
6270 .center_freq = (_freq), \
6271 .flags = (_flags), \
6272 .max_antenna_gain = 0, \
6273 .max_power = 30, \
6274}
6275
6276#define CHAN5G(_channel, _freq, _flags) { \
6277 .band = IEEE80211_BAND_5GHZ, \
6278 .hw_value = (_channel), \
6279 .center_freq = (_freq), \
6280 .flags = (_flags), \
6281 .max_antenna_gain = 0, \
6282 .max_power = 30, \
6283}
6284
6285static const struct ieee80211_channel ath10k_2ghz_channels[] = {
6286 CHAN2G(1, 2412, 0),
6287 CHAN2G(2, 2417, 0),
6288 CHAN2G(3, 2422, 0),
6289 CHAN2G(4, 2427, 0),
6290 CHAN2G(5, 2432, 0),
6291 CHAN2G(6, 2437, 0),
6292 CHAN2G(7, 2442, 0),
6293 CHAN2G(8, 2447, 0),
6294 CHAN2G(9, 2452, 0),
6295 CHAN2G(10, 2457, 0),
6296 CHAN2G(11, 2462, 0),
6297 CHAN2G(12, 2467, 0),
6298 CHAN2G(13, 2472, 0),
6299 CHAN2G(14, 2484, 0),
6300};
6301
6302static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02006303 CHAN5G(36, 5180, 0),
6304 CHAN5G(40, 5200, 0),
6305 CHAN5G(44, 5220, 0),
6306 CHAN5G(48, 5240, 0),
6307 CHAN5G(52, 5260, 0),
6308 CHAN5G(56, 5280, 0),
6309 CHAN5G(60, 5300, 0),
6310 CHAN5G(64, 5320, 0),
6311 CHAN5G(100, 5500, 0),
6312 CHAN5G(104, 5520, 0),
6313 CHAN5G(108, 5540, 0),
6314 CHAN5G(112, 5560, 0),
6315 CHAN5G(116, 5580, 0),
6316 CHAN5G(120, 5600, 0),
6317 CHAN5G(124, 5620, 0),
6318 CHAN5G(128, 5640, 0),
6319 CHAN5G(132, 5660, 0),
6320 CHAN5G(136, 5680, 0),
6321 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07006322 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02006323 CHAN5G(149, 5745, 0),
6324 CHAN5G(153, 5765, 0),
6325 CHAN5G(157, 5785, 0),
6326 CHAN5G(161, 5805, 0),
6327 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03006328};
6329
Michal Kaziore7b54192014-08-07 11:03:27 +02006330struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006331{
6332 struct ieee80211_hw *hw;
6333 struct ath10k *ar;
6334
Michal Kaziore7b54192014-08-07 11:03:27 +02006335 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006336 if (!hw)
6337 return NULL;
6338
6339 ar = hw->priv;
6340 ar->hw = hw;
6341
6342 return ar;
6343}
6344
6345void ath10k_mac_destroy(struct ath10k *ar)
6346{
6347 ieee80211_free_hw(ar->hw);
6348}
6349
6350static const struct ieee80211_iface_limit ath10k_if_limits[] = {
6351 {
6352 .max = 8,
6353 .types = BIT(NL80211_IFTYPE_STATION)
6354 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02006355 },
6356 {
6357 .max = 3,
6358 .types = BIT(NL80211_IFTYPE_P2P_GO)
6359 },
6360 {
Michal Kazior75d2bd42014-12-12 12:41:39 +01006361 .max = 1,
6362 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
6363 },
6364 {
Michal Kaziord531cb82013-07-31 10:55:13 +02006365 .max = 7,
6366 .types = BIT(NL80211_IFTYPE_AP)
6367 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03006368};
6369
Bartosz Markowskif2595092013-12-10 16:20:39 +01006370static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006371 {
6372 .max = 8,
6373 .types = BIT(NL80211_IFTYPE_AP)
6374 },
6375};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006376
6377static const struct ieee80211_iface_combination ath10k_if_comb[] = {
6378 {
6379 .limits = ath10k_if_limits,
6380 .n_limits = ARRAY_SIZE(ath10k_if_limits),
6381 .max_interfaces = 8,
6382 .num_different_channels = 1,
6383 .beacon_int_infra_match = true,
6384 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01006385};
6386
6387static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006388 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01006389 .limits = ath10k_10x_if_limits,
6390 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006391 .max_interfaces = 8,
6392 .num_different_channels = 1,
6393 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01006394#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006395 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
6396 BIT(NL80211_CHAN_WIDTH_20) |
6397 BIT(NL80211_CHAN_WIDTH_40) |
6398 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02006399#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01006400 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03006401};
6402
Michal Kaziorcf327842015-03-31 10:26:25 +00006403static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
6404 {
6405 .max = 2,
6406 .types = BIT(NL80211_IFTYPE_STATION) |
6407 BIT(NL80211_IFTYPE_AP) |
6408 BIT(NL80211_IFTYPE_P2P_CLIENT) |
6409 BIT(NL80211_IFTYPE_P2P_GO),
6410 },
6411 {
6412 .max = 1,
6413 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
6414 },
6415};
6416
6417static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
6418 {
6419 .max = 1,
6420 .types = BIT(NL80211_IFTYPE_STATION),
6421 },
6422 {
6423 .max = 1,
6424 .types = BIT(NL80211_IFTYPE_ADHOC),
6425 },
6426};
6427
6428/* FIXME: This is not thouroughly tested. These combinations may over- or
6429 * underestimate hw/fw capabilities.
6430 */
6431static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
6432 {
6433 .limits = ath10k_tlv_if_limit,
6434 .num_different_channels = 1,
6435 .max_interfaces = 3,
6436 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
6437 },
6438 {
6439 .limits = ath10k_tlv_if_limit_ibss,
6440 .num_different_channels = 1,
6441 .max_interfaces = 2,
6442 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
6443 },
6444};
6445
6446static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
6447 {
6448 .limits = ath10k_tlv_if_limit,
6449 .num_different_channels = 2,
6450 .max_interfaces = 3,
6451 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
6452 },
6453 {
6454 .limits = ath10k_tlv_if_limit_ibss,
6455 .num_different_channels = 1,
6456 .max_interfaces = 2,
6457 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
6458 },
6459};
6460
Kalle Valo5e3dd152013-06-12 20:52:10 +03006461static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
6462{
6463 struct ieee80211_sta_vht_cap vht_cap = {0};
6464 u16 mcs_map;
Michal Kaziorbc657a362015-02-26 11:11:22 +01006465 u32 val;
Michal Kazior8865bee42013-07-24 12:36:46 +02006466 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006467
6468 vht_cap.vht_supported = 1;
6469 vht_cap.cap = ar->vht_cap_info;
6470
Michal Kaziorbc657a362015-02-26 11:11:22 +01006471 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
6472 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
6473 val = ar->num_rf_chains - 1;
6474 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
6475 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
6476
6477 vht_cap.cap |= val;
6478 }
6479
6480 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
6481 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
6482 val = ar->num_rf_chains - 1;
6483 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
6484 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
6485
6486 vht_cap.cap |= val;
6487 }
6488
Michal Kazior8865bee42013-07-24 12:36:46 +02006489 mcs_map = 0;
6490 for (i = 0; i < 8; i++) {
6491 if (i < ar->num_rf_chains)
6492 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i*2);
6493 else
6494 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2);
6495 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006496
6497 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
6498 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
6499
6500 return vht_cap;
6501}
6502
6503static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
6504{
6505 int i;
6506 struct ieee80211_sta_ht_cap ht_cap = {0};
6507
6508 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
6509 return ht_cap;
6510
6511 ht_cap.ht_supported = 1;
6512 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
6513 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
6514 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6515 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
6516 ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT;
6517
6518 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
6519 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
6520
6521 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
6522 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
6523
6524 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
6525 u32 smps;
6526
6527 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
6528 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
6529
6530 ht_cap.cap |= smps;
6531 }
6532
6533 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC)
6534 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
6535
6536 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
6537 u32 stbc;
6538
6539 stbc = ar->ht_cap_info;
6540 stbc &= WMI_HT_CAP_RX_STBC;
6541 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
6542 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
6543 stbc &= IEEE80211_HT_CAP_RX_STBC;
6544
6545 ht_cap.cap |= stbc;
6546 }
6547
6548 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
6549 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
6550
6551 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
6552 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
6553
6554 /* max AMSDU is implicitly taken from vht_cap_info */
6555 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
6556 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
6557
Michal Kazior8865bee42013-07-24 12:36:46 +02006558 for (i = 0; i < ar->num_rf_chains; i++)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006559 ht_cap.mcs.rx_mask[i] = 0xFF;
6560
6561 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
6562
6563 return ht_cap;
6564}
6565
Kalle Valo5e3dd152013-06-12 20:52:10 +03006566static void ath10k_get_arvif_iter(void *data, u8 *mac,
6567 struct ieee80211_vif *vif)
6568{
6569 struct ath10k_vif_iter *arvif_iter = data;
6570 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6571
6572 if (arvif->vdev_id == arvif_iter->vdev_id)
6573 arvif_iter->arvif = arvif;
6574}
6575
6576struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
6577{
6578 struct ath10k_vif_iter arvif_iter;
6579 u32 flags;
6580
6581 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
6582 arvif_iter.vdev_id = vdev_id;
6583
6584 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
6585 ieee80211_iterate_active_interfaces_atomic(ar->hw,
6586 flags,
6587 ath10k_get_arvif_iter,
6588 &arvif_iter);
6589 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006590 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006591 return NULL;
6592 }
6593
6594 return arvif_iter.arvif;
6595}
6596
6597int ath10k_mac_register(struct ath10k *ar)
6598{
Johannes Berg3cb10942015-01-22 21:38:45 +01006599 static const u32 cipher_suites[] = {
6600 WLAN_CIPHER_SUITE_WEP40,
6601 WLAN_CIPHER_SUITE_WEP104,
6602 WLAN_CIPHER_SUITE_TKIP,
6603 WLAN_CIPHER_SUITE_CCMP,
6604 WLAN_CIPHER_SUITE_AES_CMAC,
6605 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03006606 struct ieee80211_supported_band *band;
6607 struct ieee80211_sta_vht_cap vht_cap;
6608 struct ieee80211_sta_ht_cap ht_cap;
6609 void *channels;
6610 int ret;
6611
6612 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
6613
6614 SET_IEEE80211_DEV(ar->hw, ar->dev);
6615
6616 ht_cap = ath10k_get_ht_cap(ar);
6617 vht_cap = ath10k_create_vht_cap(ar);
6618
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00006619 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
6620 ARRAY_SIZE(ath10k_5ghz_channels)) !=
6621 ATH10K_NUM_CHANS);
6622
Kalle Valo5e3dd152013-06-12 20:52:10 +03006623 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
6624 channels = kmemdup(ath10k_2ghz_channels,
6625 sizeof(ath10k_2ghz_channels),
6626 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02006627 if (!channels) {
6628 ret = -ENOMEM;
6629 goto err_free;
6630 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006631
6632 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
6633 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
6634 band->channels = channels;
6635 band->n_bitrates = ath10k_g_rates_size;
6636 band->bitrates = ath10k_g_rates;
6637 band->ht_cap = ht_cap;
6638
Yanbo Lid68bb122015-01-23 08:18:20 +08006639 /* Enable the VHT support at 2.4 GHz */
6640 band->vht_cap = vht_cap;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006641
6642 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
6643 }
6644
6645 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
6646 channels = kmemdup(ath10k_5ghz_channels,
6647 sizeof(ath10k_5ghz_channels),
6648 GFP_KERNEL);
6649 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02006650 ret = -ENOMEM;
6651 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006652 }
6653
6654 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
6655 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
6656 band->channels = channels;
6657 band->n_bitrates = ath10k_a_rates_size;
6658 band->bitrates = ath10k_a_rates;
6659 band->ht_cap = ht_cap;
6660 band->vht_cap = vht_cap;
6661 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
6662 }
6663
6664 ar->hw->wiphy->interface_modes =
6665 BIT(NL80211_IFTYPE_STATION) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01006666 BIT(NL80211_IFTYPE_AP);
6667
Ben Greear46acf7b2014-05-16 17:15:38 +03006668 ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask;
6669 ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask;
6670
Bartosz Markowskid3541812013-12-10 16:20:40 +01006671 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
6672 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01006673 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01006674 BIT(NL80211_IFTYPE_P2P_CLIENT) |
6675 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006676
6677 ar->hw->flags = IEEE80211_HW_SIGNAL_DBM |
6678 IEEE80211_HW_SUPPORTS_PS |
6679 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
Kalle Valo5e3dd152013-06-12 20:52:10 +03006680 IEEE80211_HW_MFP_CAPABLE |
6681 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
6682 IEEE80211_HW_HAS_RATE_CONTROL |
Janusz Dziedzic2f0f1122014-02-26 18:42:09 +02006683 IEEE80211_HW_AP_LINK_PS |
Johannes Berg3cb10942015-01-22 21:38:45 +01006684 IEEE80211_HW_SPECTRUM_MGMT |
Michal Kaziorcc9904e2015-03-10 16:22:01 +02006685 IEEE80211_HW_SW_CRYPTO_CONTROL |
Michal Kazior500ff9f2015-03-31 10:26:21 +00006686 IEEE80211_HW_CONNECTION_MONITOR |
6687 IEEE80211_HW_WANT_MONITOR_VIF |
Michal Kazior96d828d2015-03-31 10:26:23 +00006688 IEEE80211_HW_CHANCTX_STA_CSA |
6689 IEEE80211_HW_QUEUE_CONTROL;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006690
Eliad Peller0d8614b2014-09-10 14:07:36 +03006691 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
6692
Kalle Valo5e3dd152013-06-12 20:52:10 +03006693 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03006694 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006695
6696 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
6697 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
6698 ar->hw->flags |= IEEE80211_HW_TX_AMPDU_SETUP_IN_HW;
6699 }
6700
6701 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
6702 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
6703
6704 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01006705 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006706 ar->hw->chanctx_data_size = sizeof(struct ath10k_chanctx);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006707
Kalle Valo5e3dd152013-06-12 20:52:10 +03006708 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
6709
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02006710 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
6711 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
6712
6713 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
6714 * that userspace (e.g. wpa_supplicant/hostapd) can generate
6715 * correct Probe Responses. This is more of a hack advert..
6716 */
6717 ar->hw->wiphy->probe_resp_offload |=
6718 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
6719 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
6720 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
6721 }
6722
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006723 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
6724 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
6725
Kalle Valo5e3dd152013-06-12 20:52:10 +03006726 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01006727 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006728 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
6729
6730 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02006731 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
6732
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01006733 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
6734
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02006735 ret = ath10k_wow_init(ar);
6736 if (ret) {
6737 ath10k_warn(ar, "failed to init wow: %d\n", ret);
6738 goto err_free;
6739 }
6740
Kalle Valo5e3dd152013-06-12 20:52:10 +03006741 /*
6742 * on LL hardware queues are managed entirely by the FW
6743 * so we only advertise to mac we can do the queues thing
6744 */
Michal Kazior96d828d2015-03-31 10:26:23 +00006745 ar->hw->queues = IEEE80211_MAX_QUEUES;
6746
6747 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
6748 * something that vdev_ids can't reach so that we don't stop the queue
6749 * accidentally.
6750 */
6751 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006752
Kalle Valo5cc7caf2014-12-17 12:20:54 +02006753 switch (ar->wmi.op_version) {
6754 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01006755 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
6756 ar->hw->wiphy->n_iface_combinations =
6757 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03006758 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02006759 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00006760 case ATH10K_FW_WMI_OP_VERSION_TLV:
6761 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
6762 ar->hw->wiphy->iface_combinations =
6763 ath10k_tlv_qcs_if_comb;
6764 ar->hw->wiphy->n_iface_combinations =
6765 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
6766 } else {
6767 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
6768 ar->hw->wiphy->n_iface_combinations =
6769 ARRAY_SIZE(ath10k_tlv_if_comb);
6770 }
6771 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
6772 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02006773 case ATH10K_FW_WMI_OP_VERSION_10_1:
6774 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02006775 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02006776 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
6777 ar->hw->wiphy->n_iface_combinations =
6778 ARRAY_SIZE(ath10k_10x_if_comb);
6779 break;
6780 case ATH10K_FW_WMI_OP_VERSION_UNSET:
6781 case ATH10K_FW_WMI_OP_VERSION_MAX:
6782 WARN_ON(1);
6783 ret = -EINVAL;
6784 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01006785 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006786
Michal Kazior7c199992013-07-31 10:47:57 +02006787 ar->hw->netdev_features = NETIF_F_HW_CSUM;
6788
Janusz Dziedzic9702c682013-11-20 09:59:41 +02006789 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
6790 /* Init ath dfs pattern detector */
6791 ar->ath_common.debug_mask = ATH_DBG_DFS;
6792 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
6793 NL80211_DFS_UNSET);
6794
6795 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006796 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02006797 }
6798
Kalle Valo5e3dd152013-06-12 20:52:10 +03006799 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
6800 ath10k_reg_notifier);
6801 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006802 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Michal Kaziord6015b22013-07-22 14:13:30 +02006803 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006804 }
6805
Johannes Berg3cb10942015-01-22 21:38:45 +01006806 ar->hw->wiphy->cipher_suites = cipher_suites;
6807 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
6808
Kalle Valo5e3dd152013-06-12 20:52:10 +03006809 ret = ieee80211_register_hw(ar->hw);
6810 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006811 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Michal Kaziord6015b22013-07-22 14:13:30 +02006812 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006813 }
6814
6815 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
6816 ret = regulatory_hint(ar->hw->wiphy,
6817 ar->ath_common.regulatory.alpha2);
6818 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02006819 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006820 }
6821
6822 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02006823
6824err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006825 ieee80211_unregister_hw(ar->hw);
Michal Kaziord6015b22013-07-22 14:13:30 +02006826err_free:
6827 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
6828 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
6829
Kalle Valo5e3dd152013-06-12 20:52:10 +03006830 return ret;
6831}
6832
6833void ath10k_mac_unregister(struct ath10k *ar)
6834{
6835 ieee80211_unregister_hw(ar->hw);
6836
Janusz Dziedzic9702c682013-11-20 09:59:41 +02006837 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
6838 ar->dfs_detector->exit(ar->dfs_detector);
6839
Kalle Valo5e3dd152013-06-12 20:52:10 +03006840 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
6841 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
6842
6843 SET_IEEE80211_DEV(ar->hw, NULL);
6844}