blob: 1dd415d3c0ee9685cbe85c2ebbe994611bdd0229 [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,
Yanbo Li4b7f3532015-11-12 10:36:10 -080093 u8 hw_rate, bool cck)
Michal Kazior5528e032015-03-30 09:51:56 +030094{
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
Yanbo Li4b7f3532015-11-12 10:36:10 -0800101 if (ath10k_mac_bitrate_is_cck(rate->bitrate) != cck)
102 continue;
103
Michal Kazior5528e032015-03-30 09:51:56 +0300104 if (rate->hw_value == hw_rate)
105 return i;
106 else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
107 rate->hw_value_short == hw_rate)
108 return i;
109 }
110
111 return 0;
112}
113
Michal Kazior01cebe12015-03-30 09:51:56 +0300114u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
115 u32 bitrate)
116{
117 int i;
118
119 for (i = 0; i < sband->n_bitrates; i++)
120 if (sband->bitrates[i].bitrate == bitrate)
121 return i;
122
123 return 0;
124}
125
Michal Kazior3ae54222015-03-31 10:49:20 +0000126static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
127{
128 switch ((mcs_map >> (2 * nss)) & 0x3) {
129 case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;
130 case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;
131 case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;
132 }
133 return 0;
134}
135
Michal Kazior45c9abc2015-04-21 20:42:58 +0300136static u32
137ath10k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
138{
139 int nss;
140
141 for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--)
142 if (ht_mcs_mask[nss])
143 return nss + 1;
144
145 return 1;
146}
147
148static u32
149ath10k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
150{
151 int nss;
152
153 for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--)
154 if (vht_mcs_mask[nss])
155 return nss + 1;
156
157 return 1;
158}
Kalle Valo5e3dd152013-06-12 20:52:10 +0300159
Raja Mani7e247a92016-04-12 20:15:53 +0530160int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val)
161{
162 enum wmi_host_platform_type platform_type;
163 int ret;
164
165 if (test_bit(WMI_SERVICE_TX_MODE_DYNAMIC, ar->wmi.svc_map))
166 platform_type = WMI_HOST_PLATFORM_LOW_PERF;
167 else
168 platform_type = WMI_HOST_PLATFORM_HIGH_PERF;
169
170 ret = ath10k_wmi_ext_resource_config(ar, platform_type, val);
171
172 if (ret && ret != -EOPNOTSUPP) {
173 ath10k_warn(ar, "failed to configure ext resource: %d\n", ret);
174 return ret;
175 }
176
177 return 0;
178}
179
Kalle Valo5e3dd152013-06-12 20:52:10 +0300180/**********/
181/* Crypto */
182/**********/
183
184static int ath10k_send_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{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200189 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300190 struct wmi_vdev_install_key_arg arg = {
191 .vdev_id = arvif->vdev_id,
192 .key_idx = key->keyidx,
193 .key_len = key->keylen,
194 .key_data = key->key,
Michal Kazior370e5672015-02-18 14:02:26 +0100195 .key_flags = flags,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300196 .macaddr = macaddr,
197 };
198
Michal Kazior548db542013-07-05 16:15:15 +0300199 lockdep_assert_held(&arvif->ar->conf_mutex);
200
Kalle Valo5e3dd152013-06-12 20:52:10 +0300201 switch (key->cipher) {
202 case WLAN_CIPHER_SUITE_CCMP:
203 arg.key_cipher = WMI_CIPHER_AES_CCM;
Marek Kwaczynskie4e82e92015-01-24 12:14:53 +0200204 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300205 break;
206 case WLAN_CIPHER_SUITE_TKIP:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300207 arg.key_cipher = WMI_CIPHER_TKIP;
208 arg.key_txmic_len = 8;
209 arg.key_rxmic_len = 8;
210 break;
211 case WLAN_CIPHER_SUITE_WEP40:
212 case WLAN_CIPHER_SUITE_WEP104:
213 arg.key_cipher = WMI_CIPHER_WEP;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300214 break;
Johannes Berg3cb10942015-01-22 21:38:45 +0100215 case WLAN_CIPHER_SUITE_AES_CMAC:
Bartosz Markowskid7131c02015-03-10 14:32:19 +0100216 WARN_ON(1);
217 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300218 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200219 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300220 return -EOPNOTSUPP;
221 }
222
Kalle Valob9e284e2015-10-05 17:56:35 +0300223 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
David Liuccec9032015-07-24 20:25:32 +0300224 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
David Liuccec9032015-07-24 20:25:32 +0300225
Kalle Valo5e3dd152013-06-12 20:52:10 +0300226 if (cmd == DISABLE_KEY) {
227 arg.key_cipher = WMI_CIPHER_NONE;
228 arg.key_data = NULL;
229 }
230
231 return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
232}
233
234static int ath10k_install_key(struct ath10k_vif *arvif,
235 struct ieee80211_key_conf *key,
236 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100237 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300238{
239 struct ath10k *ar = arvif->ar;
240 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300241 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300242
Michal Kazior548db542013-07-05 16:15:15 +0300243 lockdep_assert_held(&ar->conf_mutex);
244
Wolfram Sang16735d02013-11-14 14:32:02 -0800245 reinit_completion(&ar->install_key_done);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300246
David Liuccec9032015-07-24 20:25:32 +0300247 if (arvif->nohwcrypt)
248 return 1;
249
Michal Kazior370e5672015-02-18 14:02:26 +0100250 ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300251 if (ret)
252 return ret;
253
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300254 time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);
255 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300256 return -ETIMEDOUT;
257
258 return 0;
259}
260
261static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
262 const u8 *addr)
263{
264 struct ath10k *ar = arvif->ar;
265 struct ath10k_peer *peer;
266 int ret;
267 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100268 u32 flags;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300269
270 lockdep_assert_held(&ar->conf_mutex);
271
Michal Kazior8674d902015-08-13 14:10:46 +0200272 if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP &&
Peter Oh7c97b722015-12-03 09:50:55 -0800273 arvif->vif->type != NL80211_IFTYPE_ADHOC &&
274 arvif->vif->type != NL80211_IFTYPE_MESH_POINT))
Michal Kazior8674d902015-08-13 14:10:46 +0200275 return -EINVAL;
276
Kalle Valo5e3dd152013-06-12 20:52:10 +0300277 spin_lock_bh(&ar->data_lock);
278 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
279 spin_unlock_bh(&ar->data_lock);
280
281 if (!peer)
282 return -ENOENT;
283
284 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
285 if (arvif->wep_keys[i] == NULL)
286 continue;
Michal Kazior370e5672015-02-18 14:02:26 +0100287
Michal Kazior8674d902015-08-13 14:10:46 +0200288 switch (arvif->vif->type) {
289 case NL80211_IFTYPE_AP:
290 flags = WMI_KEY_PAIRWISE;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300291
Michal Kazior8674d902015-08-13 14:10:46 +0200292 if (arvif->def_wep_key_idx == i)
293 flags |= WMI_KEY_TX_USAGE;
Michal Kaziorce90b272015-04-10 13:23:21 +0000294
Michal Kazior8674d902015-08-13 14:10:46 +0200295 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
296 SET_KEY, addr, flags);
297 if (ret < 0)
298 return ret;
299 break;
300 case NL80211_IFTYPE_ADHOC:
301 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
302 SET_KEY, addr,
303 WMI_KEY_PAIRWISE);
304 if (ret < 0)
305 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300306
Michal Kazior8674d902015-08-13 14:10:46 +0200307 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
308 SET_KEY, addr, WMI_KEY_GROUP);
309 if (ret < 0)
310 return ret;
311 break;
312 default:
313 WARN_ON(1);
314 return -EINVAL;
315 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300316
Sujith Manoharanae167132014-11-25 11:46:59 +0530317 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300318 peer->keys[i] = arvif->wep_keys[i];
Sujith Manoharanae167132014-11-25 11:46:59 +0530319 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300320 }
321
Michal Kaziorce90b272015-04-10 13:23:21 +0000322 /* In some cases (notably with static WEP IBSS with multiple keys)
323 * multicast Tx becomes broken. Both pairwise and groupwise keys are
324 * installed already. Using WMI_KEY_TX_USAGE in different combinations
325 * didn't seem help. Using def_keyid vdev parameter seems to be
326 * effective so use that.
327 *
328 * FIXME: Revisit. Perhaps this can be done in a less hacky way.
329 */
Michal Kazior8674d902015-08-13 14:10:46 +0200330 if (arvif->vif->type != NL80211_IFTYPE_ADHOC)
331 return 0;
332
Michal Kaziorce90b272015-04-10 13:23:21 +0000333 if (arvif->def_wep_key_idx == -1)
334 return 0;
335
336 ret = ath10k_wmi_vdev_set_param(arvif->ar,
337 arvif->vdev_id,
338 arvif->ar->wmi.vdev_param->def_keyid,
339 arvif->def_wep_key_idx);
340 if (ret) {
341 ath10k_warn(ar, "failed to re-set def wpa key idxon vdev %i: %d\n",
342 arvif->vdev_id, ret);
343 return ret;
344 }
345
Kalle Valo5e3dd152013-06-12 20:52:10 +0300346 return 0;
347}
348
349static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
350 const u8 *addr)
351{
352 struct ath10k *ar = arvif->ar;
353 struct ath10k_peer *peer;
354 int first_errno = 0;
355 int ret;
356 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100357 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300358
359 lockdep_assert_held(&ar->conf_mutex);
360
361 spin_lock_bh(&ar->data_lock);
362 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
363 spin_unlock_bh(&ar->data_lock);
364
365 if (!peer)
366 return -ENOENT;
367
368 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
369 if (peer->keys[i] == NULL)
370 continue;
371
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200372 /* key flags are not required to delete the key */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300373 ret = ath10k_install_key(arvif, peer->keys[i],
Michal Kazior370e5672015-02-18 14:02:26 +0100374 DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300375 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300376 first_errno = ret;
377
David Liuccec9032015-07-24 20:25:32 +0300378 if (ret < 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200379 ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300380 i, ret);
381
Sujith Manoharanae167132014-11-25 11:46:59 +0530382 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300383 peer->keys[i] = NULL;
Sujith Manoharanae167132014-11-25 11:46:59 +0530384 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300385 }
386
387 return first_errno;
388}
389
Sujith Manoharan504f6cd2014-11-25 11:46:58 +0530390bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
391 u8 keyidx)
392{
393 struct ath10k_peer *peer;
394 int i;
395
396 lockdep_assert_held(&ar->data_lock);
397
398 /* We don't know which vdev this peer belongs to,
399 * since WMI doesn't give us that information.
400 *
401 * FIXME: multi-bss needs to be handled.
402 */
403 peer = ath10k_peer_find(ar, 0, addr);
404 if (!peer)
405 return false;
406
407 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
408 if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)
409 return true;
410 }
411
412 return false;
413}
414
Kalle Valo5e3dd152013-06-12 20:52:10 +0300415static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
416 struct ieee80211_key_conf *key)
417{
418 struct ath10k *ar = arvif->ar;
419 struct ath10k_peer *peer;
420 u8 addr[ETH_ALEN];
421 int first_errno = 0;
422 int ret;
423 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100424 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300425
426 lockdep_assert_held(&ar->conf_mutex);
427
428 for (;;) {
429 /* since ath10k_install_key we can't hold data_lock all the
430 * time, so we try to remove the keys incrementally */
431 spin_lock_bh(&ar->data_lock);
432 i = 0;
433 list_for_each_entry(peer, &ar->peers, list) {
434 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
435 if (peer->keys[i] == key) {
Kalle Valob25f32c2014-09-14 12:50:49 +0300436 ether_addr_copy(addr, peer->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300437 peer->keys[i] = NULL;
438 break;
439 }
440 }
441
442 if (i < ARRAY_SIZE(peer->keys))
443 break;
444 }
445 spin_unlock_bh(&ar->data_lock);
446
447 if (i == ARRAY_SIZE(peer->keys))
448 break;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200449 /* key flags are not required to delete the key */
Michal Kazior370e5672015-02-18 14:02:26 +0100450 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300451 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300452 first_errno = ret;
453
454 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200455 ath10k_warn(ar, "failed to remove key for %pM: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +0200456 addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300457 }
458
459 return first_errno;
460}
461
Michal Kaziorad325cb2015-02-18 14:02:27 +0100462static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
463 struct ieee80211_key_conf *key)
464{
465 struct ath10k *ar = arvif->ar;
466 struct ath10k_peer *peer;
467 int ret;
468
469 lockdep_assert_held(&ar->conf_mutex);
470
471 list_for_each_entry(peer, &ar->peers, list) {
Kalle Valoc178da52016-04-13 14:13:49 +0300472 if (ether_addr_equal(peer->addr, arvif->vif->addr))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100473 continue;
474
Kalle Valoc178da52016-04-13 14:13:49 +0300475 if (ether_addr_equal(peer->addr, arvif->bssid))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100476 continue;
477
478 if (peer->keys[key->keyidx] == key)
479 continue;
480
481 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
482 arvif->vdev_id, key->keyidx);
483
484 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
485 if (ret) {
486 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
487 arvif->vdev_id, peer->addr, ret);
488 return ret;
489 }
490 }
491
492 return 0;
493}
494
Kalle Valo5e3dd152013-06-12 20:52:10 +0300495/*********************/
496/* General utilities */
497/*********************/
498
499static inline enum wmi_phy_mode
500chan_to_phymode(const struct cfg80211_chan_def *chandef)
501{
502 enum wmi_phy_mode phymode = MODE_UNKNOWN;
503
504 switch (chandef->chan->band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +0200505 case NL80211_BAND_2GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300506 switch (chandef->width) {
507 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800508 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
509 phymode = MODE_11B;
510 else
511 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300512 break;
513 case NL80211_CHAN_WIDTH_20:
514 phymode = MODE_11NG_HT20;
515 break;
516 case NL80211_CHAN_WIDTH_40:
517 phymode = MODE_11NG_HT40;
518 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400519 case NL80211_CHAN_WIDTH_5:
520 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300521 case NL80211_CHAN_WIDTH_80:
522 case NL80211_CHAN_WIDTH_80P80:
523 case NL80211_CHAN_WIDTH_160:
524 phymode = MODE_UNKNOWN;
525 break;
526 }
527 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +0200528 case NL80211_BAND_5GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300529 switch (chandef->width) {
530 case NL80211_CHAN_WIDTH_20_NOHT:
531 phymode = MODE_11A;
532 break;
533 case NL80211_CHAN_WIDTH_20:
534 phymode = MODE_11NA_HT20;
535 break;
536 case NL80211_CHAN_WIDTH_40:
537 phymode = MODE_11NA_HT40;
538 break;
539 case NL80211_CHAN_WIDTH_80:
540 phymode = MODE_11AC_VHT80;
541 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400542 case NL80211_CHAN_WIDTH_5:
543 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300544 case NL80211_CHAN_WIDTH_80P80:
545 case NL80211_CHAN_WIDTH_160:
546 phymode = MODE_UNKNOWN;
547 break;
548 }
549 break;
550 default:
551 break;
552 }
553
554 WARN_ON(phymode == MODE_UNKNOWN);
555 return phymode;
556}
557
558static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
559{
560/*
561 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
562 * 0 for no restriction
563 * 1 for 1/4 us
564 * 2 for 1/2 us
565 * 3 for 1 us
566 * 4 for 2 us
567 * 5 for 4 us
568 * 6 for 8 us
569 * 7 for 16 us
570 */
571 switch (mpdudensity) {
572 case 0:
573 return 0;
574 case 1:
575 case 2:
576 case 3:
577 /* Our lower layer calculations limit our precision to
578 1 microsecond */
579 return 1;
580 case 4:
581 return 2;
582 case 5:
583 return 4;
584 case 6:
585 return 8;
586 case 7:
587 return 16;
588 default:
589 return 0;
590 }
591}
592
Michal Kazior500ff9f2015-03-31 10:26:21 +0000593int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
594 struct cfg80211_chan_def *def)
595{
596 struct ieee80211_chanctx_conf *conf;
597
598 rcu_read_lock();
599 conf = rcu_dereference(vif->chanctx_conf);
600 if (!conf) {
601 rcu_read_unlock();
602 return -ENOENT;
603 }
604
605 *def = conf->def;
606 rcu_read_unlock();
607
608 return 0;
609}
610
611static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,
612 struct ieee80211_chanctx_conf *conf,
613 void *data)
614{
615 int *num = data;
616
617 (*num)++;
618}
619
620static int ath10k_mac_num_chanctxs(struct ath10k *ar)
621{
622 int num = 0;
623
624 ieee80211_iter_chan_contexts_atomic(ar->hw,
625 ath10k_mac_num_chanctxs_iter,
626 &num);
627
628 return num;
629}
630
631static void
632ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
633 struct ieee80211_chanctx_conf *conf,
634 void *data)
635{
636 struct cfg80211_chan_def **def = data;
637
638 *def = &conf->def;
639}
640
Michal Kazior69427262016-03-06 16:14:30 +0200641static int ath10k_peer_create(struct ath10k *ar,
642 struct ieee80211_vif *vif,
643 struct ieee80211_sta *sta,
644 u32 vdev_id,
645 const u8 *addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300646 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300647{
Michal Kaziore04cafb2015-08-05 12:15:24 +0200648 struct ath10k_vif *arvif;
Michal Kazior69427262016-03-06 16:14:30 +0200649 struct ath10k_peer *peer;
Michal Kaziore04cafb2015-08-05 12:15:24 +0200650 int num_peers = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300651 int ret;
652
653 lockdep_assert_held(&ar->conf_mutex);
654
Michal Kaziore04cafb2015-08-05 12:15:24 +0200655 num_peers = ar->num_peers;
656
657 /* Each vdev consumes a peer entry as well */
658 list_for_each_entry(arvif, &ar->arvifs, list)
659 num_peers++;
660
661 if (num_peers >= ar->max_num_peers)
Michal Kaziorcfd10612014-11-25 15:16:05 +0100662 return -ENOBUFS;
663
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300664 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800665 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200666 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200667 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300668 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800669 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300670
671 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800672 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200673 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200674 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300675 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800676 }
Michal Kazior292a7532014-11-25 15:16:04 +0100677
Michal Kazior69427262016-03-06 16:14:30 +0200678 spin_lock_bh(&ar->data_lock);
679
680 peer = ath10k_peer_find(ar, vdev_id, addr);
681 if (!peer) {
682 ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n",
683 addr, vdev_id);
684 ath10k_wmi_peer_delete(ar, vdev_id, addr);
685 spin_unlock_bh(&ar->data_lock);
686 return -ENOENT;
687 }
688
689 peer->vif = vif;
690 peer->sta = sta;
691
692 spin_unlock_bh(&ar->data_lock);
693
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100694 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300695
696 return 0;
697}
698
Kalle Valo5a13e762014-01-20 11:01:46 +0200699static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
700{
701 struct ath10k *ar = arvif->ar;
702 u32 param;
703 int ret;
704
705 param = ar->wmi.pdev_param->sta_kickout_th;
706 ret = ath10k_wmi_pdev_set_param(ar, param,
707 ATH10K_KICKOUT_THRESHOLD);
708 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200709 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200710 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200711 return ret;
712 }
713
714 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
715 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
716 ATH10K_KEEPALIVE_MIN_IDLE);
717 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200718 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200719 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200720 return ret;
721 }
722
723 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
724 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
725 ATH10K_KEEPALIVE_MAX_IDLE);
726 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200727 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200728 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200729 return ret;
730 }
731
732 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
733 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
734 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
735 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200736 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200737 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200738 return ret;
739 }
740
741 return 0;
742}
743
Vivek Natarajanacab6402014-11-26 09:06:12 +0200744static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200745{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200746 struct ath10k *ar = arvif->ar;
747 u32 vdev_param;
748
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200749 vdev_param = ar->wmi.vdev_param->rts_threshold;
750 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200751}
752
Kalle Valo5e3dd152013-06-12 20:52:10 +0300753static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
754{
755 int ret;
756
757 lockdep_assert_held(&ar->conf_mutex);
758
759 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
760 if (ret)
761 return ret;
762
763 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
764 if (ret)
765 return ret;
766
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100767 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100768
Kalle Valo5e3dd152013-06-12 20:52:10 +0300769 return 0;
770}
771
772static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
773{
774 struct ath10k_peer *peer, *tmp;
Michal Kazior69427262016-03-06 16:14:30 +0200775 int peer_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300776
777 lockdep_assert_held(&ar->conf_mutex);
778
779 spin_lock_bh(&ar->data_lock);
780 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
781 if (peer->vdev_id != vdev_id)
782 continue;
783
Michal Kazior7aa7a722014-08-25 12:09:38 +0200784 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300785 peer->addr, vdev_id);
786
Michal Kazior69427262016-03-06 16:14:30 +0200787 for_each_set_bit(peer_id, peer->peer_ids,
788 ATH10K_MAX_NUM_PEER_IDS) {
789 ar->peer_map[peer_id] = NULL;
790 }
791
Kalle Valo5e3dd152013-06-12 20:52:10 +0300792 list_del(&peer->list);
793 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100794 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300795 }
796 spin_unlock_bh(&ar->data_lock);
797}
798
Michal Kaziora96d7742013-07-16 09:38:56 +0200799static void ath10k_peer_cleanup_all(struct ath10k *ar)
800{
801 struct ath10k_peer *peer, *tmp;
802
803 lockdep_assert_held(&ar->conf_mutex);
804
805 spin_lock_bh(&ar->data_lock);
806 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
807 list_del(&peer->list);
808 kfree(peer);
809 }
810 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100811
812 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100813 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200814}
815
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300816static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
817 struct ieee80211_sta *sta,
818 enum wmi_tdls_peer_state state)
819{
820 int ret;
821 struct wmi_tdls_peer_update_cmd_arg arg = {};
822 struct wmi_tdls_peer_capab_arg cap = {};
823 struct wmi_channel_arg chan_arg = {};
824
825 lockdep_assert_held(&ar->conf_mutex);
826
827 arg.vdev_id = vdev_id;
828 arg.peer_state = state;
829 ether_addr_copy(arg.addr, sta->addr);
830
831 cap.peer_max_sp = sta->max_sp;
832 cap.peer_uapsd_queues = sta->uapsd_queues;
833
834 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
835 !sta->tdls_initiator)
836 cap.is_peer_responder = 1;
837
838 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
839 if (ret) {
840 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
841 arg.addr, vdev_id, ret);
842 return ret;
843 }
844
845 return 0;
846}
847
Kalle Valo5e3dd152013-06-12 20:52:10 +0300848/************************/
849/* Interface management */
850/************************/
851
Michal Kazior64badcb2014-09-18 11:18:02 +0300852void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
853{
854 struct ath10k *ar = arvif->ar;
855
856 lockdep_assert_held(&ar->data_lock);
857
858 if (!arvif->beacon)
859 return;
860
861 if (!arvif->beacon_buf)
862 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
863 arvif->beacon->len, DMA_TO_DEVICE);
864
Michal Kazioraf213192015-01-29 14:29:52 +0200865 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
866 arvif->beacon_state != ATH10K_BEACON_SENT))
867 return;
868
Michal Kazior64badcb2014-09-18 11:18:02 +0300869 dev_kfree_skb_any(arvif->beacon);
870
871 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200872 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300873}
874
875static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
876{
877 struct ath10k *ar = arvif->ar;
878
879 lockdep_assert_held(&ar->data_lock);
880
881 ath10k_mac_vif_beacon_free(arvif);
882
883 if (arvif->beacon_buf) {
884 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
885 arvif->beacon_buf, arvif->beacon_paddr);
886 arvif->beacon_buf = NULL;
887 }
888}
889
Kalle Valo5e3dd152013-06-12 20:52:10 +0300890static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
891{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300892 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300893
Michal Kazior548db542013-07-05 16:15:15 +0300894 lockdep_assert_held(&ar->conf_mutex);
895
Michal Kazior7962b0d2014-10-28 10:34:38 +0100896 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
897 return -ESHUTDOWN;
898
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300899 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
900 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
901 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300902 return -ETIMEDOUT;
903
904 return 0;
905}
906
Michal Kazior1bbc0972014-04-08 09:45:47 +0300907static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300908{
Michal Kazior500ff9f2015-03-31 10:26:21 +0000909 struct cfg80211_chan_def *chandef = NULL;
Maninder Singh19be9e92015-07-16 09:25:33 +0530910 struct ieee80211_channel *channel = NULL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300911 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300912 int ret = 0;
913
914 lockdep_assert_held(&ar->conf_mutex);
915
Michal Kazior500ff9f2015-03-31 10:26:21 +0000916 ieee80211_iter_chan_contexts_atomic(ar->hw,
917 ath10k_mac_get_any_chandef_iter,
918 &chandef);
919 if (WARN_ON_ONCE(!chandef))
920 return -ENOENT;
921
922 channel = chandef->chan;
923
Kalle Valo5e3dd152013-06-12 20:52:10 +0300924 arg.vdev_id = vdev_id;
925 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +0100926 arg.channel.band_center_freq1 = chandef->center_freq1;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300927
928 /* TODO setup this dynamically, what in case we
929 don't have any vifs? */
Michal Kaziorc930f742014-01-23 11:38:25 +0100930 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200931 arg.channel.chan_radar =
932 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300933
Michal Kazior89c5c842013-10-23 04:02:13 -0700934 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -0700935 arg.channel.max_power = channel->max_power * 2;
936 arg.channel.max_reg_power = channel->max_reg_power * 2;
937 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300938
Michal Kazior7962b0d2014-10-28 10:34:38 +0100939 reinit_completion(&ar->vdev_setup_done);
940
Kalle Valo5e3dd152013-06-12 20:52:10 +0300941 ret = ath10k_wmi_vdev_start(ar, &arg);
942 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200943 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200944 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300945 return ret;
946 }
947
948 ret = ath10k_vdev_setup_sync(ar);
949 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +0200950 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200951 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300952 return ret;
953 }
954
955 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
956 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200957 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200958 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300959 goto vdev_stop;
960 }
961
962 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300963
Michal Kazior7aa7a722014-08-25 12:09:38 +0200964 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300965 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300966 return 0;
967
968vdev_stop:
969 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
970 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200971 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200972 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300973
974 return ret;
975}
976
Michal Kazior1bbc0972014-04-08 09:45:47 +0300977static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300978{
979 int ret = 0;
980
981 lockdep_assert_held(&ar->conf_mutex);
982
Marek Puzyniak52fa0192013-09-24 14:06:24 +0200983 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
984 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200985 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200986 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300987
Michal Kazior7962b0d2014-10-28 10:34:38 +0100988 reinit_completion(&ar->vdev_setup_done);
989
Kalle Valo5e3dd152013-06-12 20:52:10 +0300990 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
991 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200992 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200993 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300994
995 ret = ath10k_vdev_setup_sync(ar);
996 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +0200997 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200998 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300999
Michal Kazior7aa7a722014-08-25 12:09:38 +02001000 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001001 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001002 return ret;
1003}
1004
Michal Kazior1bbc0972014-04-08 09:45:47 +03001005static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001006{
1007 int bit, ret = 0;
1008
1009 lockdep_assert_held(&ar->conf_mutex);
1010
Ben Greeara9aefb32014-08-12 11:02:19 +03001011 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001012 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03001013 return -ENOMEM;
1014 }
1015
Ben Greear16c11172014-09-23 14:17:16 -07001016 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +03001017
Ben Greear16c11172014-09-23 14:17:16 -07001018 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001019
1020 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
1021 WMI_VDEV_TYPE_MONITOR,
1022 0, ar->mac_addr);
1023 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001024 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001025 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +03001026 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001027 }
1028
Ben Greear16c11172014-09-23 14:17:16 -07001029 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +02001030 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001031 ar->monitor_vdev_id);
1032
Kalle Valo5e3dd152013-06-12 20:52:10 +03001033 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001034}
1035
Michal Kazior1bbc0972014-04-08 09:45:47 +03001036static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001037{
1038 int ret = 0;
1039
1040 lockdep_assert_held(&ar->conf_mutex);
1041
Kalle Valo5e3dd152013-06-12 20:52:10 +03001042 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
1043 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001044 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001045 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001046 return ret;
1047 }
1048
Ben Greear16c11172014-09-23 14:17:16 -07001049 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001050
Michal Kazior7aa7a722014-08-25 12:09:38 +02001051 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001052 ar->monitor_vdev_id);
1053 return ret;
1054}
1055
Michal Kazior1bbc0972014-04-08 09:45:47 +03001056static int ath10k_monitor_start(struct ath10k *ar)
1057{
1058 int ret;
1059
1060 lockdep_assert_held(&ar->conf_mutex);
1061
Michal Kazior1bbc0972014-04-08 09:45:47 +03001062 ret = ath10k_monitor_vdev_create(ar);
1063 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001064 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001065 return ret;
1066 }
1067
1068 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
1069 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001070 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001071 ath10k_monitor_vdev_delete(ar);
1072 return ret;
1073 }
1074
1075 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001076 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +03001077
1078 return 0;
1079}
1080
Michal Kazior19337472014-08-28 12:58:16 +02001081static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +03001082{
1083 int ret;
1084
1085 lockdep_assert_held(&ar->conf_mutex);
1086
Michal Kazior1bbc0972014-04-08 09:45:47 +03001087 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001088 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001089 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001090 return ret;
1091 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001092
1093 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001094 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001095 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001096 return ret;
1097 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001098
1099 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001100 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +02001101
1102 return 0;
1103}
1104
Michal Kazior500ff9f2015-03-31 10:26:21 +00001105static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1106{
1107 int num_ctx;
1108
1109 /* At least one chanctx is required to derive a channel to start
1110 * monitor vdev on.
1111 */
1112 num_ctx = ath10k_mac_num_chanctxs(ar);
1113 if (num_ctx == 0)
1114 return false;
1115
1116 /* If there's already an existing special monitor interface then don't
1117 * bother creating another monitor vdev.
1118 */
1119 if (ar->monitor_arvif)
1120 return false;
1121
1122 return ar->monitor ||
Bob Copeland0d031c82015-09-09 12:47:34 -04001123 ar->filter_flags & FIF_OTHER_BSS ||
Michal Kazior500ff9f2015-03-31 10:26:21 +00001124 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1125}
1126
1127static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1128{
1129 int num_ctx;
1130
1131 num_ctx = ath10k_mac_num_chanctxs(ar);
1132
1133 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1134 * shouldn't allow this but make sure to prevent handling the following
1135 * case anyway since multi-channel DFS hasn't been tested at all.
1136 */
1137 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1138 return false;
1139
1140 return true;
1141}
1142
Michal Kazior19337472014-08-28 12:58:16 +02001143static int ath10k_monitor_recalc(struct ath10k *ar)
1144{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001145 bool needed;
1146 bool allowed;
1147 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001148
1149 lockdep_assert_held(&ar->conf_mutex);
1150
Michal Kazior500ff9f2015-03-31 10:26:21 +00001151 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1152 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001153
1154 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001155 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1156 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001157
Michal Kazior500ff9f2015-03-31 10:26:21 +00001158 if (WARN_ON(needed && !allowed)) {
1159 if (ar->monitor_started) {
1160 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1161
1162 ret = ath10k_monitor_stop(ar);
1163 if (ret)
Kalle Valo2a995082015-10-05 17:56:37 +03001164 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",
1165 ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001166 /* not serious */
1167 }
1168
1169 return -EPERM;
1170 }
1171
1172 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001173 return 0;
1174
Michal Kazior500ff9f2015-03-31 10:26:21 +00001175 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001176 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001177 else
1178 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001179}
1180
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001181static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1182{
1183 struct ath10k *ar = arvif->ar;
1184 u32 vdev_param, rts_cts = 0;
1185
1186 lockdep_assert_held(&ar->conf_mutex);
1187
1188 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1189
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001190 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001191
1192 if (arvif->num_legacy_stations > 0)
1193 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1194 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001195 else
1196 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1197 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001198
1199 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1200 rts_cts);
1201}
1202
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001203static int ath10k_start_cac(struct ath10k *ar)
1204{
1205 int ret;
1206
1207 lockdep_assert_held(&ar->conf_mutex);
1208
1209 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1210
Michal Kazior19337472014-08-28 12:58:16 +02001211 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001212 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001213 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001214 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1215 return ret;
1216 }
1217
Michal Kazior7aa7a722014-08-25 12:09:38 +02001218 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001219 ar->monitor_vdev_id);
1220
1221 return 0;
1222}
1223
1224static int ath10k_stop_cac(struct ath10k *ar)
1225{
1226 lockdep_assert_held(&ar->conf_mutex);
1227
1228 /* CAC is not running - do nothing */
1229 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1230 return 0;
1231
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001232 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001233 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001234
Michal Kazior7aa7a722014-08-25 12:09:38 +02001235 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001236
1237 return 0;
1238}
1239
Michal Kazior500ff9f2015-03-31 10:26:21 +00001240static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1241 struct ieee80211_chanctx_conf *conf,
1242 void *data)
1243{
1244 bool *ret = data;
1245
1246 if (!*ret && conf->radar_enabled)
1247 *ret = true;
1248}
1249
1250static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1251{
1252 bool has_radar = false;
1253
1254 ieee80211_iter_chan_contexts_atomic(ar->hw,
1255 ath10k_mac_has_radar_iter,
1256 &has_radar);
1257
1258 return has_radar;
1259}
1260
Michal Kaziord6500972014-04-08 09:56:09 +03001261static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001262{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001263 int ret;
1264
1265 lockdep_assert_held(&ar->conf_mutex);
1266
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001267 ath10k_stop_cac(ar);
1268
Michal Kazior500ff9f2015-03-31 10:26:21 +00001269 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001270 return;
1271
Michal Kaziord6500972014-04-08 09:56:09 +03001272 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001273 return;
1274
1275 ret = ath10k_start_cac(ar);
1276 if (ret) {
1277 /*
1278 * Not possible to start CAC on current channel so starting
1279 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1280 * by indicating that radar was detected.
1281 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001282 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001283 ieee80211_radar_detected(ar->hw);
1284 }
1285}
1286
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301287static int ath10k_vdev_stop(struct ath10k_vif *arvif)
Michal Kazior72654fa2014-04-08 09:56:09 +03001288{
1289 struct ath10k *ar = arvif->ar;
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301290 int ret;
1291
1292 lockdep_assert_held(&ar->conf_mutex);
1293
1294 reinit_completion(&ar->vdev_setup_done);
1295
1296 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1297 if (ret) {
1298 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1299 arvif->vdev_id, ret);
1300 return ret;
1301 }
1302
1303 ret = ath10k_vdev_setup_sync(ar);
1304 if (ret) {
1305 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
1306 arvif->vdev_id, ret);
1307 return ret;
1308 }
1309
1310 WARN_ON(ar->num_started_vdevs == 0);
1311
1312 if (ar->num_started_vdevs != 0) {
1313 ar->num_started_vdevs--;
1314 ath10k_recalc_radar_detection(ar);
1315 }
1316
1317 return ret;
1318}
1319
Michal Kazior500ff9f2015-03-31 10:26:21 +00001320static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1321 const struct cfg80211_chan_def *chandef,
1322 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001323{
1324 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001325 struct wmi_vdev_start_request_arg arg = {};
1326 int ret = 0;
1327
1328 lockdep_assert_held(&ar->conf_mutex);
1329
1330 reinit_completion(&ar->vdev_setup_done);
1331
1332 arg.vdev_id = arvif->vdev_id;
1333 arg.dtim_period = arvif->dtim_period;
1334 arg.bcn_intval = arvif->beacon_interval;
1335
1336 arg.channel.freq = chandef->chan->center_freq;
1337 arg.channel.band_center_freq1 = chandef->center_freq1;
1338 arg.channel.mode = chan_to_phymode(chandef);
1339
1340 arg.channel.min_power = 0;
1341 arg.channel.max_power = chandef->chan->max_power * 2;
1342 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1343 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1344
1345 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1346 arg.ssid = arvif->u.ap.ssid;
1347 arg.ssid_len = arvif->u.ap.ssid_len;
1348 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1349
1350 /* For now allow DFS for AP mode */
1351 arg.channel.chan_radar =
1352 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1353 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1354 arg.ssid = arvif->vif->bss_conf.ssid;
1355 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1356 }
1357
Michal Kazior7aa7a722014-08-25 12:09:38 +02001358 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001359 "mac vdev %d start center_freq %d phymode %s\n",
1360 arg.vdev_id, arg.channel.freq,
1361 ath10k_wmi_phymode_str(arg.channel.mode));
1362
Michal Kaziordc55e302014-07-29 12:53:36 +03001363 if (restart)
1364 ret = ath10k_wmi_vdev_restart(ar, &arg);
1365 else
1366 ret = ath10k_wmi_vdev_start(ar, &arg);
1367
Michal Kazior72654fa2014-04-08 09:56:09 +03001368 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001369 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001370 arg.vdev_id, ret);
1371 return ret;
1372 }
1373
1374 ret = ath10k_vdev_setup_sync(ar);
1375 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001376 ath10k_warn(ar,
1377 "failed to synchronize setup for vdev %i restart %d: %d\n",
1378 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001379 return ret;
1380 }
1381
Michal Kaziord6500972014-04-08 09:56:09 +03001382 ar->num_started_vdevs++;
1383 ath10k_recalc_radar_detection(ar);
1384
Michal Kazior72654fa2014-04-08 09:56:09 +03001385 return ret;
1386}
1387
Michal Kazior500ff9f2015-03-31 10:26:21 +00001388static int ath10k_vdev_start(struct ath10k_vif *arvif,
1389 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001390{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001391 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001392}
1393
Michal Kazior500ff9f2015-03-31 10:26:21 +00001394static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1395 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001396{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001397 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kazior72654fa2014-04-08 09:56:09 +03001398}
1399
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001400static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1401 struct sk_buff *bcn)
1402{
1403 struct ath10k *ar = arvif->ar;
1404 struct ieee80211_mgmt *mgmt;
1405 const u8 *p2p_ie;
1406 int ret;
1407
Peter Oh08c27be2016-01-28 13:54:09 -08001408 if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001409 return 0;
1410
1411 mgmt = (void *)bcn->data;
1412 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1413 mgmt->u.beacon.variable,
1414 bcn->len - (mgmt->u.beacon.variable -
1415 bcn->data));
1416 if (!p2p_ie)
1417 return -ENOENT;
1418
1419 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1420 if (ret) {
1421 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1422 arvif->vdev_id, ret);
1423 return ret;
1424 }
1425
1426 return 0;
1427}
1428
1429static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1430 u8 oui_type, size_t ie_offset)
1431{
1432 size_t len;
1433 const u8 *next;
1434 const u8 *end;
1435 u8 *ie;
1436
1437 if (WARN_ON(skb->len < ie_offset))
1438 return -EINVAL;
1439
1440 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1441 skb->data + ie_offset,
1442 skb->len - ie_offset);
1443 if (!ie)
1444 return -ENOENT;
1445
1446 len = ie[1] + 2;
1447 end = skb->data + skb->len;
1448 next = ie + len;
1449
1450 if (WARN_ON(next > end))
1451 return -EINVAL;
1452
1453 memmove(ie, next, end - next);
1454 skb_trim(skb, skb->len - len);
1455
1456 return 0;
1457}
1458
1459static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1460{
1461 struct ath10k *ar = arvif->ar;
1462 struct ieee80211_hw *hw = ar->hw;
1463 struct ieee80211_vif *vif = arvif->vif;
1464 struct ieee80211_mutable_offsets offs = {};
1465 struct sk_buff *bcn;
1466 int ret;
1467
1468 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1469 return 0;
1470
Michal Kazior81a9a172015-03-05 16:02:17 +02001471 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1472 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1473 return 0;
1474
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001475 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1476 if (!bcn) {
1477 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1478 return -EPERM;
1479 }
1480
1481 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1482 if (ret) {
1483 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1484 kfree_skb(bcn);
1485 return ret;
1486 }
1487
1488 /* P2P IE is inserted by firmware automatically (as configured above)
1489 * so remove it from the base beacon template to avoid duplicate P2P
1490 * IEs in beacon frames.
1491 */
1492 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1493 offsetof(struct ieee80211_mgmt,
1494 u.beacon.variable));
1495
1496 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1497 0, NULL, 0);
1498 kfree_skb(bcn);
1499
1500 if (ret) {
1501 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1502 ret);
1503 return ret;
1504 }
1505
1506 return 0;
1507}
1508
1509static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1510{
1511 struct ath10k *ar = arvif->ar;
1512 struct ieee80211_hw *hw = ar->hw;
1513 struct ieee80211_vif *vif = arvif->vif;
1514 struct sk_buff *prb;
1515 int ret;
1516
1517 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1518 return 0;
1519
Michal Kazior81a9a172015-03-05 16:02:17 +02001520 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1521 return 0;
1522
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001523 prb = ieee80211_proberesp_get(hw, vif);
1524 if (!prb) {
1525 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1526 return -EPERM;
1527 }
1528
1529 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1530 kfree_skb(prb);
1531
1532 if (ret) {
1533 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1534 ret);
1535 return ret;
1536 }
1537
1538 return 0;
1539}
1540
Michal Kazior500ff9f2015-03-31 10:26:21 +00001541static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1542{
1543 struct ath10k *ar = arvif->ar;
1544 struct cfg80211_chan_def def;
1545 int ret;
1546
1547 /* When originally vdev is started during assign_vif_chanctx() some
1548 * information is missing, notably SSID. Firmware revisions with beacon
1549 * offloading require the SSID to be provided during vdev (re)start to
1550 * handle hidden SSID properly.
1551 *
1552 * Vdev restart must be done after vdev has been both started and
1553 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1554 * deliver vdev restart response event causing timeouts during vdev
1555 * syncing in ath10k.
1556 *
1557 * Note: The vdev down/up and template reinstallation could be skipped
1558 * since only wmi-tlv firmware are known to have beacon offload and
1559 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1560 * response delivery. It's probably more robust to keep it as is.
1561 */
1562 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1563 return 0;
1564
1565 if (WARN_ON(!arvif->is_started))
1566 return -EINVAL;
1567
1568 if (WARN_ON(!arvif->is_up))
1569 return -EINVAL;
1570
1571 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1572 return -EINVAL;
1573
1574 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1575 if (ret) {
1576 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1577 arvif->vdev_id, ret);
1578 return ret;
1579 }
1580
1581 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1582 * firmware will crash upon vdev up.
1583 */
1584
1585 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1586 if (ret) {
1587 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1588 return ret;
1589 }
1590
1591 ret = ath10k_mac_setup_prb_tmpl(arvif);
1592 if (ret) {
1593 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1594 return ret;
1595 }
1596
1597 ret = ath10k_vdev_restart(arvif, &def);
1598 if (ret) {
1599 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1600 arvif->vdev_id, ret);
1601 return ret;
1602 }
1603
1604 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1605 arvif->bssid);
1606 if (ret) {
1607 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1608 arvif->vdev_id, ret);
1609 return ret;
1610 }
1611
1612 return 0;
1613}
1614
Kalle Valo5e3dd152013-06-12 20:52:10 +03001615static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001616 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001617{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001618 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001619 int ret = 0;
1620
Michal Kazior548db542013-07-05 16:15:15 +03001621 lockdep_assert_held(&arvif->ar->conf_mutex);
1622
Kalle Valo5e3dd152013-06-12 20:52:10 +03001623 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001624 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1625 if (ret)
1626 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1627 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001628
Michal Kaziorc930f742014-01-23 11:38:25 +01001629 arvif->is_up = false;
1630
Michal Kazior748afc42014-01-23 12:48:21 +01001631 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001632 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001633 spin_unlock_bh(&arvif->ar->data_lock);
1634
Kalle Valo5e3dd152013-06-12 20:52:10 +03001635 return;
1636 }
1637
1638 arvif->tx_seq_no = 0x1000;
1639
Michal Kaziorc930f742014-01-23 11:38:25 +01001640 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001641 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001642
1643 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1644 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001645 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001646 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001647 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001648 return;
1649 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001650
Michal Kaziorc930f742014-01-23 11:38:25 +01001651 arvif->is_up = true;
1652
Michal Kazior500ff9f2015-03-31 10:26:21 +00001653 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1654 if (ret) {
1655 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1656 arvif->vdev_id, ret);
1657 return;
1658 }
1659
Michal Kazior7aa7a722014-08-25 12:09:38 +02001660 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001661}
1662
1663static void ath10k_control_ibss(struct ath10k_vif *arvif,
1664 struct ieee80211_bss_conf *info,
1665 const u8 self_peer[ETH_ALEN])
1666{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001667 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001668 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001669 int ret = 0;
1670
Michal Kazior548db542013-07-05 16:15:15 +03001671 lockdep_assert_held(&arvif->ar->conf_mutex);
1672
Kalle Valo5e3dd152013-06-12 20:52:10 +03001673 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001674 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001675 return;
1676
Joe Perches93803b32015-03-02 19:54:49 -08001677 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001678
1679 return;
1680 }
1681
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001682 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1683 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001684 ATH10K_DEFAULT_ATIM);
1685 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001686 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001687 arvif->vdev_id, ret);
1688}
1689
Michal Kazior9f9b5742014-12-12 12:41:36 +01001690static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1691{
1692 struct ath10k *ar = arvif->ar;
1693 u32 param;
1694 u32 value;
1695 int ret;
1696
1697 lockdep_assert_held(&arvif->ar->conf_mutex);
1698
1699 if (arvif->u.sta.uapsd)
1700 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1701 else
1702 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1703
1704 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1705 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1706 if (ret) {
1707 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1708 value, arvif->vdev_id, ret);
1709 return ret;
1710 }
1711
1712 return 0;
1713}
1714
1715static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1716{
1717 struct ath10k *ar = arvif->ar;
1718 u32 param;
1719 u32 value;
1720 int ret;
1721
1722 lockdep_assert_held(&arvif->ar->conf_mutex);
1723
1724 if (arvif->u.sta.uapsd)
1725 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1726 else
1727 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1728
1729 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1730 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1731 param, value);
1732 if (ret) {
1733 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1734 value, arvif->vdev_id, ret);
1735 return ret;
1736 }
1737
1738 return 0;
1739}
1740
Michal Kazior424f2632015-07-09 13:08:35 +02001741static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001742{
1743 struct ath10k_vif *arvif;
1744 int num = 0;
1745
1746 lockdep_assert_held(&ar->conf_mutex);
1747
1748 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001749 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001750 num++;
1751
1752 return num;
1753}
1754
Michal Kaziorad088bf2013-10-16 15:44:46 +03001755static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001756{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001757 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001758 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001759 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001760 enum wmi_sta_powersave_param param;
1761 enum wmi_sta_ps_mode psmode;
1762 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001763 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001764 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001765
Michal Kazior548db542013-07-05 16:15:15 +03001766 lockdep_assert_held(&arvif->ar->conf_mutex);
1767
Michal Kaziorad088bf2013-10-16 15:44:46 +03001768 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1769 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001770
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001771 enable_ps = arvif->ps;
1772
Michal Kazior424f2632015-07-09 13:08:35 +02001773 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001774 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
Kalle Valoc4cdf752016-04-20 19:45:18 +03001775 ar->running_fw->fw_file.fw_features)) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001776 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1777 arvif->vdev_id);
1778 enable_ps = false;
1779 }
1780
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001781 if (!arvif->is_started) {
1782 /* mac80211 can update vif powersave state while disconnected.
1783 * Firmware doesn't behave nicely and consumes more power than
1784 * necessary if PS is disabled on a non-started vdev. Hence
1785 * force-enable PS for non-running vdevs.
1786 */
1787 psmode = WMI_STA_PS_MODE_ENABLED;
1788 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001789 psmode = WMI_STA_PS_MODE_ENABLED;
1790 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1791
Michal Kazior526549a2014-12-12 12:41:37 +01001792 ps_timeout = conf->dynamic_ps_timeout;
1793 if (ps_timeout == 0) {
1794 /* Firmware doesn't like 0 */
1795 ps_timeout = ieee80211_tu_to_usec(
1796 vif->bss_conf.beacon_int) / 1000;
1797 }
1798
Michal Kaziorad088bf2013-10-16 15:44:46 +03001799 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001800 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001801 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001802 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001803 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001804 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001805 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001806 } else {
1807 psmode = WMI_STA_PS_MODE_DISABLED;
1808 }
1809
Michal Kazior7aa7a722014-08-25 12:09:38 +02001810 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001811 arvif->vdev_id, psmode ? "enable" : "disable");
1812
Michal Kaziorad088bf2013-10-16 15:44:46 +03001813 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1814 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001815 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001816 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001817 return ret;
1818 }
1819
1820 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001821}
1822
Michal Kazior46725b152015-01-28 09:57:49 +02001823static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1824{
1825 struct ath10k *ar = arvif->ar;
1826 struct wmi_sta_keepalive_arg arg = {};
1827 int ret;
1828
1829 lockdep_assert_held(&arvif->ar->conf_mutex);
1830
1831 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1832 return 0;
1833
1834 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1835 return 0;
1836
1837 /* Some firmware revisions have a bug and ignore the `enabled` field.
1838 * Instead use the interval to disable the keepalive.
1839 */
1840 arg.vdev_id = arvif->vdev_id;
1841 arg.enabled = 1;
1842 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1843 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1844
1845 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1846 if (ret) {
1847 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1848 arvif->vdev_id, ret);
1849 return ret;
1850 }
1851
1852 return 0;
1853}
1854
Michal Kazior81a9a172015-03-05 16:02:17 +02001855static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1856{
1857 struct ath10k *ar = arvif->ar;
1858 struct ieee80211_vif *vif = arvif->vif;
1859 int ret;
1860
Michal Kazior8513d952015-03-09 14:19:24 +01001861 lockdep_assert_held(&arvif->ar->conf_mutex);
1862
1863 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1864 return;
1865
Michal Kazior81a9a172015-03-05 16:02:17 +02001866 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1867 return;
1868
1869 if (!vif->csa_active)
1870 return;
1871
1872 if (!arvif->is_up)
1873 return;
1874
1875 if (!ieee80211_csa_is_complete(vif)) {
1876 ieee80211_csa_update_counter(vif);
1877
1878 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1879 if (ret)
1880 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1881 ret);
1882
1883 ret = ath10k_mac_setup_prb_tmpl(arvif);
1884 if (ret)
1885 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1886 ret);
1887 } else {
1888 ieee80211_csa_finish(vif);
1889 }
1890}
1891
1892static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1893{
1894 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1895 ap_csa_work);
1896 struct ath10k *ar = arvif->ar;
1897
1898 mutex_lock(&ar->conf_mutex);
1899 ath10k_mac_vif_ap_csa_count_down(arvif);
1900 mutex_unlock(&ar->conf_mutex);
1901}
1902
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001903static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1904 struct ieee80211_vif *vif)
1905{
1906 struct sk_buff *skb = data;
1907 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1908 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1909
1910 if (vif->type != NL80211_IFTYPE_STATION)
1911 return;
1912
1913 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1914 return;
1915
1916 cancel_delayed_work(&arvif->connection_loss_work);
1917}
1918
1919void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
1920{
1921 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1922 IEEE80211_IFACE_ITER_NORMAL,
1923 ath10k_mac_handle_beacon_iter,
1924 skb);
1925}
1926
1927static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
1928 struct ieee80211_vif *vif)
1929{
1930 u32 *vdev_id = data;
1931 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1932 struct ath10k *ar = arvif->ar;
1933 struct ieee80211_hw *hw = ar->hw;
1934
1935 if (arvif->vdev_id != *vdev_id)
1936 return;
1937
1938 if (!arvif->is_up)
1939 return;
1940
1941 ieee80211_beacon_loss(vif);
1942
1943 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
1944 * (done by mac80211) succeeds but beacons do not resume then it
1945 * doesn't make sense to continue operation. Queue connection loss work
1946 * which can be cancelled when beacon is received.
1947 */
1948 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
1949 ATH10K_CONNECTION_LOSS_HZ);
1950}
1951
1952void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
1953{
1954 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1955 IEEE80211_IFACE_ITER_NORMAL,
1956 ath10k_mac_handle_beacon_miss_iter,
1957 &vdev_id);
1958}
1959
1960static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
1961{
1962 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1963 connection_loss_work.work);
1964 struct ieee80211_vif *vif = arvif->vif;
1965
1966 if (!arvif->is_up)
1967 return;
1968
1969 ieee80211_connection_loss(vif);
1970}
1971
Kalle Valo5e3dd152013-06-12 20:52:10 +03001972/**********************/
1973/* Station management */
1974/**********************/
1975
Michal Kazior590922a2014-10-21 10:10:29 +03001976static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
1977 struct ieee80211_vif *vif)
1978{
1979 /* Some firmware revisions have unstable STA powersave when listen
1980 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
1981 * generate NullFunc frames properly even if buffered frames have been
1982 * indicated in Beacon TIM. Firmware would seldom wake up to pull
1983 * buffered frames. Often pinging the device from AP would simply fail.
1984 *
1985 * As a workaround set it to 1.
1986 */
1987 if (vif->type == NL80211_IFTYPE_STATION)
1988 return 1;
1989
1990 return ar->hw->conf.listen_interval;
1991}
1992
Kalle Valo5e3dd152013-06-12 20:52:10 +03001993static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03001994 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001995 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001996 struct wmi_peer_assoc_complete_arg *arg)
1997{
Michal Kazior590922a2014-10-21 10:10:29 +03001998 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorc51880e2015-03-30 09:51:57 +03001999 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03002000
Michal Kazior548db542013-07-05 16:15:15 +03002001 lockdep_assert_held(&ar->conf_mutex);
2002
Michal Kaziorc51880e2015-03-30 09:51:57 +03002003 if (vif->type == NL80211_IFTYPE_STATION)
2004 aid = vif->bss_conf.aid;
2005 else
2006 aid = sta->aid;
2007
Kalle Valob25f32c2014-09-14 12:50:49 +03002008 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002009 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002010 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002011 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03002012 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002013 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03002014 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002015}
2016
2017static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002018 struct ieee80211_vif *vif,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002019 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002020 struct wmi_peer_assoc_complete_arg *arg)
2021{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002022 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002023 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002024 struct cfg80211_bss *bss;
2025 const u8 *rsnie = NULL;
2026 const u8 *wpaie = NULL;
2027
Michal Kazior548db542013-07-05 16:15:15 +03002028 lockdep_assert_held(&ar->conf_mutex);
2029
Michal Kazior500ff9f2015-03-31 10:26:21 +00002030 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2031 return;
2032
2033 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
2034 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002035 if (bss) {
2036 const struct cfg80211_bss_ies *ies;
2037
2038 rcu_read_lock();
2039 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
2040
2041 ies = rcu_dereference(bss->ies);
2042
2043 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03002044 WLAN_OUI_TYPE_MICROSOFT_WPA,
2045 ies->data,
2046 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002047 rcu_read_unlock();
2048 cfg80211_put_bss(ar->hw->wiphy, bss);
2049 }
2050
2051 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2052 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002053 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002054 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002055 }
2056
2057 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002058 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002059 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002060 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002061
2062 if (sta->mfp &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03002063 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT,
2064 ar->running_fw->fw_file.fw_features)) {
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002065 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002066 }
2067}
2068
2069static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002070 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002071 struct ieee80211_sta *sta,
2072 struct wmi_peer_assoc_complete_arg *arg)
2073{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002074 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002075 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002076 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002077 const struct ieee80211_supported_band *sband;
2078 const struct ieee80211_rate *rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002079 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002080 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002081 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002082 int i;
2083
Michal Kazior548db542013-07-05 16:15:15 +03002084 lockdep_assert_held(&ar->conf_mutex);
2085
Michal Kazior500ff9f2015-03-31 10:26:21 +00002086 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2087 return;
2088
Michal Kazior45c9abc2015-04-21 20:42:58 +03002089 band = def.chan->band;
2090 sband = ar->hw->wiphy->bands[band];
2091 ratemask = sta->supp_rates[band];
2092 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002093 rates = sband->bitrates;
2094
2095 rateset->num_rates = 0;
2096
2097 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2098 if (!(ratemask & 1))
2099 continue;
2100
Michal Kazior486017c2015-03-30 09:51:54 +03002101 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2102 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002103 rateset->num_rates++;
2104 }
2105}
2106
Michal Kazior45c9abc2015-04-21 20:42:58 +03002107static bool
2108ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2109{
2110 int nss;
2111
2112 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2113 if (ht_mcs_mask[nss])
2114 return false;
2115
2116 return true;
2117}
2118
2119static bool
2120ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2121{
2122 int nss;
2123
2124 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2125 if (vht_mcs_mask[nss])
2126 return false;
2127
2128 return true;
2129}
2130
Kalle Valo5e3dd152013-06-12 20:52:10 +03002131static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002132 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002133 struct ieee80211_sta *sta,
2134 struct wmi_peer_assoc_complete_arg *arg)
2135{
2136 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002137 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2138 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002139 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002140 const u8 *ht_mcs_mask;
2141 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002142 int i, n;
2143 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002144 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002145
Michal Kazior548db542013-07-05 16:15:15 +03002146 lockdep_assert_held(&ar->conf_mutex);
2147
Michal Kazior45c9abc2015-04-21 20:42:58 +03002148 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2149 return;
2150
Kalle Valo5e3dd152013-06-12 20:52:10 +03002151 if (!ht_cap->ht_supported)
2152 return;
2153
Michal Kazior45c9abc2015-04-21 20:42:58 +03002154 band = def.chan->band;
2155 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2156 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2157
2158 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2159 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2160 return;
2161
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002162 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002163 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2164 ht_cap->ampdu_factor)) - 1;
2165
2166 arg->peer_mpdu_density =
2167 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2168
2169 arg->peer_ht_caps = ht_cap->cap;
2170 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2171
2172 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002173 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002174
2175 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002176 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002177 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2178 }
2179
Michal Kazior45c9abc2015-04-21 20:42:58 +03002180 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2181 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2182 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002183
Michal Kazior45c9abc2015-04-21 20:42:58 +03002184 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2185 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2186 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002187
2188 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2189 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002190 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002191 }
2192
2193 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002194 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2195 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2196 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2197 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002198 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002199 }
2200
Kalle Valo5e3dd152013-06-12 20:52:10 +03002201 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2202 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2203 else if (ht_cap->mcs.rx_mask[1])
2204 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2205
Michal Kazior45c9abc2015-04-21 20:42:58 +03002206 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2207 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2208 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2209 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002210 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002211 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002212
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002213 /*
2214 * This is a workaround for HT-enabled STAs which break the spec
2215 * and have no HT capabilities RX mask (no HT RX MCS map).
2216 *
2217 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2218 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2219 *
2220 * Firmware asserts if such situation occurs.
2221 */
2222 if (n == 0) {
2223 arg->peer_ht_rates.num_rates = 8;
2224 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2225 arg->peer_ht_rates.rates[i] = i;
2226 } else {
2227 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002228 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002229 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002230
Michal Kazior7aa7a722014-08-25 12:09:38 +02002231 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002232 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002233 arg->peer_ht_rates.num_rates,
2234 arg->peer_num_spatial_streams);
2235}
2236
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002237static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2238 struct ath10k_vif *arvif,
2239 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002240{
2241 u32 uapsd = 0;
2242 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002243 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002244
Michal Kazior548db542013-07-05 16:15:15 +03002245 lockdep_assert_held(&ar->conf_mutex);
2246
Kalle Valo5e3dd152013-06-12 20:52:10 +03002247 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002248 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002249 sta->uapsd_queues, sta->max_sp);
2250
Kalle Valo5e3dd152013-06-12 20:52:10 +03002251 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2252 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2253 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2254 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2255 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2256 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2257 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2258 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2259 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2260 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2261 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2262 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2263
Kalle Valo5e3dd152013-06-12 20:52:10 +03002264 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2265 max_sp = sta->max_sp;
2266
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002267 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2268 sta->addr,
2269 WMI_AP_PS_PEER_PARAM_UAPSD,
2270 uapsd);
2271 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002272 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002273 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002274 return ret;
2275 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002276
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002277 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2278 sta->addr,
2279 WMI_AP_PS_PEER_PARAM_MAX_SP,
2280 max_sp);
2281 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002282 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002283 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002284 return ret;
2285 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002286
2287 /* TODO setup this based on STA listen interval and
2288 beacon interval. Currently we don't know
2289 sta->listen_interval - mac80211 patch required.
2290 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002291 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002292 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2293 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002294 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002295 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002296 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002297 return ret;
2298 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002299 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002300
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002301 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002302}
2303
Michal Kazior45c9abc2015-04-21 20:42:58 +03002304static u16
2305ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2306 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2307{
2308 int idx_limit;
2309 int nss;
2310 u16 mcs_map;
2311 u16 mcs;
2312
2313 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2314 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2315 vht_mcs_limit[nss];
2316
2317 if (mcs_map)
2318 idx_limit = fls(mcs_map) - 1;
2319 else
2320 idx_limit = -1;
2321
2322 switch (idx_limit) {
2323 case 0: /* fall through */
2324 case 1: /* fall through */
2325 case 2: /* fall through */
2326 case 3: /* fall through */
2327 case 4: /* fall through */
2328 case 5: /* fall through */
2329 case 6: /* fall through */
2330 default:
2331 /* see ath10k_mac_can_set_bitrate_mask() */
2332 WARN_ON(1);
2333 /* fall through */
2334 case -1:
2335 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2336 break;
2337 case 7:
2338 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2339 break;
2340 case 8:
2341 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2342 break;
2343 case 9:
2344 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2345 break;
2346 }
2347
2348 tx_mcs_set &= ~(0x3 << (nss * 2));
2349 tx_mcs_set |= mcs << (nss * 2);
2350 }
2351
2352 return tx_mcs_set;
2353}
2354
Kalle Valo5e3dd152013-06-12 20:52:10 +03002355static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002356 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002357 struct ieee80211_sta *sta,
2358 struct wmi_peer_assoc_complete_arg *arg)
2359{
2360 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002361 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002362 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002363 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002364 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002365 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002366
Michal Kazior500ff9f2015-03-31 10:26:21 +00002367 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2368 return;
2369
Kalle Valo5e3dd152013-06-12 20:52:10 +03002370 if (!vht_cap->vht_supported)
2371 return;
2372
Michal Kazior45c9abc2015-04-21 20:42:58 +03002373 band = def.chan->band;
2374 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2375
2376 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2377 return;
2378
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002379 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002380
Johannes Berg57fbcce2016-04-12 15:56:15 +02002381 if (def.chan->band == NL80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002382 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002383
Kalle Valo5e3dd152013-06-12 20:52:10 +03002384 arg->peer_vht_caps = vht_cap->cap;
2385
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002386 ampdu_factor = (vht_cap->cap &
2387 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2388 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2389
2390 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2391 * zero in VHT IE. Using it would result in degraded throughput.
2392 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2393 * it if VHT max_mpdu is smaller. */
2394 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2395 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2396 ampdu_factor)) - 1);
2397
Kalle Valo5e3dd152013-06-12 20:52:10 +03002398 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002399 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002400
2401 arg->peer_vht_rates.rx_max_rate =
2402 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2403 arg->peer_vht_rates.rx_mcs_set =
2404 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2405 arg->peer_vht_rates.tx_max_rate =
2406 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002407 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2408 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002409
Michal Kazior7aa7a722014-08-25 12:09:38 +02002410 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002411 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002412}
2413
2414static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002415 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002416 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002417 struct wmi_peer_assoc_complete_arg *arg)
2418{
Michal Kazior590922a2014-10-21 10:10:29 +03002419 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2420
Kalle Valo5e3dd152013-06-12 20:52:10 +03002421 switch (arvif->vdev_type) {
2422 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002423 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002424 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002425
2426 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002427 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002428 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2429 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002430 break;
2431 case WMI_VDEV_TYPE_STA:
Michal Kazior590922a2014-10-21 10:10:29 +03002432 if (vif->bss_conf.qos)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002433 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002434 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002435 case WMI_VDEV_TYPE_IBSS:
2436 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002437 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002438 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002439 default:
2440 break;
2441 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002442
2443 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002444 sta->addr, !!(arg->peer_flags &
2445 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002446}
2447
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002448static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002449{
Johannes Berg57fbcce2016-04-12 15:56:15 +02002450 return sta->supp_rates[NL80211_BAND_2GHZ] >>
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002451 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002452}
2453
Kalle Valo5e3dd152013-06-12 20:52:10 +03002454static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002455 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002456 struct ieee80211_sta *sta,
2457 struct wmi_peer_assoc_complete_arg *arg)
2458{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002459 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002460 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002461 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002462 const u8 *ht_mcs_mask;
2463 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002464 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2465
Michal Kazior500ff9f2015-03-31 10:26:21 +00002466 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2467 return;
2468
Michal Kazior45c9abc2015-04-21 20:42:58 +03002469 band = def.chan->band;
2470 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2471 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2472
2473 switch (band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02002474 case NL80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002475 if (sta->vht_cap.vht_supported &&
2476 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002477 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2478 phymode = MODE_11AC_VHT40;
2479 else
2480 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002481 } else if (sta->ht_cap.ht_supported &&
2482 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002483 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2484 phymode = MODE_11NG_HT40;
2485 else
2486 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002487 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002488 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002489 } else {
2490 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002491 }
2492
2493 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002494 case NL80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002495 /*
2496 * Check VHT first.
2497 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002498 if (sta->vht_cap.vht_supported &&
2499 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002500 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2501 phymode = MODE_11AC_VHT80;
2502 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2503 phymode = MODE_11AC_VHT40;
2504 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2505 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002506 } else if (sta->ht_cap.ht_supported &&
2507 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2508 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002509 phymode = MODE_11NA_HT40;
2510 else
2511 phymode = MODE_11NA_HT20;
2512 } else {
2513 phymode = MODE_11A;
2514 }
2515
2516 break;
2517 default:
2518 break;
2519 }
2520
Michal Kazior7aa7a722014-08-25 12:09:38 +02002521 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002522 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002523
Kalle Valo5e3dd152013-06-12 20:52:10 +03002524 arg->peer_phymode = phymode;
2525 WARN_ON(phymode == MODE_UNKNOWN);
2526}
2527
Kalle Valob9ada652013-10-16 15:44:46 +03002528static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002529 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002530 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002531 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002532{
Michal Kazior548db542013-07-05 16:15:15 +03002533 lockdep_assert_held(&ar->conf_mutex);
2534
Kalle Valob9ada652013-10-16 15:44:46 +03002535 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002536
Michal Kazior590922a2014-10-21 10:10:29 +03002537 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002538 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002539 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002540 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002541 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002542 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2543 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002544
Kalle Valob9ada652013-10-16 15:44:46 +03002545 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002546}
2547
Michal Kazior90046f52014-02-14 14:45:51 +01002548static const u32 ath10k_smps_map[] = {
2549 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2550 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2551 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2552 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2553};
2554
2555static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2556 const u8 *addr,
2557 const struct ieee80211_sta_ht_cap *ht_cap)
2558{
2559 int smps;
2560
2561 if (!ht_cap->ht_supported)
2562 return 0;
2563
2564 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2565 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2566
2567 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2568 return -EINVAL;
2569
2570 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2571 WMI_PEER_SMPS_STATE,
2572 ath10k_smps_map[smps]);
2573}
2574
Michal Kazior139e1702015-02-15 16:50:42 +02002575static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2576 struct ieee80211_vif *vif,
2577 struct ieee80211_sta_vht_cap vht_cap)
2578{
2579 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2580 int ret;
2581 u32 param;
2582 u32 value;
2583
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302584 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2585 return 0;
2586
Michal Kazior139e1702015-02-15 16:50:42 +02002587 if (!(ar->vht_cap_info &
2588 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2589 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2590 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2591 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2592 return 0;
2593
2594 param = ar->wmi.vdev_param->txbf;
2595 value = 0;
2596
2597 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2598 return 0;
2599
2600 /* The following logic is correct. If a remote STA advertises support
2601 * for being a beamformer then we should enable us being a beamformee.
2602 */
2603
2604 if (ar->vht_cap_info &
2605 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2606 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2607 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2608 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2609
2610 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2611 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2612 }
2613
2614 if (ar->vht_cap_info &
2615 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2616 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2617 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2618 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2619
2620 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2621 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2622 }
2623
2624 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2625 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2626
2627 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2628 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2629
2630 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2631 if (ret) {
2632 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2633 value, ret);
2634 return ret;
2635 }
2636
2637 return 0;
2638}
2639
Kalle Valo5e3dd152013-06-12 20:52:10 +03002640/* can be called only in mac80211 callbacks due to `key_count` usage */
2641static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2642 struct ieee80211_vif *vif,
2643 struct ieee80211_bss_conf *bss_conf)
2644{
2645 struct ath10k *ar = hw->priv;
2646 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002647 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002648 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002649 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002650 struct ieee80211_sta *ap_sta;
2651 int ret;
2652
Michal Kazior548db542013-07-05 16:15:15 +03002653 lockdep_assert_held(&ar->conf_mutex);
2654
Michal Kazior077efc82014-10-21 10:10:29 +03002655 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2656 arvif->vdev_id, arvif->bssid, arvif->aid);
2657
Kalle Valo5e3dd152013-06-12 20:52:10 +03002658 rcu_read_lock();
2659
2660 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2661 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002662 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002663 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002664 rcu_read_unlock();
2665 return;
2666 }
2667
Michal Kazior90046f52014-02-14 14:45:51 +01002668 /* ap_sta must be accessed only within rcu section which must be left
2669 * before calling ath10k_setup_peer_smps() which might sleep. */
2670 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002671 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002672
Michal Kazior590922a2014-10-21 10:10:29 +03002673 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002674 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002675 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002676 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002677 rcu_read_unlock();
2678 return;
2679 }
2680
2681 rcu_read_unlock();
2682
Kalle Valob9ada652013-10-16 15:44:46 +03002683 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2684 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002685 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002686 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002687 return;
2688 }
2689
Michal Kazior90046f52014-02-14 14:45:51 +01002690 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2691 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002692 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002693 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002694 return;
2695 }
2696
Michal Kazior139e1702015-02-15 16:50:42 +02002697 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2698 if (ret) {
2699 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2700 arvif->vdev_id, bss_conf->bssid, ret);
2701 return;
2702 }
2703
Michal Kazior7aa7a722014-08-25 12:09:38 +02002704 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002705 "mac vdev %d up (associated) bssid %pM aid %d\n",
2706 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2707
Michal Kazior077efc82014-10-21 10:10:29 +03002708 WARN_ON(arvif->is_up);
2709
Michal Kaziorc930f742014-01-23 11:38:25 +01002710 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002711 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002712
2713 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2714 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002715 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002716 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002717 return;
2718 }
2719
2720 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002721
2722 /* Workaround: Some firmware revisions (tested with qca6174
2723 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2724 * poked with peer param command.
2725 */
2726 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2727 WMI_PEER_DUMMY_VAR, 1);
2728 if (ret) {
2729 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2730 arvif->bssid, arvif->vdev_id, ret);
2731 return;
2732 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002733}
2734
Kalle Valo5e3dd152013-06-12 20:52:10 +03002735static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2736 struct ieee80211_vif *vif)
2737{
2738 struct ath10k *ar = hw->priv;
2739 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002740 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002741 int ret;
2742
Michal Kazior548db542013-07-05 16:15:15 +03002743 lockdep_assert_held(&ar->conf_mutex);
2744
Michal Kazior077efc82014-10-21 10:10:29 +03002745 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2746 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002747
Kalle Valo5e3dd152013-06-12 20:52:10 +03002748 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002749 if (ret)
2750 ath10k_warn(ar, "faield to down vdev %i: %d\n",
2751 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002752
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002753 arvif->def_wep_key_idx = -1;
2754
Michal Kazior139e1702015-02-15 16:50:42 +02002755 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2756 if (ret) {
2757 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2758 arvif->vdev_id, ret);
2759 return;
2760 }
2761
Michal Kaziorc930f742014-01-23 11:38:25 +01002762 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002763
2764 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002765}
2766
Michal Kazior590922a2014-10-21 10:10:29 +03002767static int ath10k_station_assoc(struct ath10k *ar,
2768 struct ieee80211_vif *vif,
2769 struct ieee80211_sta *sta,
2770 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002771{
Michal Kazior590922a2014-10-21 10:10:29 +03002772 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002773 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002774 int ret = 0;
2775
Michal Kazior548db542013-07-05 16:15:15 +03002776 lockdep_assert_held(&ar->conf_mutex);
2777
Michal Kazior590922a2014-10-21 10:10:29 +03002778 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002779 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002780 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002781 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002782 return ret;
2783 }
2784
2785 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2786 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002787 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002788 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002789 return ret;
2790 }
2791
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002792 /* Re-assoc is run only to update supported rates for given station. It
2793 * doesn't make much sense to reconfigure the peer completely.
2794 */
2795 if (!reassoc) {
2796 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2797 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002798 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002799 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002800 arvif->vdev_id, ret);
2801 return ret;
2802 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002803
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002804 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2805 if (ret) {
2806 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2807 sta->addr, arvif->vdev_id, ret);
2808 return ret;
2809 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002810
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002811 if (!sta->wme) {
2812 arvif->num_legacy_stations++;
2813 ret = ath10k_recalc_rtscts_prot(arvif);
2814 if (ret) {
2815 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2816 arvif->vdev_id, ret);
2817 return ret;
2818 }
2819 }
2820
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002821 /* Plumb cached keys only for static WEP */
2822 if (arvif->def_wep_key_idx != -1) {
2823 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2824 if (ret) {
2825 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2826 arvif->vdev_id, ret);
2827 return ret;
2828 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002829 }
2830 }
2831
Kalle Valo5e3dd152013-06-12 20:52:10 +03002832 return ret;
2833}
2834
Michal Kazior590922a2014-10-21 10:10:29 +03002835static int ath10k_station_disassoc(struct ath10k *ar,
2836 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002837 struct ieee80211_sta *sta)
2838{
Michal Kazior590922a2014-10-21 10:10:29 +03002839 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002840 int ret = 0;
2841
2842 lockdep_assert_held(&ar->conf_mutex);
2843
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002844 if (!sta->wme) {
2845 arvif->num_legacy_stations--;
2846 ret = ath10k_recalc_rtscts_prot(arvif);
2847 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002848 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002849 arvif->vdev_id, ret);
2850 return ret;
2851 }
2852 }
2853
Kalle Valo5e3dd152013-06-12 20:52:10 +03002854 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2855 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002856 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002857 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002858 return ret;
2859 }
2860
2861 return ret;
2862}
2863
2864/**************/
2865/* Regulatory */
2866/**************/
2867
2868static int ath10k_update_channel_list(struct ath10k *ar)
2869{
2870 struct ieee80211_hw *hw = ar->hw;
2871 struct ieee80211_supported_band **bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002872 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002873 struct ieee80211_channel *channel;
2874 struct wmi_scan_chan_list_arg arg = {0};
2875 struct wmi_channel_arg *ch;
2876 bool passive;
2877 int len;
2878 int ret;
2879 int i;
2880
Michal Kazior548db542013-07-05 16:15:15 +03002881 lockdep_assert_held(&ar->conf_mutex);
2882
Kalle Valo5e3dd152013-06-12 20:52:10 +03002883 bands = hw->wiphy->bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002884 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002885 if (!bands[band])
2886 continue;
2887
2888 for (i = 0; i < bands[band]->n_channels; i++) {
2889 if (bands[band]->channels[i].flags &
2890 IEEE80211_CHAN_DISABLED)
2891 continue;
2892
2893 arg.n_channels++;
2894 }
2895 }
2896
2897 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2898 arg.channels = kzalloc(len, GFP_KERNEL);
2899 if (!arg.channels)
2900 return -ENOMEM;
2901
2902 ch = arg.channels;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002903 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002904 if (!bands[band])
2905 continue;
2906
2907 for (i = 0; i < bands[band]->n_channels; i++) {
2908 channel = &bands[band]->channels[i];
2909
2910 if (channel->flags & IEEE80211_CHAN_DISABLED)
2911 continue;
2912
2913 ch->allow_ht = true;
2914
2915 /* FIXME: when should we really allow VHT? */
2916 ch->allow_vht = true;
2917
2918 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002919 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002920
2921 ch->ht40plus =
2922 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2923
Marek Puzyniake8a50f82013-11-20 09:59:47 +02002924 ch->chan_radar =
2925 !!(channel->flags & IEEE80211_CHAN_RADAR);
2926
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002927 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002928 ch->passive = passive;
2929
2930 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02002931 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07002932 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07002933 ch->max_power = channel->max_power * 2;
2934 ch->max_reg_power = channel->max_reg_power * 2;
2935 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002936 ch->reg_class_id = 0; /* FIXME */
2937
2938 /* FIXME: why use only legacy modes, why not any
2939 * HT/VHT modes? Would that even make any
2940 * difference? */
Johannes Berg57fbcce2016-04-12 15:56:15 +02002941 if (channel->band == NL80211_BAND_2GHZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002942 ch->mode = MODE_11G;
2943 else
2944 ch->mode = MODE_11A;
2945
2946 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
2947 continue;
2948
Michal Kazior7aa7a722014-08-25 12:09:38 +02002949 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002950 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
2951 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002952 ch->freq, ch->max_power, ch->max_reg_power,
2953 ch->max_antenna_gain, ch->mode);
2954
2955 ch++;
2956 }
2957 }
2958
2959 ret = ath10k_wmi_scan_chan_list(ar, &arg);
2960 kfree(arg.channels);
2961
2962 return ret;
2963}
2964
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002965static enum wmi_dfs_region
2966ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
2967{
2968 switch (dfs_region) {
2969 case NL80211_DFS_UNSET:
2970 return WMI_UNINIT_DFS_DOMAIN;
2971 case NL80211_DFS_FCC:
2972 return WMI_FCC_DFS_DOMAIN;
2973 case NL80211_DFS_ETSI:
2974 return WMI_ETSI_DFS_DOMAIN;
2975 case NL80211_DFS_JP:
2976 return WMI_MKK4_DFS_DOMAIN;
2977 }
2978 return WMI_UNINIT_DFS_DOMAIN;
2979}
2980
Michal Kaziorf7843d72013-07-16 09:38:52 +02002981static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002982{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002983 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002984 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002985 enum wmi_dfs_region wmi_dfs_reg;
2986 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002987
Michal Kaziorf7843d72013-07-16 09:38:52 +02002988 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002989
2990 ret = ath10k_update_channel_list(ar);
2991 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002992 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002993
2994 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002995
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002996 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
2997 nl_dfs_reg = ar->dfs_detector->region;
2998 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
2999 } else {
3000 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
3001 }
3002
Kalle Valo5e3dd152013-06-12 20:52:10 +03003003 /* Target allows setting up per-band regdomain but ath_common provides
3004 * a combined one only */
3005 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02003006 regpair->reg_domain,
3007 regpair->reg_domain, /* 2ghz */
3008 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003009 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003010 regpair->reg_5ghz_ctl,
3011 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003012 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003013 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02003014}
Michal Kazior548db542013-07-05 16:15:15 +03003015
Michal Kaziorf7843d72013-07-16 09:38:52 +02003016static void ath10k_reg_notifier(struct wiphy *wiphy,
3017 struct regulatory_request *request)
3018{
3019 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
3020 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003021 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003022
3023 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3024
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003025 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003026 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003027 request->dfs_region);
3028 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3029 request->dfs_region);
3030 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003031 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003032 request->dfs_region);
3033 }
3034
Michal Kaziorf7843d72013-07-16 09:38:52 +02003035 mutex_lock(&ar->conf_mutex);
3036 if (ar->state == ATH10K_STATE_ON)
3037 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003038 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003039}
3040
3041/***************/
3042/* TX handlers */
3043/***************/
3044
Michal Kaziora30c7d02016-03-06 16:14:23 +02003045enum ath10k_mac_tx_path {
3046 ATH10K_MAC_TX_HTT,
3047 ATH10K_MAC_TX_HTT_MGMT,
3048 ATH10K_MAC_TX_WMI_MGMT,
3049 ATH10K_MAC_TX_UNKNOWN,
3050};
3051
Michal Kazior96d828d2015-03-31 10:26:23 +00003052void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3053{
3054 lockdep_assert_held(&ar->htt.tx_lock);
3055
3056 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3057 ar->tx_paused |= BIT(reason);
3058 ieee80211_stop_queues(ar->hw);
3059}
3060
3061static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3062 struct ieee80211_vif *vif)
3063{
3064 struct ath10k *ar = data;
3065 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3066
3067 if (arvif->tx_paused)
3068 return;
3069
3070 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3071}
3072
3073void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3074{
3075 lockdep_assert_held(&ar->htt.tx_lock);
3076
3077 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3078 ar->tx_paused &= ~BIT(reason);
3079
3080 if (ar->tx_paused)
3081 return;
3082
3083 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3084 IEEE80211_IFACE_ITER_RESUME_ALL,
3085 ath10k_mac_tx_unlock_iter,
3086 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003087
3088 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003089}
3090
3091void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3092{
3093 struct ath10k *ar = arvif->ar;
3094
3095 lockdep_assert_held(&ar->htt.tx_lock);
3096
3097 WARN_ON(reason >= BITS_PER_LONG);
3098 arvif->tx_paused |= BIT(reason);
3099 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3100}
3101
3102void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3103{
3104 struct ath10k *ar = arvif->ar;
3105
3106 lockdep_assert_held(&ar->htt.tx_lock);
3107
3108 WARN_ON(reason >= BITS_PER_LONG);
3109 arvif->tx_paused &= ~BIT(reason);
3110
3111 if (ar->tx_paused)
3112 return;
3113
3114 if (arvif->tx_paused)
3115 return;
3116
3117 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3118}
3119
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003120static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3121 enum wmi_tlv_tx_pause_id pause_id,
3122 enum wmi_tlv_tx_pause_action action)
3123{
3124 struct ath10k *ar = arvif->ar;
3125
3126 lockdep_assert_held(&ar->htt.tx_lock);
3127
Michal Kazioracd0b272015-07-09 13:08:38 +02003128 switch (action) {
3129 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3130 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003131 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003132 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3133 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3134 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003135 default:
Michal Kazioracd0b272015-07-09 13:08:38 +02003136 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
3137 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003138 break;
3139 }
3140}
3141
3142struct ath10k_mac_tx_pause {
3143 u32 vdev_id;
3144 enum wmi_tlv_tx_pause_id pause_id;
3145 enum wmi_tlv_tx_pause_action action;
3146};
3147
3148static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3149 struct ieee80211_vif *vif)
3150{
3151 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3152 struct ath10k_mac_tx_pause *arg = data;
3153
Michal Kazioracd0b272015-07-09 13:08:38 +02003154 if (arvif->vdev_id != arg->vdev_id)
3155 return;
3156
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003157 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3158}
3159
Michal Kazioracd0b272015-07-09 13:08:38 +02003160void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3161 enum wmi_tlv_tx_pause_id pause_id,
3162 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003163{
3164 struct ath10k_mac_tx_pause arg = {
3165 .vdev_id = vdev_id,
3166 .pause_id = pause_id,
3167 .action = action,
3168 };
3169
3170 spin_lock_bh(&ar->htt.tx_lock);
3171 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3172 IEEE80211_IFACE_ITER_RESUME_ALL,
3173 ath10k_mac_handle_tx_pause_iter,
3174 &arg);
3175 spin_unlock_bh(&ar->htt.tx_lock);
3176}
3177
Michal Kaziord740d8f2015-03-30 09:51:51 +03003178static enum ath10k_hw_txrx_mode
Michal Kazior6a2636d2015-11-18 06:59:16 +01003179ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3180 struct ieee80211_vif *vif,
3181 struct ieee80211_sta *sta,
3182 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003183{
3184 const struct ieee80211_hdr *hdr = (void *)skb->data;
3185 __le16 fc = hdr->frame_control;
3186
3187 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3188 return ATH10K_HW_TXRX_RAW;
3189
3190 if (ieee80211_is_mgmt(fc))
3191 return ATH10K_HW_TXRX_MGMT;
3192
3193 /* Workaround:
3194 *
3195 * NullFunc frames are mostly used to ping if a client or AP are still
3196 * reachable and responsive. This implies tx status reports must be
3197 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3198 * come to a conclusion that the other end disappeared and tear down
3199 * BSS connection or it can never disconnect from BSS/client (which is
3200 * the case).
3201 *
3202 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3203 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3204 * which seems to deliver correct tx reports for NullFunc frames. The
3205 * downside of using it is it ignores client powersave state so it can
3206 * end up disconnecting sleeping clients in AP mode. It should fix STA
3207 * mode though because AP don't sleep.
3208 */
3209 if (ar->htt.target_version_major < 3 &&
3210 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03003211 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3212 ar->running_fw->fw_file.fw_features))
Michal Kaziord740d8f2015-03-30 09:51:51 +03003213 return ATH10K_HW_TXRX_MGMT;
3214
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003215 /* Workaround:
3216 *
3217 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3218 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3219 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003220 *
3221 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003222 */
3223 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3224 return ATH10K_HW_TXRX_ETHERNET;
3225
David Liuccec9032015-07-24 20:25:32 +03003226 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3227 return ATH10K_HW_TXRX_RAW;
3228
Michal Kaziord740d8f2015-03-30 09:51:51 +03003229 return ATH10K_HW_TXRX_NATIVE_WIFI;
3230}
3231
David Liuccec9032015-07-24 20:25:32 +03003232static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003233 struct sk_buff *skb)
3234{
3235 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3236 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003237 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3238 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003239
3240 if (!ieee80211_has_protected(hdr->frame_control))
3241 return false;
3242
David Liuccec9032015-07-24 20:25:32 +03003243 if ((info->flags & mask) == mask)
3244 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003245
David Liuccec9032015-07-24 20:25:32 +03003246 if (vif)
3247 return !ath10k_vif_to_arvif(vif)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003248
David Liuccec9032015-07-24 20:25:32 +03003249 return true;
3250}
3251
Michal Kazior4b604552014-07-21 21:03:09 +03003252/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3253 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003254 */
Michal Kazior4b604552014-07-21 21:03:09 +03003255static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003256{
3257 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003258 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003259 u8 *qos_ctl;
3260
3261 if (!ieee80211_is_data_qos(hdr->frame_control))
3262 return;
3263
3264 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003265 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3266 skb->data, (void *)qos_ctl - (void *)skb->data);
3267 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003268
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003269 /* Some firmware revisions don't handle sending QoS NullFunc well.
3270 * These frames are mainly used for CQM purposes so it doesn't really
3271 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003272 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003273 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003274 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003275 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003276
3277 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003278}
3279
Michal Kaziord740d8f2015-03-30 09:51:51 +03003280static void ath10k_tx_h_8023(struct sk_buff *skb)
3281{
3282 struct ieee80211_hdr *hdr;
3283 struct rfc1042_hdr *rfc1042;
3284 struct ethhdr *eth;
3285 size_t hdrlen;
3286 u8 da[ETH_ALEN];
3287 u8 sa[ETH_ALEN];
3288 __be16 type;
3289
3290 hdr = (void *)skb->data;
3291 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3292 rfc1042 = (void *)skb->data + hdrlen;
3293
3294 ether_addr_copy(da, ieee80211_get_DA(hdr));
3295 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3296 type = rfc1042->snap_type;
3297
3298 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3299 skb_push(skb, sizeof(*eth));
3300
3301 eth = (void *)skb->data;
3302 ether_addr_copy(eth->h_dest, da);
3303 ether_addr_copy(eth->h_source, sa);
3304 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003305}
3306
Michal Kazior4b604552014-07-21 21:03:09 +03003307static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3308 struct ieee80211_vif *vif,
3309 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003310{
3311 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003312 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3313
3314 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003315 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003316 return;
3317
3318 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3319 spin_lock_bh(&ar->data_lock);
3320 if (arvif->u.ap.noa_data)
3321 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3322 GFP_ATOMIC))
3323 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3324 arvif->u.ap.noa_data,
3325 arvif->u.ap.noa_len);
3326 spin_unlock_bh(&ar->data_lock);
3327 }
3328}
3329
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003330static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3331 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003332 struct ieee80211_txq *txq,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003333 struct sk_buff *skb)
3334{
3335 struct ieee80211_hdr *hdr = (void *)skb->data;
3336 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3337
3338 cb->flags = 0;
3339 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3340 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3341
3342 if (ieee80211_is_mgmt(hdr->frame_control))
3343 cb->flags |= ATH10K_SKB_F_MGMT;
3344
3345 if (ieee80211_is_data_qos(hdr->frame_control))
3346 cb->flags |= ATH10K_SKB_F_QOS;
3347
3348 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003349 cb->txq = txq;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003350}
3351
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303352bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003353{
3354 /* FIXME: Not really sure since when the behaviour changed. At some
3355 * point new firmware stopped requiring creation of peer entries for
3356 * offchannel tx (and actually creating them causes issues with wmi-htc
3357 * tx credit replenishment and reliability). Assuming it's at least 3.4
3358 * because that's when the `freq` was introduced to TX_FRM HTT command.
3359 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303360 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303361 ar->htt.target_version_minor >= 4 &&
Kalle Valo77561f92016-04-20 19:45:47 +03003362 ar->running_fw->fw_file.htt_op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003363}
3364
Michal Kaziord740d8f2015-03-30 09:51:51 +03003365static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003366{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003367 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003368 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003369
Michal Kaziord740d8f2015-03-30 09:51:51 +03003370 spin_lock_bh(&ar->data_lock);
3371
3372 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3373 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3374 ret = -ENOSPC;
3375 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003376 }
3377
Michal Kaziord740d8f2015-03-30 09:51:51 +03003378 __skb_queue_tail(q, skb);
3379 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3380
3381unlock:
3382 spin_unlock_bh(&ar->data_lock);
3383
3384 return ret;
3385}
3386
Michal Kaziora30c7d02016-03-06 16:14:23 +02003387static enum ath10k_mac_tx_path
3388ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3389 struct sk_buff *skb,
3390 enum ath10k_hw_txrx_mode txmode)
3391{
3392 switch (txmode) {
3393 case ATH10K_HW_TXRX_RAW:
3394 case ATH10K_HW_TXRX_NATIVE_WIFI:
3395 case ATH10K_HW_TXRX_ETHERNET:
3396 return ATH10K_MAC_TX_HTT;
3397 case ATH10K_HW_TXRX_MGMT:
3398 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Kalle Valoc4cdf752016-04-20 19:45:18 +03003399 ar->running_fw->fw_file.fw_features))
Michal Kaziora30c7d02016-03-06 16:14:23 +02003400 return ATH10K_MAC_TX_WMI_MGMT;
3401 else if (ar->htt.target_version_major >= 3)
3402 return ATH10K_MAC_TX_HTT;
3403 else
3404 return ATH10K_MAC_TX_HTT_MGMT;
3405 }
3406
3407 return ATH10K_MAC_TX_UNKNOWN;
3408}
3409
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003410static int ath10k_mac_tx_submit(struct ath10k *ar,
3411 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003412 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003413 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003414{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003415 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003416 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003417
3418 switch (txpath) {
3419 case ATH10K_MAC_TX_HTT:
Michal Kazior8a933962015-11-18 06:59:17 +01003420 ret = ath10k_htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003421 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003422 case ATH10K_MAC_TX_HTT_MGMT:
3423 ret = ath10k_htt_mgmt_tx(htt, skb);
3424 break;
3425 case ATH10K_MAC_TX_WMI_MGMT:
3426 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3427 break;
3428 case ATH10K_MAC_TX_UNKNOWN:
3429 WARN_ON_ONCE(1);
3430 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003431 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003432 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003433
3434 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003435 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3436 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003437 ieee80211_free_txskb(ar->hw, skb);
3438 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003439
3440 return ret;
3441}
3442
3443/* This function consumes the sk_buff regardless of return value as far as
3444 * caller is concerned so no freeing is necessary afterwards.
3445 */
3446static int ath10k_mac_tx(struct ath10k *ar,
3447 struct ieee80211_vif *vif,
3448 struct ieee80211_sta *sta,
3449 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003450 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003451 struct sk_buff *skb)
3452{
3453 struct ieee80211_hw *hw = ar->hw;
3454 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3455 int ret;
3456
3457 /* We should disable CCK RATE due to P2P */
3458 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3459 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3460
3461 switch (txmode) {
3462 case ATH10K_HW_TXRX_MGMT:
3463 case ATH10K_HW_TXRX_NATIVE_WIFI:
3464 ath10k_tx_h_nwifi(hw, skb);
3465 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3466 ath10k_tx_h_seq_no(vif, skb);
3467 break;
3468 case ATH10K_HW_TXRX_ETHERNET:
3469 ath10k_tx_h_8023(skb);
3470 break;
3471 case ATH10K_HW_TXRX_RAW:
3472 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3473 WARN_ON_ONCE(1);
3474 ieee80211_free_txskb(hw, skb);
3475 return -ENOTSUPP;
3476 }
3477 }
3478
3479 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3480 if (!ath10k_mac_tx_frm_has_freq(ar)) {
3481 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
3482 skb);
3483
3484 skb_queue_tail(&ar->offchan_tx_queue, skb);
3485 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3486 return 0;
3487 }
3488 }
3489
Michal Kazior6421969f2016-03-06 16:14:25 +02003490 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003491 if (ret) {
3492 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3493 return ret;
3494 }
3495
3496 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003497}
3498
3499void ath10k_offchan_tx_purge(struct ath10k *ar)
3500{
3501 struct sk_buff *skb;
3502
3503 for (;;) {
3504 skb = skb_dequeue(&ar->offchan_tx_queue);
3505 if (!skb)
3506 break;
3507
3508 ieee80211_free_txskb(ar->hw, skb);
3509 }
3510}
3511
3512void ath10k_offchan_tx_work(struct work_struct *work)
3513{
3514 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3515 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003516 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003517 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003518 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003519 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003520 struct ieee80211_vif *vif;
3521 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003522 struct sk_buff *skb;
3523 const u8 *peer_addr;
3524 int vdev_id;
3525 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003526 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003527 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003528
3529 /* FW requirement: We must create a peer before FW will send out
3530 * an offchannel frame. Otherwise the frame will be stuck and
3531 * never transmitted. We delete the peer upon tx completion.
3532 * It is unlikely that a peer for offchannel tx will already be
3533 * present. However it may be in some rare cases so account for that.
3534 * Otherwise we might remove a legitimate peer and break stuff. */
3535
3536 for (;;) {
3537 skb = skb_dequeue(&ar->offchan_tx_queue);
3538 if (!skb)
3539 break;
3540
3541 mutex_lock(&ar->conf_mutex);
3542
Michal Kazior7aa7a722014-08-25 12:09:38 +02003543 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003544 skb);
3545
3546 hdr = (struct ieee80211_hdr *)skb->data;
3547 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003548
3549 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003550 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003551 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3552 spin_unlock_bh(&ar->data_lock);
3553
3554 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003555 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003556 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003557 peer_addr, vdev_id);
3558
3559 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003560 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3561 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003562 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003563 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003564 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003565 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003566 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003567 }
3568
3569 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003570 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003571 ar->offchan_tx_skb = skb;
3572 spin_unlock_bh(&ar->data_lock);
3573
Michal Kazior8a933962015-11-18 06:59:17 +01003574 /* It's safe to access vif and sta - conf_mutex guarantees that
3575 * sta_state() and remove_interface() are locked exclusively
3576 * out wrt to this offchannel worker.
3577 */
3578 arvif = ath10k_get_arvif(ar, vdev_id);
3579 if (arvif) {
3580 vif = arvif->vif;
3581 sta = ieee80211_find_sta(vif, peer_addr);
3582 } else {
3583 vif = NULL;
3584 sta = NULL;
3585 }
3586
3587 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003588 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003589
Michal Kazior6421969f2016-03-06 16:14:25 +02003590 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003591 if (ret) {
3592 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3593 ret);
3594 /* not serious */
3595 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003596
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003597 time_left =
3598 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3599 if (time_left == 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003600 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003601 skb);
3602
Michal Kazioradaeed72015-08-05 12:15:23 +02003603 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003604 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3605 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003606 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003607 peer_addr, vdev_id, ret);
3608 }
3609
3610 mutex_unlock(&ar->conf_mutex);
3611 }
3612}
3613
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003614void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3615{
3616 struct sk_buff *skb;
3617
3618 for (;;) {
3619 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3620 if (!skb)
3621 break;
3622
3623 ieee80211_free_txskb(ar->hw, skb);
3624 }
3625}
3626
3627void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3628{
3629 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3630 struct sk_buff *skb;
3631 int ret;
3632
3633 for (;;) {
3634 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3635 if (!skb)
3636 break;
3637
3638 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003639 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003640 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003641 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003642 ieee80211_free_txskb(ar->hw, skb);
3643 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003644 }
3645}
3646
Michal Kazior29946872016-03-06 16:14:34 +02003647static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3648{
3649 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3650
3651 if (!txq)
3652 return;
3653
3654 INIT_LIST_HEAD(&artxq->list);
3655}
3656
3657static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3658{
3659 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003660 struct ath10k_skb_cb *cb;
3661 struct sk_buff *msdu;
3662 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003663
3664 if (!txq)
3665 return;
3666
3667 spin_lock_bh(&ar->txqs_lock);
3668 if (!list_empty(&artxq->list))
3669 list_del_init(&artxq->list);
3670 spin_unlock_bh(&ar->txqs_lock);
Michal Kaziordd4717b2016-03-06 16:14:39 +02003671
3672 spin_lock_bh(&ar->htt.tx_lock);
3673 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3674 cb = ATH10K_SKB_CB(msdu);
3675 if (cb->txq == txq)
3676 cb->txq = NULL;
3677 }
3678 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003679}
3680
Michal Kazior426e10e2016-03-06 16:14:43 +02003681struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
3682 u16 peer_id,
3683 u8 tid)
3684{
3685 struct ath10k_peer *peer;
3686
3687 lockdep_assert_held(&ar->data_lock);
3688
3689 peer = ar->peer_map[peer_id];
3690 if (!peer)
3691 return NULL;
3692
3693 if (peer->sta)
3694 return peer->sta->txq[tid];
3695 else if (peer->vif)
3696 return peer->vif->txq;
3697 else
3698 return NULL;
3699}
3700
Michal Kazior29946872016-03-06 16:14:34 +02003701static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3702 struct ieee80211_txq *txq)
3703{
Michal Kazior426e10e2016-03-06 16:14:43 +02003704 struct ath10k *ar = hw->priv;
3705 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3706
3707 /* No need to get locks */
3708
3709 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3710 return true;
3711
3712 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3713 return true;
3714
3715 if (artxq->num_fw_queued < artxq->num_push_allowed)
3716 return true;
3717
3718 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003719}
3720
Michal Kazior426e10e2016-03-06 16:14:43 +02003721int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3722 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02003723{
Michal Kazior29946872016-03-06 16:14:34 +02003724 struct ath10k *ar = hw->priv;
3725 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003726 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003727 struct ieee80211_vif *vif = txq->vif;
3728 struct ieee80211_sta *sta = txq->sta;
3729 enum ath10k_hw_txrx_mode txmode;
3730 enum ath10k_mac_tx_path txpath;
3731 struct sk_buff *skb;
Michal Kazior426e10e2016-03-06 16:14:43 +02003732 size_t skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003733 int ret;
3734
3735 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303736 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003737 spin_unlock_bh(&ar->htt.tx_lock);
3738
3739 if (ret)
3740 return ret;
3741
3742 skb = ieee80211_tx_dequeue(hw, txq);
3743 if (!skb) {
3744 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303745 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003746 spin_unlock_bh(&ar->htt.tx_lock);
3747
3748 return -ENOENT;
3749 }
3750
Michal Kaziordd4717b2016-03-06 16:14:39 +02003751 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Michal Kazior29946872016-03-06 16:14:34 +02003752
Michal Kazior426e10e2016-03-06 16:14:43 +02003753 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02003754 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
3755 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
3756
3757 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
3758 if (unlikely(ret)) {
3759 ath10k_warn(ar, "failed to push frame: %d\n", ret);
3760
3761 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303762 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003763 spin_unlock_bh(&ar->htt.tx_lock);
3764
3765 return ret;
3766 }
3767
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003768 spin_lock_bh(&ar->htt.tx_lock);
3769 artxq->num_fw_queued++;
3770 spin_unlock_bh(&ar->htt.tx_lock);
3771
Michal Kazior426e10e2016-03-06 16:14:43 +02003772 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003773}
3774
3775void ath10k_mac_tx_push_pending(struct ath10k *ar)
3776{
3777 struct ieee80211_hw *hw = ar->hw;
3778 struct ieee80211_txq *txq;
3779 struct ath10k_txq *artxq;
3780 struct ath10k_txq *last;
3781 int ret;
3782 int max;
3783
Michal Kazior7a0adc82016-05-23 23:12:45 +03003784 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
3785 return;
3786
Michal Kazior29946872016-03-06 16:14:34 +02003787 spin_lock_bh(&ar->txqs_lock);
3788 rcu_read_lock();
3789
3790 last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
3791 while (!list_empty(&ar->txqs)) {
3792 artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
3793 txq = container_of((void *)artxq, struct ieee80211_txq,
3794 drv_priv);
3795
3796 /* Prevent aggressive sta/tid taking over tx queue */
3797 max = 16;
Michal Kazior750eeed2016-03-17 10:51:05 +01003798 ret = 0;
3799 while (ath10k_mac_tx_can_push(hw, txq) && max--) {
Michal Kazior29946872016-03-06 16:14:34 +02003800 ret = ath10k_mac_tx_push_txq(hw, txq);
3801 if (ret < 0)
3802 break;
3803 }
3804
3805 list_del_init(&artxq->list);
Michal Kazior9d71d472016-03-17 10:51:04 +01003806 if (ret != -ENOENT)
3807 list_add_tail(&artxq->list, &ar->txqs);
3808
Michal Kaziorc1a43d92016-03-06 16:14:36 +02003809 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02003810
Michal Kazior9d71d472016-03-17 10:51:04 +01003811 if (artxq == last || (ret < 0 && ret != -ENOENT))
Michal Kazior29946872016-03-06 16:14:34 +02003812 break;
Michal Kazior29946872016-03-06 16:14:34 +02003813 }
3814
3815 rcu_read_unlock();
3816 spin_unlock_bh(&ar->txqs_lock);
3817}
3818
Kalle Valo5e3dd152013-06-12 20:52:10 +03003819/************/
3820/* Scanning */
3821/************/
3822
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003823void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003824{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003825 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003826
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003827 switch (ar->scan.state) {
3828 case ATH10K_SCAN_IDLE:
3829 break;
3830 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01003831 case ATH10K_SCAN_ABORTING:
3832 if (!ar->scan.is_roc)
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003833 ieee80211_scan_completed(ar->hw,
3834 (ar->scan.state ==
3835 ATH10K_SCAN_ABORTING));
Michal Kaziord710e752015-07-09 13:08:36 +02003836 else if (ar->scan.roc_notify)
3837 ieee80211_remain_on_channel_expired(ar->hw);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003838 /* fall through */
3839 case ATH10K_SCAN_STARTING:
3840 ar->scan.state = ATH10K_SCAN_IDLE;
3841 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01003842 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003843 ath10k_offchan_tx_purge(ar);
3844 cancel_delayed_work(&ar->scan.timeout);
3845 complete_all(&ar->scan.completed);
3846 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003847 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003848}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003849
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003850void ath10k_scan_finish(struct ath10k *ar)
3851{
3852 spin_lock_bh(&ar->data_lock);
3853 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003854 spin_unlock_bh(&ar->data_lock);
3855}
3856
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003857static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003858{
3859 struct wmi_stop_scan_arg arg = {
3860 .req_id = 1, /* FIXME */
3861 .req_type = WMI_SCAN_STOP_ONE,
3862 .u.scan_id = ATH10K_SCAN_ID,
3863 };
3864 int ret;
3865
3866 lockdep_assert_held(&ar->conf_mutex);
3867
Kalle Valo5e3dd152013-06-12 20:52:10 +03003868 ret = ath10k_wmi_stop_scan(ar, &arg);
3869 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003870 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003871 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003872 }
3873
Kalle Valo14e105c2016-04-13 14:13:21 +03003874 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003875 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003876 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003877 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003878 } else if (ret > 0) {
3879 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003880 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003881
3882out:
3883 /* Scan state should be updated upon scan completion but in case
3884 * firmware fails to deliver the event (for whatever reason) it is
3885 * desired to clean up scan state anyway. Firmware may have just
3886 * dropped the scan completion event delivery due to transport pipe
3887 * being overflown with data and/or it can recover on its own before
3888 * next scan request is submitted.
3889 */
3890 spin_lock_bh(&ar->data_lock);
3891 if (ar->scan.state != ATH10K_SCAN_IDLE)
3892 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003893 spin_unlock_bh(&ar->data_lock);
3894
3895 return ret;
3896}
3897
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003898static void ath10k_scan_abort(struct ath10k *ar)
3899{
3900 int ret;
3901
3902 lockdep_assert_held(&ar->conf_mutex);
3903
3904 spin_lock_bh(&ar->data_lock);
3905
3906 switch (ar->scan.state) {
3907 case ATH10K_SCAN_IDLE:
3908 /* This can happen if timeout worker kicked in and called
3909 * abortion while scan completion was being processed.
3910 */
3911 break;
3912 case ATH10K_SCAN_STARTING:
3913 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02003914 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003915 ath10k_scan_state_str(ar->scan.state),
3916 ar->scan.state);
3917 break;
3918 case ATH10K_SCAN_RUNNING:
3919 ar->scan.state = ATH10K_SCAN_ABORTING;
3920 spin_unlock_bh(&ar->data_lock);
3921
3922 ret = ath10k_scan_stop(ar);
3923 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003924 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003925
3926 spin_lock_bh(&ar->data_lock);
3927 break;
3928 }
3929
3930 spin_unlock_bh(&ar->data_lock);
3931}
3932
3933void ath10k_scan_timeout_work(struct work_struct *work)
3934{
3935 struct ath10k *ar = container_of(work, struct ath10k,
3936 scan.timeout.work);
3937
3938 mutex_lock(&ar->conf_mutex);
3939 ath10k_scan_abort(ar);
3940 mutex_unlock(&ar->conf_mutex);
3941}
3942
Kalle Valo5e3dd152013-06-12 20:52:10 +03003943static int ath10k_start_scan(struct ath10k *ar,
3944 const struct wmi_start_scan_arg *arg)
3945{
3946 int ret;
3947
3948 lockdep_assert_held(&ar->conf_mutex);
3949
3950 ret = ath10k_wmi_start_scan(ar, arg);
3951 if (ret)
3952 return ret;
3953
Kalle Valo14e105c2016-04-13 14:13:21 +03003954 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003955 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003956 ret = ath10k_scan_stop(ar);
3957 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003958 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003959
3960 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003961 }
3962
Ben Greear2f9eec02015-02-15 16:50:38 +02003963 /* If we failed to start the scan, return error code at
3964 * this point. This is probably due to some issue in the
3965 * firmware, but no need to wedge the driver due to that...
3966 */
3967 spin_lock_bh(&ar->data_lock);
3968 if (ar->scan.state == ATH10K_SCAN_IDLE) {
3969 spin_unlock_bh(&ar->data_lock);
3970 return -EINVAL;
3971 }
3972 spin_unlock_bh(&ar->data_lock);
3973
Kalle Valo5e3dd152013-06-12 20:52:10 +03003974 return 0;
3975}
3976
3977/**********************/
3978/* mac80211 callbacks */
3979/**********************/
3980
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003981static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
3982 struct ieee80211_tx_control *control,
3983 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003984{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003985 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02003986 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03003987 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3988 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003989 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003990 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02003991 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01003992 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003993 enum ath10k_mac_tx_path txpath;
3994 bool is_htt;
3995 bool is_mgmt;
3996 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003997 int ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003998
Michal Kaziordd4717b2016-03-06 16:14:39 +02003999 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004000
Michal Kazior8a933962015-11-18 06:59:17 +01004001 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004002 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
4003 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
4004 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304005 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004006
Michal Kazior6421969f2016-03-06 16:14:25 +02004007 if (is_htt) {
4008 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004009 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4010
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304011 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004012 if (ret) {
4013 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4014 ret);
4015 spin_unlock_bh(&ar->htt.tx_lock);
4016 ieee80211_free_txskb(ar->hw, skb);
4017 return;
4018 }
4019
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304020 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4021 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304022 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4023 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304024 ath10k_htt_tx_dec_pending(htt);
4025 spin_unlock_bh(&ar->htt.tx_lock);
4026 ieee80211_free_txskb(ar->hw, skb);
4027 return;
4028 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004029 spin_unlock_bh(&ar->htt.tx_lock);
4030 }
4031
4032 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
4033 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004034 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004035 if (is_htt) {
4036 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304037 ath10k_htt_tx_dec_pending(htt);
4038 if (is_mgmt)
4039 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004040 spin_unlock_bh(&ar->htt.tx_lock);
4041 }
4042 return;
4043 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004044}
4045
Michal Kazior29946872016-03-06 16:14:34 +02004046static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4047 struct ieee80211_txq *txq)
4048{
4049 struct ath10k *ar = hw->priv;
4050 struct ath10k_txq *artxq = (void *)txq->drv_priv;
4051
Michal Kazior750eeed2016-03-17 10:51:05 +01004052 spin_lock_bh(&ar->txqs_lock);
4053 if (list_empty(&artxq->list))
4054 list_add_tail(&artxq->list, &ar->txqs);
4055 spin_unlock_bh(&ar->txqs_lock);
Michal Kazior29946872016-03-06 16:14:34 +02004056
Michal Kazior7a0adc82016-05-23 23:12:45 +03004057 ath10k_mac_tx_push_pending(ar);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004058 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02004059}
4060
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004061/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004062void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004063{
4064 /* make sure rcu-protected mac80211 tx path itself is drained */
4065 synchronize_net();
4066
4067 ath10k_offchan_tx_purge(ar);
4068 ath10k_mgmt_over_wmi_tx_purge(ar);
4069
4070 cancel_work_sync(&ar->offchan_tx_work);
4071 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4072}
4073
Michal Kazioraffd3212013-07-16 09:54:35 +02004074void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004075{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004076 struct ath10k_vif *arvif;
4077
Michal Kazior818bdd12013-07-16 09:38:57 +02004078 lockdep_assert_held(&ar->conf_mutex);
4079
Michal Kazior19337472014-08-28 12:58:16 +02004080 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4081 ar->filter_flags = 0;
4082 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004083 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004084
4085 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004086 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004087
4088 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004089 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004090
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004091 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004092 ath10k_peer_cleanup_all(ar);
4093 ath10k_core_stop(ar);
4094 ath10k_hif_power_down(ar);
4095
4096 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004097 list_for_each_entry(arvif, &ar->arvifs, list)
4098 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004099 spin_unlock_bh(&ar->data_lock);
4100}
4101
Ben Greear46acf7b2014-05-16 17:15:38 +03004102static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4103{
4104 struct ath10k *ar = hw->priv;
4105
4106 mutex_lock(&ar->conf_mutex);
4107
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304108 *tx_ant = ar->cfg_tx_chainmask;
4109 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03004110
4111 mutex_unlock(&ar->conf_mutex);
4112
4113 return 0;
4114}
4115
Ben Greear5572a952014-11-24 16:22:10 +02004116static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4117{
4118 /* It is not clear that allowing gaps in chainmask
4119 * is helpful. Probably it will not do what user
4120 * is hoping for, so warn in that case.
4121 */
4122 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4123 return;
4124
4125 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4126 dbg, cm);
4127}
4128
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304129static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4130{
4131 int nsts = ar->vht_cap_info;
4132
4133 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4134 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4135
4136 /* If firmware does not deliver to host number of space-time
4137 * streams supported, assume it support up to 4 BF STS and return
4138 * the value for VHT CAP: nsts-1)
4139 */
4140 if (nsts == 0)
4141 return 3;
4142
4143 return nsts;
4144}
4145
4146static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4147{
4148 int sound_dim = ar->vht_cap_info;
4149
4150 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4151 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4152
4153 /* If the sounding dimension is not advertised by the firmware,
4154 * let's use a default value of 1
4155 */
4156 if (sound_dim == 0)
4157 return 1;
4158
4159 return sound_dim;
4160}
4161
4162static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4163{
4164 struct ieee80211_sta_vht_cap vht_cap = {0};
4165 u16 mcs_map;
4166 u32 val;
4167 int i;
4168
4169 vht_cap.vht_supported = 1;
4170 vht_cap.cap = ar->vht_cap_info;
4171
4172 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4173 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4174 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4175 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4176 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4177
4178 vht_cap.cap |= val;
4179 }
4180
4181 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4182 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4183 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4184 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4185 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4186
4187 vht_cap.cap |= val;
4188 }
4189
4190 mcs_map = 0;
4191 for (i = 0; i < 8; i++) {
4192 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4193 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4194 else
4195 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4196 }
4197
4198 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4199 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4200
4201 return vht_cap;
4202}
4203
4204static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4205{
4206 int i;
4207 struct ieee80211_sta_ht_cap ht_cap = {0};
4208
4209 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4210 return ht_cap;
4211
4212 ht_cap.ht_supported = 1;
4213 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4214 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4215 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4216 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004217 ht_cap.cap |=
4218 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304219
4220 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4221 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4222
4223 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4224 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4225
4226 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4227 u32 smps;
4228
4229 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4230 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4231
4232 ht_cap.cap |= smps;
4233 }
4234
4235 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC)
4236 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4237
4238 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4239 u32 stbc;
4240
4241 stbc = ar->ht_cap_info;
4242 stbc &= WMI_HT_CAP_RX_STBC;
4243 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4244 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4245 stbc &= IEEE80211_HT_CAP_RX_STBC;
4246
4247 ht_cap.cap |= stbc;
4248 }
4249
4250 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
4251 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4252
4253 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4254 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4255
4256 /* max AMSDU is implicitly taken from vht_cap_info */
4257 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4258 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4259
4260 for (i = 0; i < ar->num_rf_chains; i++) {
4261 if (ar->cfg_rx_chainmask & BIT(i))
4262 ht_cap.mcs.rx_mask[i] = 0xFF;
4263 }
4264
4265 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4266
4267 return ht_cap;
4268}
4269
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304270static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4271{
4272 struct ieee80211_supported_band *band;
4273 struct ieee80211_sta_vht_cap vht_cap;
4274 struct ieee80211_sta_ht_cap ht_cap;
4275
4276 ht_cap = ath10k_get_ht_cap(ar);
4277 vht_cap = ath10k_create_vht_cap(ar);
4278
4279 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004280 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304281 band->ht_cap = ht_cap;
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304282 }
4283 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004284 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304285 band->ht_cap = ht_cap;
4286 band->vht_cap = vht_cap;
4287 }
4288}
4289
Ben Greear46acf7b2014-05-16 17:15:38 +03004290static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4291{
4292 int ret;
4293
4294 lockdep_assert_held(&ar->conf_mutex);
4295
Ben Greear5572a952014-11-24 16:22:10 +02004296 ath10k_check_chain_mask(ar, tx_ant, "tx");
4297 ath10k_check_chain_mask(ar, rx_ant, "rx");
4298
Ben Greear46acf7b2014-05-16 17:15:38 +03004299 ar->cfg_tx_chainmask = tx_ant;
4300 ar->cfg_rx_chainmask = rx_ant;
4301
4302 if ((ar->state != ATH10K_STATE_ON) &&
4303 (ar->state != ATH10K_STATE_RESTARTED))
4304 return 0;
4305
4306 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4307 tx_ant);
4308 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004309 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004310 ret, tx_ant);
4311 return ret;
4312 }
4313
4314 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4315 rx_ant);
4316 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004317 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004318 ret, rx_ant);
4319 return ret;
4320 }
4321
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304322 /* Reload HT/VHT capability */
4323 ath10k_mac_setup_ht_vht_cap(ar);
4324
Ben Greear46acf7b2014-05-16 17:15:38 +03004325 return 0;
4326}
4327
4328static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4329{
4330 struct ath10k *ar = hw->priv;
4331 int ret;
4332
4333 mutex_lock(&ar->conf_mutex);
4334 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4335 mutex_unlock(&ar->conf_mutex);
4336 return ret;
4337}
4338
Kalle Valo5e3dd152013-06-12 20:52:10 +03004339static int ath10k_start(struct ieee80211_hw *hw)
4340{
4341 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304342 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004343 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004344
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004345 /*
4346 * This makes sense only when restarting hw. It is harmless to call
Mohammed Shafi Shajakhan6dfdbfc2016-04-26 14:41:36 +03004347 * unconditionally. This is necessary to make sure no HTT/WMI tx
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004348 * commands will be submitted while restarting.
4349 */
4350 ath10k_drain_tx(ar);
4351
Michal Kazior548db542013-07-05 16:15:15 +03004352 mutex_lock(&ar->conf_mutex);
4353
Michal Kaziorc5058f52014-05-26 12:46:03 +03004354 switch (ar->state) {
4355 case ATH10K_STATE_OFF:
4356 ar->state = ATH10K_STATE_ON;
4357 break;
4358 case ATH10K_STATE_RESTARTING:
4359 ath10k_halt(ar);
4360 ar->state = ATH10K_STATE_RESTARTED;
4361 break;
4362 case ATH10K_STATE_ON:
4363 case ATH10K_STATE_RESTARTED:
4364 case ATH10K_STATE_WEDGED:
4365 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004366 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004367 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004368 case ATH10K_STATE_UTF:
4369 ret = -EBUSY;
4370 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004371 }
4372
4373 ret = ath10k_hif_power_up(ar);
4374 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004375 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004376 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004377 }
4378
Kalle Valo7ebf7212016-04-20 19:44:51 +03004379 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
4380 &ar->normal_mode_fw);
Michal Kazior818bdd12013-07-16 09:38:57 +02004381 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004382 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004383 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004384 }
4385
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304386 param = ar->wmi.pdev_param->pmf_qos;
4387 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004388 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004389 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004390 goto err_core_stop;
4391 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004392
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304393 param = ar->wmi.pdev_param->dynamic_bw;
4394 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004395 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004396 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004397 goto err_core_stop;
4398 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004399
Michal Kaziorcf327842015-03-31 10:26:25 +00004400 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4401 ret = ath10k_wmi_adaptive_qcs(ar, true);
4402 if (ret) {
4403 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4404 ret);
4405 goto err_core_stop;
4406 }
4407 }
4408
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004409 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304410 param = ar->wmi.pdev_param->burst_enable;
4411 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004412 if (ret) {
4413 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4414 goto err_core_stop;
4415 }
4416 }
4417
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304418 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7b2014-05-16 17:15:38 +03004419
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004420 /*
4421 * By default FW set ARP frames ac to voice (6). In that case ARP
4422 * exchange is not working properly for UAPSD enabled AP. ARP requests
4423 * which arrives with access category 0 are processed by network stack
4424 * and send back with access category 0, but FW changes access category
4425 * to 6. Set ARP frames access category to best effort (0) solves
4426 * this problem.
4427 */
4428
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304429 param = ar->wmi.pdev_param->arp_ac_override;
4430 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004431 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004432 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004433 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004434 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004435 }
4436
Maharaja62f77f02015-10-21 11:49:18 +03004437 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
Kalle Valoc4cdf752016-04-20 19:45:18 +03004438 ar->running_fw->fw_file.fw_features)) {
Maharaja62f77f02015-10-21 11:49:18 +03004439 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4440 WMI_CCA_DETECT_LEVEL_AUTO,
4441 WMI_CCA_DETECT_MARGIN_AUTO);
4442 if (ret) {
4443 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4444 ret);
4445 goto err_core_stop;
4446 }
4447 }
4448
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304449 param = ar->wmi.pdev_param->ani_enable;
4450 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304451 if (ret) {
4452 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4453 ret);
4454 goto err_core_stop;
4455 }
4456
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304457 ar->ani_enabled = true;
4458
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304459 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304460 param = ar->wmi.pdev_param->peer_stats_update_period;
4461 ret = ath10k_wmi_pdev_set_param(ar, param,
4462 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4463 if (ret) {
4464 ath10k_warn(ar,
4465 "failed to set peer stats period : %d\n",
4466 ret);
4467 goto err_core_stop;
4468 }
4469 }
4470
Michal Kaziord6500972014-04-08 09:56:09 +03004471 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004472 ath10k_regd_update(ar);
4473
Simon Wunderlich855aed12014-08-02 09:12:54 +03004474 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304475 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004476
Michal Kaziorae254432014-05-26 12:46:02 +03004477 mutex_unlock(&ar->conf_mutex);
4478 return 0;
4479
4480err_core_stop:
4481 ath10k_core_stop(ar);
4482
4483err_power_down:
4484 ath10k_hif_power_down(ar);
4485
4486err_off:
4487 ar->state = ATH10K_STATE_OFF;
4488
4489err:
Michal Kazior548db542013-07-05 16:15:15 +03004490 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004491 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004492}
4493
4494static void ath10k_stop(struct ieee80211_hw *hw)
4495{
4496 struct ath10k *ar = hw->priv;
4497
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004498 ath10k_drain_tx(ar);
4499
Michal Kazior548db542013-07-05 16:15:15 +03004500 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004501 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004502 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004503 ar->state = ATH10K_STATE_OFF;
4504 }
Michal Kazior548db542013-07-05 16:15:15 +03004505 mutex_unlock(&ar->conf_mutex);
4506
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004507 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004508 cancel_work_sync(&ar->restart_work);
4509}
4510
Michal Kaziorad088bf2013-10-16 15:44:46 +03004511static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004512{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004513 struct ath10k_vif *arvif;
4514 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004515
4516 lockdep_assert_held(&ar->conf_mutex);
4517
Michal Kaziorad088bf2013-10-16 15:44:46 +03004518 list_for_each_entry(arvif, &ar->arvifs, list) {
4519 ret = ath10k_mac_vif_setup_ps(arvif);
4520 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004521 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004522 break;
4523 }
4524 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004525
Michal Kaziorad088bf2013-10-16 15:44:46 +03004526 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004527}
4528
Michal Kazior7d9d5582014-10-21 10:40:15 +03004529static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4530{
4531 int ret;
4532 u32 param;
4533
4534 lockdep_assert_held(&ar->conf_mutex);
4535
4536 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4537
4538 param = ar->wmi.pdev_param->txpower_limit2g;
4539 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4540 if (ret) {
4541 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4542 txpower, ret);
4543 return ret;
4544 }
4545
4546 param = ar->wmi.pdev_param->txpower_limit5g;
4547 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4548 if (ret) {
4549 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4550 txpower, ret);
4551 return ret;
4552 }
4553
4554 return 0;
4555}
4556
4557static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4558{
4559 struct ath10k_vif *arvif;
4560 int ret, txpower = -1;
4561
4562 lockdep_assert_held(&ar->conf_mutex);
4563
4564 list_for_each_entry(arvif, &ar->arvifs, list) {
4565 WARN_ON(arvif->txpower < 0);
4566
4567 if (txpower == -1)
4568 txpower = arvif->txpower;
4569 else
4570 txpower = min(txpower, arvif->txpower);
4571 }
4572
4573 if (WARN_ON(txpower == -1))
4574 return -EINVAL;
4575
4576 ret = ath10k_mac_txpower_setup(ar, txpower);
4577 if (ret) {
4578 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4579 txpower, ret);
4580 return ret;
4581 }
4582
4583 return 0;
4584}
4585
Kalle Valo5e3dd152013-06-12 20:52:10 +03004586static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4587{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004588 struct ath10k *ar = hw->priv;
4589 struct ieee80211_conf *conf = &hw->conf;
4590 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004591
4592 mutex_lock(&ar->conf_mutex);
4593
Michal Kazioraffd3212013-07-16 09:54:35 +02004594 if (changed & IEEE80211_CONF_CHANGE_PS)
4595 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004596
4597 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004598 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4599 ret = ath10k_monitor_recalc(ar);
4600 if (ret)
4601 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004602 }
4603
4604 mutex_unlock(&ar->conf_mutex);
4605 return ret;
4606}
4607
Ben Greear5572a952014-11-24 16:22:10 +02004608static u32 get_nss_from_chainmask(u16 chain_mask)
4609{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05304610 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02004611 return 4;
4612 else if ((chain_mask & 0x7) == 0x7)
4613 return 3;
4614 else if ((chain_mask & 0x3) == 0x3)
4615 return 2;
4616 return 1;
4617}
4618
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304619static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4620{
4621 u32 value = 0;
4622 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004623 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004624 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304625
4626 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4627 return 0;
4628
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004629 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304630 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4631 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004632 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304633
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004634 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304635 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4636 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004637 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304638
4639 if (!value)
4640 return 0;
4641
4642 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4643 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4644
4645 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4646 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4647 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4648
4649 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4650 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4651
4652 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4653 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4654 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4655
4656 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4657 ar->wmi.vdev_param->txbf, value);
4658}
4659
Kalle Valo5e3dd152013-06-12 20:52:10 +03004660/*
4661 * TODO:
4662 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4663 * because we will send mgmt frames without CCK. This requirement
4664 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4665 * in the TX packet.
4666 */
4667static int ath10k_add_interface(struct ieee80211_hw *hw,
4668 struct ieee80211_vif *vif)
4669{
4670 struct ath10k *ar = hw->priv;
4671 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004672 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004673 enum wmi_sta_powersave_param param;
4674 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004675 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004676 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004677 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004678 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004679
Johannes Berg848955c2014-11-11 12:48:42 +01004680 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4681
Kalle Valo5e3dd152013-06-12 20:52:10 +03004682 mutex_lock(&ar->conf_mutex);
4683
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004684 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02004685 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004686
Kalle Valo5e3dd152013-06-12 20:52:10 +03004687 arvif->ar = ar;
4688 arvif->vif = vif;
4689
Ben Greeare63b33f2013-10-22 14:54:14 -07004690 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004691 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004692 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4693 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004694
Michal Kazior45c9abc2015-04-21 20:42:58 +03004695 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4696 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4697 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4698 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4699 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4700 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4701 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004702
Michal Kaziore04cafb2015-08-05 12:15:24 +02004703 if (ar->num_peers >= ar->max_num_peers) {
4704 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004705 ret = -ENOBUFS;
4706 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004707 }
4708
Ben Greeara9aefb32014-08-12 11:02:19 +03004709 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004710 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004711 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03004712 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004713 }
Ben Greear16c11172014-09-23 14:17:16 -07004714 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004715
Ben Greear16c11172014-09-23 14:17:16 -07004716 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4717 bit, ar->free_vdev_map);
4718
4719 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004720 arvif->vdev_subtype =
4721 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004722
Kalle Valo5e3dd152013-06-12 20:52:10 +03004723 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004724 case NL80211_IFTYPE_P2P_DEVICE:
4725 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004726 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4727 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01004728 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004729 case NL80211_IFTYPE_UNSPECIFIED:
4730 case NL80211_IFTYPE_STATION:
4731 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4732 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004733 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4734 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004735 break;
4736 case NL80211_IFTYPE_ADHOC:
4737 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4738 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004739 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08004740 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08004741 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4742 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08004743 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004744 ret = -EINVAL;
4745 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
4746 goto err;
4747 }
4748 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4749 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004750 case NL80211_IFTYPE_AP:
4751 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4752
4753 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004754 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4755 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004756 break;
4757 case NL80211_IFTYPE_MONITOR:
4758 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4759 break;
4760 default:
4761 WARN_ON(1);
4762 break;
4763 }
4764
Michal Kazior96d828d2015-03-31 10:26:23 +00004765 /* Using vdev_id as queue number will make it very easy to do per-vif
4766 * tx queue locking. This shouldn't wrap due to interface combinations
4767 * but do a modulo for correctness sake and prevent using offchannel tx
4768 * queues for regular vif tx.
4769 */
4770 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4771 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4772 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4773
Michal Kazior64badcb2014-09-18 11:18:02 +03004774 /* Some firmware revisions don't wait for beacon tx completion before
4775 * sending another SWBA event. This could lead to hardware using old
4776 * (freed) beacon data in some cases, e.g. tx credit starvation
4777 * combined with missed TBTT. This is very very rare.
4778 *
4779 * On non-IOMMU-enabled hosts this could be a possible security issue
4780 * because hw could beacon some random data on the air. On
4781 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4782 * device would crash.
4783 *
4784 * Since there are no beacon tx completions (implicit nor explicit)
4785 * propagated to host the only workaround for this is to allocate a
4786 * DMA-coherent buffer for a lifetime of a vif and use it for all
4787 * beacon tx commands. Worst case for this approach is some beacons may
4788 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4789 */
4790 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004791 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03004792 vif->type == NL80211_IFTYPE_AP) {
4793 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4794 IEEE80211_MAX_FRAME_LEN,
4795 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304796 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004797 if (!arvif->beacon_buf) {
4798 ret = -ENOMEM;
4799 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4800 ret);
4801 goto err;
4802 }
4803 }
David Liuccec9032015-07-24 20:25:32 +03004804 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
4805 arvif->nohwcrypt = true;
4806
4807 if (arvif->nohwcrypt &&
4808 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4809 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
4810 goto err;
4811 }
Michal Kazior64badcb2014-09-18 11:18:02 +03004812
4813 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4814 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4815 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004816
4817 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4818 arvif->vdev_subtype, vif->addr);
4819 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004820 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004821 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004822 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004823 }
4824
Ben Greear16c11172014-09-23 14:17:16 -07004825 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Michal Kazior05791192013-10-16 15:44:45 +03004826 list_add(&arvif->list, &ar->arvifs);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004827
Michal Kazior46725b152015-01-28 09:57:49 +02004828 /* It makes no sense to have firmware do keepalives. mac80211 already
4829 * takes care of this with idle connection polling.
4830 */
4831 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004832 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02004833 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004834 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004835 goto err_vdev_delete;
4836 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004837
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004838 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004839
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004840 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4841 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004842 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004843 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03004844 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004845 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004846 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004847 goto err_vdev_delete;
4848 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004849
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05304850 /* Configuring number of spatial stream for monitor interface is causing
4851 * target assert in qca9888 and qca6174.
4852 */
4853 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02004854 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
4855
4856 vdev_param = ar->wmi.vdev_param->nss;
4857 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4858 nss);
4859 if (ret) {
4860 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
4861 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
4862 ret);
4863 goto err_vdev_delete;
4864 }
4865 }
4866
Michal Kaziore57e0572015-03-24 13:14:03 +00004867 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4868 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02004869 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
4870 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004871 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00004872 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004873 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004874 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004875 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004876
4877 spin_lock_bh(&ar->data_lock);
4878
4879 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
4880 if (!peer) {
4881 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
4882 vif->addr, arvif->vdev_id);
4883 spin_unlock_bh(&ar->data_lock);
4884 ret = -ENOENT;
4885 goto err_peer_delete;
4886 }
4887
4888 arvif->peer_id = find_first_bit(peer->peer_ids,
4889 ATH10K_MAX_NUM_PEER_IDS);
4890
4891 spin_unlock_bh(&ar->data_lock);
4892 } else {
4893 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00004894 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01004895
Michal Kaziore57e0572015-03-24 13:14:03 +00004896 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02004897 ret = ath10k_mac_set_kickout(arvif);
4898 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004899 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004900 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02004901 goto err_peer_delete;
4902 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004903 }
4904
4905 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
4906 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
4907 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
4908 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
4909 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004910 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004911 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004912 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004913 goto err_peer_delete;
4914 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004915
Michal Kazior9f9b5742014-12-12 12:41:36 +01004916 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004917 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004918 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004919 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004920 goto err_peer_delete;
4921 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004922
Michal Kazior9f9b5742014-12-12 12:41:36 +01004923 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004924 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004925 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004926 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004927 goto err_peer_delete;
4928 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004929 }
4930
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304931 ret = ath10k_mac_set_txbf_conf(arvif);
4932 if (ret) {
4933 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
4934 arvif->vdev_id, ret);
4935 goto err_peer_delete;
4936 }
4937
Michal Kazior424121c2013-07-22 14:13:31 +02004938 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004939 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004940 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03004941 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004942 goto err_peer_delete;
4943 }
Michal Kazior679c54a2013-07-05 16:15:04 +03004944
Michal Kazior7d9d5582014-10-21 10:40:15 +03004945 arvif->txpower = vif->bss_conf.txpower;
4946 ret = ath10k_mac_txpower_recalc(ar);
4947 if (ret) {
4948 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4949 goto err_peer_delete;
4950 }
4951
Michal Kazior500ff9f2015-03-31 10:26:21 +00004952 if (vif->type == NL80211_IFTYPE_MONITOR) {
4953 ar->monitor_arvif = arvif;
4954 ret = ath10k_monitor_recalc(ar);
4955 if (ret) {
4956 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
4957 goto err_peer_delete;
4958 }
4959 }
4960
Michal Kazior6d2d51e2015-08-07 09:08:21 +02004961 spin_lock_bh(&ar->htt.tx_lock);
4962 if (!ar->tx_paused)
4963 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
4964 spin_unlock_bh(&ar->htt.tx_lock);
4965
Kalle Valo5e3dd152013-06-12 20:52:10 +03004966 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004967 return 0;
4968
4969err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00004970 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4971 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14a2013-10-16 15:44:45 +03004972 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
4973
4974err_vdev_delete:
4975 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07004976 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004977 list_del(&arvif->list);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004978
4979err:
Michal Kazior64badcb2014-09-18 11:18:02 +03004980 if (arvif->beacon_buf) {
4981 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
4982 arvif->beacon_buf, arvif->beacon_paddr);
4983 arvif->beacon_buf = NULL;
4984 }
4985
Michal Kazior9dad14a2013-10-16 15:44:45 +03004986 mutex_unlock(&ar->conf_mutex);
4987
Kalle Valo5e3dd152013-06-12 20:52:10 +03004988 return ret;
4989}
4990
Michal Kaziorb4aa5392015-03-31 10:26:24 +00004991static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
4992{
4993 int i;
4994
4995 for (i = 0; i < BITS_PER_LONG; i++)
4996 ath10k_mac_vif_tx_unlock(arvif, i);
4997}
4998
Kalle Valo5e3dd152013-06-12 20:52:10 +03004999static void ath10k_remove_interface(struct ieee80211_hw *hw,
5000 struct ieee80211_vif *vif)
5001{
5002 struct ath10k *ar = hw->priv;
5003 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior69427262016-03-06 16:14:30 +02005004 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005005 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005006 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005007
Michal Kazior81a9a172015-03-05 16:02:17 +02005008 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005009 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005010
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305011 mutex_lock(&ar->conf_mutex);
5012
Michal Kaziored543882013-09-13 14:16:56 +02005013 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03005014 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02005015 spin_unlock_bh(&ar->data_lock);
5016
Simon Wunderlich855aed12014-08-02 09:12:54 +03005017 ret = ath10k_spectral_vif_stop(arvif);
5018 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005019 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005020 arvif->vdev_id, ret);
5021
Ben Greear16c11172014-09-23 14:17:16 -07005022 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03005023 list_del(&arvif->list);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005024
Michal Kaziore57e0572015-03-24 13:14:03 +00005025 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5026 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005027 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5028 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005029 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005030 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005031 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005032
5033 kfree(arvif->u.ap.noa_data);
5034 }
5035
Michal Kazior7aa7a722014-08-25 12:09:38 +02005036 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005037 arvif->vdev_id);
5038
Kalle Valo5e3dd152013-06-12 20:52:10 +03005039 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5040 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005041 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005042 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005043
Michal Kazior2c512052015-02-15 16:50:40 +02005044 /* Some firmware revisions don't notify host about self-peer removal
5045 * until after associated vdev is deleted.
5046 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005047 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5048 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005049 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5050 vif->addr);
5051 if (ret)
5052 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5053 arvif->vdev_id, ret);
5054
5055 spin_lock_bh(&ar->data_lock);
5056 ar->num_peers--;
5057 spin_unlock_bh(&ar->data_lock);
5058 }
5059
Michal Kazior69427262016-03-06 16:14:30 +02005060 spin_lock_bh(&ar->data_lock);
5061 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5062 peer = ar->peer_map[i];
5063 if (!peer)
5064 continue;
5065
5066 if (peer->vif == vif) {
5067 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5068 vif->addr, arvif->vdev_id);
5069 peer->vif = NULL;
5070 }
5071 }
5072 spin_unlock_bh(&ar->data_lock);
5073
Kalle Valo5e3dd152013-06-12 20:52:10 +03005074 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005075 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005076
Michal Kazior500ff9f2015-03-31 10:26:21 +00005077 if (vif->type == NL80211_IFTYPE_MONITOR) {
5078 ar->monitor_arvif = NULL;
5079 ret = ath10k_monitor_recalc(ar);
5080 if (ret)
5081 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5082 }
5083
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005084 spin_lock_bh(&ar->htt.tx_lock);
5085 ath10k_mac_vif_tx_unlock_all(arvif);
5086 spin_unlock_bh(&ar->htt.tx_lock);
5087
Michal Kazior29946872016-03-06 16:14:34 +02005088 ath10k_mac_txq_unref(ar, vif->txq);
5089
Kalle Valo5e3dd152013-06-12 20:52:10 +03005090 mutex_unlock(&ar->conf_mutex);
5091}
5092
5093/*
5094 * FIXME: Has to be verified.
5095 */
5096#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005097 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005098 FIF_CONTROL | \
5099 FIF_PSPOLL | \
5100 FIF_OTHER_BSS | \
5101 FIF_BCN_PRBRESP_PROMISC | \
5102 FIF_PROBE_REQ | \
5103 FIF_FCSFAIL)
5104
5105static void ath10k_configure_filter(struct ieee80211_hw *hw,
5106 unsigned int changed_flags,
5107 unsigned int *total_flags,
5108 u64 multicast)
5109{
5110 struct ath10k *ar = hw->priv;
5111 int ret;
5112
5113 mutex_lock(&ar->conf_mutex);
5114
5115 changed_flags &= SUPPORTED_FILTERS;
5116 *total_flags &= SUPPORTED_FILTERS;
5117 ar->filter_flags = *total_flags;
5118
Michal Kazior19337472014-08-28 12:58:16 +02005119 ret = ath10k_monitor_recalc(ar);
5120 if (ret)
5121 ath10k_warn(ar, "failed to recalc montior: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005122
5123 mutex_unlock(&ar->conf_mutex);
5124}
5125
5126static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5127 struct ieee80211_vif *vif,
5128 struct ieee80211_bss_conf *info,
5129 u32 changed)
5130{
5131 struct ath10k *ar = hw->priv;
5132 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5133 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03005134 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005135
5136 mutex_lock(&ar->conf_mutex);
5137
5138 if (changed & BSS_CHANGED_IBSS)
5139 ath10k_control_ibss(arvif, info, vif->addr);
5140
5141 if (changed & BSS_CHANGED_BEACON_INT) {
5142 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005143 vdev_param = ar->wmi.vdev_param->beacon_interval;
5144 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005145 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005146 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005147 "mac vdev %d beacon_interval %d\n",
5148 arvif->vdev_id, arvif->beacon_interval);
5149
Kalle Valo5e3dd152013-06-12 20:52:10 +03005150 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005151 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005152 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005153 }
5154
5155 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005156 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005157 "vdev %d set beacon tx mode to staggered\n",
5158 arvif->vdev_id);
5159
Bartosz Markowski226a3392013-09-26 17:47:16 +02005160 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5161 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005162 WMI_BEACON_STAGGERED_MODE);
5163 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005164 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005165 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005166
5167 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5168 if (ret)
5169 ath10k_warn(ar, "failed to update beacon template: %d\n",
5170 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005171
5172 if (ieee80211_vif_is_mesh(vif)) {
5173 /* mesh doesn't use SSID but firmware needs it */
5174 strncpy(arvif->u.ap.ssid, "mesh",
5175 sizeof(arvif->u.ap.ssid));
5176 arvif->u.ap.ssid_len = 4;
5177 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005178 }
5179
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005180 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5181 ret = ath10k_mac_setup_prb_tmpl(arvif);
5182 if (ret)
5183 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5184 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005185 }
5186
Michal Kaziorba2479f2015-01-24 12:14:51 +02005187 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005188 arvif->dtim_period = info->dtim_period;
5189
Michal Kazior7aa7a722014-08-25 12:09:38 +02005190 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005191 "mac vdev %d dtim_period %d\n",
5192 arvif->vdev_id, arvif->dtim_period);
5193
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005194 vdev_param = ar->wmi.vdev_param->dtim_period;
5195 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005196 arvif->dtim_period);
5197 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005198 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005199 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005200 }
5201
5202 if (changed & BSS_CHANGED_SSID &&
5203 vif->type == NL80211_IFTYPE_AP) {
5204 arvif->u.ap.ssid_len = info->ssid_len;
5205 if (info->ssid_len)
5206 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5207 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5208 }
5209
Michal Kazior077efc82014-10-21 10:10:29 +03005210 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5211 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005212
5213 if (changed & BSS_CHANGED_BEACON_ENABLED)
5214 ath10k_control_beaconing(arvif, info);
5215
5216 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005217 arvif->use_cts_prot = info->use_cts_prot;
Michal Kazior7aa7a722014-08-25 12:09:38 +02005218 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005219 arvif->vdev_id, info->use_cts_prot);
Kalle Valo60c3daa2013-09-08 17:56:07 +03005220
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005221 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005222 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005223 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005224 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005225
5226 vdev_param = ar->wmi.vdev_param->protection_mode;
5227 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5228 info->use_cts_prot ? 1 : 0);
5229 if (ret)
5230 ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
Kalle Valo617b0f42015-10-05 17:56:35 +03005231 info->use_cts_prot, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005232 }
5233
5234 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005235 if (info->use_short_slot)
5236 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5237
5238 else
5239 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5240
Michal Kazior7aa7a722014-08-25 12:09:38 +02005241 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005242 arvif->vdev_id, slottime);
5243
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005244 vdev_param = ar->wmi.vdev_param->slot_time;
5245 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005246 slottime);
5247 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005248 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005249 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005250 }
5251
5252 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005253 if (info->use_short_preamble)
5254 preamble = WMI_VDEV_PREAMBLE_SHORT;
5255 else
5256 preamble = WMI_VDEV_PREAMBLE_LONG;
5257
Michal Kazior7aa7a722014-08-25 12:09:38 +02005258 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005259 "mac vdev %d preamble %dn",
5260 arvif->vdev_id, preamble);
5261
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005262 vdev_param = ar->wmi.vdev_param->preamble;
5263 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005264 preamble);
5265 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005266 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005267 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005268 }
5269
5270 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005271 if (info->assoc) {
5272 /* Workaround: Make sure monitor vdev is not running
5273 * when associating to prevent some firmware revisions
5274 * (e.g. 10.1 and 10.2) from crashing.
5275 */
5276 if (ar->monitor_started)
5277 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005278 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005279 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005280 } else {
5281 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005282 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005283 }
5284
Michal Kazior7d9d5582014-10-21 10:40:15 +03005285 if (changed & BSS_CHANGED_TXPOWER) {
5286 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5287 arvif->vdev_id, info->txpower);
5288
5289 arvif->txpower = info->txpower;
5290 ret = ath10k_mac_txpower_recalc(ar);
5291 if (ret)
5292 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5293 }
5294
Michal Kaziorbf14e652014-12-12 12:41:38 +01005295 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005296 arvif->ps = vif->bss_conf.ps;
5297
5298 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005299 if (ret)
5300 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5301 arvif->vdev_id, ret);
5302 }
5303
Kalle Valo5e3dd152013-06-12 20:52:10 +03005304 mutex_unlock(&ar->conf_mutex);
5305}
5306
5307static int ath10k_hw_scan(struct ieee80211_hw *hw,
5308 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005309 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005310{
5311 struct ath10k *ar = hw->priv;
5312 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02005313 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005314 struct wmi_start_scan_arg arg;
5315 int ret = 0;
5316 int i;
5317
5318 mutex_lock(&ar->conf_mutex);
5319
5320 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005321 switch (ar->scan.state) {
5322 case ATH10K_SCAN_IDLE:
5323 reinit_completion(&ar->scan.started);
5324 reinit_completion(&ar->scan.completed);
5325 ar->scan.state = ATH10K_SCAN_STARTING;
5326 ar->scan.is_roc = false;
5327 ar->scan.vdev_id = arvif->vdev_id;
5328 ret = 0;
5329 break;
5330 case ATH10K_SCAN_STARTING:
5331 case ATH10K_SCAN_RUNNING:
5332 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005333 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005334 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005335 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005336 spin_unlock_bh(&ar->data_lock);
5337
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005338 if (ret)
5339 goto exit;
5340
Kalle Valo5e3dd152013-06-12 20:52:10 +03005341 memset(&arg, 0, sizeof(arg));
5342 ath10k_wmi_start_scan_init(ar, &arg);
5343 arg.vdev_id = arvif->vdev_id;
5344 arg.scan_id = ATH10K_SCAN_ID;
5345
Kalle Valo5e3dd152013-06-12 20:52:10 +03005346 if (req->ie_len) {
5347 arg.ie_len = req->ie_len;
5348 memcpy(arg.ie, req->ie, arg.ie_len);
5349 }
5350
5351 if (req->n_ssids) {
5352 arg.n_ssids = req->n_ssids;
5353 for (i = 0; i < arg.n_ssids; i++) {
5354 arg.ssids[i].len = req->ssids[i].ssid_len;
5355 arg.ssids[i].ssid = req->ssids[i].ssid;
5356 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005357 } else {
5358 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005359 }
5360
5361 if (req->n_channels) {
5362 arg.n_channels = req->n_channels;
5363 for (i = 0; i < arg.n_channels; i++)
5364 arg.channels[i] = req->channels[i]->center_freq;
5365 }
5366
5367 ret = ath10k_start_scan(ar, &arg);
5368 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005369 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005370 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005371 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005372 spin_unlock_bh(&ar->data_lock);
5373 }
5374
Michal Kazior634349b2015-09-03 10:43:45 +02005375 /* Add a 200ms margin to account for event/command processing */
5376 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5377 msecs_to_jiffies(arg.max_scan_time +
5378 200));
5379
Kalle Valo5e3dd152013-06-12 20:52:10 +03005380exit:
5381 mutex_unlock(&ar->conf_mutex);
5382 return ret;
5383}
5384
5385static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5386 struct ieee80211_vif *vif)
5387{
5388 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005389
5390 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005391 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005392 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01005393
5394 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005395}
5396
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005397static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
5398 struct ath10k_vif *arvif,
5399 enum set_key_cmd cmd,
5400 struct ieee80211_key_conf *key)
5401{
5402 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
5403 int ret;
5404
5405 /* 10.1 firmware branch requires default key index to be set to group
5406 * key index after installing it. Otherwise FW/HW Txes corrupted
5407 * frames with multi-vif APs. This is not required for main firmware
5408 * branch (e.g. 636).
5409 *
Michal Kazior8461baf2015-04-10 13:23:22 +00005410 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
5411 *
5412 * FIXME: It remains unknown if this is required for multi-vif STA
5413 * interfaces on 10.1.
5414 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005415
Michal Kazior8461baf2015-04-10 13:23:22 +00005416 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
5417 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005418 return;
5419
5420 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
5421 return;
5422
5423 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
5424 return;
5425
5426 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5427 return;
5428
5429 if (cmd != SET_KEY)
5430 return;
5431
5432 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5433 key->keyidx);
5434 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005435 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005436 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005437}
5438
Kalle Valo5e3dd152013-06-12 20:52:10 +03005439static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5440 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5441 struct ieee80211_key_conf *key)
5442{
5443 struct ath10k *ar = hw->priv;
5444 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5445 struct ath10k_peer *peer;
5446 const u8 *peer_addr;
5447 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5448 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5449 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005450 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005451 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005452 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005453
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005454 /* this one needs to be done in software */
5455 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
5456 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005457
David Liuccec9032015-07-24 20:25:32 +03005458 if (arvif->nohwcrypt)
5459 return 1;
5460
Kalle Valo5e3dd152013-06-12 20:52:10 +03005461 if (key->keyidx > WMI_MAX_KEY_INDEX)
5462 return -ENOSPC;
5463
5464 mutex_lock(&ar->conf_mutex);
5465
5466 if (sta)
5467 peer_addr = sta->addr;
5468 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5469 peer_addr = vif->bss_conf.bssid;
5470 else
5471 peer_addr = vif->addr;
5472
5473 key->hw_key_idx = key->keyidx;
5474
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005475 if (is_wep) {
5476 if (cmd == SET_KEY)
5477 arvif->wep_keys[key->keyidx] = key;
5478 else
5479 arvif->wep_keys[key->keyidx] = NULL;
5480 }
5481
Kalle Valo5e3dd152013-06-12 20:52:10 +03005482 /* the peer should not disappear in mid-way (unless FW goes awry) since
5483 * we already hold conf_mutex. we just make sure its there now. */
5484 spin_lock_bh(&ar->data_lock);
5485 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5486 spin_unlock_bh(&ar->data_lock);
5487
5488 if (!peer) {
5489 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005490 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005491 peer_addr);
5492 ret = -EOPNOTSUPP;
5493 goto exit;
5494 } else {
5495 /* if the peer doesn't exist there is no key to disable
5496 * anymore */
5497 goto exit;
5498 }
5499 }
5500
Michal Kazior7cc45732015-03-09 14:24:17 +01005501 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5502 flags |= WMI_KEY_PAIRWISE;
5503 else
5504 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005505
Kalle Valo5e3dd152013-06-12 20:52:10 +03005506 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005507 if (cmd == DISABLE_KEY)
5508 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005509
Michal Kaziorad325cb2015-02-18 14:02:27 +01005510 /* When WEP keys are uploaded it's possible that there are
5511 * stations associated already (e.g. when merging) without any
5512 * keys. Static WEP needs an explicit per-peer key upload.
5513 */
5514 if (vif->type == NL80211_IFTYPE_ADHOC &&
5515 cmd == SET_KEY)
5516 ath10k_mac_vif_update_wep_key(arvif, key);
5517
Michal Kazior370e5672015-02-18 14:02:26 +01005518 /* 802.1x never sets the def_wep_key_idx so each set_key()
5519 * call changes default tx key.
5520 *
5521 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5522 * after first set_key().
5523 */
5524 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5525 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005526 }
5527
Michal Kazior370e5672015-02-18 14:02:26 +01005528 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005529 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005530 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005531 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005532 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005533 goto exit;
5534 }
5535
Michal Kazior29a10002015-04-10 13:05:58 +00005536 /* mac80211 sets static WEP keys as groupwise while firmware requires
5537 * them to be installed twice as both pairwise and groupwise.
5538 */
5539 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5540 flags2 = flags;
5541 flags2 &= ~WMI_KEY_GROUP;
5542 flags2 |= WMI_KEY_PAIRWISE;
5543
5544 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5545 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005546 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005547 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5548 arvif->vdev_id, peer_addr, ret);
5549 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5550 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005551 if (ret2) {
5552 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005553 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5554 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005555 }
Michal Kazior29a10002015-04-10 13:05:58 +00005556 goto exit;
5557 }
5558 }
5559
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005560 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5561
Kalle Valo5e3dd152013-06-12 20:52:10 +03005562 spin_lock_bh(&ar->data_lock);
5563 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5564 if (peer && cmd == SET_KEY)
5565 peer->keys[key->keyidx] = key;
5566 else if (peer && cmd == DISABLE_KEY)
5567 peer->keys[key->keyidx] = NULL;
5568 else if (peer == NULL)
5569 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005570 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005571 spin_unlock_bh(&ar->data_lock);
5572
5573exit:
5574 mutex_unlock(&ar->conf_mutex);
5575 return ret;
5576}
5577
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005578static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5579 struct ieee80211_vif *vif,
5580 int keyidx)
5581{
5582 struct ath10k *ar = hw->priv;
5583 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5584 int ret;
5585
5586 mutex_lock(&arvif->ar->conf_mutex);
5587
5588 if (arvif->ar->state != ATH10K_STATE_ON)
5589 goto unlock;
5590
5591 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5592 arvif->vdev_id, keyidx);
5593
5594 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5595 arvif->vdev_id,
5596 arvif->ar->wmi.vdev_param->def_keyid,
5597 keyidx);
5598
5599 if (ret) {
5600 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5601 arvif->vdev_id,
5602 ret);
5603 goto unlock;
5604 }
5605
5606 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005607
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005608unlock:
5609 mutex_unlock(&arvif->ar->conf_mutex);
5610}
5611
Michal Kazior9797feb2014-02-14 14:49:48 +01005612static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5613{
5614 struct ath10k *ar;
5615 struct ath10k_vif *arvif;
5616 struct ath10k_sta *arsta;
5617 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005618 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02005619 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005620 const u8 *ht_mcs_mask;
5621 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005622 u32 changed, bw, nss, smps;
5623 int err;
5624
5625 arsta = container_of(wk, struct ath10k_sta, update_wk);
5626 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5627 arvif = arsta->arvif;
5628 ar = arvif->ar;
5629
Michal Kazior45c9abc2015-04-21 20:42:58 +03005630 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5631 return;
5632
5633 band = def.chan->band;
5634 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5635 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5636
Michal Kazior9797feb2014-02-14 14:49:48 +01005637 spin_lock_bh(&ar->data_lock);
5638
5639 changed = arsta->changed;
5640 arsta->changed = 0;
5641
5642 bw = arsta->bw;
5643 nss = arsta->nss;
5644 smps = arsta->smps;
5645
5646 spin_unlock_bh(&ar->data_lock);
5647
5648 mutex_lock(&ar->conf_mutex);
5649
Michal Kazior45c9abc2015-04-21 20:42:58 +03005650 nss = max_t(u32, 1, nss);
5651 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
5652 ath10k_mac_max_vht_nss(vht_mcs_mask)));
5653
Michal Kazior9797feb2014-02-14 14:49:48 +01005654 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005655 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005656 sta->addr, bw);
5657
5658 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5659 WMI_PEER_CHAN_WIDTH, bw);
5660 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005661 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005662 sta->addr, bw, err);
5663 }
5664
5665 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005666 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005667 sta->addr, nss);
5668
5669 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5670 WMI_PEER_NSS, nss);
5671 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005672 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005673 sta->addr, nss, err);
5674 }
5675
5676 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005677 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005678 sta->addr, smps);
5679
5680 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5681 WMI_PEER_SMPS_STATE, smps);
5682 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005683 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005684 sta->addr, smps, err);
5685 }
5686
Janusz Dziedzic55884c02014-12-17 12:30:02 +02005687 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
5688 changed & IEEE80211_RC_NSS_CHANGED) {
5689 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005690 sta->addr);
5691
Michal Kazior590922a2014-10-21 10:10:29 +03005692 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005693 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005694 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005695 sta->addr);
5696 }
5697
Michal Kazior9797feb2014-02-14 14:49:48 +01005698 mutex_unlock(&ar->conf_mutex);
5699}
5700
Marek Puzyniak7c354242015-03-30 09:51:52 +03005701static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
5702 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005703{
5704 struct ath10k *ar = arvif->ar;
5705
5706 lockdep_assert_held(&ar->conf_mutex);
5707
Marek Puzyniak7c354242015-03-30 09:51:52 +03005708 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005709 return 0;
5710
5711 if (ar->num_stations >= ar->max_num_stations)
5712 return -ENOBUFS;
5713
5714 ar->num_stations++;
5715
5716 return 0;
5717}
5718
Marek Puzyniak7c354242015-03-30 09:51:52 +03005719static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
5720 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005721{
5722 struct ath10k *ar = arvif->ar;
5723
5724 lockdep_assert_held(&ar->conf_mutex);
5725
Marek Puzyniak7c354242015-03-30 09:51:52 +03005726 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005727 return;
5728
5729 ar->num_stations--;
5730}
5731
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005732struct ath10k_mac_tdls_iter_data {
5733 u32 num_tdls_stations;
5734 struct ieee80211_vif *curr_vif;
5735};
5736
5737static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5738 struct ieee80211_sta *sta)
5739{
5740 struct ath10k_mac_tdls_iter_data *iter_data = data;
5741 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5742 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5743
5744 if (sta->tdls && sta_vif == iter_data->curr_vif)
5745 iter_data->num_tdls_stations++;
5746}
5747
5748static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5749 struct ieee80211_vif *vif)
5750{
5751 struct ath10k_mac_tdls_iter_data data = {};
5752
5753 data.curr_vif = vif;
5754
5755 ieee80211_iterate_stations_atomic(hw,
5756 ath10k_mac_tdls_vif_stations_count_iter,
5757 &data);
5758 return data.num_tdls_stations;
5759}
5760
5761static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5762 struct ieee80211_vif *vif)
5763{
5764 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5765 int *num_tdls_vifs = data;
5766
5767 if (vif->type != NL80211_IFTYPE_STATION)
5768 return;
5769
5770 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5771 (*num_tdls_vifs)++;
5772}
5773
5774static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5775{
5776 int num_tdls_vifs = 0;
5777
5778 ieee80211_iterate_active_interfaces_atomic(hw,
5779 IEEE80211_IFACE_ITER_NORMAL,
5780 ath10k_mac_tdls_vifs_count_iter,
5781 &num_tdls_vifs);
5782 return num_tdls_vifs;
5783}
5784
Kalle Valo5e3dd152013-06-12 20:52:10 +03005785static int ath10k_sta_state(struct ieee80211_hw *hw,
5786 struct ieee80211_vif *vif,
5787 struct ieee80211_sta *sta,
5788 enum ieee80211_sta_state old_state,
5789 enum ieee80211_sta_state new_state)
5790{
5791 struct ath10k *ar = hw->priv;
5792 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005793 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005794 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005795 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02005796 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005797
Michal Kazior76f90022014-02-25 09:29:57 +02005798 if (old_state == IEEE80211_STA_NOTEXIST &&
5799 new_state == IEEE80211_STA_NONE) {
5800 memset(arsta, 0, sizeof(*arsta));
5801 arsta->arvif = arvif;
5802 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02005803
5804 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5805 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02005806 }
5807
Michal Kazior9797feb2014-02-14 14:49:48 +01005808 /* cancel must be done outside the mutex to avoid deadlock */
5809 if ((old_state == IEEE80211_STA_NONE &&
5810 new_state == IEEE80211_STA_NOTEXIST))
5811 cancel_work_sync(&arsta->update_wk);
5812
Kalle Valo5e3dd152013-06-12 20:52:10 +03005813 mutex_lock(&ar->conf_mutex);
5814
5815 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005816 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005817 /*
5818 * New station addition.
5819 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005820 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5821 u32 num_tdls_stations;
5822 u32 num_tdls_vifs;
5823
Michal Kaziorcfd10612014-11-25 15:16:05 +01005824 ath10k_dbg(ar, ATH10K_DBG_MAC,
5825 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5826 arvif->vdev_id, sta->addr,
5827 ar->num_stations + 1, ar->max_num_stations,
5828 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005829
Marek Puzyniak7c354242015-03-30 09:51:52 +03005830 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005831 if (ret) {
5832 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5833 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005834 goto exit;
5835 }
5836
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005837 if (sta->tdls)
5838 peer_type = WMI_PEER_TYPE_TDLS;
5839
Michal Kazior69427262016-03-06 16:14:30 +02005840 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
5841 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005842 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005843 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 -08005844 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005845 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005846 goto exit;
5847 }
Michal Kazior077efc82014-10-21 10:10:29 +03005848
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005849 spin_lock_bh(&ar->data_lock);
5850
5851 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
5852 if (!peer) {
5853 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5854 vif->addr, arvif->vdev_id);
5855 spin_unlock_bh(&ar->data_lock);
5856 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5857 ath10k_mac_dec_num_stations(arvif, sta);
5858 ret = -ENOENT;
5859 goto exit;
5860 }
5861
5862 arsta->peer_id = find_first_bit(peer->peer_ids,
5863 ATH10K_MAX_NUM_PEER_IDS);
5864
5865 spin_unlock_bh(&ar->data_lock);
5866
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005867 if (!sta->tdls)
5868 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03005869
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005870 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
5871 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
5872
5873 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
5874 num_tdls_stations == 0) {
5875 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
5876 arvif->vdev_id, ar->max_num_tdls_vdevs);
5877 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5878 ath10k_mac_dec_num_stations(arvif, sta);
5879 ret = -ENOBUFS;
5880 goto exit;
5881 }
5882
5883 if (num_tdls_stations == 0) {
5884 /* This is the first tdls peer in current vif */
5885 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
5886
5887 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5888 state);
Michal Kazior077efc82014-10-21 10:10:29 +03005889 if (ret) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005890 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
Michal Kazior077efc82014-10-21 10:10:29 +03005891 arvif->vdev_id, ret);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005892 ath10k_peer_delete(ar, arvif->vdev_id,
5893 sta->addr);
5894 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03005895 goto exit;
5896 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005897 }
Michal Kazior077efc82014-10-21 10:10:29 +03005898
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005899 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5900 WMI_TDLS_PEER_STATE_PEERING);
5901 if (ret) {
5902 ath10k_warn(ar,
5903 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
5904 sta->addr, arvif->vdev_id, ret);
5905 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5906 ath10k_mac_dec_num_stations(arvif, sta);
5907
5908 if (num_tdls_stations != 0)
5909 goto exit;
5910 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5911 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03005912 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005913 } else if ((old_state == IEEE80211_STA_NONE &&
5914 new_state == IEEE80211_STA_NOTEXIST)) {
5915 /*
5916 * Existing station deletion.
5917 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005918 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005919 "mac vdev %d peer delete %pM (sta gone)\n",
5920 arvif->vdev_id, sta->addr);
Michal Kazior077efc82014-10-21 10:10:29 +03005921
Kalle Valo5e3dd152013-06-12 20:52:10 +03005922 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5923 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005924 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005925 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005926
Marek Puzyniak7c354242015-03-30 09:51:52 +03005927 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005928
Michal Kazior69427262016-03-06 16:14:30 +02005929 spin_lock_bh(&ar->data_lock);
5930 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5931 peer = ar->peer_map[i];
5932 if (!peer)
5933 continue;
5934
5935 if (peer->sta == sta) {
5936 ath10k_warn(ar, "found sta peer %pM entry on vdev %i after it was supposedly removed\n",
5937 sta->addr, arvif->vdev_id);
5938 peer->sta = NULL;
5939 }
5940 }
5941 spin_unlock_bh(&ar->data_lock);
5942
Michal Kazior29946872016-03-06 16:14:34 +02005943 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5944 ath10k_mac_txq_unref(ar, sta->txq[i]);
5945
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005946 if (!sta->tdls)
5947 goto exit;
5948
5949 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
5950 goto exit;
5951
5952 /* This was the last tdls peer in current vif */
5953 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5954 WMI_TDLS_DISABLE);
5955 if (ret) {
5956 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
5957 arvif->vdev_id, ret);
5958 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005959 } else if (old_state == IEEE80211_STA_AUTH &&
5960 new_state == IEEE80211_STA_ASSOC &&
5961 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005962 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03005963 vif->type == NL80211_IFTYPE_ADHOC)) {
5964 /*
5965 * New association.
5966 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005967 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005968 sta->addr);
5969
Michal Kazior590922a2014-10-21 10:10:29 +03005970 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005971 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005972 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005973 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005974 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005975 new_state == IEEE80211_STA_AUTHORIZED &&
5976 sta->tdls) {
5977 /*
5978 * Tdls station authorized.
5979 */
5980 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
5981 sta->addr);
5982
5983 ret = ath10k_station_assoc(ar, vif, sta, false);
5984 if (ret) {
5985 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
5986 sta->addr, arvif->vdev_id, ret);
5987 goto exit;
5988 }
5989
5990 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5991 WMI_TDLS_PEER_STATE_CONNECTED);
5992 if (ret)
5993 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
5994 sta->addr, arvif->vdev_id, ret);
5995 } else if (old_state == IEEE80211_STA_ASSOC &&
5996 new_state == IEEE80211_STA_AUTH &&
5997 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005998 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005999 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006000 /*
6001 * Disassociation.
6002 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006003 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006004 sta->addr);
6005
Michal Kazior590922a2014-10-21 10:10:29 +03006006 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006007 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006008 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006009 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006010 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006011exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006012 mutex_unlock(&ar->conf_mutex);
6013 return ret;
6014}
6015
6016static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006017 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006018{
6019 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02006020 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6021 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006022 u32 value = 0;
6023 int ret = 0;
6024
Michal Kazior548db542013-07-05 16:15:15 +03006025 lockdep_assert_held(&ar->conf_mutex);
6026
Kalle Valo5e3dd152013-06-12 20:52:10 +03006027 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6028 return 0;
6029
6030 switch (ac) {
6031 case IEEE80211_AC_VO:
6032 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6033 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006034 prio = 7;
6035 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006036 break;
6037 case IEEE80211_AC_VI:
6038 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6039 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006040 prio = 5;
6041 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006042 break;
6043 case IEEE80211_AC_BE:
6044 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6045 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006046 prio = 2;
6047 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006048 break;
6049 case IEEE80211_AC_BK:
6050 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6051 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006052 prio = 0;
6053 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006054 break;
6055 }
6056
6057 if (enable)
6058 arvif->u.sta.uapsd |= value;
6059 else
6060 arvif->u.sta.uapsd &= ~value;
6061
6062 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6063 WMI_STA_PS_PARAM_UAPSD,
6064 arvif->u.sta.uapsd);
6065 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006066 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006067 goto exit;
6068 }
6069
6070 if (arvif->u.sta.uapsd)
6071 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6072 else
6073 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6074
6075 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6076 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6077 value);
6078 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006079 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006080
Michal Kazior9f9b5742014-12-12 12:41:36 +01006081 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6082 if (ret) {
6083 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6084 arvif->vdev_id, ret);
6085 return ret;
6086 }
6087
6088 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6089 if (ret) {
6090 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6091 arvif->vdev_id, ret);
6092 return ret;
6093 }
6094
Michal Kaziorb0e56152015-01-24 12:14:52 +02006095 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6096 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6097 /* Only userspace can make an educated decision when to send
6098 * trigger frame. The following effectively disables u-UAPSD
6099 * autotrigger in firmware (which is enabled by default
6100 * provided the autotrigger service is available).
6101 */
6102
6103 arg.wmm_ac = acc;
6104 arg.user_priority = prio;
6105 arg.service_interval = 0;
6106 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6107 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6108
6109 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6110 arvif->bssid, &arg, 1);
6111 if (ret) {
6112 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6113 ret);
6114 return ret;
6115 }
6116 }
6117
Kalle Valo5e3dd152013-06-12 20:52:10 +03006118exit:
6119 return ret;
6120}
6121
6122static int ath10k_conf_tx(struct ieee80211_hw *hw,
6123 struct ieee80211_vif *vif, u16 ac,
6124 const struct ieee80211_tx_queue_params *params)
6125{
6126 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01006127 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006128 struct wmi_wmm_params_arg *p = NULL;
6129 int ret;
6130
6131 mutex_lock(&ar->conf_mutex);
6132
6133 switch (ac) {
6134 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006135 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006136 break;
6137 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006138 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006139 break;
6140 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006141 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006142 break;
6143 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006144 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006145 break;
6146 }
6147
6148 if (WARN_ON(!p)) {
6149 ret = -EINVAL;
6150 goto exit;
6151 }
6152
6153 p->cwmin = params->cw_min;
6154 p->cwmax = params->cw_max;
6155 p->aifs = params->aifs;
6156
6157 /*
6158 * The channel time duration programmed in the HW is in absolute
6159 * microseconds, while mac80211 gives the txop in units of
6160 * 32 microseconds.
6161 */
6162 p->txop = params->txop * 32;
6163
Michal Kazior7fc979a2015-01-28 09:57:28 +02006164 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6165 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6166 &arvif->wmm_params);
6167 if (ret) {
6168 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6169 arvif->vdev_id, ret);
6170 goto exit;
6171 }
6172 } else {
6173 /* This won't work well with multi-interface cases but it's
6174 * better than nothing.
6175 */
6176 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6177 if (ret) {
6178 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6179 goto exit;
6180 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006181 }
6182
6183 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6184 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006185 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006186
6187exit:
6188 mutex_unlock(&ar->conf_mutex);
6189 return ret;
6190}
6191
Kalle Valo14e105c2016-04-13 14:13:21 +03006192#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006193
6194static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6195 struct ieee80211_vif *vif,
6196 struct ieee80211_channel *chan,
6197 int duration,
6198 enum ieee80211_roc_type type)
6199{
6200 struct ath10k *ar = hw->priv;
6201 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6202 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006203 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006204 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006205
6206 mutex_lock(&ar->conf_mutex);
6207
6208 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006209 switch (ar->scan.state) {
6210 case ATH10K_SCAN_IDLE:
6211 reinit_completion(&ar->scan.started);
6212 reinit_completion(&ar->scan.completed);
6213 reinit_completion(&ar->scan.on_channel);
6214 ar->scan.state = ATH10K_SCAN_STARTING;
6215 ar->scan.is_roc = true;
6216 ar->scan.vdev_id = arvif->vdev_id;
6217 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006218 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006219 ret = 0;
6220 break;
6221 case ATH10K_SCAN_STARTING:
6222 case ATH10K_SCAN_RUNNING:
6223 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006224 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006225 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006226 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006227 spin_unlock_bh(&ar->data_lock);
6228
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006229 if (ret)
6230 goto exit;
6231
Michal Kaziorfcf98442015-03-31 11:03:47 +00006232 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006233
Kalle Valo5e3dd152013-06-12 20:52:10 +03006234 memset(&arg, 0, sizeof(arg));
6235 ath10k_wmi_start_scan_init(ar, &arg);
6236 arg.vdev_id = arvif->vdev_id;
6237 arg.scan_id = ATH10K_SCAN_ID;
6238 arg.n_channels = 1;
6239 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006240 arg.dwell_time_active = scan_time_msec;
6241 arg.dwell_time_passive = scan_time_msec;
6242 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006243 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6244 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006245 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006246
6247 ret = ath10k_start_scan(ar, &arg);
6248 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006249 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006250 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006251 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006252 spin_unlock_bh(&ar->data_lock);
6253 goto exit;
6254 }
6255
Kalle Valo14e105c2016-04-13 14:13:21 +03006256 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006257 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006258 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006259
6260 ret = ath10k_scan_stop(ar);
6261 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006262 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006263
Kalle Valo5e3dd152013-06-12 20:52:10 +03006264 ret = -ETIMEDOUT;
6265 goto exit;
6266 }
6267
Michal Kaziorfcf98442015-03-31 11:03:47 +00006268 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6269 msecs_to_jiffies(duration));
6270
Kalle Valo5e3dd152013-06-12 20:52:10 +03006271 ret = 0;
6272exit:
6273 mutex_unlock(&ar->conf_mutex);
6274 return ret;
6275}
6276
6277static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6278{
6279 struct ath10k *ar = hw->priv;
6280
6281 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006282
6283 spin_lock_bh(&ar->data_lock);
6284 ar->scan.roc_notify = false;
6285 spin_unlock_bh(&ar->data_lock);
6286
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006287 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006288
Kalle Valo5e3dd152013-06-12 20:52:10 +03006289 mutex_unlock(&ar->conf_mutex);
6290
Michal Kazior4eb2e162014-10-28 10:23:09 +01006291 cancel_delayed_work_sync(&ar->scan.timeout);
6292
Kalle Valo5e3dd152013-06-12 20:52:10 +03006293 return 0;
6294}
6295
6296/*
6297 * Both RTS and Fragmentation threshold are interface-specific
6298 * in ath10k, but device-specific in mac80211.
6299 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006300
6301static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6302{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006303 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006304 struct ath10k_vif *arvif;
6305 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006306
Michal Kaziorad088bf2013-10-16 15:44:46 +03006307 mutex_lock(&ar->conf_mutex);
6308 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006309 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006310 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006311
Michal Kaziorad088bf2013-10-16 15:44:46 +03006312 ret = ath10k_mac_set_rts(arvif, value);
6313 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006314 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006315 arvif->vdev_id, ret);
6316 break;
6317 }
6318 }
6319 mutex_unlock(&ar->conf_mutex);
6320
6321 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006322}
6323
Michal Kazior92092fe2015-08-03 11:16:43 +02006324static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6325{
6326 /* Even though there's a WMI enum for fragmentation threshold no known
6327 * firmware actually implements it. Moreover it is not possible to rely
6328 * frame fragmentation to mac80211 because firmware clears the "more
6329 * fragments" bit in frame control making it impossible for remote
6330 * devices to reassemble frames.
6331 *
6332 * Hence implement a dummy callback just to say fragmentation isn't
6333 * supported. This effectively prevents mac80211 from doing frame
6334 * fragmentation in software.
6335 */
6336 return -EOPNOTSUPP;
6337}
6338
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02006339static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6340 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006341{
6342 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02006343 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006344 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006345
6346 /* mac80211 doesn't care if we really xmit queued frames or not
6347 * we'll collect those frames either way if we stop/delete vdevs */
6348 if (drop)
6349 return;
6350
Michal Kazior548db542013-07-05 16:15:15 +03006351 mutex_lock(&ar->conf_mutex);
6352
Michal Kazioraffd3212013-07-16 09:54:35 +02006353 if (ar->state == ATH10K_STATE_WEDGED)
6354 goto skip;
6355
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006356 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006357 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006358
Michal Kazioredb82362013-07-05 16:15:14 +03006359 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006360 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006361 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006362
Michal Kazior7962b0d2014-10-28 10:34:38 +01006363 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6364 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6365 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006366
6367 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006368 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006369
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006370 if (time_left == 0 || skip)
6371 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6372 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03006373
Michal Kazioraffd3212013-07-16 09:54:35 +02006374skip:
Michal Kazior548db542013-07-05 16:15:15 +03006375 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006376}
6377
6378/* TODO: Implement this function properly
6379 * For now it is needed to reply to Probe Requests in IBSS mode.
6380 * Propably we need this information from FW.
6381 */
6382static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
6383{
6384 return 1;
6385}
6386
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006387static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
6388 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02006389{
6390 struct ath10k *ar = hw->priv;
6391
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006392 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
6393 return;
6394
Michal Kazioraffd3212013-07-16 09:54:35 +02006395 mutex_lock(&ar->conf_mutex);
6396
6397 /* If device failed to restart it will be in a different state, e.g.
6398 * ATH10K_STATE_WEDGED */
6399 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006400 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02006401 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01006402 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02006403 }
6404
6405 mutex_unlock(&ar->conf_mutex);
6406}
6407
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306408static void
6409ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
6410 struct ieee80211_channel *channel)
6411{
6412 int ret;
6413 enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
6414
6415 lockdep_assert_held(&ar->conf_mutex);
6416
6417 if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
6418 (ar->rx_channel != channel))
6419 return;
6420
6421 if (ar->scan.state != ATH10K_SCAN_IDLE) {
6422 ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
6423 return;
6424 }
6425
6426 reinit_completion(&ar->bss_survey_done);
6427
6428 ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
6429 if (ret) {
6430 ath10k_warn(ar, "failed to send pdev bss chan info request\n");
6431 return;
6432 }
6433
6434 ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
6435 if (!ret) {
6436 ath10k_warn(ar, "bss channel survey timed out\n");
6437 return;
6438 }
6439}
6440
Michal Kazior2e1dea42013-07-31 10:32:40 +02006441static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
6442 struct survey_info *survey)
6443{
6444 struct ath10k *ar = hw->priv;
6445 struct ieee80211_supported_band *sband;
6446 struct survey_info *ar_survey = &ar->survey[idx];
6447 int ret = 0;
6448
6449 mutex_lock(&ar->conf_mutex);
6450
Johannes Berg57fbcce2016-04-12 15:56:15 +02006451 sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006452 if (sband && idx >= sband->n_channels) {
6453 idx -= sband->n_channels;
6454 sband = NULL;
6455 }
6456
6457 if (!sband)
Johannes Berg57fbcce2016-04-12 15:56:15 +02006458 sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006459
6460 if (!sband || idx >= sband->n_channels) {
6461 ret = -ENOENT;
6462 goto exit;
6463 }
6464
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306465 ath10k_mac_update_bss_chan_survey(ar, survey->channel);
6466
Michal Kazior2e1dea42013-07-31 10:32:40 +02006467 spin_lock_bh(&ar->data_lock);
6468 memcpy(survey, ar_survey, sizeof(*survey));
6469 spin_unlock_bh(&ar->data_lock);
6470
6471 survey->channel = &sband->channels[idx];
6472
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03006473 if (ar->rx_channel == survey->channel)
6474 survey->filled |= SURVEY_INFO_IN_USE;
6475
Michal Kazior2e1dea42013-07-31 10:32:40 +02006476exit:
6477 mutex_unlock(&ar->conf_mutex);
6478 return ret;
6479}
6480
Michal Kazior3ae54222015-03-31 10:49:20 +00006481static bool
6482ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006483 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006484 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006485{
Michal Kazior3ae54222015-03-31 10:49:20 +00006486 int num_rates = 0;
6487 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006488
Michal Kazior3ae54222015-03-31 10:49:20 +00006489 num_rates += hweight32(mask->control[band].legacy);
6490
6491 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
6492 num_rates += hweight8(mask->control[band].ht_mcs[i]);
6493
6494 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
6495 num_rates += hweight16(mask->control[band].vht_mcs[i]);
6496
6497 return num_rates == 1;
6498}
6499
6500static bool
6501ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006502 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006503 const struct cfg80211_bitrate_mask *mask,
6504 int *nss)
6505{
6506 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6507 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6508 u8 ht_nss_mask = 0;
6509 u8 vht_nss_mask = 0;
6510 int i;
6511
6512 if (mask->control[band].legacy)
6513 return false;
6514
6515 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6516 if (mask->control[band].ht_mcs[i] == 0)
6517 continue;
6518 else if (mask->control[band].ht_mcs[i] ==
6519 sband->ht_cap.mcs.rx_mask[i])
6520 ht_nss_mask |= BIT(i);
6521 else
6522 return false;
6523 }
6524
6525 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6526 if (mask->control[band].vht_mcs[i] == 0)
6527 continue;
6528 else if (mask->control[band].vht_mcs[i] ==
6529 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6530 vht_nss_mask |= BIT(i);
6531 else
6532 return false;
6533 }
6534
6535 if (ht_nss_mask != vht_nss_mask)
6536 return false;
6537
6538 if (ht_nss_mask == 0)
6539 return false;
6540
6541 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6542 return false;
6543
6544 *nss = fls(ht_nss_mask);
6545
6546 return true;
6547}
6548
6549static int
6550ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006551 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006552 const struct cfg80211_bitrate_mask *mask,
6553 u8 *rate, u8 *nss)
6554{
6555 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6556 int rate_idx;
6557 int i;
6558 u16 bitrate;
6559 u8 preamble;
6560 u8 hw_rate;
6561
6562 if (hweight32(mask->control[band].legacy) == 1) {
6563 rate_idx = ffs(mask->control[band].legacy) - 1;
6564
6565 hw_rate = sband->bitrates[rate_idx].hw_value;
6566 bitrate = sband->bitrates[rate_idx].bitrate;
6567
6568 if (ath10k_mac_bitrate_is_cck(bitrate))
6569 preamble = WMI_RATE_PREAMBLE_CCK;
6570 else
6571 preamble = WMI_RATE_PREAMBLE_OFDM;
6572
6573 *nss = 1;
6574 *rate = preamble << 6 |
6575 (*nss - 1) << 4 |
6576 hw_rate << 0;
6577
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006578 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006579 }
6580
Michal Kazior3ae54222015-03-31 10:49:20 +00006581 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6582 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6583 *nss = i + 1;
6584 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6585 (*nss - 1) << 4 |
6586 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006587
Michal Kazior3ae54222015-03-31 10:49:20 +00006588 return 0;
6589 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006590 }
6591
Michal Kazior3ae54222015-03-31 10:49:20 +00006592 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6593 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6594 *nss = i + 1;
6595 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6596 (*nss - 1) << 4 |
6597 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006598
Michal Kazior3ae54222015-03-31 10:49:20 +00006599 return 0;
6600 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006601 }
6602
Michal Kazior3ae54222015-03-31 10:49:20 +00006603 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006604}
6605
Michal Kazior3ae54222015-03-31 10:49:20 +00006606static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306607 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006608{
6609 struct ath10k *ar = arvif->ar;
6610 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006611 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006612
Michal Kazior3ae54222015-03-31 10:49:20 +00006613 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006614
Michal Kazior3ae54222015-03-31 10:49:20 +00006615 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6616 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006617
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006618 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006619 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006620 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006621 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006622 rate, ret);
6623 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006624 }
6625
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006626 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006627 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006628 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006629 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6630 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006631 }
6632
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006633 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006634 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006635 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006636 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6637 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006638 }
6639
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306640 vdev_param = ar->wmi.vdev_param->ldpc;
6641 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6642 if (ret) {
6643 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6644 return ret;
6645 }
6646
Michal Kazior3ae54222015-03-31 10:49:20 +00006647 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006648}
6649
Michal Kazior45c9abc2015-04-21 20:42:58 +03006650static bool
6651ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006652 enum nl80211_band band,
Michal Kazior45c9abc2015-04-21 20:42:58 +03006653 const struct cfg80211_bitrate_mask *mask)
6654{
6655 int i;
6656 u16 vht_mcs;
6657
6658 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6659 * to express all VHT MCS rate masks. Effectively only the following
6660 * ranges can be used: none, 0-7, 0-8 and 0-9.
6661 */
6662 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6663 vht_mcs = mask->control[band].vht_mcs[i];
6664
6665 switch (vht_mcs) {
6666 case 0:
6667 case BIT(8) - 1:
6668 case BIT(9) - 1:
6669 case BIT(10) - 1:
6670 break;
6671 default:
6672 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6673 return false;
6674 }
6675 }
6676
6677 return true;
6678}
6679
6680static void ath10k_mac_set_bitrate_mask_iter(void *data,
6681 struct ieee80211_sta *sta)
6682{
6683 struct ath10k_vif *arvif = data;
6684 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6685 struct ath10k *ar = arvif->ar;
6686
6687 if (arsta->arvif != arvif)
6688 return;
6689
6690 spin_lock_bh(&ar->data_lock);
6691 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
6692 spin_unlock_bh(&ar->data_lock);
6693
6694 ieee80211_queue_work(ar->hw, &arsta->update_wk);
6695}
6696
Michal Kazior3ae54222015-03-31 10:49:20 +00006697static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
6698 struct ieee80211_vif *vif,
6699 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006700{
6701 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006702 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006703 struct ath10k *ar = arvif->ar;
Johannes Berg57fbcce2016-04-12 15:56:15 +02006704 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006705 const u8 *ht_mcs_mask;
6706 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00006707 u8 rate;
6708 u8 nss;
6709 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306710 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00006711 int single_nss;
6712 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006713
Michal Kazior500ff9f2015-03-31 10:26:21 +00006714 if (ath10k_mac_vif_chan(vif, &def))
6715 return -EPERM;
6716
Michal Kazior500ff9f2015-03-31 10:26:21 +00006717 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006718 ht_mcs_mask = mask->control[band].ht_mcs;
6719 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306720 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006721
Michal Kazior3ae54222015-03-31 10:49:20 +00006722 sgi = mask->control[band].gi;
6723 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006724 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006725
Michal Kazior3ae54222015-03-31 10:49:20 +00006726 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
6727 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
6728 &rate, &nss);
6729 if (ret) {
6730 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
6731 arvif->vdev_id, ret);
6732 return ret;
6733 }
6734 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
6735 &single_nss)) {
6736 rate = WMI_FIXED_RATE_NONE;
6737 nss = single_nss;
6738 } else {
6739 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006740 nss = min(ar->num_rf_chains,
6741 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6742 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6743
6744 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
6745 return -EINVAL;
6746
6747 mutex_lock(&ar->conf_mutex);
6748
6749 arvif->bitrate_mask = *mask;
6750 ieee80211_iterate_stations_atomic(ar->hw,
6751 ath10k_mac_set_bitrate_mask_iter,
6752 arvif);
6753
6754 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006755 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006756
6757 mutex_lock(&ar->conf_mutex);
6758
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306759 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006760 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006761 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
6762 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006763 goto exit;
6764 }
6765
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006766exit:
6767 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00006768
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006769 return ret;
6770}
6771
Michal Kazior9797feb2014-02-14 14:49:48 +01006772static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6773 struct ieee80211_vif *vif,
6774 struct ieee80211_sta *sta,
6775 u32 changed)
6776{
6777 struct ath10k *ar = hw->priv;
6778 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6779 u32 bw, smps;
6780
6781 spin_lock_bh(&ar->data_lock);
6782
Michal Kazior7aa7a722014-08-25 12:09:38 +02006783 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01006784 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
6785 sta->addr, changed, sta->bandwidth, sta->rx_nss,
6786 sta->smps_mode);
6787
6788 if (changed & IEEE80211_RC_BW_CHANGED) {
6789 bw = WMI_PEER_CHWIDTH_20MHZ;
6790
6791 switch (sta->bandwidth) {
6792 case IEEE80211_STA_RX_BW_20:
6793 bw = WMI_PEER_CHWIDTH_20MHZ;
6794 break;
6795 case IEEE80211_STA_RX_BW_40:
6796 bw = WMI_PEER_CHWIDTH_40MHZ;
6797 break;
6798 case IEEE80211_STA_RX_BW_80:
6799 bw = WMI_PEER_CHWIDTH_80MHZ;
6800 break;
6801 case IEEE80211_STA_RX_BW_160:
Masanari Iidad939be32015-02-27 23:52:31 +09006802 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006803 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006804 bw = WMI_PEER_CHWIDTH_20MHZ;
6805 break;
6806 }
6807
6808 arsta->bw = bw;
6809 }
6810
6811 if (changed & IEEE80211_RC_NSS_CHANGED)
6812 arsta->nss = sta->rx_nss;
6813
6814 if (changed & IEEE80211_RC_SMPS_CHANGED) {
6815 smps = WMI_PEER_SMPS_PS_NONE;
6816
6817 switch (sta->smps_mode) {
6818 case IEEE80211_SMPS_AUTOMATIC:
6819 case IEEE80211_SMPS_OFF:
6820 smps = WMI_PEER_SMPS_PS_NONE;
6821 break;
6822 case IEEE80211_SMPS_STATIC:
6823 smps = WMI_PEER_SMPS_STATIC;
6824 break;
6825 case IEEE80211_SMPS_DYNAMIC:
6826 smps = WMI_PEER_SMPS_DYNAMIC;
6827 break;
6828 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02006829 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006830 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006831 smps = WMI_PEER_SMPS_PS_NONE;
6832 break;
6833 }
6834
6835 arsta->smps = smps;
6836 }
6837
Michal Kazior9797feb2014-02-14 14:49:48 +01006838 arsta->changed |= changed;
6839
6840 spin_unlock_bh(&ar->data_lock);
6841
6842 ieee80211_queue_work(hw, &arsta->update_wk);
6843}
6844
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006845static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
6846{
6847 /*
6848 * FIXME: Return 0 for time being. Need to figure out whether FW
6849 * has the API to fetch 64-bit local TSF
6850 */
6851
6852 return 0;
6853}
6854
Peter Oh9f0b7e72016-04-04 16:19:14 -07006855static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
Kalle Valo4d165442016-04-13 14:14:16 +03006856 u64 tsf)
Peter Oh9f0b7e72016-04-04 16:19:14 -07006857{
6858 struct ath10k *ar = hw->priv;
6859 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6860 u32 tsf_offset, vdev_param = ar->wmi.vdev_param->set_tsf;
6861 int ret;
6862
6863 /* Workaround:
6864 *
6865 * Given tsf argument is entire TSF value, but firmware accepts
6866 * only TSF offset to current TSF.
6867 *
6868 * get_tsf function is used to get offset value, however since
6869 * ath10k_get_tsf is not implemented properly, it will return 0 always.
6870 * Luckily all the caller functions to set_tsf, as of now, also rely on
6871 * get_tsf function to get entire tsf value such get_tsf() + tsf_delta,
6872 * final tsf offset value to firmware will be arithmetically correct.
6873 */
6874 tsf_offset = tsf - ath10k_get_tsf(hw, vif);
6875 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
6876 vdev_param, tsf_offset);
6877 if (ret && ret != -EOPNOTSUPP)
6878 ath10k_warn(ar, "failed to set tsf offset: %d\n", ret);
6879}
6880
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006881static int ath10k_ampdu_action(struct ieee80211_hw *hw,
6882 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02006883 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006884{
Michal Kazior7aa7a722014-08-25 12:09:38 +02006885 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006886 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Sara Sharon50ea05e2015-12-30 16:06:04 +02006887 struct ieee80211_sta *sta = params->sta;
6888 enum ieee80211_ampdu_mlme_action action = params->action;
6889 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006890
Michal Kazior7aa7a722014-08-25 12:09:38 +02006891 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 +02006892 arvif->vdev_id, sta->addr, tid, action);
6893
6894 switch (action) {
6895 case IEEE80211_AMPDU_RX_START:
6896 case IEEE80211_AMPDU_RX_STOP:
6897 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
6898 * creation/removal. Do we need to verify this?
6899 */
6900 return 0;
6901 case IEEE80211_AMPDU_TX_START:
6902 case IEEE80211_AMPDU_TX_STOP_CONT:
6903 case IEEE80211_AMPDU_TX_STOP_FLUSH:
6904 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
6905 case IEEE80211_AMPDU_TX_OPERATIONAL:
6906 /* Firmware offloads Tx aggregation entirely so deny mac80211
6907 * Tx aggregation requests.
6908 */
6909 return -EOPNOTSUPP;
6910 }
6911
6912 return -EINVAL;
6913}
6914
Michal Kazior500ff9f2015-03-31 10:26:21 +00006915static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006916ath10k_mac_update_rx_channel(struct ath10k *ar,
6917 struct ieee80211_chanctx_conf *ctx,
6918 struct ieee80211_vif_chanctx_switch *vifs,
6919 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00006920{
6921 struct cfg80211_chan_def *def = NULL;
6922
6923 /* Both locks are required because ar->rx_channel is modified. This
6924 * allows readers to hold either lock.
6925 */
6926 lockdep_assert_held(&ar->conf_mutex);
6927 lockdep_assert_held(&ar->data_lock);
6928
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006929 WARN_ON(ctx && vifs);
6930 WARN_ON(vifs && n_vifs != 1);
6931
Michal Kazior500ff9f2015-03-31 10:26:21 +00006932 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
6933 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
6934 * ppdu on Rx may reduce performance on low-end systems. It should be
6935 * possible to make tables/hashmaps to speed the lookup up (be vary of
6936 * cpu data cache lines though regarding sizes) but to keep the initial
6937 * implementation simple and less intrusive fallback to the slow lookup
6938 * only for multi-channel cases. Single-channel cases will remain to
6939 * use the old channel derival and thus performance should not be
6940 * affected much.
6941 */
6942 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006943 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00006944 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03006945 ath10k_mac_get_any_chandef_iter,
6946 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006947
6948 if (vifs)
6949 def = &vifs[0].new_ctx->def;
6950
Michal Kazior500ff9f2015-03-31 10:26:21 +00006951 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05306952 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
6953 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
6954 /* During driver restart due to firmware assert, since mac80211
6955 * already has valid channel context for given radio, channel
6956 * context iteration return num_chanctx > 0. So fix rx_channel
6957 * when restart is in progress.
6958 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006959 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006960 } else {
6961 ar->rx_channel = NULL;
6962 }
6963 rcu_read_unlock();
6964}
6965
Michal Kazior7be6d1b2015-09-03 10:44:51 +02006966static void
6967ath10k_mac_update_vif_chan(struct ath10k *ar,
6968 struct ieee80211_vif_chanctx_switch *vifs,
6969 int n_vifs)
6970{
6971 struct ath10k_vif *arvif;
6972 int ret;
6973 int i;
6974
6975 lockdep_assert_held(&ar->conf_mutex);
6976
6977 /* First stop monitor interface. Some FW versions crash if there's a
6978 * lone monitor interface.
6979 */
6980 if (ar->monitor_started)
6981 ath10k_monitor_stop(ar);
6982
6983 for (i = 0; i < n_vifs; i++) {
6984 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6985
6986 ath10k_dbg(ar, ATH10K_DBG_MAC,
6987 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
6988 arvif->vdev_id,
6989 vifs[i].old_ctx->def.chan->center_freq,
6990 vifs[i].new_ctx->def.chan->center_freq,
6991 vifs[i].old_ctx->def.width,
6992 vifs[i].new_ctx->def.width);
6993
6994 if (WARN_ON(!arvif->is_started))
6995 continue;
6996
6997 if (WARN_ON(!arvif->is_up))
6998 continue;
6999
7000 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7001 if (ret) {
7002 ath10k_warn(ar, "failed to down vdev %d: %d\n",
7003 arvif->vdev_id, ret);
7004 continue;
7005 }
7006 }
7007
7008 /* All relevant vdevs are downed and associated channel resources
7009 * should be available for the channel switch now.
7010 */
7011
7012 spin_lock_bh(&ar->data_lock);
7013 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
7014 spin_unlock_bh(&ar->data_lock);
7015
7016 for (i = 0; i < n_vifs; i++) {
7017 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7018
7019 if (WARN_ON(!arvif->is_started))
7020 continue;
7021
7022 if (WARN_ON(!arvif->is_up))
7023 continue;
7024
7025 ret = ath10k_mac_setup_bcn_tmpl(arvif);
7026 if (ret)
7027 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
7028 ret);
7029
7030 ret = ath10k_mac_setup_prb_tmpl(arvif);
7031 if (ret)
7032 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
7033 ret);
7034
7035 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7036 if (ret) {
7037 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7038 arvif->vdev_id, ret);
7039 continue;
7040 }
7041
7042 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7043 arvif->bssid);
7044 if (ret) {
7045 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7046 arvif->vdev_id, ret);
7047 continue;
7048 }
7049 }
7050
7051 ath10k_monitor_recalc(ar);
7052}
7053
Michal Kazior500ff9f2015-03-31 10:26:21 +00007054static int
7055ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7056 struct ieee80211_chanctx_conf *ctx)
7057{
7058 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007059
7060 ath10k_dbg(ar, ATH10K_DBG_MAC,
7061 "mac chanctx add freq %hu width %d ptr %p\n",
7062 ctx->def.chan->center_freq, ctx->def.width, ctx);
7063
7064 mutex_lock(&ar->conf_mutex);
7065
7066 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007067 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007068 spin_unlock_bh(&ar->data_lock);
7069
7070 ath10k_recalc_radar_detection(ar);
7071 ath10k_monitor_recalc(ar);
7072
7073 mutex_unlock(&ar->conf_mutex);
7074
7075 return 0;
7076}
7077
7078static void
7079ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7080 struct ieee80211_chanctx_conf *ctx)
7081{
7082 struct ath10k *ar = hw->priv;
7083
7084 ath10k_dbg(ar, ATH10K_DBG_MAC,
7085 "mac chanctx remove freq %hu width %d ptr %p\n",
7086 ctx->def.chan->center_freq, ctx->def.width, ctx);
7087
7088 mutex_lock(&ar->conf_mutex);
7089
7090 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007091 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007092 spin_unlock_bh(&ar->data_lock);
7093
7094 ath10k_recalc_radar_detection(ar);
7095 ath10k_monitor_recalc(ar);
7096
7097 mutex_unlock(&ar->conf_mutex);
7098}
7099
Michal Kazior9713e3d2015-09-03 10:44:52 +02007100struct ath10k_mac_change_chanctx_arg {
7101 struct ieee80211_chanctx_conf *ctx;
7102 struct ieee80211_vif_chanctx_switch *vifs;
7103 int n_vifs;
7104 int next_vif;
7105};
7106
7107static void
7108ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
7109 struct ieee80211_vif *vif)
7110{
7111 struct ath10k_mac_change_chanctx_arg *arg = data;
7112
7113 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
7114 return;
7115
7116 arg->n_vifs++;
7117}
7118
7119static void
7120ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
7121 struct ieee80211_vif *vif)
7122{
7123 struct ath10k_mac_change_chanctx_arg *arg = data;
7124 struct ieee80211_chanctx_conf *ctx;
7125
7126 ctx = rcu_access_pointer(vif->chanctx_conf);
7127 if (ctx != arg->ctx)
7128 return;
7129
7130 if (WARN_ON(arg->next_vif == arg->n_vifs))
7131 return;
7132
7133 arg->vifs[arg->next_vif].vif = vif;
7134 arg->vifs[arg->next_vif].old_ctx = ctx;
7135 arg->vifs[arg->next_vif].new_ctx = ctx;
7136 arg->next_vif++;
7137}
7138
Michal Kazior500ff9f2015-03-31 10:26:21 +00007139static void
7140ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7141 struct ieee80211_chanctx_conf *ctx,
7142 u32 changed)
7143{
7144 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007145 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007146
7147 mutex_lock(&ar->conf_mutex);
7148
7149 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007150 "mac chanctx change freq %hu width %d ptr %p changed %x\n",
7151 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007152
7153 /* This shouldn't really happen because channel switching should use
7154 * switch_vif_chanctx().
7155 */
7156 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7157 goto unlock;
7158
Michal Kazior9713e3d2015-09-03 10:44:52 +02007159 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7160 ieee80211_iterate_active_interfaces_atomic(
7161 hw,
7162 IEEE80211_IFACE_ITER_NORMAL,
7163 ath10k_mac_change_chanctx_cnt_iter,
7164 &arg);
7165 if (arg.n_vifs == 0)
7166 goto radar;
7167
7168 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7169 GFP_KERNEL);
7170 if (!arg.vifs)
7171 goto radar;
7172
7173 ieee80211_iterate_active_interfaces_atomic(
7174 hw,
7175 IEEE80211_IFACE_ITER_NORMAL,
7176 ath10k_mac_change_chanctx_fill_iter,
7177 &arg);
7178 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7179 kfree(arg.vifs);
7180 }
7181
7182radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007183 ath10k_recalc_radar_detection(ar);
7184
7185 /* FIXME: How to configure Rx chains properly? */
7186
7187 /* No other actions are actually necessary. Firmware maintains channel
7188 * definitions per vdev internally and there's no host-side channel
7189 * context abstraction to configure, e.g. channel width.
7190 */
7191
7192unlock:
7193 mutex_unlock(&ar->conf_mutex);
7194}
7195
7196static int
7197ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7198 struct ieee80211_vif *vif,
7199 struct ieee80211_chanctx_conf *ctx)
7200{
7201 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007202 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7203 int ret;
7204
7205 mutex_lock(&ar->conf_mutex);
7206
7207 ath10k_dbg(ar, ATH10K_DBG_MAC,
7208 "mac chanctx assign ptr %p vdev_id %i\n",
7209 ctx, arvif->vdev_id);
7210
7211 if (WARN_ON(arvif->is_started)) {
7212 mutex_unlock(&ar->conf_mutex);
7213 return -EBUSY;
7214 }
7215
Michal Kazior089ab7a2015-06-03 12:16:55 +02007216 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007217 if (ret) {
7218 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7219 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007220 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007221 goto err;
7222 }
7223
7224 arvif->is_started = true;
7225
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007226 ret = ath10k_mac_vif_setup_ps(arvif);
7227 if (ret) {
7228 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7229 arvif->vdev_id, ret);
7230 goto err_stop;
7231 }
7232
Michal Kazior500ff9f2015-03-31 10:26:21 +00007233 if (vif->type == NL80211_IFTYPE_MONITOR) {
7234 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7235 if (ret) {
7236 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7237 arvif->vdev_id, ret);
7238 goto err_stop;
7239 }
7240
7241 arvif->is_up = true;
7242 }
7243
7244 mutex_unlock(&ar->conf_mutex);
7245 return 0;
7246
7247err_stop:
7248 ath10k_vdev_stop(arvif);
7249 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007250 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007251
7252err:
7253 mutex_unlock(&ar->conf_mutex);
7254 return ret;
7255}
7256
7257static void
7258ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7259 struct ieee80211_vif *vif,
7260 struct ieee80211_chanctx_conf *ctx)
7261{
7262 struct ath10k *ar = hw->priv;
7263 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7264 int ret;
7265
7266 mutex_lock(&ar->conf_mutex);
7267
7268 ath10k_dbg(ar, ATH10K_DBG_MAC,
7269 "mac chanctx unassign ptr %p vdev_id %i\n",
7270 ctx, arvif->vdev_id);
7271
7272 WARN_ON(!arvif->is_started);
7273
7274 if (vif->type == NL80211_IFTYPE_MONITOR) {
7275 WARN_ON(!arvif->is_up);
7276
7277 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7278 if (ret)
7279 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7280 arvif->vdev_id, ret);
7281
7282 arvif->is_up = false;
7283 }
7284
7285 ret = ath10k_vdev_stop(arvif);
7286 if (ret)
7287 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7288 arvif->vdev_id, ret);
7289
7290 arvif->is_started = false;
7291
7292 mutex_unlock(&ar->conf_mutex);
7293}
7294
7295static int
7296ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7297 struct ieee80211_vif_chanctx_switch *vifs,
7298 int n_vifs,
7299 enum ieee80211_chanctx_switch_mode mode)
7300{
7301 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007302
7303 mutex_lock(&ar->conf_mutex);
7304
7305 ath10k_dbg(ar, ATH10K_DBG_MAC,
7306 "mac chanctx switch n_vifs %d mode %d\n",
7307 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007308 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007309
7310 mutex_unlock(&ar->conf_mutex);
7311 return 0;
7312}
7313
Kalle Valo5e3dd152013-06-12 20:52:10 +03007314static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01007315 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02007316 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007317 .start = ath10k_start,
7318 .stop = ath10k_stop,
7319 .config = ath10k_config,
7320 .add_interface = ath10k_add_interface,
7321 .remove_interface = ath10k_remove_interface,
7322 .configure_filter = ath10k_configure_filter,
7323 .bss_info_changed = ath10k_bss_info_changed,
7324 .hw_scan = ath10k_hw_scan,
7325 .cancel_hw_scan = ath10k_cancel_hw_scan,
7326 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02007327 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007328 .sta_state = ath10k_sta_state,
7329 .conf_tx = ath10k_conf_tx,
7330 .remain_on_channel = ath10k_remain_on_channel,
7331 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
7332 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02007333 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007334 .flush = ath10k_flush,
7335 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03007336 .set_antenna = ath10k_set_antenna,
7337 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007338 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02007339 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00007340 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01007341 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02007342 .get_tsf = ath10k_get_tsf,
Peter Oh9f0b7e72016-04-04 16:19:14 -07007343 .set_tsf = ath10k_set_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007344 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03007345 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7346 .get_et_stats = ath10k_debug_get_et_stats,
7347 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00007348 .add_chanctx = ath10k_mac_op_add_chanctx,
7349 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7350 .change_chanctx = ath10k_mac_op_change_chanctx,
7351 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7352 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7353 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Kalle Valo43d2a302014-09-10 18:23:30 +03007354
7355 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7356
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007357#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007358 .suspend = ath10k_wow_op_suspend,
7359 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007360#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007361#ifdef CONFIG_MAC80211_DEBUGFS
7362 .sta_add_debugfs = ath10k_sta_add_debugfs,
7363#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03007364};
7365
Kalle Valo5e3dd152013-06-12 20:52:10 +03007366#define CHAN2G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007367 .band = NL80211_BAND_2GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007368 .hw_value = (_channel), \
7369 .center_freq = (_freq), \
7370 .flags = (_flags), \
7371 .max_antenna_gain = 0, \
7372 .max_power = 30, \
7373}
7374
7375#define CHAN5G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007376 .band = NL80211_BAND_5GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007377 .hw_value = (_channel), \
7378 .center_freq = (_freq), \
7379 .flags = (_flags), \
7380 .max_antenna_gain = 0, \
7381 .max_power = 30, \
7382}
7383
7384static const struct ieee80211_channel ath10k_2ghz_channels[] = {
7385 CHAN2G(1, 2412, 0),
7386 CHAN2G(2, 2417, 0),
7387 CHAN2G(3, 2422, 0),
7388 CHAN2G(4, 2427, 0),
7389 CHAN2G(5, 2432, 0),
7390 CHAN2G(6, 2437, 0),
7391 CHAN2G(7, 2442, 0),
7392 CHAN2G(8, 2447, 0),
7393 CHAN2G(9, 2452, 0),
7394 CHAN2G(10, 2457, 0),
7395 CHAN2G(11, 2462, 0),
7396 CHAN2G(12, 2467, 0),
7397 CHAN2G(13, 2472, 0),
7398 CHAN2G(14, 2484, 0),
7399};
7400
7401static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02007402 CHAN5G(36, 5180, 0),
7403 CHAN5G(40, 5200, 0),
7404 CHAN5G(44, 5220, 0),
7405 CHAN5G(48, 5240, 0),
7406 CHAN5G(52, 5260, 0),
7407 CHAN5G(56, 5280, 0),
7408 CHAN5G(60, 5300, 0),
7409 CHAN5G(64, 5320, 0),
7410 CHAN5G(100, 5500, 0),
7411 CHAN5G(104, 5520, 0),
7412 CHAN5G(108, 5540, 0),
7413 CHAN5G(112, 5560, 0),
7414 CHAN5G(116, 5580, 0),
7415 CHAN5G(120, 5600, 0),
7416 CHAN5G(124, 5620, 0),
7417 CHAN5G(128, 5640, 0),
7418 CHAN5G(132, 5660, 0),
7419 CHAN5G(136, 5680, 0),
7420 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07007421 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02007422 CHAN5G(149, 5745, 0),
7423 CHAN5G(153, 5765, 0),
7424 CHAN5G(157, 5785, 0),
7425 CHAN5G(161, 5805, 0),
7426 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03007427};
7428
Michal Kaziore7b54192014-08-07 11:03:27 +02007429struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007430{
7431 struct ieee80211_hw *hw;
7432 struct ath10k *ar;
7433
Michal Kaziore7b54192014-08-07 11:03:27 +02007434 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007435 if (!hw)
7436 return NULL;
7437
7438 ar = hw->priv;
7439 ar->hw = hw;
7440
7441 return ar;
7442}
7443
7444void ath10k_mac_destroy(struct ath10k *ar)
7445{
7446 ieee80211_free_hw(ar->hw);
7447}
7448
7449static const struct ieee80211_iface_limit ath10k_if_limits[] = {
7450 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307451 .max = 8,
7452 .types = BIT(NL80211_IFTYPE_STATION)
7453 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02007454 },
7455 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307456 .max = 3,
7457 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02007458 },
7459 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307460 .max = 1,
7461 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01007462 },
7463 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307464 .max = 7,
7465 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007466#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307467 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007468#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02007469 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007470};
7471
Bartosz Markowskif2595092013-12-10 16:20:39 +01007472static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007473 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307474 .max = 8,
7475 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007476#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307477 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007478#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007479 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307480 {
7481 .max = 1,
7482 .types = BIT(NL80211_IFTYPE_STATION)
7483 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007484};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007485
7486static const struct ieee80211_iface_combination ath10k_if_comb[] = {
7487 {
7488 .limits = ath10k_if_limits,
7489 .n_limits = ARRAY_SIZE(ath10k_if_limits),
7490 .max_interfaces = 8,
7491 .num_different_channels = 1,
7492 .beacon_int_infra_match = true,
7493 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01007494};
7495
7496static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007497 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01007498 .limits = ath10k_10x_if_limits,
7499 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007500 .max_interfaces = 8,
7501 .num_different_channels = 1,
7502 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01007503#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007504 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7505 BIT(NL80211_CHAN_WIDTH_20) |
7506 BIT(NL80211_CHAN_WIDTH_40) |
7507 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007508#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01007509 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007510};
7511
Michal Kaziorcf327842015-03-31 10:26:25 +00007512static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
7513 {
7514 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02007515 .types = BIT(NL80211_IFTYPE_STATION),
7516 },
7517 {
7518 .max = 2,
7519 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007520#ifdef CONFIG_MAC80211_MESH
7521 BIT(NL80211_IFTYPE_MESH_POINT) |
7522#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00007523 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7524 BIT(NL80211_IFTYPE_P2P_GO),
7525 },
7526 {
7527 .max = 1,
7528 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7529 },
7530};
7531
Michal Kaziored25b112015-07-09 13:08:39 +02007532static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
7533 {
7534 .max = 2,
7535 .types = BIT(NL80211_IFTYPE_STATION),
7536 },
7537 {
7538 .max = 2,
7539 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
7540 },
7541 {
7542 .max = 1,
7543 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007544#ifdef CONFIG_MAC80211_MESH
7545 BIT(NL80211_IFTYPE_MESH_POINT) |
7546#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007547 BIT(NL80211_IFTYPE_P2P_GO),
7548 },
7549 {
7550 .max = 1,
7551 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7552 },
7553};
7554
Michal Kaziorcf327842015-03-31 10:26:25 +00007555static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7556 {
7557 .max = 1,
7558 .types = BIT(NL80211_IFTYPE_STATION),
7559 },
7560 {
7561 .max = 1,
7562 .types = BIT(NL80211_IFTYPE_ADHOC),
7563 },
7564};
7565
7566/* FIXME: This is not thouroughly tested. These combinations may over- or
7567 * underestimate hw/fw capabilities.
7568 */
7569static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7570 {
7571 .limits = ath10k_tlv_if_limit,
7572 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007573 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007574 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7575 },
7576 {
7577 .limits = ath10k_tlv_if_limit_ibss,
7578 .num_different_channels = 1,
7579 .max_interfaces = 2,
7580 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7581 },
7582};
7583
7584static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7585 {
7586 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007587 .num_different_channels = 1,
7588 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007589 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7590 },
7591 {
Michal Kaziored25b112015-07-09 13:08:39 +02007592 .limits = ath10k_tlv_qcs_if_limit,
7593 .num_different_channels = 2,
7594 .max_interfaces = 4,
7595 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7596 },
7597 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007598 .limits = ath10k_tlv_if_limit_ibss,
7599 .num_different_channels = 1,
7600 .max_interfaces = 2,
7601 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7602 },
7603};
7604
Raja Manicf36fef2015-06-22 20:22:25 +05307605static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
7606 {
7607 .max = 1,
7608 .types = BIT(NL80211_IFTYPE_STATION),
7609 },
7610 {
7611 .max = 16,
7612 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007613#ifdef CONFIG_MAC80211_MESH
7614 | BIT(NL80211_IFTYPE_MESH_POINT)
7615#endif
Raja Manicf36fef2015-06-22 20:22:25 +05307616 },
7617};
7618
7619static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
7620 {
7621 .limits = ath10k_10_4_if_limits,
7622 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
7623 .max_interfaces = 16,
7624 .num_different_channels = 1,
7625 .beacon_int_infra_match = true,
7626#ifdef CONFIG_ATH10K_DFS_CERTIFIED
7627 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7628 BIT(NL80211_CHAN_WIDTH_20) |
7629 BIT(NL80211_CHAN_WIDTH_40) |
7630 BIT(NL80211_CHAN_WIDTH_80),
7631#endif
7632 },
7633};
7634
Kalle Valo5e3dd152013-06-12 20:52:10 +03007635static void ath10k_get_arvif_iter(void *data, u8 *mac,
7636 struct ieee80211_vif *vif)
7637{
7638 struct ath10k_vif_iter *arvif_iter = data;
7639 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7640
7641 if (arvif->vdev_id == arvif_iter->vdev_id)
7642 arvif_iter->arvif = arvif;
7643}
7644
7645struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
7646{
7647 struct ath10k_vif_iter arvif_iter;
7648 u32 flags;
7649
7650 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
7651 arvif_iter.vdev_id = vdev_id;
7652
7653 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
7654 ieee80211_iterate_active_interfaces_atomic(ar->hw,
7655 flags,
7656 ath10k_get_arvif_iter,
7657 &arvif_iter);
7658 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007659 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007660 return NULL;
7661 }
7662
7663 return arvif_iter.arvif;
7664}
7665
7666int ath10k_mac_register(struct ath10k *ar)
7667{
Johannes Berg3cb10942015-01-22 21:38:45 +01007668 static const u32 cipher_suites[] = {
7669 WLAN_CIPHER_SUITE_WEP40,
7670 WLAN_CIPHER_SUITE_WEP104,
7671 WLAN_CIPHER_SUITE_TKIP,
7672 WLAN_CIPHER_SUITE_CCMP,
7673 WLAN_CIPHER_SUITE_AES_CMAC,
7674 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03007675 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007676 void *channels;
7677 int ret;
7678
7679 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
7680
7681 SET_IEEE80211_DEV(ar->hw, ar->dev);
7682
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00007683 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
7684 ARRAY_SIZE(ath10k_5ghz_channels)) !=
7685 ATH10K_NUM_CHANS);
7686
Kalle Valo5e3dd152013-06-12 20:52:10 +03007687 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
7688 channels = kmemdup(ath10k_2ghz_channels,
7689 sizeof(ath10k_2ghz_channels),
7690 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02007691 if (!channels) {
7692 ret = -ENOMEM;
7693 goto err_free;
7694 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007695
Johannes Berg57fbcce2016-04-12 15:56:15 +02007696 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007697 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
7698 band->channels = channels;
7699 band->n_bitrates = ath10k_g_rates_size;
7700 band->bitrates = ath10k_g_rates;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007701
Johannes Berg57fbcce2016-04-12 15:56:15 +02007702 ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007703 }
7704
7705 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
7706 channels = kmemdup(ath10k_5ghz_channels,
7707 sizeof(ath10k_5ghz_channels),
7708 GFP_KERNEL);
7709 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02007710 ret = -ENOMEM;
7711 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007712 }
7713
Johannes Berg57fbcce2016-04-12 15:56:15 +02007714 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007715 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
7716 band->channels = channels;
7717 band->n_bitrates = ath10k_a_rates_size;
7718 band->bitrates = ath10k_a_rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02007719 ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007720 }
7721
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05307722 ath10k_mac_setup_ht_vht_cap(ar);
7723
Kalle Valo5e3dd152013-06-12 20:52:10 +03007724 ar->hw->wiphy->interface_modes =
7725 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007726 BIT(NL80211_IFTYPE_AP) |
7727 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01007728
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05307729 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
7730 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03007731
Kalle Valoc4cdf752016-04-20 19:45:18 +03007732 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))
Bartosz Markowskid3541812013-12-10 16:20:40 +01007733 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01007734 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01007735 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7736 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007737
Johannes Berg30686bf2015-06-02 21:39:54 +02007738 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
7739 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
7740 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
7741 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
7742 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
7743 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
7744 ieee80211_hw_set(ar->hw, AP_LINK_PS);
7745 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02007746 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
7747 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
7748 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
7749 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
7750 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
7751 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007752
David Liuccec9032015-07-24 20:25:32 +03007753 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7754 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
7755
Eliad Peller0d8614b2014-09-10 14:07:36 +03007756 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00007757 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03007758
Kalle Valo5e3dd152013-06-12 20:52:10 +03007759 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03007760 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007761
7762 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02007763 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
7764 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007765 }
7766
7767 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
7768 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
7769
7770 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01007771 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02007772 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007773
Kalle Valo5e3dd152013-06-12 20:52:10 +03007774 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
7775
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02007776 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
7777 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
7778
7779 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
7780 * that userspace (e.g. wpa_supplicant/hostapd) can generate
7781 * correct Probe Responses. This is more of a hack advert..
7782 */
7783 ar->hw->wiphy->probe_resp_offload |=
7784 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
7785 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
7786 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
7787 }
7788
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03007789 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
7790 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7791
Kalle Valo5e3dd152013-06-12 20:52:10 +03007792 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01007793 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007794 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
7795
7796 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05307797 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
7798 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02007799
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01007800 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
7801
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007802 ret = ath10k_wow_init(ar);
7803 if (ret) {
7804 ath10k_warn(ar, "failed to init wow: %d\n", ret);
7805 goto err_free;
7806 }
7807
Janusz Dziedzicc7025342015-06-15 14:46:41 +03007808 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
7809
Kalle Valo5e3dd152013-06-12 20:52:10 +03007810 /*
7811 * on LL hardware queues are managed entirely by the FW
7812 * so we only advertise to mac we can do the queues thing
7813 */
Michal Kazior96d828d2015-03-31 10:26:23 +00007814 ar->hw->queues = IEEE80211_MAX_QUEUES;
7815
7816 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
7817 * something that vdev_ids can't reach so that we don't stop the queue
7818 * accidentally.
7819 */
7820 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007821
Kalle Valobf3c13a2016-04-20 19:45:33 +03007822 switch (ar->running_fw->fw_file.wmi_op_version) {
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007823 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01007824 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
7825 ar->hw->wiphy->n_iface_combinations =
7826 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03007827 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007828 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00007829 case ATH10K_FW_WMI_OP_VERSION_TLV:
7830 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
7831 ar->hw->wiphy->iface_combinations =
7832 ath10k_tlv_qcs_if_comb;
7833 ar->hw->wiphy->n_iface_combinations =
7834 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
7835 } else {
7836 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
7837 ar->hw->wiphy->n_iface_combinations =
7838 ARRAY_SIZE(ath10k_tlv_if_comb);
7839 }
7840 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
7841 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007842 case ATH10K_FW_WMI_OP_VERSION_10_1:
7843 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02007844 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007845 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
7846 ar->hw->wiphy->n_iface_combinations =
7847 ARRAY_SIZE(ath10k_10x_if_comb);
7848 break;
Raja Mani9bd21322015-06-22 20:10:09 +05307849 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05307850 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
7851 ar->hw->wiphy->n_iface_combinations =
7852 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05307853 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007854 case ATH10K_FW_WMI_OP_VERSION_UNSET:
7855 case ATH10K_FW_WMI_OP_VERSION_MAX:
7856 WARN_ON(1);
7857 ret = -EINVAL;
7858 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01007859 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007860
David Liuccec9032015-07-24 20:25:32 +03007861 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7862 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02007863
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007864 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
7865 /* Init ath dfs pattern detector */
7866 ar->ath_common.debug_mask = ATH_DBG_DFS;
7867 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
7868 NL80211_DFS_UNSET);
7869
7870 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02007871 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007872 }
7873
Kalle Valo5e3dd152013-06-12 20:52:10 +03007874 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
7875 ath10k_reg_notifier);
7876 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007877 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007878 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007879 }
7880
Johannes Berg3cb10942015-01-22 21:38:45 +01007881 ar->hw->wiphy->cipher_suites = cipher_suites;
7882 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
7883
Kalle Valo5e3dd152013-06-12 20:52:10 +03007884 ret = ieee80211_register_hw(ar->hw);
7885 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007886 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007887 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007888 }
7889
7890 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
7891 ret = regulatory_hint(ar->hw->wiphy,
7892 ar->ath_common.regulatory.alpha2);
7893 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02007894 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007895 }
7896
7897 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02007898
7899err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03007900 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07007901
7902err_dfs_detector_exit:
7903 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7904 ar->dfs_detector->exit(ar->dfs_detector);
7905
Michal Kaziord6015b22013-07-22 14:13:30 +02007906err_free:
Johannes Berg57fbcce2016-04-12 15:56:15 +02007907 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
7908 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Michal Kaziord6015b22013-07-22 14:13:30 +02007909
Jeff Johnson0e339442015-10-08 09:15:53 -07007910 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007911 return ret;
7912}
7913
7914void ath10k_mac_unregister(struct ath10k *ar)
7915{
7916 ieee80211_unregister_hw(ar->hw);
7917
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007918 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7919 ar->dfs_detector->exit(ar->dfs_detector);
7920
Johannes Berg57fbcce2016-04-12 15:56:15 +02007921 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
7922 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007923
7924 SET_IEEE80211_DEV(ar->hw, NULL);
7925}