blob: fb393596f23643b02ba2783adef43a387fac6785 [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) {
505 case IEEE80211_BAND_2GHZ:
506 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;
528 case IEEE80211_BAND_5GHZ:
529 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,
1775 ar->fw_features)) {
1776 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 &&
2063 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT, ar->fw_features)) {
2064 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002065 }
2066}
2067
2068static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002069 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002070 struct ieee80211_sta *sta,
2071 struct wmi_peer_assoc_complete_arg *arg)
2072{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002073 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002074 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002075 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002076 const struct ieee80211_supported_band *sband;
2077 const struct ieee80211_rate *rates;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002078 enum ieee80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002079 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002080 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002081 int i;
2082
Michal Kazior548db542013-07-05 16:15:15 +03002083 lockdep_assert_held(&ar->conf_mutex);
2084
Michal Kazior500ff9f2015-03-31 10:26:21 +00002085 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2086 return;
2087
Michal Kazior45c9abc2015-04-21 20:42:58 +03002088 band = def.chan->band;
2089 sband = ar->hw->wiphy->bands[band];
2090 ratemask = sta->supp_rates[band];
2091 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002092 rates = sband->bitrates;
2093
2094 rateset->num_rates = 0;
2095
2096 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2097 if (!(ratemask & 1))
2098 continue;
2099
Michal Kazior486017c2015-03-30 09:51:54 +03002100 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2101 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002102 rateset->num_rates++;
2103 }
2104}
2105
Michal Kazior45c9abc2015-04-21 20:42:58 +03002106static bool
2107ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2108{
2109 int nss;
2110
2111 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2112 if (ht_mcs_mask[nss])
2113 return false;
2114
2115 return true;
2116}
2117
2118static bool
2119ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2120{
2121 int nss;
2122
2123 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2124 if (vht_mcs_mask[nss])
2125 return false;
2126
2127 return true;
2128}
2129
Kalle Valo5e3dd152013-06-12 20:52:10 +03002130static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002131 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002132 struct ieee80211_sta *sta,
2133 struct wmi_peer_assoc_complete_arg *arg)
2134{
2135 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002136 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2137 struct cfg80211_chan_def def;
2138 enum ieee80211_band band;
2139 const u8 *ht_mcs_mask;
2140 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002141 int i, n;
2142 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002143 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002144
Michal Kazior548db542013-07-05 16:15:15 +03002145 lockdep_assert_held(&ar->conf_mutex);
2146
Michal Kazior45c9abc2015-04-21 20:42:58 +03002147 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2148 return;
2149
Kalle Valo5e3dd152013-06-12 20:52:10 +03002150 if (!ht_cap->ht_supported)
2151 return;
2152
Michal Kazior45c9abc2015-04-21 20:42:58 +03002153 band = def.chan->band;
2154 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2155 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2156
2157 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2158 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2159 return;
2160
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002161 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002162 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2163 ht_cap->ampdu_factor)) - 1;
2164
2165 arg->peer_mpdu_density =
2166 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2167
2168 arg->peer_ht_caps = ht_cap->cap;
2169 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2170
2171 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002172 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002173
2174 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002175 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002176 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2177 }
2178
Michal Kazior45c9abc2015-04-21 20:42:58 +03002179 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2180 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2181 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002182
Michal Kazior45c9abc2015-04-21 20:42:58 +03002183 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2184 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2185 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002186
2187 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2188 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002189 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002190 }
2191
2192 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002193 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2194 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2195 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2196 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002197 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002198 }
2199
Kalle Valo5e3dd152013-06-12 20:52:10 +03002200 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2201 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2202 else if (ht_cap->mcs.rx_mask[1])
2203 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2204
Michal Kazior45c9abc2015-04-21 20:42:58 +03002205 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2206 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2207 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2208 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002209 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002210 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002211
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002212 /*
2213 * This is a workaround for HT-enabled STAs which break the spec
2214 * and have no HT capabilities RX mask (no HT RX MCS map).
2215 *
2216 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2217 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2218 *
2219 * Firmware asserts if such situation occurs.
2220 */
2221 if (n == 0) {
2222 arg->peer_ht_rates.num_rates = 8;
2223 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2224 arg->peer_ht_rates.rates[i] = i;
2225 } else {
2226 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002227 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002228 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002229
Michal Kazior7aa7a722014-08-25 12:09:38 +02002230 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002231 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002232 arg->peer_ht_rates.num_rates,
2233 arg->peer_num_spatial_streams);
2234}
2235
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002236static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2237 struct ath10k_vif *arvif,
2238 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002239{
2240 u32 uapsd = 0;
2241 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002242 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002243
Michal Kazior548db542013-07-05 16:15:15 +03002244 lockdep_assert_held(&ar->conf_mutex);
2245
Kalle Valo5e3dd152013-06-12 20:52:10 +03002246 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002247 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002248 sta->uapsd_queues, sta->max_sp);
2249
Kalle Valo5e3dd152013-06-12 20:52:10 +03002250 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2251 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2252 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2253 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2254 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2255 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2256 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2257 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2258 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2259 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2260 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2261 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2262
Kalle Valo5e3dd152013-06-12 20:52:10 +03002263 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2264 max_sp = sta->max_sp;
2265
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002266 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2267 sta->addr,
2268 WMI_AP_PS_PEER_PARAM_UAPSD,
2269 uapsd);
2270 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002271 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002272 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002273 return ret;
2274 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002275
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002276 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2277 sta->addr,
2278 WMI_AP_PS_PEER_PARAM_MAX_SP,
2279 max_sp);
2280 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002281 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002282 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002283 return ret;
2284 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002285
2286 /* TODO setup this based on STA listen interval and
2287 beacon interval. Currently we don't know
2288 sta->listen_interval - mac80211 patch required.
2289 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002290 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002291 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2292 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002293 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002294 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002295 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002296 return ret;
2297 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002298 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002299
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002300 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002301}
2302
Michal Kazior45c9abc2015-04-21 20:42:58 +03002303static u16
2304ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2305 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2306{
2307 int idx_limit;
2308 int nss;
2309 u16 mcs_map;
2310 u16 mcs;
2311
2312 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2313 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2314 vht_mcs_limit[nss];
2315
2316 if (mcs_map)
2317 idx_limit = fls(mcs_map) - 1;
2318 else
2319 idx_limit = -1;
2320
2321 switch (idx_limit) {
2322 case 0: /* fall through */
2323 case 1: /* fall through */
2324 case 2: /* fall through */
2325 case 3: /* fall through */
2326 case 4: /* fall through */
2327 case 5: /* fall through */
2328 case 6: /* fall through */
2329 default:
2330 /* see ath10k_mac_can_set_bitrate_mask() */
2331 WARN_ON(1);
2332 /* fall through */
2333 case -1:
2334 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2335 break;
2336 case 7:
2337 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2338 break;
2339 case 8:
2340 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2341 break;
2342 case 9:
2343 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2344 break;
2345 }
2346
2347 tx_mcs_set &= ~(0x3 << (nss * 2));
2348 tx_mcs_set |= mcs << (nss * 2);
2349 }
2350
2351 return tx_mcs_set;
2352}
2353
Kalle Valo5e3dd152013-06-12 20:52:10 +03002354static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002355 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002356 struct ieee80211_sta *sta,
2357 struct wmi_peer_assoc_complete_arg *arg)
2358{
2359 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002360 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002361 struct cfg80211_chan_def def;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002362 enum ieee80211_band band;
2363 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002364 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002365
Michal Kazior500ff9f2015-03-31 10:26:21 +00002366 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2367 return;
2368
Kalle Valo5e3dd152013-06-12 20:52:10 +03002369 if (!vht_cap->vht_supported)
2370 return;
2371
Michal Kazior45c9abc2015-04-21 20:42:58 +03002372 band = def.chan->band;
2373 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2374
2375 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2376 return;
2377
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002378 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002379
Michal Kazior500ff9f2015-03-31 10:26:21 +00002380 if (def.chan->band == IEEE80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002381 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002382
Kalle Valo5e3dd152013-06-12 20:52:10 +03002383 arg->peer_vht_caps = vht_cap->cap;
2384
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002385 ampdu_factor = (vht_cap->cap &
2386 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2387 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2388
2389 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2390 * zero in VHT IE. Using it would result in degraded throughput.
2391 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2392 * it if VHT max_mpdu is smaller. */
2393 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2394 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2395 ampdu_factor)) - 1);
2396
Kalle Valo5e3dd152013-06-12 20:52:10 +03002397 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002398 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002399
2400 arg->peer_vht_rates.rx_max_rate =
2401 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2402 arg->peer_vht_rates.rx_mcs_set =
2403 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2404 arg->peer_vht_rates.tx_max_rate =
2405 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002406 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2407 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002408
Michal Kazior7aa7a722014-08-25 12:09:38 +02002409 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002410 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002411}
2412
2413static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002414 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002415 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002416 struct wmi_peer_assoc_complete_arg *arg)
2417{
Michal Kazior590922a2014-10-21 10:10:29 +03002418 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2419
Kalle Valo5e3dd152013-06-12 20:52:10 +03002420 switch (arvif->vdev_type) {
2421 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002422 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002423 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002424
2425 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002426 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002427 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2428 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002429 break;
2430 case WMI_VDEV_TYPE_STA:
Michal Kazior590922a2014-10-21 10:10:29 +03002431 if (vif->bss_conf.qos)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002432 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002433 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002434 case WMI_VDEV_TYPE_IBSS:
2435 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002436 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002437 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002438 default:
2439 break;
2440 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002441
2442 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002443 sta->addr, !!(arg->peer_flags &
2444 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002445}
2446
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002447static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002448{
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002449 return sta->supp_rates[IEEE80211_BAND_2GHZ] >>
2450 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002451}
2452
Kalle Valo5e3dd152013-06-12 20:52:10 +03002453static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002454 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002455 struct ieee80211_sta *sta,
2456 struct wmi_peer_assoc_complete_arg *arg)
2457{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002458 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002459 struct cfg80211_chan_def def;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002460 enum ieee80211_band band;
2461 const u8 *ht_mcs_mask;
2462 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002463 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2464
Michal Kazior500ff9f2015-03-31 10:26:21 +00002465 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2466 return;
2467
Michal Kazior45c9abc2015-04-21 20:42:58 +03002468 band = def.chan->band;
2469 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2470 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2471
2472 switch (band) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002473 case IEEE80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002474 if (sta->vht_cap.vht_supported &&
2475 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002476 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2477 phymode = MODE_11AC_VHT40;
2478 else
2479 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002480 } else if (sta->ht_cap.ht_supported &&
2481 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002482 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2483 phymode = MODE_11NG_HT40;
2484 else
2485 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002486 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002487 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002488 } else {
2489 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002490 }
2491
2492 break;
2493 case IEEE80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002494 /*
2495 * Check VHT first.
2496 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002497 if (sta->vht_cap.vht_supported &&
2498 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002499 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2500 phymode = MODE_11AC_VHT80;
2501 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2502 phymode = MODE_11AC_VHT40;
2503 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2504 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002505 } else if (sta->ht_cap.ht_supported &&
2506 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2507 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002508 phymode = MODE_11NA_HT40;
2509 else
2510 phymode = MODE_11NA_HT20;
2511 } else {
2512 phymode = MODE_11A;
2513 }
2514
2515 break;
2516 default:
2517 break;
2518 }
2519
Michal Kazior7aa7a722014-08-25 12:09:38 +02002520 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002521 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002522
Kalle Valo5e3dd152013-06-12 20:52:10 +03002523 arg->peer_phymode = phymode;
2524 WARN_ON(phymode == MODE_UNKNOWN);
2525}
2526
Kalle Valob9ada652013-10-16 15:44:46 +03002527static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002528 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002529 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002530 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002531{
Michal Kazior548db542013-07-05 16:15:15 +03002532 lockdep_assert_held(&ar->conf_mutex);
2533
Kalle Valob9ada652013-10-16 15:44:46 +03002534 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002535
Michal Kazior590922a2014-10-21 10:10:29 +03002536 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002537 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002538 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002539 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002540 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002541 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2542 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002543
Kalle Valob9ada652013-10-16 15:44:46 +03002544 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002545}
2546
Michal Kazior90046f52014-02-14 14:45:51 +01002547static const u32 ath10k_smps_map[] = {
2548 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2549 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2550 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2551 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2552};
2553
2554static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2555 const u8 *addr,
2556 const struct ieee80211_sta_ht_cap *ht_cap)
2557{
2558 int smps;
2559
2560 if (!ht_cap->ht_supported)
2561 return 0;
2562
2563 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2564 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2565
2566 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2567 return -EINVAL;
2568
2569 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2570 WMI_PEER_SMPS_STATE,
2571 ath10k_smps_map[smps]);
2572}
2573
Michal Kazior139e1702015-02-15 16:50:42 +02002574static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2575 struct ieee80211_vif *vif,
2576 struct ieee80211_sta_vht_cap vht_cap)
2577{
2578 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2579 int ret;
2580 u32 param;
2581 u32 value;
2582
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302583 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2584 return 0;
2585
Michal Kazior139e1702015-02-15 16:50:42 +02002586 if (!(ar->vht_cap_info &
2587 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2588 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2589 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2590 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2591 return 0;
2592
2593 param = ar->wmi.vdev_param->txbf;
2594 value = 0;
2595
2596 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2597 return 0;
2598
2599 /* The following logic is correct. If a remote STA advertises support
2600 * for being a beamformer then we should enable us being a beamformee.
2601 */
2602
2603 if (ar->vht_cap_info &
2604 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2605 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2606 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2607 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2608
2609 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2610 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2611 }
2612
2613 if (ar->vht_cap_info &
2614 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2615 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2616 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2617 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2618
2619 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2620 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2621 }
2622
2623 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2624 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2625
2626 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2627 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2628
2629 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2630 if (ret) {
2631 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2632 value, ret);
2633 return ret;
2634 }
2635
2636 return 0;
2637}
2638
Kalle Valo5e3dd152013-06-12 20:52:10 +03002639/* can be called only in mac80211 callbacks due to `key_count` usage */
2640static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2641 struct ieee80211_vif *vif,
2642 struct ieee80211_bss_conf *bss_conf)
2643{
2644 struct ath10k *ar = hw->priv;
2645 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002646 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002647 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002648 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002649 struct ieee80211_sta *ap_sta;
2650 int ret;
2651
Michal Kazior548db542013-07-05 16:15:15 +03002652 lockdep_assert_held(&ar->conf_mutex);
2653
Michal Kazior077efc82014-10-21 10:10:29 +03002654 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2655 arvif->vdev_id, arvif->bssid, arvif->aid);
2656
Kalle Valo5e3dd152013-06-12 20:52:10 +03002657 rcu_read_lock();
2658
2659 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2660 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002661 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002662 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002663 rcu_read_unlock();
2664 return;
2665 }
2666
Michal Kazior90046f52014-02-14 14:45:51 +01002667 /* ap_sta must be accessed only within rcu section which must be left
2668 * before calling ath10k_setup_peer_smps() which might sleep. */
2669 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002670 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002671
Michal Kazior590922a2014-10-21 10:10:29 +03002672 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002673 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002674 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002675 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002676 rcu_read_unlock();
2677 return;
2678 }
2679
2680 rcu_read_unlock();
2681
Kalle Valob9ada652013-10-16 15:44:46 +03002682 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2683 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002684 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002685 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002686 return;
2687 }
2688
Michal Kazior90046f52014-02-14 14:45:51 +01002689 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2690 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002691 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002692 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002693 return;
2694 }
2695
Michal Kazior139e1702015-02-15 16:50:42 +02002696 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2697 if (ret) {
2698 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2699 arvif->vdev_id, bss_conf->bssid, ret);
2700 return;
2701 }
2702
Michal Kazior7aa7a722014-08-25 12:09:38 +02002703 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002704 "mac vdev %d up (associated) bssid %pM aid %d\n",
2705 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2706
Michal Kazior077efc82014-10-21 10:10:29 +03002707 WARN_ON(arvif->is_up);
2708
Michal Kaziorc930f742014-01-23 11:38:25 +01002709 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002710 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002711
2712 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2713 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002714 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002715 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002716 return;
2717 }
2718
2719 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002720
2721 /* Workaround: Some firmware revisions (tested with qca6174
2722 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2723 * poked with peer param command.
2724 */
2725 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2726 WMI_PEER_DUMMY_VAR, 1);
2727 if (ret) {
2728 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2729 arvif->bssid, arvif->vdev_id, ret);
2730 return;
2731 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002732}
2733
Kalle Valo5e3dd152013-06-12 20:52:10 +03002734static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2735 struct ieee80211_vif *vif)
2736{
2737 struct ath10k *ar = hw->priv;
2738 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002739 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002740 int ret;
2741
Michal Kazior548db542013-07-05 16:15:15 +03002742 lockdep_assert_held(&ar->conf_mutex);
2743
Michal Kazior077efc82014-10-21 10:10:29 +03002744 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2745 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002746
Kalle Valo5e3dd152013-06-12 20:52:10 +03002747 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002748 if (ret)
2749 ath10k_warn(ar, "faield to down vdev %i: %d\n",
2750 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002751
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002752 arvif->def_wep_key_idx = -1;
2753
Michal Kazior139e1702015-02-15 16:50:42 +02002754 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2755 if (ret) {
2756 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2757 arvif->vdev_id, ret);
2758 return;
2759 }
2760
Michal Kaziorc930f742014-01-23 11:38:25 +01002761 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002762
2763 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002764}
2765
Michal Kazior590922a2014-10-21 10:10:29 +03002766static int ath10k_station_assoc(struct ath10k *ar,
2767 struct ieee80211_vif *vif,
2768 struct ieee80211_sta *sta,
2769 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002770{
Michal Kazior590922a2014-10-21 10:10:29 +03002771 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002772 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002773 int ret = 0;
2774
Michal Kazior548db542013-07-05 16:15:15 +03002775 lockdep_assert_held(&ar->conf_mutex);
2776
Michal Kazior590922a2014-10-21 10:10:29 +03002777 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002778 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002779 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002780 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002781 return ret;
2782 }
2783
2784 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2785 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002786 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002787 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002788 return ret;
2789 }
2790
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002791 /* Re-assoc is run only to update supported rates for given station. It
2792 * doesn't make much sense to reconfigure the peer completely.
2793 */
2794 if (!reassoc) {
2795 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2796 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002797 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002798 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002799 arvif->vdev_id, ret);
2800 return ret;
2801 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002802
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002803 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2804 if (ret) {
2805 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2806 sta->addr, arvif->vdev_id, ret);
2807 return ret;
2808 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002809
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002810 if (!sta->wme) {
2811 arvif->num_legacy_stations++;
2812 ret = ath10k_recalc_rtscts_prot(arvif);
2813 if (ret) {
2814 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2815 arvif->vdev_id, ret);
2816 return ret;
2817 }
2818 }
2819
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002820 /* Plumb cached keys only for static WEP */
2821 if (arvif->def_wep_key_idx != -1) {
2822 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2823 if (ret) {
2824 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2825 arvif->vdev_id, ret);
2826 return ret;
2827 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002828 }
2829 }
2830
Kalle Valo5e3dd152013-06-12 20:52:10 +03002831 return ret;
2832}
2833
Michal Kazior590922a2014-10-21 10:10:29 +03002834static int ath10k_station_disassoc(struct ath10k *ar,
2835 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002836 struct ieee80211_sta *sta)
2837{
Michal Kazior590922a2014-10-21 10:10:29 +03002838 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002839 int ret = 0;
2840
2841 lockdep_assert_held(&ar->conf_mutex);
2842
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002843 if (!sta->wme) {
2844 arvif->num_legacy_stations--;
2845 ret = ath10k_recalc_rtscts_prot(arvif);
2846 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002847 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002848 arvif->vdev_id, ret);
2849 return ret;
2850 }
2851 }
2852
Kalle Valo5e3dd152013-06-12 20:52:10 +03002853 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2854 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002855 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002856 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002857 return ret;
2858 }
2859
2860 return ret;
2861}
2862
2863/**************/
2864/* Regulatory */
2865/**************/
2866
2867static int ath10k_update_channel_list(struct ath10k *ar)
2868{
2869 struct ieee80211_hw *hw = ar->hw;
2870 struct ieee80211_supported_band **bands;
2871 enum ieee80211_band band;
2872 struct ieee80211_channel *channel;
2873 struct wmi_scan_chan_list_arg arg = {0};
2874 struct wmi_channel_arg *ch;
2875 bool passive;
2876 int len;
2877 int ret;
2878 int i;
2879
Michal Kazior548db542013-07-05 16:15:15 +03002880 lockdep_assert_held(&ar->conf_mutex);
2881
Kalle Valo5e3dd152013-06-12 20:52:10 +03002882 bands = hw->wiphy->bands;
2883 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2884 if (!bands[band])
2885 continue;
2886
2887 for (i = 0; i < bands[band]->n_channels; i++) {
2888 if (bands[band]->channels[i].flags &
2889 IEEE80211_CHAN_DISABLED)
2890 continue;
2891
2892 arg.n_channels++;
2893 }
2894 }
2895
2896 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2897 arg.channels = kzalloc(len, GFP_KERNEL);
2898 if (!arg.channels)
2899 return -ENOMEM;
2900
2901 ch = arg.channels;
2902 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2903 if (!bands[band])
2904 continue;
2905
2906 for (i = 0; i < bands[band]->n_channels; i++) {
2907 channel = &bands[band]->channels[i];
2908
2909 if (channel->flags & IEEE80211_CHAN_DISABLED)
2910 continue;
2911
2912 ch->allow_ht = true;
2913
2914 /* FIXME: when should we really allow VHT? */
2915 ch->allow_vht = true;
2916
2917 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002918 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002919
2920 ch->ht40plus =
2921 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2922
Marek Puzyniake8a50f82013-11-20 09:59:47 +02002923 ch->chan_radar =
2924 !!(channel->flags & IEEE80211_CHAN_RADAR);
2925
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002926 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002927 ch->passive = passive;
2928
2929 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02002930 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07002931 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07002932 ch->max_power = channel->max_power * 2;
2933 ch->max_reg_power = channel->max_reg_power * 2;
2934 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002935 ch->reg_class_id = 0; /* FIXME */
2936
2937 /* FIXME: why use only legacy modes, why not any
2938 * HT/VHT modes? Would that even make any
2939 * difference? */
2940 if (channel->band == IEEE80211_BAND_2GHZ)
2941 ch->mode = MODE_11G;
2942 else
2943 ch->mode = MODE_11A;
2944
2945 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
2946 continue;
2947
Michal Kazior7aa7a722014-08-25 12:09:38 +02002948 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002949 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
2950 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002951 ch->freq, ch->max_power, ch->max_reg_power,
2952 ch->max_antenna_gain, ch->mode);
2953
2954 ch++;
2955 }
2956 }
2957
2958 ret = ath10k_wmi_scan_chan_list(ar, &arg);
2959 kfree(arg.channels);
2960
2961 return ret;
2962}
2963
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002964static enum wmi_dfs_region
2965ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
2966{
2967 switch (dfs_region) {
2968 case NL80211_DFS_UNSET:
2969 return WMI_UNINIT_DFS_DOMAIN;
2970 case NL80211_DFS_FCC:
2971 return WMI_FCC_DFS_DOMAIN;
2972 case NL80211_DFS_ETSI:
2973 return WMI_ETSI_DFS_DOMAIN;
2974 case NL80211_DFS_JP:
2975 return WMI_MKK4_DFS_DOMAIN;
2976 }
2977 return WMI_UNINIT_DFS_DOMAIN;
2978}
2979
Michal Kaziorf7843d72013-07-16 09:38:52 +02002980static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002981{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002982 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002983 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002984 enum wmi_dfs_region wmi_dfs_reg;
2985 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002986
Michal Kaziorf7843d72013-07-16 09:38:52 +02002987 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002988
2989 ret = ath10k_update_channel_list(ar);
2990 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02002991 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002992
2993 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02002994
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002995 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
2996 nl_dfs_reg = ar->dfs_detector->region;
2997 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
2998 } else {
2999 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
3000 }
3001
Kalle Valo5e3dd152013-06-12 20:52:10 +03003002 /* Target allows setting up per-band regdomain but ath_common provides
3003 * a combined one only */
3004 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02003005 regpair->reg_domain,
3006 regpair->reg_domain, /* 2ghz */
3007 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003008 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003009 regpair->reg_5ghz_ctl,
3010 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003011 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003012 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02003013}
Michal Kazior548db542013-07-05 16:15:15 +03003014
Michal Kaziorf7843d72013-07-16 09:38:52 +02003015static void ath10k_reg_notifier(struct wiphy *wiphy,
3016 struct regulatory_request *request)
3017{
3018 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
3019 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003020 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003021
3022 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3023
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003024 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003025 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003026 request->dfs_region);
3027 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3028 request->dfs_region);
3029 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003030 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003031 request->dfs_region);
3032 }
3033
Michal Kaziorf7843d72013-07-16 09:38:52 +02003034 mutex_lock(&ar->conf_mutex);
3035 if (ar->state == ATH10K_STATE_ON)
3036 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003037 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003038}
3039
3040/***************/
3041/* TX handlers */
3042/***************/
3043
Michal Kaziora30c7d02016-03-06 16:14:23 +02003044enum ath10k_mac_tx_path {
3045 ATH10K_MAC_TX_HTT,
3046 ATH10K_MAC_TX_HTT_MGMT,
3047 ATH10K_MAC_TX_WMI_MGMT,
3048 ATH10K_MAC_TX_UNKNOWN,
3049};
3050
Michal Kazior96d828d2015-03-31 10:26:23 +00003051void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3052{
3053 lockdep_assert_held(&ar->htt.tx_lock);
3054
3055 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3056 ar->tx_paused |= BIT(reason);
3057 ieee80211_stop_queues(ar->hw);
3058}
3059
3060static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3061 struct ieee80211_vif *vif)
3062{
3063 struct ath10k *ar = data;
3064 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3065
3066 if (arvif->tx_paused)
3067 return;
3068
3069 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3070}
3071
3072void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3073{
3074 lockdep_assert_held(&ar->htt.tx_lock);
3075
3076 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3077 ar->tx_paused &= ~BIT(reason);
3078
3079 if (ar->tx_paused)
3080 return;
3081
3082 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3083 IEEE80211_IFACE_ITER_RESUME_ALL,
3084 ath10k_mac_tx_unlock_iter,
3085 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003086
3087 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003088}
3089
3090void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3091{
3092 struct ath10k *ar = arvif->ar;
3093
3094 lockdep_assert_held(&ar->htt.tx_lock);
3095
3096 WARN_ON(reason >= BITS_PER_LONG);
3097 arvif->tx_paused |= BIT(reason);
3098 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3099}
3100
3101void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3102{
3103 struct ath10k *ar = arvif->ar;
3104
3105 lockdep_assert_held(&ar->htt.tx_lock);
3106
3107 WARN_ON(reason >= BITS_PER_LONG);
3108 arvif->tx_paused &= ~BIT(reason);
3109
3110 if (ar->tx_paused)
3111 return;
3112
3113 if (arvif->tx_paused)
3114 return;
3115
3116 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3117}
3118
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003119static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3120 enum wmi_tlv_tx_pause_id pause_id,
3121 enum wmi_tlv_tx_pause_action action)
3122{
3123 struct ath10k *ar = arvif->ar;
3124
3125 lockdep_assert_held(&ar->htt.tx_lock);
3126
Michal Kazioracd0b272015-07-09 13:08:38 +02003127 switch (action) {
3128 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3129 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003130 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003131 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3132 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3133 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003134 default:
Michal Kazioracd0b272015-07-09 13:08:38 +02003135 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
3136 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003137 break;
3138 }
3139}
3140
3141struct ath10k_mac_tx_pause {
3142 u32 vdev_id;
3143 enum wmi_tlv_tx_pause_id pause_id;
3144 enum wmi_tlv_tx_pause_action action;
3145};
3146
3147static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3148 struct ieee80211_vif *vif)
3149{
3150 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3151 struct ath10k_mac_tx_pause *arg = data;
3152
Michal Kazioracd0b272015-07-09 13:08:38 +02003153 if (arvif->vdev_id != arg->vdev_id)
3154 return;
3155
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003156 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3157}
3158
Michal Kazioracd0b272015-07-09 13:08:38 +02003159void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3160 enum wmi_tlv_tx_pause_id pause_id,
3161 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003162{
3163 struct ath10k_mac_tx_pause arg = {
3164 .vdev_id = vdev_id,
3165 .pause_id = pause_id,
3166 .action = action,
3167 };
3168
3169 spin_lock_bh(&ar->htt.tx_lock);
3170 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3171 IEEE80211_IFACE_ITER_RESUME_ALL,
3172 ath10k_mac_handle_tx_pause_iter,
3173 &arg);
3174 spin_unlock_bh(&ar->htt.tx_lock);
3175}
3176
Michal Kaziord740d8f2015-03-30 09:51:51 +03003177static enum ath10k_hw_txrx_mode
Michal Kazior6a2636d2015-11-18 06:59:16 +01003178ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3179 struct ieee80211_vif *vif,
3180 struct ieee80211_sta *sta,
3181 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003182{
3183 const struct ieee80211_hdr *hdr = (void *)skb->data;
3184 __le16 fc = hdr->frame_control;
3185
3186 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3187 return ATH10K_HW_TXRX_RAW;
3188
3189 if (ieee80211_is_mgmt(fc))
3190 return ATH10K_HW_TXRX_MGMT;
3191
3192 /* Workaround:
3193 *
3194 * NullFunc frames are mostly used to ping if a client or AP are still
3195 * reachable and responsive. This implies tx status reports must be
3196 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3197 * come to a conclusion that the other end disappeared and tear down
3198 * BSS connection or it can never disconnect from BSS/client (which is
3199 * the case).
3200 *
3201 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3202 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3203 * which seems to deliver correct tx reports for NullFunc frames. The
3204 * downside of using it is it ignores client powersave state so it can
3205 * end up disconnecting sleeping clients in AP mode. It should fix STA
3206 * mode though because AP don't sleep.
3207 */
3208 if (ar->htt.target_version_major < 3 &&
3209 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
3210 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, ar->fw_features))
3211 return ATH10K_HW_TXRX_MGMT;
3212
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003213 /* Workaround:
3214 *
3215 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3216 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3217 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003218 *
3219 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003220 */
3221 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3222 return ATH10K_HW_TXRX_ETHERNET;
3223
David Liuccec9032015-07-24 20:25:32 +03003224 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3225 return ATH10K_HW_TXRX_RAW;
3226
Michal Kaziord740d8f2015-03-30 09:51:51 +03003227 return ATH10K_HW_TXRX_NATIVE_WIFI;
3228}
3229
David Liuccec9032015-07-24 20:25:32 +03003230static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003231 struct sk_buff *skb)
3232{
3233 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3234 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003235 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3236 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003237
3238 if (!ieee80211_has_protected(hdr->frame_control))
3239 return false;
3240
David Liuccec9032015-07-24 20:25:32 +03003241 if ((info->flags & mask) == mask)
3242 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003243
David Liuccec9032015-07-24 20:25:32 +03003244 if (vif)
3245 return !ath10k_vif_to_arvif(vif)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003246
David Liuccec9032015-07-24 20:25:32 +03003247 return true;
3248}
3249
Michal Kazior4b604552014-07-21 21:03:09 +03003250/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3251 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003252 */
Michal Kazior4b604552014-07-21 21:03:09 +03003253static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003254{
3255 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003256 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003257 u8 *qos_ctl;
3258
3259 if (!ieee80211_is_data_qos(hdr->frame_control))
3260 return;
3261
3262 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003263 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3264 skb->data, (void *)qos_ctl - (void *)skb->data);
3265 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003266
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003267 /* Some firmware revisions don't handle sending QoS NullFunc well.
3268 * These frames are mainly used for CQM purposes so it doesn't really
3269 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003270 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003271 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003272 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003273 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003274
3275 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003276}
3277
Michal Kaziord740d8f2015-03-30 09:51:51 +03003278static void ath10k_tx_h_8023(struct sk_buff *skb)
3279{
3280 struct ieee80211_hdr *hdr;
3281 struct rfc1042_hdr *rfc1042;
3282 struct ethhdr *eth;
3283 size_t hdrlen;
3284 u8 da[ETH_ALEN];
3285 u8 sa[ETH_ALEN];
3286 __be16 type;
3287
3288 hdr = (void *)skb->data;
3289 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3290 rfc1042 = (void *)skb->data + hdrlen;
3291
3292 ether_addr_copy(da, ieee80211_get_DA(hdr));
3293 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3294 type = rfc1042->snap_type;
3295
3296 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3297 skb_push(skb, sizeof(*eth));
3298
3299 eth = (void *)skb->data;
3300 ether_addr_copy(eth->h_dest, da);
3301 ether_addr_copy(eth->h_source, sa);
3302 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003303}
3304
Michal Kazior4b604552014-07-21 21:03:09 +03003305static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3306 struct ieee80211_vif *vif,
3307 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003308{
3309 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003310 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3311
3312 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003313 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003314 return;
3315
3316 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3317 spin_lock_bh(&ar->data_lock);
3318 if (arvif->u.ap.noa_data)
3319 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3320 GFP_ATOMIC))
3321 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3322 arvif->u.ap.noa_data,
3323 arvif->u.ap.noa_len);
3324 spin_unlock_bh(&ar->data_lock);
3325 }
3326}
3327
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003328static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3329 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003330 struct ieee80211_txq *txq,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003331 struct sk_buff *skb)
3332{
3333 struct ieee80211_hdr *hdr = (void *)skb->data;
3334 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3335
3336 cb->flags = 0;
3337 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3338 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3339
3340 if (ieee80211_is_mgmt(hdr->frame_control))
3341 cb->flags |= ATH10K_SKB_F_MGMT;
3342
3343 if (ieee80211_is_data_qos(hdr->frame_control))
3344 cb->flags |= ATH10K_SKB_F_QOS;
3345
3346 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003347 cb->txq = txq;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003348}
3349
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303350bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003351{
3352 /* FIXME: Not really sure since when the behaviour changed. At some
3353 * point new firmware stopped requiring creation of peer entries for
3354 * offchannel tx (and actually creating them causes issues with wmi-htc
3355 * tx credit replenishment and reliability). Assuming it's at least 3.4
3356 * because that's when the `freq` was introduced to TX_FRM HTT command.
3357 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303358 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303359 ar->htt.target_version_minor >= 4 &&
3360 ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003361}
3362
Michal Kaziord740d8f2015-03-30 09:51:51 +03003363static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003364{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003365 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003366 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003367
Michal Kaziord740d8f2015-03-30 09:51:51 +03003368 spin_lock_bh(&ar->data_lock);
3369
3370 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3371 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3372 ret = -ENOSPC;
3373 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003374 }
3375
Michal Kaziord740d8f2015-03-30 09:51:51 +03003376 __skb_queue_tail(q, skb);
3377 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3378
3379unlock:
3380 spin_unlock_bh(&ar->data_lock);
3381
3382 return ret;
3383}
3384
Michal Kaziora30c7d02016-03-06 16:14:23 +02003385static enum ath10k_mac_tx_path
3386ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3387 struct sk_buff *skb,
3388 enum ath10k_hw_txrx_mode txmode)
3389{
3390 switch (txmode) {
3391 case ATH10K_HW_TXRX_RAW:
3392 case ATH10K_HW_TXRX_NATIVE_WIFI:
3393 case ATH10K_HW_TXRX_ETHERNET:
3394 return ATH10K_MAC_TX_HTT;
3395 case ATH10K_HW_TXRX_MGMT:
3396 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3397 ar->fw_features))
3398 return ATH10K_MAC_TX_WMI_MGMT;
3399 else if (ar->htt.target_version_major >= 3)
3400 return ATH10K_MAC_TX_HTT;
3401 else
3402 return ATH10K_MAC_TX_HTT_MGMT;
3403 }
3404
3405 return ATH10K_MAC_TX_UNKNOWN;
3406}
3407
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003408static int ath10k_mac_tx_submit(struct ath10k *ar,
3409 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003410 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003411 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003412{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003413 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003414 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003415
3416 switch (txpath) {
3417 case ATH10K_MAC_TX_HTT:
Michal Kazior8a933962015-11-18 06:59:17 +01003418 ret = ath10k_htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003419 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003420 case ATH10K_MAC_TX_HTT_MGMT:
3421 ret = ath10k_htt_mgmt_tx(htt, skb);
3422 break;
3423 case ATH10K_MAC_TX_WMI_MGMT:
3424 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3425 break;
3426 case ATH10K_MAC_TX_UNKNOWN:
3427 WARN_ON_ONCE(1);
3428 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003429 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003430 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003431
3432 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003433 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3434 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003435 ieee80211_free_txskb(ar->hw, skb);
3436 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003437
3438 return ret;
3439}
3440
3441/* This function consumes the sk_buff regardless of return value as far as
3442 * caller is concerned so no freeing is necessary afterwards.
3443 */
3444static int ath10k_mac_tx(struct ath10k *ar,
3445 struct ieee80211_vif *vif,
3446 struct ieee80211_sta *sta,
3447 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003448 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003449 struct sk_buff *skb)
3450{
3451 struct ieee80211_hw *hw = ar->hw;
3452 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3453 int ret;
3454
3455 /* We should disable CCK RATE due to P2P */
3456 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3457 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3458
3459 switch (txmode) {
3460 case ATH10K_HW_TXRX_MGMT:
3461 case ATH10K_HW_TXRX_NATIVE_WIFI:
3462 ath10k_tx_h_nwifi(hw, skb);
3463 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3464 ath10k_tx_h_seq_no(vif, skb);
3465 break;
3466 case ATH10K_HW_TXRX_ETHERNET:
3467 ath10k_tx_h_8023(skb);
3468 break;
3469 case ATH10K_HW_TXRX_RAW:
3470 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3471 WARN_ON_ONCE(1);
3472 ieee80211_free_txskb(hw, skb);
3473 return -ENOTSUPP;
3474 }
3475 }
3476
3477 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3478 if (!ath10k_mac_tx_frm_has_freq(ar)) {
3479 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
3480 skb);
3481
3482 skb_queue_tail(&ar->offchan_tx_queue, skb);
3483 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3484 return 0;
3485 }
3486 }
3487
Michal Kazior6421969f2016-03-06 16:14:25 +02003488 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003489 if (ret) {
3490 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3491 return ret;
3492 }
3493
3494 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003495}
3496
3497void ath10k_offchan_tx_purge(struct ath10k *ar)
3498{
3499 struct sk_buff *skb;
3500
3501 for (;;) {
3502 skb = skb_dequeue(&ar->offchan_tx_queue);
3503 if (!skb)
3504 break;
3505
3506 ieee80211_free_txskb(ar->hw, skb);
3507 }
3508}
3509
3510void ath10k_offchan_tx_work(struct work_struct *work)
3511{
3512 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3513 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003514 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003515 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003516 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003517 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003518 struct ieee80211_vif *vif;
3519 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003520 struct sk_buff *skb;
3521 const u8 *peer_addr;
3522 int vdev_id;
3523 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003524 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003525 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003526
3527 /* FW requirement: We must create a peer before FW will send out
3528 * an offchannel frame. Otherwise the frame will be stuck and
3529 * never transmitted. We delete the peer upon tx completion.
3530 * It is unlikely that a peer for offchannel tx will already be
3531 * present. However it may be in some rare cases so account for that.
3532 * Otherwise we might remove a legitimate peer and break stuff. */
3533
3534 for (;;) {
3535 skb = skb_dequeue(&ar->offchan_tx_queue);
3536 if (!skb)
3537 break;
3538
3539 mutex_lock(&ar->conf_mutex);
3540
Michal Kazior7aa7a722014-08-25 12:09:38 +02003541 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003542 skb);
3543
3544 hdr = (struct ieee80211_hdr *)skb->data;
3545 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003546
3547 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003548 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003549 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3550 spin_unlock_bh(&ar->data_lock);
3551
3552 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003553 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003554 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003555 peer_addr, vdev_id);
3556
3557 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003558 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3559 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003560 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003561 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003562 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003563 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003564 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003565 }
3566
3567 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003568 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003569 ar->offchan_tx_skb = skb;
3570 spin_unlock_bh(&ar->data_lock);
3571
Michal Kazior8a933962015-11-18 06:59:17 +01003572 /* It's safe to access vif and sta - conf_mutex guarantees that
3573 * sta_state() and remove_interface() are locked exclusively
3574 * out wrt to this offchannel worker.
3575 */
3576 arvif = ath10k_get_arvif(ar, vdev_id);
3577 if (arvif) {
3578 vif = arvif->vif;
3579 sta = ieee80211_find_sta(vif, peer_addr);
3580 } else {
3581 vif = NULL;
3582 sta = NULL;
3583 }
3584
3585 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003586 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003587
Michal Kazior6421969f2016-03-06 16:14:25 +02003588 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003589 if (ret) {
3590 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3591 ret);
3592 /* not serious */
3593 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003594
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003595 time_left =
3596 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3597 if (time_left == 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003598 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003599 skb);
3600
Michal Kazioradaeed72015-08-05 12:15:23 +02003601 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003602 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3603 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003604 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003605 peer_addr, vdev_id, ret);
3606 }
3607
3608 mutex_unlock(&ar->conf_mutex);
3609 }
3610}
3611
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003612void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3613{
3614 struct sk_buff *skb;
3615
3616 for (;;) {
3617 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3618 if (!skb)
3619 break;
3620
3621 ieee80211_free_txskb(ar->hw, skb);
3622 }
3623}
3624
3625void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3626{
3627 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3628 struct sk_buff *skb;
3629 int ret;
3630
3631 for (;;) {
3632 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3633 if (!skb)
3634 break;
3635
3636 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003637 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003638 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003639 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003640 ieee80211_free_txskb(ar->hw, skb);
3641 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003642 }
3643}
3644
Michal Kazior29946872016-03-06 16:14:34 +02003645static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3646{
3647 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3648
3649 if (!txq)
3650 return;
3651
3652 INIT_LIST_HEAD(&artxq->list);
3653}
3654
3655static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3656{
3657 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003658 struct ath10k_skb_cb *cb;
3659 struct sk_buff *msdu;
3660 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003661
3662 if (!txq)
3663 return;
3664
3665 spin_lock_bh(&ar->txqs_lock);
3666 if (!list_empty(&artxq->list))
3667 list_del_init(&artxq->list);
3668 spin_unlock_bh(&ar->txqs_lock);
Michal Kaziordd4717b2016-03-06 16:14:39 +02003669
3670 spin_lock_bh(&ar->htt.tx_lock);
3671 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3672 cb = ATH10K_SKB_CB(msdu);
3673 if (cb->txq == txq)
3674 cb->txq = NULL;
3675 }
3676 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003677}
3678
Michal Kazior426e10e2016-03-06 16:14:43 +02003679struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
3680 u16 peer_id,
3681 u8 tid)
3682{
3683 struct ath10k_peer *peer;
3684
3685 lockdep_assert_held(&ar->data_lock);
3686
3687 peer = ar->peer_map[peer_id];
3688 if (!peer)
3689 return NULL;
3690
3691 if (peer->sta)
3692 return peer->sta->txq[tid];
3693 else if (peer->vif)
3694 return peer->vif->txq;
3695 else
3696 return NULL;
3697}
3698
Michal Kazior29946872016-03-06 16:14:34 +02003699static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3700 struct ieee80211_txq *txq)
3701{
Michal Kazior426e10e2016-03-06 16:14:43 +02003702 struct ath10k *ar = hw->priv;
3703 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3704
3705 /* No need to get locks */
3706
3707 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3708 return true;
3709
3710 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3711 return true;
3712
3713 if (artxq->num_fw_queued < artxq->num_push_allowed)
3714 return true;
3715
3716 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003717}
3718
Michal Kazior426e10e2016-03-06 16:14:43 +02003719int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3720 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02003721{
Michal Kazior29946872016-03-06 16:14:34 +02003722 struct ath10k *ar = hw->priv;
3723 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003724 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003725 struct ieee80211_vif *vif = txq->vif;
3726 struct ieee80211_sta *sta = txq->sta;
3727 enum ath10k_hw_txrx_mode txmode;
3728 enum ath10k_mac_tx_path txpath;
3729 struct sk_buff *skb;
Michal Kazior426e10e2016-03-06 16:14:43 +02003730 size_t skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003731 int ret;
3732
3733 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303734 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003735 spin_unlock_bh(&ar->htt.tx_lock);
3736
3737 if (ret)
3738 return ret;
3739
3740 skb = ieee80211_tx_dequeue(hw, txq);
3741 if (!skb) {
3742 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303743 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003744 spin_unlock_bh(&ar->htt.tx_lock);
3745
3746 return -ENOENT;
3747 }
3748
Michal Kaziordd4717b2016-03-06 16:14:39 +02003749 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Michal Kazior29946872016-03-06 16:14:34 +02003750
Michal Kazior426e10e2016-03-06 16:14:43 +02003751 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02003752 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
3753 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
3754
3755 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
3756 if (unlikely(ret)) {
3757 ath10k_warn(ar, "failed to push frame: %d\n", ret);
3758
3759 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303760 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003761 spin_unlock_bh(&ar->htt.tx_lock);
3762
3763 return ret;
3764 }
3765
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003766 spin_lock_bh(&ar->htt.tx_lock);
3767 artxq->num_fw_queued++;
3768 spin_unlock_bh(&ar->htt.tx_lock);
3769
Michal Kazior426e10e2016-03-06 16:14:43 +02003770 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003771}
3772
3773void ath10k_mac_tx_push_pending(struct ath10k *ar)
3774{
3775 struct ieee80211_hw *hw = ar->hw;
3776 struct ieee80211_txq *txq;
3777 struct ath10k_txq *artxq;
3778 struct ath10k_txq *last;
3779 int ret;
3780 int max;
3781
3782 spin_lock_bh(&ar->txqs_lock);
3783 rcu_read_lock();
3784
3785 last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
3786 while (!list_empty(&ar->txqs)) {
3787 artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
3788 txq = container_of((void *)artxq, struct ieee80211_txq,
3789 drv_priv);
3790
3791 /* Prevent aggressive sta/tid taking over tx queue */
3792 max = 16;
Michal Kazior750eeed2016-03-17 10:51:05 +01003793 ret = 0;
3794 while (ath10k_mac_tx_can_push(hw, txq) && max--) {
Michal Kazior29946872016-03-06 16:14:34 +02003795 ret = ath10k_mac_tx_push_txq(hw, txq);
3796 if (ret < 0)
3797 break;
3798 }
3799
3800 list_del_init(&artxq->list);
Michal Kazior9d71d472016-03-17 10:51:04 +01003801 if (ret != -ENOENT)
3802 list_add_tail(&artxq->list, &ar->txqs);
3803
Michal Kaziorc1a43d92016-03-06 16:14:36 +02003804 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02003805
Michal Kazior9d71d472016-03-17 10:51:04 +01003806 if (artxq == last || (ret < 0 && ret != -ENOENT))
Michal Kazior29946872016-03-06 16:14:34 +02003807 break;
Michal Kazior29946872016-03-06 16:14:34 +02003808 }
3809
3810 rcu_read_unlock();
3811 spin_unlock_bh(&ar->txqs_lock);
3812}
3813
Kalle Valo5e3dd152013-06-12 20:52:10 +03003814/************/
3815/* Scanning */
3816/************/
3817
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003818void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003819{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003820 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003821
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003822 switch (ar->scan.state) {
3823 case ATH10K_SCAN_IDLE:
3824 break;
3825 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01003826 case ATH10K_SCAN_ABORTING:
3827 if (!ar->scan.is_roc)
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003828 ieee80211_scan_completed(ar->hw,
3829 (ar->scan.state ==
3830 ATH10K_SCAN_ABORTING));
Michal Kaziord710e752015-07-09 13:08:36 +02003831 else if (ar->scan.roc_notify)
3832 ieee80211_remain_on_channel_expired(ar->hw);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003833 /* fall through */
3834 case ATH10K_SCAN_STARTING:
3835 ar->scan.state = ATH10K_SCAN_IDLE;
3836 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01003837 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003838 ath10k_offchan_tx_purge(ar);
3839 cancel_delayed_work(&ar->scan.timeout);
3840 complete_all(&ar->scan.completed);
3841 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003842 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003843}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003844
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003845void ath10k_scan_finish(struct ath10k *ar)
3846{
3847 spin_lock_bh(&ar->data_lock);
3848 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003849 spin_unlock_bh(&ar->data_lock);
3850}
3851
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003852static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003853{
3854 struct wmi_stop_scan_arg arg = {
3855 .req_id = 1, /* FIXME */
3856 .req_type = WMI_SCAN_STOP_ONE,
3857 .u.scan_id = ATH10K_SCAN_ID,
3858 };
3859 int ret;
3860
3861 lockdep_assert_held(&ar->conf_mutex);
3862
Kalle Valo5e3dd152013-06-12 20:52:10 +03003863 ret = ath10k_wmi_stop_scan(ar, &arg);
3864 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003865 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003866 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003867 }
3868
Kalle Valo14e105c2016-04-13 14:13:21 +03003869 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003870 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003871 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003872 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003873 } else if (ret > 0) {
3874 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003875 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003876
3877out:
3878 /* Scan state should be updated upon scan completion but in case
3879 * firmware fails to deliver the event (for whatever reason) it is
3880 * desired to clean up scan state anyway. Firmware may have just
3881 * dropped the scan completion event delivery due to transport pipe
3882 * being overflown with data and/or it can recover on its own before
3883 * next scan request is submitted.
3884 */
3885 spin_lock_bh(&ar->data_lock);
3886 if (ar->scan.state != ATH10K_SCAN_IDLE)
3887 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003888 spin_unlock_bh(&ar->data_lock);
3889
3890 return ret;
3891}
3892
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003893static void ath10k_scan_abort(struct ath10k *ar)
3894{
3895 int ret;
3896
3897 lockdep_assert_held(&ar->conf_mutex);
3898
3899 spin_lock_bh(&ar->data_lock);
3900
3901 switch (ar->scan.state) {
3902 case ATH10K_SCAN_IDLE:
3903 /* This can happen if timeout worker kicked in and called
3904 * abortion while scan completion was being processed.
3905 */
3906 break;
3907 case ATH10K_SCAN_STARTING:
3908 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02003909 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003910 ath10k_scan_state_str(ar->scan.state),
3911 ar->scan.state);
3912 break;
3913 case ATH10K_SCAN_RUNNING:
3914 ar->scan.state = ATH10K_SCAN_ABORTING;
3915 spin_unlock_bh(&ar->data_lock);
3916
3917 ret = ath10k_scan_stop(ar);
3918 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003919 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003920
3921 spin_lock_bh(&ar->data_lock);
3922 break;
3923 }
3924
3925 spin_unlock_bh(&ar->data_lock);
3926}
3927
3928void ath10k_scan_timeout_work(struct work_struct *work)
3929{
3930 struct ath10k *ar = container_of(work, struct ath10k,
3931 scan.timeout.work);
3932
3933 mutex_lock(&ar->conf_mutex);
3934 ath10k_scan_abort(ar);
3935 mutex_unlock(&ar->conf_mutex);
3936}
3937
Kalle Valo5e3dd152013-06-12 20:52:10 +03003938static int ath10k_start_scan(struct ath10k *ar,
3939 const struct wmi_start_scan_arg *arg)
3940{
3941 int ret;
3942
3943 lockdep_assert_held(&ar->conf_mutex);
3944
3945 ret = ath10k_wmi_start_scan(ar, arg);
3946 if (ret)
3947 return ret;
3948
Kalle Valo14e105c2016-04-13 14:13:21 +03003949 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003950 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003951 ret = ath10k_scan_stop(ar);
3952 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003953 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003954
3955 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003956 }
3957
Ben Greear2f9eec02015-02-15 16:50:38 +02003958 /* If we failed to start the scan, return error code at
3959 * this point. This is probably due to some issue in the
3960 * firmware, but no need to wedge the driver due to that...
3961 */
3962 spin_lock_bh(&ar->data_lock);
3963 if (ar->scan.state == ATH10K_SCAN_IDLE) {
3964 spin_unlock_bh(&ar->data_lock);
3965 return -EINVAL;
3966 }
3967 spin_unlock_bh(&ar->data_lock);
3968
Kalle Valo5e3dd152013-06-12 20:52:10 +03003969 return 0;
3970}
3971
3972/**********************/
3973/* mac80211 callbacks */
3974/**********************/
3975
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003976static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
3977 struct ieee80211_tx_control *control,
3978 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003979{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003980 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02003981 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03003982 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3983 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003984 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003985 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02003986 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01003987 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003988 enum ath10k_mac_tx_path txpath;
3989 bool is_htt;
3990 bool is_mgmt;
3991 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003992 int ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003993
Michal Kaziordd4717b2016-03-06 16:14:39 +02003994 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003995
Michal Kazior8a933962015-11-18 06:59:17 +01003996 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003997 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
3998 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
3999 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304000 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004001
Michal Kazior6421969f2016-03-06 16:14:25 +02004002 if (is_htt) {
4003 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004004 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4005
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304006 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004007 if (ret) {
4008 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4009 ret);
4010 spin_unlock_bh(&ar->htt.tx_lock);
4011 ieee80211_free_txskb(ar->hw, skb);
4012 return;
4013 }
4014
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304015 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4016 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304017 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4018 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304019 ath10k_htt_tx_dec_pending(htt);
4020 spin_unlock_bh(&ar->htt.tx_lock);
4021 ieee80211_free_txskb(ar->hw, skb);
4022 return;
4023 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004024 spin_unlock_bh(&ar->htt.tx_lock);
4025 }
4026
4027 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
4028 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004029 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004030 if (is_htt) {
4031 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304032 ath10k_htt_tx_dec_pending(htt);
4033 if (is_mgmt)
4034 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004035 spin_unlock_bh(&ar->htt.tx_lock);
4036 }
4037 return;
4038 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004039}
4040
Michal Kazior29946872016-03-06 16:14:34 +02004041static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4042 struct ieee80211_txq *txq)
4043{
4044 struct ath10k *ar = hw->priv;
4045 struct ath10k_txq *artxq = (void *)txq->drv_priv;
4046
Michal Kazior750eeed2016-03-17 10:51:05 +01004047 spin_lock_bh(&ar->txqs_lock);
4048 if (list_empty(&artxq->list))
4049 list_add_tail(&artxq->list, &ar->txqs);
4050 spin_unlock_bh(&ar->txqs_lock);
Michal Kazior29946872016-03-06 16:14:34 +02004051
Michal Kazior750eeed2016-03-17 10:51:05 +01004052 if (ath10k_mac_tx_can_push(hw, txq))
Michal Kazior29946872016-03-06 16:14:34 +02004053 tasklet_schedule(&ar->htt.txrx_compl_task);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004054
4055 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02004056}
4057
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004058/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004059void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004060{
4061 /* make sure rcu-protected mac80211 tx path itself is drained */
4062 synchronize_net();
4063
4064 ath10k_offchan_tx_purge(ar);
4065 ath10k_mgmt_over_wmi_tx_purge(ar);
4066
4067 cancel_work_sync(&ar->offchan_tx_work);
4068 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4069}
4070
Michal Kazioraffd3212013-07-16 09:54:35 +02004071void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004072{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004073 struct ath10k_vif *arvif;
4074
Michal Kazior818bdd12013-07-16 09:38:57 +02004075 lockdep_assert_held(&ar->conf_mutex);
4076
Michal Kazior19337472014-08-28 12:58:16 +02004077 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4078 ar->filter_flags = 0;
4079 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004080 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004081
4082 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004083 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004084
4085 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004086 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004087
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004088 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004089 ath10k_peer_cleanup_all(ar);
4090 ath10k_core_stop(ar);
4091 ath10k_hif_power_down(ar);
4092
4093 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004094 list_for_each_entry(arvif, &ar->arvifs, list)
4095 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004096 spin_unlock_bh(&ar->data_lock);
4097}
4098
Ben Greear46acf7b2014-05-16 17:15:38 +03004099static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4100{
4101 struct ath10k *ar = hw->priv;
4102
4103 mutex_lock(&ar->conf_mutex);
4104
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304105 *tx_ant = ar->cfg_tx_chainmask;
4106 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03004107
4108 mutex_unlock(&ar->conf_mutex);
4109
4110 return 0;
4111}
4112
Ben Greear5572a952014-11-24 16:22:10 +02004113static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4114{
4115 /* It is not clear that allowing gaps in chainmask
4116 * is helpful. Probably it will not do what user
4117 * is hoping for, so warn in that case.
4118 */
4119 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4120 return;
4121
4122 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4123 dbg, cm);
4124}
4125
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304126static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4127{
4128 int nsts = ar->vht_cap_info;
4129
4130 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4131 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4132
4133 /* If firmware does not deliver to host number of space-time
4134 * streams supported, assume it support up to 4 BF STS and return
4135 * the value for VHT CAP: nsts-1)
4136 */
4137 if (nsts == 0)
4138 return 3;
4139
4140 return nsts;
4141}
4142
4143static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4144{
4145 int sound_dim = ar->vht_cap_info;
4146
4147 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4148 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4149
4150 /* If the sounding dimension is not advertised by the firmware,
4151 * let's use a default value of 1
4152 */
4153 if (sound_dim == 0)
4154 return 1;
4155
4156 return sound_dim;
4157}
4158
4159static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4160{
4161 struct ieee80211_sta_vht_cap vht_cap = {0};
4162 u16 mcs_map;
4163 u32 val;
4164 int i;
4165
4166 vht_cap.vht_supported = 1;
4167 vht_cap.cap = ar->vht_cap_info;
4168
4169 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4170 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4171 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4172 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4173 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4174
4175 vht_cap.cap |= val;
4176 }
4177
4178 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4179 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4180 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4181 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4182 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4183
4184 vht_cap.cap |= val;
4185 }
4186
4187 mcs_map = 0;
4188 for (i = 0; i < 8; i++) {
4189 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4190 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4191 else
4192 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4193 }
4194
4195 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4196 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4197
4198 return vht_cap;
4199}
4200
4201static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4202{
4203 int i;
4204 struct ieee80211_sta_ht_cap ht_cap = {0};
4205
4206 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4207 return ht_cap;
4208
4209 ht_cap.ht_supported = 1;
4210 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4211 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4212 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4213 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004214 ht_cap.cap |=
4215 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304216
4217 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4218 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4219
4220 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4221 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4222
4223 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4224 u32 smps;
4225
4226 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4227 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4228
4229 ht_cap.cap |= smps;
4230 }
4231
4232 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC)
4233 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4234
4235 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4236 u32 stbc;
4237
4238 stbc = ar->ht_cap_info;
4239 stbc &= WMI_HT_CAP_RX_STBC;
4240 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4241 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4242 stbc &= IEEE80211_HT_CAP_RX_STBC;
4243
4244 ht_cap.cap |= stbc;
4245 }
4246
4247 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
4248 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4249
4250 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4251 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4252
4253 /* max AMSDU is implicitly taken from vht_cap_info */
4254 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4255 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4256
4257 for (i = 0; i < ar->num_rf_chains; i++) {
4258 if (ar->cfg_rx_chainmask & BIT(i))
4259 ht_cap.mcs.rx_mask[i] = 0xFF;
4260 }
4261
4262 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4263
4264 return ht_cap;
4265}
4266
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304267static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4268{
4269 struct ieee80211_supported_band *band;
4270 struct ieee80211_sta_vht_cap vht_cap;
4271 struct ieee80211_sta_ht_cap ht_cap;
4272
4273 ht_cap = ath10k_get_ht_cap(ar);
4274 vht_cap = ath10k_create_vht_cap(ar);
4275
4276 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
4277 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
4278 band->ht_cap = ht_cap;
4279
4280 /* Enable the VHT support at 2.4 GHz */
4281 band->vht_cap = vht_cap;
4282 }
4283 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
4284 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
4285 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
4347 * uncoditionally. This is necessary to make sure no HTT/WMI tx
4348 * 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 Valo43d2a302014-09-10 18:23:30 +03004379 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
Michal Kazior818bdd12013-07-16 09:38:57 +02004380 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004381 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004382 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004383 }
4384
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304385 param = ar->wmi.pdev_param->pmf_qos;
4386 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004387 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004388 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004389 goto err_core_stop;
4390 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004391
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304392 param = ar->wmi.pdev_param->dynamic_bw;
4393 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004394 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004395 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004396 goto err_core_stop;
4397 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004398
Michal Kaziorcf327842015-03-31 10:26:25 +00004399 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4400 ret = ath10k_wmi_adaptive_qcs(ar, true);
4401 if (ret) {
4402 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4403 ret);
4404 goto err_core_stop;
4405 }
4406 }
4407
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004408 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304409 param = ar->wmi.pdev_param->burst_enable;
4410 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004411 if (ret) {
4412 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4413 goto err_core_stop;
4414 }
4415 }
4416
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304417 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7b2014-05-16 17:15:38 +03004418
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004419 /*
4420 * By default FW set ARP frames ac to voice (6). In that case ARP
4421 * exchange is not working properly for UAPSD enabled AP. ARP requests
4422 * which arrives with access category 0 are processed by network stack
4423 * and send back with access category 0, but FW changes access category
4424 * to 6. Set ARP frames access category to best effort (0) solves
4425 * this problem.
4426 */
4427
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304428 param = ar->wmi.pdev_param->arp_ac_override;
4429 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004430 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004431 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004432 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004433 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004434 }
4435
Maharaja62f77f02015-10-21 11:49:18 +03004436 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
4437 ar->fw_features)) {
4438 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4439 WMI_CCA_DETECT_LEVEL_AUTO,
4440 WMI_CCA_DETECT_MARGIN_AUTO);
4441 if (ret) {
4442 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4443 ret);
4444 goto err_core_stop;
4445 }
4446 }
4447
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304448 param = ar->wmi.pdev_param->ani_enable;
4449 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304450 if (ret) {
4451 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4452 ret);
4453 goto err_core_stop;
4454 }
4455
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304456 ar->ani_enabled = true;
4457
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304458 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304459 param = ar->wmi.pdev_param->peer_stats_update_period;
4460 ret = ath10k_wmi_pdev_set_param(ar, param,
4461 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4462 if (ret) {
4463 ath10k_warn(ar,
4464 "failed to set peer stats period : %d\n",
4465 ret);
4466 goto err_core_stop;
4467 }
4468 }
4469
Michal Kaziord6500972014-04-08 09:56:09 +03004470 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004471 ath10k_regd_update(ar);
4472
Simon Wunderlich855aed12014-08-02 09:12:54 +03004473 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304474 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004475
Michal Kaziorae254432014-05-26 12:46:02 +03004476 mutex_unlock(&ar->conf_mutex);
4477 return 0;
4478
4479err_core_stop:
4480 ath10k_core_stop(ar);
4481
4482err_power_down:
4483 ath10k_hif_power_down(ar);
4484
4485err_off:
4486 ar->state = ATH10K_STATE_OFF;
4487
4488err:
Michal Kazior548db542013-07-05 16:15:15 +03004489 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004490 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004491}
4492
4493static void ath10k_stop(struct ieee80211_hw *hw)
4494{
4495 struct ath10k *ar = hw->priv;
4496
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004497 ath10k_drain_tx(ar);
4498
Michal Kazior548db542013-07-05 16:15:15 +03004499 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004500 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004501 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004502 ar->state = ATH10K_STATE_OFF;
4503 }
Michal Kazior548db542013-07-05 16:15:15 +03004504 mutex_unlock(&ar->conf_mutex);
4505
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004506 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004507 cancel_work_sync(&ar->restart_work);
4508}
4509
Michal Kaziorad088bf2013-10-16 15:44:46 +03004510static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004511{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004512 struct ath10k_vif *arvif;
4513 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004514
4515 lockdep_assert_held(&ar->conf_mutex);
4516
Michal Kaziorad088bf2013-10-16 15:44:46 +03004517 list_for_each_entry(arvif, &ar->arvifs, list) {
4518 ret = ath10k_mac_vif_setup_ps(arvif);
4519 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004520 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004521 break;
4522 }
4523 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004524
Michal Kaziorad088bf2013-10-16 15:44:46 +03004525 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004526}
4527
Michal Kazior7d9d5582014-10-21 10:40:15 +03004528static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4529{
4530 int ret;
4531 u32 param;
4532
4533 lockdep_assert_held(&ar->conf_mutex);
4534
4535 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4536
4537 param = ar->wmi.pdev_param->txpower_limit2g;
4538 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4539 if (ret) {
4540 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4541 txpower, ret);
4542 return ret;
4543 }
4544
4545 param = ar->wmi.pdev_param->txpower_limit5g;
4546 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4547 if (ret) {
4548 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4549 txpower, ret);
4550 return ret;
4551 }
4552
4553 return 0;
4554}
4555
4556static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4557{
4558 struct ath10k_vif *arvif;
4559 int ret, txpower = -1;
4560
4561 lockdep_assert_held(&ar->conf_mutex);
4562
4563 list_for_each_entry(arvif, &ar->arvifs, list) {
4564 WARN_ON(arvif->txpower < 0);
4565
4566 if (txpower == -1)
4567 txpower = arvif->txpower;
4568 else
4569 txpower = min(txpower, arvif->txpower);
4570 }
4571
4572 if (WARN_ON(txpower == -1))
4573 return -EINVAL;
4574
4575 ret = ath10k_mac_txpower_setup(ar, txpower);
4576 if (ret) {
4577 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4578 txpower, ret);
4579 return ret;
4580 }
4581
4582 return 0;
4583}
4584
Kalle Valo5e3dd152013-06-12 20:52:10 +03004585static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4586{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004587 struct ath10k *ar = hw->priv;
4588 struct ieee80211_conf *conf = &hw->conf;
4589 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004590
4591 mutex_lock(&ar->conf_mutex);
4592
Michal Kazioraffd3212013-07-16 09:54:35 +02004593 if (changed & IEEE80211_CONF_CHANGE_PS)
4594 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004595
4596 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004597 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4598 ret = ath10k_monitor_recalc(ar);
4599 if (ret)
4600 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004601 }
4602
4603 mutex_unlock(&ar->conf_mutex);
4604 return ret;
4605}
4606
Ben Greear5572a952014-11-24 16:22:10 +02004607static u32 get_nss_from_chainmask(u16 chain_mask)
4608{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05304609 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02004610 return 4;
4611 else if ((chain_mask & 0x7) == 0x7)
4612 return 3;
4613 else if ((chain_mask & 0x3) == 0x3)
4614 return 2;
4615 return 1;
4616}
4617
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304618static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4619{
4620 u32 value = 0;
4621 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004622 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004623 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304624
4625 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4626 return 0;
4627
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004628 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304629 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4630 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004631 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304632
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004633 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304634 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4635 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004636 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304637
4638 if (!value)
4639 return 0;
4640
4641 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4642 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4643
4644 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4645 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4646 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4647
4648 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4649 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4650
4651 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4652 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4653 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4654
4655 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4656 ar->wmi.vdev_param->txbf, value);
4657}
4658
Kalle Valo5e3dd152013-06-12 20:52:10 +03004659/*
4660 * TODO:
4661 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4662 * because we will send mgmt frames without CCK. This requirement
4663 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4664 * in the TX packet.
4665 */
4666static int ath10k_add_interface(struct ieee80211_hw *hw,
4667 struct ieee80211_vif *vif)
4668{
4669 struct ath10k *ar = hw->priv;
4670 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004671 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004672 enum wmi_sta_powersave_param param;
4673 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004674 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004675 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004676 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004677 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004678
Johannes Berg848955c2014-11-11 12:48:42 +01004679 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4680
Kalle Valo5e3dd152013-06-12 20:52:10 +03004681 mutex_lock(&ar->conf_mutex);
4682
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004683 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02004684 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004685
Kalle Valo5e3dd152013-06-12 20:52:10 +03004686 arvif->ar = ar;
4687 arvif->vif = vif;
4688
Ben Greeare63b33f2013-10-22 14:54:14 -07004689 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004690 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004691 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4692 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004693
Michal Kazior45c9abc2015-04-21 20:42:58 +03004694 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4695 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4696 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4697 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4698 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4699 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4700 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004701
Michal Kaziore04cafb2015-08-05 12:15:24 +02004702 if (ar->num_peers >= ar->max_num_peers) {
4703 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004704 ret = -ENOBUFS;
4705 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004706 }
4707
Ben Greeara9aefb32014-08-12 11:02:19 +03004708 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004709 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004710 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03004711 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004712 }
Ben Greear16c11172014-09-23 14:17:16 -07004713 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004714
Ben Greear16c11172014-09-23 14:17:16 -07004715 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4716 bit, ar->free_vdev_map);
4717
4718 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004719 arvif->vdev_subtype =
4720 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004721
Kalle Valo5e3dd152013-06-12 20:52:10 +03004722 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004723 case NL80211_IFTYPE_P2P_DEVICE:
4724 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004725 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4726 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01004727 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004728 case NL80211_IFTYPE_UNSPECIFIED:
4729 case NL80211_IFTYPE_STATION:
4730 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4731 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004732 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4733 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004734 break;
4735 case NL80211_IFTYPE_ADHOC:
4736 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4737 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004738 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08004739 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08004740 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4741 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08004742 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004743 ret = -EINVAL;
4744 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
4745 goto err;
4746 }
4747 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4748 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004749 case NL80211_IFTYPE_AP:
4750 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4751
4752 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004753 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4754 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004755 break;
4756 case NL80211_IFTYPE_MONITOR:
4757 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4758 break;
4759 default:
4760 WARN_ON(1);
4761 break;
4762 }
4763
Michal Kazior96d828d2015-03-31 10:26:23 +00004764 /* Using vdev_id as queue number will make it very easy to do per-vif
4765 * tx queue locking. This shouldn't wrap due to interface combinations
4766 * but do a modulo for correctness sake and prevent using offchannel tx
4767 * queues for regular vif tx.
4768 */
4769 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4770 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4771 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4772
Michal Kazior64badcb2014-09-18 11:18:02 +03004773 /* Some firmware revisions don't wait for beacon tx completion before
4774 * sending another SWBA event. This could lead to hardware using old
4775 * (freed) beacon data in some cases, e.g. tx credit starvation
4776 * combined with missed TBTT. This is very very rare.
4777 *
4778 * On non-IOMMU-enabled hosts this could be a possible security issue
4779 * because hw could beacon some random data on the air. On
4780 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4781 * device would crash.
4782 *
4783 * Since there are no beacon tx completions (implicit nor explicit)
4784 * propagated to host the only workaround for this is to allocate a
4785 * DMA-coherent buffer for a lifetime of a vif and use it for all
4786 * beacon tx commands. Worst case for this approach is some beacons may
4787 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4788 */
4789 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004790 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03004791 vif->type == NL80211_IFTYPE_AP) {
4792 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4793 IEEE80211_MAX_FRAME_LEN,
4794 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304795 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004796 if (!arvif->beacon_buf) {
4797 ret = -ENOMEM;
4798 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4799 ret);
4800 goto err;
4801 }
4802 }
David Liuccec9032015-07-24 20:25:32 +03004803 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
4804 arvif->nohwcrypt = true;
4805
4806 if (arvif->nohwcrypt &&
4807 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4808 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
4809 goto err;
4810 }
Michal Kazior64badcb2014-09-18 11:18:02 +03004811
4812 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4813 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4814 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004815
4816 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4817 arvif->vdev_subtype, vif->addr);
4818 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004819 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004820 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004821 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004822 }
4823
Ben Greear16c11172014-09-23 14:17:16 -07004824 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Michal Kazior05791192013-10-16 15:44:45 +03004825 list_add(&arvif->list, &ar->arvifs);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004826
Michal Kazior46725b152015-01-28 09:57:49 +02004827 /* It makes no sense to have firmware do keepalives. mac80211 already
4828 * takes care of this with idle connection polling.
4829 */
4830 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004831 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02004832 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004833 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004834 goto err_vdev_delete;
4835 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004836
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004837 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004838
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004839 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4840 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004841 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004842 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03004843 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004844 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004845 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004846 goto err_vdev_delete;
4847 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004848
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05304849 /* Configuring number of spatial stream for monitor interface is causing
4850 * target assert in qca9888 and qca6174.
4851 */
4852 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02004853 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
4854
4855 vdev_param = ar->wmi.vdev_param->nss;
4856 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4857 nss);
4858 if (ret) {
4859 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
4860 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
4861 ret);
4862 goto err_vdev_delete;
4863 }
4864 }
4865
Michal Kaziore57e0572015-03-24 13:14:03 +00004866 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4867 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02004868 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
4869 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004870 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00004871 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004872 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004873 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004874 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004875
4876 spin_lock_bh(&ar->data_lock);
4877
4878 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
4879 if (!peer) {
4880 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
4881 vif->addr, arvif->vdev_id);
4882 spin_unlock_bh(&ar->data_lock);
4883 ret = -ENOENT;
4884 goto err_peer_delete;
4885 }
4886
4887 arvif->peer_id = find_first_bit(peer->peer_ids,
4888 ATH10K_MAX_NUM_PEER_IDS);
4889
4890 spin_unlock_bh(&ar->data_lock);
4891 } else {
4892 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00004893 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01004894
Michal Kaziore57e0572015-03-24 13:14:03 +00004895 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02004896 ret = ath10k_mac_set_kickout(arvif);
4897 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004898 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004899 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02004900 goto err_peer_delete;
4901 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004902 }
4903
4904 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
4905 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
4906 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
4907 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
4908 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004909 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004910 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004911 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004912 goto err_peer_delete;
4913 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004914
Michal Kazior9f9b5742014-12-12 12:41:36 +01004915 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004916 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004917 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004918 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004919 goto err_peer_delete;
4920 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004921
Michal Kazior9f9b5742014-12-12 12:41:36 +01004922 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004923 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004924 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004925 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004926 goto err_peer_delete;
4927 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004928 }
4929
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304930 ret = ath10k_mac_set_txbf_conf(arvif);
4931 if (ret) {
4932 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
4933 arvif->vdev_id, ret);
4934 goto err_peer_delete;
4935 }
4936
Michal Kazior424121c2013-07-22 14:13:31 +02004937 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004938 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004939 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03004940 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004941 goto err_peer_delete;
4942 }
Michal Kazior679c54a2013-07-05 16:15:04 +03004943
Michal Kazior7d9d5582014-10-21 10:40:15 +03004944 arvif->txpower = vif->bss_conf.txpower;
4945 ret = ath10k_mac_txpower_recalc(ar);
4946 if (ret) {
4947 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4948 goto err_peer_delete;
4949 }
4950
Michal Kazior500ff9f2015-03-31 10:26:21 +00004951 if (vif->type == NL80211_IFTYPE_MONITOR) {
4952 ar->monitor_arvif = arvif;
4953 ret = ath10k_monitor_recalc(ar);
4954 if (ret) {
4955 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
4956 goto err_peer_delete;
4957 }
4958 }
4959
Michal Kazior6d2d51e2015-08-07 09:08:21 +02004960 spin_lock_bh(&ar->htt.tx_lock);
4961 if (!ar->tx_paused)
4962 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
4963 spin_unlock_bh(&ar->htt.tx_lock);
4964
Kalle Valo5e3dd152013-06-12 20:52:10 +03004965 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004966 return 0;
4967
4968err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00004969 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4970 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14a2013-10-16 15:44:45 +03004971 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
4972
4973err_vdev_delete:
4974 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07004975 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03004976 list_del(&arvif->list);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004977
4978err:
Michal Kazior64badcb2014-09-18 11:18:02 +03004979 if (arvif->beacon_buf) {
4980 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
4981 arvif->beacon_buf, arvif->beacon_paddr);
4982 arvif->beacon_buf = NULL;
4983 }
4984
Michal Kazior9dad14a2013-10-16 15:44:45 +03004985 mutex_unlock(&ar->conf_mutex);
4986
Kalle Valo5e3dd152013-06-12 20:52:10 +03004987 return ret;
4988}
4989
Michal Kaziorb4aa5392015-03-31 10:26:24 +00004990static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
4991{
4992 int i;
4993
4994 for (i = 0; i < BITS_PER_LONG; i++)
4995 ath10k_mac_vif_tx_unlock(arvif, i);
4996}
4997
Kalle Valo5e3dd152013-06-12 20:52:10 +03004998static void ath10k_remove_interface(struct ieee80211_hw *hw,
4999 struct ieee80211_vif *vif)
5000{
5001 struct ath10k *ar = hw->priv;
5002 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior69427262016-03-06 16:14:30 +02005003 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005004 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005005 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005006
Michal Kazior81a9a172015-03-05 16:02:17 +02005007 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005008 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005009
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305010 mutex_lock(&ar->conf_mutex);
5011
Michal Kaziored543882013-09-13 14:16:56 +02005012 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03005013 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02005014 spin_unlock_bh(&ar->data_lock);
5015
Simon Wunderlich855aed12014-08-02 09:12:54 +03005016 ret = ath10k_spectral_vif_stop(arvif);
5017 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005018 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005019 arvif->vdev_id, ret);
5020
Ben Greear16c11172014-09-23 14:17:16 -07005021 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03005022 list_del(&arvif->list);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005023
Michal Kaziore57e0572015-03-24 13:14:03 +00005024 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5025 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005026 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5027 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005028 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005029 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005030 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005031
5032 kfree(arvif->u.ap.noa_data);
5033 }
5034
Michal Kazior7aa7a722014-08-25 12:09:38 +02005035 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005036 arvif->vdev_id);
5037
Kalle Valo5e3dd152013-06-12 20:52:10 +03005038 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5039 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005040 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005041 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005042
Michal Kazior2c512052015-02-15 16:50:40 +02005043 /* Some firmware revisions don't notify host about self-peer removal
5044 * until after associated vdev is deleted.
5045 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005046 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5047 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005048 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5049 vif->addr);
5050 if (ret)
5051 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5052 arvif->vdev_id, ret);
5053
5054 spin_lock_bh(&ar->data_lock);
5055 ar->num_peers--;
5056 spin_unlock_bh(&ar->data_lock);
5057 }
5058
Michal Kazior69427262016-03-06 16:14:30 +02005059 spin_lock_bh(&ar->data_lock);
5060 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5061 peer = ar->peer_map[i];
5062 if (!peer)
5063 continue;
5064
5065 if (peer->vif == vif) {
5066 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5067 vif->addr, arvif->vdev_id);
5068 peer->vif = NULL;
5069 }
5070 }
5071 spin_unlock_bh(&ar->data_lock);
5072
Kalle Valo5e3dd152013-06-12 20:52:10 +03005073 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005074 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005075
Michal Kazior500ff9f2015-03-31 10:26:21 +00005076 if (vif->type == NL80211_IFTYPE_MONITOR) {
5077 ar->monitor_arvif = NULL;
5078 ret = ath10k_monitor_recalc(ar);
5079 if (ret)
5080 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5081 }
5082
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005083 spin_lock_bh(&ar->htt.tx_lock);
5084 ath10k_mac_vif_tx_unlock_all(arvif);
5085 spin_unlock_bh(&ar->htt.tx_lock);
5086
Michal Kazior29946872016-03-06 16:14:34 +02005087 ath10k_mac_txq_unref(ar, vif->txq);
5088
Kalle Valo5e3dd152013-06-12 20:52:10 +03005089 mutex_unlock(&ar->conf_mutex);
5090}
5091
5092/*
5093 * FIXME: Has to be verified.
5094 */
5095#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005096 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005097 FIF_CONTROL | \
5098 FIF_PSPOLL | \
5099 FIF_OTHER_BSS | \
5100 FIF_BCN_PRBRESP_PROMISC | \
5101 FIF_PROBE_REQ | \
5102 FIF_FCSFAIL)
5103
5104static void ath10k_configure_filter(struct ieee80211_hw *hw,
5105 unsigned int changed_flags,
5106 unsigned int *total_flags,
5107 u64 multicast)
5108{
5109 struct ath10k *ar = hw->priv;
5110 int ret;
5111
5112 mutex_lock(&ar->conf_mutex);
5113
5114 changed_flags &= SUPPORTED_FILTERS;
5115 *total_flags &= SUPPORTED_FILTERS;
5116 ar->filter_flags = *total_flags;
5117
Michal Kazior19337472014-08-28 12:58:16 +02005118 ret = ath10k_monitor_recalc(ar);
5119 if (ret)
5120 ath10k_warn(ar, "failed to recalc montior: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005121
5122 mutex_unlock(&ar->conf_mutex);
5123}
5124
5125static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5126 struct ieee80211_vif *vif,
5127 struct ieee80211_bss_conf *info,
5128 u32 changed)
5129{
5130 struct ath10k *ar = hw->priv;
5131 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5132 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03005133 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005134
5135 mutex_lock(&ar->conf_mutex);
5136
5137 if (changed & BSS_CHANGED_IBSS)
5138 ath10k_control_ibss(arvif, info, vif->addr);
5139
5140 if (changed & BSS_CHANGED_BEACON_INT) {
5141 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005142 vdev_param = ar->wmi.vdev_param->beacon_interval;
5143 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005144 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005145 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005146 "mac vdev %d beacon_interval %d\n",
5147 arvif->vdev_id, arvif->beacon_interval);
5148
Kalle Valo5e3dd152013-06-12 20:52:10 +03005149 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005150 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005151 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005152 }
5153
5154 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005155 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005156 "vdev %d set beacon tx mode to staggered\n",
5157 arvif->vdev_id);
5158
Bartosz Markowski226a3392013-09-26 17:47:16 +02005159 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5160 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005161 WMI_BEACON_STAGGERED_MODE);
5162 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005163 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005164 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005165
5166 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5167 if (ret)
5168 ath10k_warn(ar, "failed to update beacon template: %d\n",
5169 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005170
5171 if (ieee80211_vif_is_mesh(vif)) {
5172 /* mesh doesn't use SSID but firmware needs it */
5173 strncpy(arvif->u.ap.ssid, "mesh",
5174 sizeof(arvif->u.ap.ssid));
5175 arvif->u.ap.ssid_len = 4;
5176 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005177 }
5178
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005179 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5180 ret = ath10k_mac_setup_prb_tmpl(arvif);
5181 if (ret)
5182 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5183 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005184 }
5185
Michal Kaziorba2479f2015-01-24 12:14:51 +02005186 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005187 arvif->dtim_period = info->dtim_period;
5188
Michal Kazior7aa7a722014-08-25 12:09:38 +02005189 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005190 "mac vdev %d dtim_period %d\n",
5191 arvif->vdev_id, arvif->dtim_period);
5192
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005193 vdev_param = ar->wmi.vdev_param->dtim_period;
5194 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005195 arvif->dtim_period);
5196 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005197 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005198 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005199 }
5200
5201 if (changed & BSS_CHANGED_SSID &&
5202 vif->type == NL80211_IFTYPE_AP) {
5203 arvif->u.ap.ssid_len = info->ssid_len;
5204 if (info->ssid_len)
5205 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5206 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5207 }
5208
Michal Kazior077efc82014-10-21 10:10:29 +03005209 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5210 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005211
5212 if (changed & BSS_CHANGED_BEACON_ENABLED)
5213 ath10k_control_beaconing(arvif, info);
5214
5215 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005216 arvif->use_cts_prot = info->use_cts_prot;
Michal Kazior7aa7a722014-08-25 12:09:38 +02005217 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005218 arvif->vdev_id, info->use_cts_prot);
Kalle Valo60c3daa2013-09-08 17:56:07 +03005219
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005220 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005221 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005222 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005223 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005224
5225 vdev_param = ar->wmi.vdev_param->protection_mode;
5226 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5227 info->use_cts_prot ? 1 : 0);
5228 if (ret)
5229 ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
Kalle Valo617b0f42015-10-05 17:56:35 +03005230 info->use_cts_prot, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005231 }
5232
5233 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005234 if (info->use_short_slot)
5235 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5236
5237 else
5238 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5239
Michal Kazior7aa7a722014-08-25 12:09:38 +02005240 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005241 arvif->vdev_id, slottime);
5242
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005243 vdev_param = ar->wmi.vdev_param->slot_time;
5244 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005245 slottime);
5246 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005247 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005248 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005249 }
5250
5251 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005252 if (info->use_short_preamble)
5253 preamble = WMI_VDEV_PREAMBLE_SHORT;
5254 else
5255 preamble = WMI_VDEV_PREAMBLE_LONG;
5256
Michal Kazior7aa7a722014-08-25 12:09:38 +02005257 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005258 "mac vdev %d preamble %dn",
5259 arvif->vdev_id, preamble);
5260
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005261 vdev_param = ar->wmi.vdev_param->preamble;
5262 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005263 preamble);
5264 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005265 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005266 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005267 }
5268
5269 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005270 if (info->assoc) {
5271 /* Workaround: Make sure monitor vdev is not running
5272 * when associating to prevent some firmware revisions
5273 * (e.g. 10.1 and 10.2) from crashing.
5274 */
5275 if (ar->monitor_started)
5276 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005277 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005278 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005279 } else {
5280 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005281 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005282 }
5283
Michal Kazior7d9d5582014-10-21 10:40:15 +03005284 if (changed & BSS_CHANGED_TXPOWER) {
5285 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5286 arvif->vdev_id, info->txpower);
5287
5288 arvif->txpower = info->txpower;
5289 ret = ath10k_mac_txpower_recalc(ar);
5290 if (ret)
5291 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5292 }
5293
Michal Kaziorbf14e652014-12-12 12:41:38 +01005294 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005295 arvif->ps = vif->bss_conf.ps;
5296
5297 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005298 if (ret)
5299 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5300 arvif->vdev_id, ret);
5301 }
5302
Kalle Valo5e3dd152013-06-12 20:52:10 +03005303 mutex_unlock(&ar->conf_mutex);
5304}
5305
5306static int ath10k_hw_scan(struct ieee80211_hw *hw,
5307 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005308 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005309{
5310 struct ath10k *ar = hw->priv;
5311 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02005312 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005313 struct wmi_start_scan_arg arg;
5314 int ret = 0;
5315 int i;
5316
5317 mutex_lock(&ar->conf_mutex);
5318
5319 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005320 switch (ar->scan.state) {
5321 case ATH10K_SCAN_IDLE:
5322 reinit_completion(&ar->scan.started);
5323 reinit_completion(&ar->scan.completed);
5324 ar->scan.state = ATH10K_SCAN_STARTING;
5325 ar->scan.is_roc = false;
5326 ar->scan.vdev_id = arvif->vdev_id;
5327 ret = 0;
5328 break;
5329 case ATH10K_SCAN_STARTING:
5330 case ATH10K_SCAN_RUNNING:
5331 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005332 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005333 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005334 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005335 spin_unlock_bh(&ar->data_lock);
5336
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005337 if (ret)
5338 goto exit;
5339
Kalle Valo5e3dd152013-06-12 20:52:10 +03005340 memset(&arg, 0, sizeof(arg));
5341 ath10k_wmi_start_scan_init(ar, &arg);
5342 arg.vdev_id = arvif->vdev_id;
5343 arg.scan_id = ATH10K_SCAN_ID;
5344
Kalle Valo5e3dd152013-06-12 20:52:10 +03005345 if (req->ie_len) {
5346 arg.ie_len = req->ie_len;
5347 memcpy(arg.ie, req->ie, arg.ie_len);
5348 }
5349
5350 if (req->n_ssids) {
5351 arg.n_ssids = req->n_ssids;
5352 for (i = 0; i < arg.n_ssids; i++) {
5353 arg.ssids[i].len = req->ssids[i].ssid_len;
5354 arg.ssids[i].ssid = req->ssids[i].ssid;
5355 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005356 } else {
5357 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005358 }
5359
5360 if (req->n_channels) {
5361 arg.n_channels = req->n_channels;
5362 for (i = 0; i < arg.n_channels; i++)
5363 arg.channels[i] = req->channels[i]->center_freq;
5364 }
5365
5366 ret = ath10k_start_scan(ar, &arg);
5367 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005368 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005369 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005370 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005371 spin_unlock_bh(&ar->data_lock);
5372 }
5373
Michal Kazior634349b2015-09-03 10:43:45 +02005374 /* Add a 200ms margin to account for event/command processing */
5375 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5376 msecs_to_jiffies(arg.max_scan_time +
5377 200));
5378
Kalle Valo5e3dd152013-06-12 20:52:10 +03005379exit:
5380 mutex_unlock(&ar->conf_mutex);
5381 return ret;
5382}
5383
5384static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5385 struct ieee80211_vif *vif)
5386{
5387 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005388
5389 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005390 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005391 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01005392
5393 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005394}
5395
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005396static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
5397 struct ath10k_vif *arvif,
5398 enum set_key_cmd cmd,
5399 struct ieee80211_key_conf *key)
5400{
5401 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
5402 int ret;
5403
5404 /* 10.1 firmware branch requires default key index to be set to group
5405 * key index after installing it. Otherwise FW/HW Txes corrupted
5406 * frames with multi-vif APs. This is not required for main firmware
5407 * branch (e.g. 636).
5408 *
Michal Kazior8461baf2015-04-10 13:23:22 +00005409 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
5410 *
5411 * FIXME: It remains unknown if this is required for multi-vif STA
5412 * interfaces on 10.1.
5413 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005414
Michal Kazior8461baf2015-04-10 13:23:22 +00005415 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
5416 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005417 return;
5418
5419 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
5420 return;
5421
5422 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
5423 return;
5424
5425 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5426 return;
5427
5428 if (cmd != SET_KEY)
5429 return;
5430
5431 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5432 key->keyidx);
5433 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005434 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005435 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005436}
5437
Kalle Valo5e3dd152013-06-12 20:52:10 +03005438static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5439 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5440 struct ieee80211_key_conf *key)
5441{
5442 struct ath10k *ar = hw->priv;
5443 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5444 struct ath10k_peer *peer;
5445 const u8 *peer_addr;
5446 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5447 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5448 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005449 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005450 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005451 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005452
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005453 /* this one needs to be done in software */
5454 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
5455 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005456
David Liuccec9032015-07-24 20:25:32 +03005457 if (arvif->nohwcrypt)
5458 return 1;
5459
Kalle Valo5e3dd152013-06-12 20:52:10 +03005460 if (key->keyidx > WMI_MAX_KEY_INDEX)
5461 return -ENOSPC;
5462
5463 mutex_lock(&ar->conf_mutex);
5464
5465 if (sta)
5466 peer_addr = sta->addr;
5467 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5468 peer_addr = vif->bss_conf.bssid;
5469 else
5470 peer_addr = vif->addr;
5471
5472 key->hw_key_idx = key->keyidx;
5473
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005474 if (is_wep) {
5475 if (cmd == SET_KEY)
5476 arvif->wep_keys[key->keyidx] = key;
5477 else
5478 arvif->wep_keys[key->keyidx] = NULL;
5479 }
5480
Kalle Valo5e3dd152013-06-12 20:52:10 +03005481 /* the peer should not disappear in mid-way (unless FW goes awry) since
5482 * we already hold conf_mutex. we just make sure its there now. */
5483 spin_lock_bh(&ar->data_lock);
5484 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5485 spin_unlock_bh(&ar->data_lock);
5486
5487 if (!peer) {
5488 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005489 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005490 peer_addr);
5491 ret = -EOPNOTSUPP;
5492 goto exit;
5493 } else {
5494 /* if the peer doesn't exist there is no key to disable
5495 * anymore */
5496 goto exit;
5497 }
5498 }
5499
Michal Kazior7cc45732015-03-09 14:24:17 +01005500 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5501 flags |= WMI_KEY_PAIRWISE;
5502 else
5503 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005504
Kalle Valo5e3dd152013-06-12 20:52:10 +03005505 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005506 if (cmd == DISABLE_KEY)
5507 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005508
Michal Kaziorad325cb2015-02-18 14:02:27 +01005509 /* When WEP keys are uploaded it's possible that there are
5510 * stations associated already (e.g. when merging) without any
5511 * keys. Static WEP needs an explicit per-peer key upload.
5512 */
5513 if (vif->type == NL80211_IFTYPE_ADHOC &&
5514 cmd == SET_KEY)
5515 ath10k_mac_vif_update_wep_key(arvif, key);
5516
Michal Kazior370e5672015-02-18 14:02:26 +01005517 /* 802.1x never sets the def_wep_key_idx so each set_key()
5518 * call changes default tx key.
5519 *
5520 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5521 * after first set_key().
5522 */
5523 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5524 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005525 }
5526
Michal Kazior370e5672015-02-18 14:02:26 +01005527 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005528 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005529 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005530 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005531 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005532 goto exit;
5533 }
5534
Michal Kazior29a10002015-04-10 13:05:58 +00005535 /* mac80211 sets static WEP keys as groupwise while firmware requires
5536 * them to be installed twice as both pairwise and groupwise.
5537 */
5538 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5539 flags2 = flags;
5540 flags2 &= ~WMI_KEY_GROUP;
5541 flags2 |= WMI_KEY_PAIRWISE;
5542
5543 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5544 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005545 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005546 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5547 arvif->vdev_id, peer_addr, ret);
5548 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5549 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005550 if (ret2) {
5551 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005552 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5553 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005554 }
Michal Kazior29a10002015-04-10 13:05:58 +00005555 goto exit;
5556 }
5557 }
5558
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005559 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5560
Kalle Valo5e3dd152013-06-12 20:52:10 +03005561 spin_lock_bh(&ar->data_lock);
5562 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5563 if (peer && cmd == SET_KEY)
5564 peer->keys[key->keyidx] = key;
5565 else if (peer && cmd == DISABLE_KEY)
5566 peer->keys[key->keyidx] = NULL;
5567 else if (peer == NULL)
5568 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005569 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005570 spin_unlock_bh(&ar->data_lock);
5571
5572exit:
5573 mutex_unlock(&ar->conf_mutex);
5574 return ret;
5575}
5576
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005577static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5578 struct ieee80211_vif *vif,
5579 int keyidx)
5580{
5581 struct ath10k *ar = hw->priv;
5582 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5583 int ret;
5584
5585 mutex_lock(&arvif->ar->conf_mutex);
5586
5587 if (arvif->ar->state != ATH10K_STATE_ON)
5588 goto unlock;
5589
5590 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5591 arvif->vdev_id, keyidx);
5592
5593 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5594 arvif->vdev_id,
5595 arvif->ar->wmi.vdev_param->def_keyid,
5596 keyidx);
5597
5598 if (ret) {
5599 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5600 arvif->vdev_id,
5601 ret);
5602 goto unlock;
5603 }
5604
5605 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005606
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005607unlock:
5608 mutex_unlock(&arvif->ar->conf_mutex);
5609}
5610
Michal Kazior9797feb2014-02-14 14:49:48 +01005611static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5612{
5613 struct ath10k *ar;
5614 struct ath10k_vif *arvif;
5615 struct ath10k_sta *arsta;
5616 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005617 struct cfg80211_chan_def def;
5618 enum ieee80211_band band;
5619 const u8 *ht_mcs_mask;
5620 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005621 u32 changed, bw, nss, smps;
5622 int err;
5623
5624 arsta = container_of(wk, struct ath10k_sta, update_wk);
5625 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5626 arvif = arsta->arvif;
5627 ar = arvif->ar;
5628
Michal Kazior45c9abc2015-04-21 20:42:58 +03005629 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5630 return;
5631
5632 band = def.chan->band;
5633 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5634 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5635
Michal Kazior9797feb2014-02-14 14:49:48 +01005636 spin_lock_bh(&ar->data_lock);
5637
5638 changed = arsta->changed;
5639 arsta->changed = 0;
5640
5641 bw = arsta->bw;
5642 nss = arsta->nss;
5643 smps = arsta->smps;
5644
5645 spin_unlock_bh(&ar->data_lock);
5646
5647 mutex_lock(&ar->conf_mutex);
5648
Michal Kazior45c9abc2015-04-21 20:42:58 +03005649 nss = max_t(u32, 1, nss);
5650 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
5651 ath10k_mac_max_vht_nss(vht_mcs_mask)));
5652
Michal Kazior9797feb2014-02-14 14:49:48 +01005653 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005654 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005655 sta->addr, bw);
5656
5657 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5658 WMI_PEER_CHAN_WIDTH, bw);
5659 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005660 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005661 sta->addr, bw, err);
5662 }
5663
5664 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005665 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005666 sta->addr, nss);
5667
5668 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5669 WMI_PEER_NSS, nss);
5670 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005671 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005672 sta->addr, nss, err);
5673 }
5674
5675 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005676 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005677 sta->addr, smps);
5678
5679 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5680 WMI_PEER_SMPS_STATE, smps);
5681 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005682 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005683 sta->addr, smps, err);
5684 }
5685
Janusz Dziedzic55884c02014-12-17 12:30:02 +02005686 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
5687 changed & IEEE80211_RC_NSS_CHANGED) {
5688 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005689 sta->addr);
5690
Michal Kazior590922a2014-10-21 10:10:29 +03005691 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005692 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005693 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005694 sta->addr);
5695 }
5696
Michal Kazior9797feb2014-02-14 14:49:48 +01005697 mutex_unlock(&ar->conf_mutex);
5698}
5699
Marek Puzyniak7c354242015-03-30 09:51:52 +03005700static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
5701 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005702{
5703 struct ath10k *ar = arvif->ar;
5704
5705 lockdep_assert_held(&ar->conf_mutex);
5706
Marek Puzyniak7c354242015-03-30 09:51:52 +03005707 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005708 return 0;
5709
5710 if (ar->num_stations >= ar->max_num_stations)
5711 return -ENOBUFS;
5712
5713 ar->num_stations++;
5714
5715 return 0;
5716}
5717
Marek Puzyniak7c354242015-03-30 09:51:52 +03005718static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
5719 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005720{
5721 struct ath10k *ar = arvif->ar;
5722
5723 lockdep_assert_held(&ar->conf_mutex);
5724
Marek Puzyniak7c354242015-03-30 09:51:52 +03005725 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005726 return;
5727
5728 ar->num_stations--;
5729}
5730
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005731struct ath10k_mac_tdls_iter_data {
5732 u32 num_tdls_stations;
5733 struct ieee80211_vif *curr_vif;
5734};
5735
5736static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5737 struct ieee80211_sta *sta)
5738{
5739 struct ath10k_mac_tdls_iter_data *iter_data = data;
5740 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5741 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5742
5743 if (sta->tdls && sta_vif == iter_data->curr_vif)
5744 iter_data->num_tdls_stations++;
5745}
5746
5747static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5748 struct ieee80211_vif *vif)
5749{
5750 struct ath10k_mac_tdls_iter_data data = {};
5751
5752 data.curr_vif = vif;
5753
5754 ieee80211_iterate_stations_atomic(hw,
5755 ath10k_mac_tdls_vif_stations_count_iter,
5756 &data);
5757 return data.num_tdls_stations;
5758}
5759
5760static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5761 struct ieee80211_vif *vif)
5762{
5763 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5764 int *num_tdls_vifs = data;
5765
5766 if (vif->type != NL80211_IFTYPE_STATION)
5767 return;
5768
5769 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5770 (*num_tdls_vifs)++;
5771}
5772
5773static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5774{
5775 int num_tdls_vifs = 0;
5776
5777 ieee80211_iterate_active_interfaces_atomic(hw,
5778 IEEE80211_IFACE_ITER_NORMAL,
5779 ath10k_mac_tdls_vifs_count_iter,
5780 &num_tdls_vifs);
5781 return num_tdls_vifs;
5782}
5783
Kalle Valo5e3dd152013-06-12 20:52:10 +03005784static int ath10k_sta_state(struct ieee80211_hw *hw,
5785 struct ieee80211_vif *vif,
5786 struct ieee80211_sta *sta,
5787 enum ieee80211_sta_state old_state,
5788 enum ieee80211_sta_state new_state)
5789{
5790 struct ath10k *ar = hw->priv;
5791 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005792 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005793 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005794 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02005795 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005796
Michal Kazior76f90022014-02-25 09:29:57 +02005797 if (old_state == IEEE80211_STA_NOTEXIST &&
5798 new_state == IEEE80211_STA_NONE) {
5799 memset(arsta, 0, sizeof(*arsta));
5800 arsta->arvif = arvif;
5801 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02005802
5803 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5804 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02005805 }
5806
Michal Kazior9797feb2014-02-14 14:49:48 +01005807 /* cancel must be done outside the mutex to avoid deadlock */
5808 if ((old_state == IEEE80211_STA_NONE &&
5809 new_state == IEEE80211_STA_NOTEXIST))
5810 cancel_work_sync(&arsta->update_wk);
5811
Kalle Valo5e3dd152013-06-12 20:52:10 +03005812 mutex_lock(&ar->conf_mutex);
5813
5814 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005815 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005816 /*
5817 * New station addition.
5818 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005819 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5820 u32 num_tdls_stations;
5821 u32 num_tdls_vifs;
5822
Michal Kaziorcfd10612014-11-25 15:16:05 +01005823 ath10k_dbg(ar, ATH10K_DBG_MAC,
5824 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5825 arvif->vdev_id, sta->addr,
5826 ar->num_stations + 1, ar->max_num_stations,
5827 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005828
Marek Puzyniak7c354242015-03-30 09:51:52 +03005829 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005830 if (ret) {
5831 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5832 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005833 goto exit;
5834 }
5835
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005836 if (sta->tdls)
5837 peer_type = WMI_PEER_TYPE_TDLS;
5838
Michal Kazior69427262016-03-06 16:14:30 +02005839 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
5840 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005841 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005842 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 -08005843 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005844 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005845 goto exit;
5846 }
Michal Kazior077efc82014-10-21 10:10:29 +03005847
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005848 spin_lock_bh(&ar->data_lock);
5849
5850 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
5851 if (!peer) {
5852 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5853 vif->addr, arvif->vdev_id);
5854 spin_unlock_bh(&ar->data_lock);
5855 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5856 ath10k_mac_dec_num_stations(arvif, sta);
5857 ret = -ENOENT;
5858 goto exit;
5859 }
5860
5861 arsta->peer_id = find_first_bit(peer->peer_ids,
5862 ATH10K_MAX_NUM_PEER_IDS);
5863
5864 spin_unlock_bh(&ar->data_lock);
5865
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005866 if (!sta->tdls)
5867 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03005868
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005869 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
5870 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
5871
5872 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
5873 num_tdls_stations == 0) {
5874 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
5875 arvif->vdev_id, ar->max_num_tdls_vdevs);
5876 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5877 ath10k_mac_dec_num_stations(arvif, sta);
5878 ret = -ENOBUFS;
5879 goto exit;
5880 }
5881
5882 if (num_tdls_stations == 0) {
5883 /* This is the first tdls peer in current vif */
5884 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
5885
5886 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5887 state);
Michal Kazior077efc82014-10-21 10:10:29 +03005888 if (ret) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005889 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
Michal Kazior077efc82014-10-21 10:10:29 +03005890 arvif->vdev_id, ret);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005891 ath10k_peer_delete(ar, arvif->vdev_id,
5892 sta->addr);
5893 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03005894 goto exit;
5895 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005896 }
Michal Kazior077efc82014-10-21 10:10:29 +03005897
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005898 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5899 WMI_TDLS_PEER_STATE_PEERING);
5900 if (ret) {
5901 ath10k_warn(ar,
5902 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
5903 sta->addr, arvif->vdev_id, ret);
5904 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5905 ath10k_mac_dec_num_stations(arvif, sta);
5906
5907 if (num_tdls_stations != 0)
5908 goto exit;
5909 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5910 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03005911 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005912 } else if ((old_state == IEEE80211_STA_NONE &&
5913 new_state == IEEE80211_STA_NOTEXIST)) {
5914 /*
5915 * Existing station deletion.
5916 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005917 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005918 "mac vdev %d peer delete %pM (sta gone)\n",
5919 arvif->vdev_id, sta->addr);
Michal Kazior077efc82014-10-21 10:10:29 +03005920
Kalle Valo5e3dd152013-06-12 20:52:10 +03005921 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5922 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005923 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005924 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005925
Marek Puzyniak7c354242015-03-30 09:51:52 +03005926 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005927
Michal Kazior69427262016-03-06 16:14:30 +02005928 spin_lock_bh(&ar->data_lock);
5929 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5930 peer = ar->peer_map[i];
5931 if (!peer)
5932 continue;
5933
5934 if (peer->sta == sta) {
5935 ath10k_warn(ar, "found sta peer %pM entry on vdev %i after it was supposedly removed\n",
5936 sta->addr, arvif->vdev_id);
5937 peer->sta = NULL;
5938 }
5939 }
5940 spin_unlock_bh(&ar->data_lock);
5941
Michal Kazior29946872016-03-06 16:14:34 +02005942 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5943 ath10k_mac_txq_unref(ar, sta->txq[i]);
5944
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005945 if (!sta->tdls)
5946 goto exit;
5947
5948 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
5949 goto exit;
5950
5951 /* This was the last tdls peer in current vif */
5952 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5953 WMI_TDLS_DISABLE);
5954 if (ret) {
5955 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
5956 arvif->vdev_id, ret);
5957 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005958 } else if (old_state == IEEE80211_STA_AUTH &&
5959 new_state == IEEE80211_STA_ASSOC &&
5960 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005961 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03005962 vif->type == NL80211_IFTYPE_ADHOC)) {
5963 /*
5964 * New association.
5965 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005966 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005967 sta->addr);
5968
Michal Kazior590922a2014-10-21 10:10:29 +03005969 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005970 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005971 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005972 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005973 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005974 new_state == IEEE80211_STA_AUTHORIZED &&
5975 sta->tdls) {
5976 /*
5977 * Tdls station authorized.
5978 */
5979 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
5980 sta->addr);
5981
5982 ret = ath10k_station_assoc(ar, vif, sta, false);
5983 if (ret) {
5984 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
5985 sta->addr, arvif->vdev_id, ret);
5986 goto exit;
5987 }
5988
5989 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5990 WMI_TDLS_PEER_STATE_CONNECTED);
5991 if (ret)
5992 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
5993 sta->addr, arvif->vdev_id, ret);
5994 } else if (old_state == IEEE80211_STA_ASSOC &&
5995 new_state == IEEE80211_STA_AUTH &&
5996 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005997 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005998 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005999 /*
6000 * Disassociation.
6001 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006002 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006003 sta->addr);
6004
Michal Kazior590922a2014-10-21 10:10:29 +03006005 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006006 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006007 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006008 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006009 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006010exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006011 mutex_unlock(&ar->conf_mutex);
6012 return ret;
6013}
6014
6015static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006016 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006017{
6018 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02006019 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6020 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006021 u32 value = 0;
6022 int ret = 0;
6023
Michal Kazior548db542013-07-05 16:15:15 +03006024 lockdep_assert_held(&ar->conf_mutex);
6025
Kalle Valo5e3dd152013-06-12 20:52:10 +03006026 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6027 return 0;
6028
6029 switch (ac) {
6030 case IEEE80211_AC_VO:
6031 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6032 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006033 prio = 7;
6034 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006035 break;
6036 case IEEE80211_AC_VI:
6037 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6038 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006039 prio = 5;
6040 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006041 break;
6042 case IEEE80211_AC_BE:
6043 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6044 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006045 prio = 2;
6046 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006047 break;
6048 case IEEE80211_AC_BK:
6049 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6050 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006051 prio = 0;
6052 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006053 break;
6054 }
6055
6056 if (enable)
6057 arvif->u.sta.uapsd |= value;
6058 else
6059 arvif->u.sta.uapsd &= ~value;
6060
6061 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6062 WMI_STA_PS_PARAM_UAPSD,
6063 arvif->u.sta.uapsd);
6064 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006065 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006066 goto exit;
6067 }
6068
6069 if (arvif->u.sta.uapsd)
6070 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6071 else
6072 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6073
6074 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6075 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6076 value);
6077 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006078 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006079
Michal Kazior9f9b5742014-12-12 12:41:36 +01006080 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6081 if (ret) {
6082 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6083 arvif->vdev_id, ret);
6084 return ret;
6085 }
6086
6087 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6088 if (ret) {
6089 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6090 arvif->vdev_id, ret);
6091 return ret;
6092 }
6093
Michal Kaziorb0e56152015-01-24 12:14:52 +02006094 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6095 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6096 /* Only userspace can make an educated decision when to send
6097 * trigger frame. The following effectively disables u-UAPSD
6098 * autotrigger in firmware (which is enabled by default
6099 * provided the autotrigger service is available).
6100 */
6101
6102 arg.wmm_ac = acc;
6103 arg.user_priority = prio;
6104 arg.service_interval = 0;
6105 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6106 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6107
6108 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6109 arvif->bssid, &arg, 1);
6110 if (ret) {
6111 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6112 ret);
6113 return ret;
6114 }
6115 }
6116
Kalle Valo5e3dd152013-06-12 20:52:10 +03006117exit:
6118 return ret;
6119}
6120
6121static int ath10k_conf_tx(struct ieee80211_hw *hw,
6122 struct ieee80211_vif *vif, u16 ac,
6123 const struct ieee80211_tx_queue_params *params)
6124{
6125 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01006126 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006127 struct wmi_wmm_params_arg *p = NULL;
6128 int ret;
6129
6130 mutex_lock(&ar->conf_mutex);
6131
6132 switch (ac) {
6133 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006134 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006135 break;
6136 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006137 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006138 break;
6139 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006140 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006141 break;
6142 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006143 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006144 break;
6145 }
6146
6147 if (WARN_ON(!p)) {
6148 ret = -EINVAL;
6149 goto exit;
6150 }
6151
6152 p->cwmin = params->cw_min;
6153 p->cwmax = params->cw_max;
6154 p->aifs = params->aifs;
6155
6156 /*
6157 * The channel time duration programmed in the HW is in absolute
6158 * microseconds, while mac80211 gives the txop in units of
6159 * 32 microseconds.
6160 */
6161 p->txop = params->txop * 32;
6162
Michal Kazior7fc979a2015-01-28 09:57:28 +02006163 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6164 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6165 &arvif->wmm_params);
6166 if (ret) {
6167 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6168 arvif->vdev_id, ret);
6169 goto exit;
6170 }
6171 } else {
6172 /* This won't work well with multi-interface cases but it's
6173 * better than nothing.
6174 */
6175 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6176 if (ret) {
6177 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6178 goto exit;
6179 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006180 }
6181
6182 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6183 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006184 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006185
6186exit:
6187 mutex_unlock(&ar->conf_mutex);
6188 return ret;
6189}
6190
Kalle Valo14e105c2016-04-13 14:13:21 +03006191#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006192
6193static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6194 struct ieee80211_vif *vif,
6195 struct ieee80211_channel *chan,
6196 int duration,
6197 enum ieee80211_roc_type type)
6198{
6199 struct ath10k *ar = hw->priv;
6200 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6201 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006202 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006203 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006204
6205 mutex_lock(&ar->conf_mutex);
6206
6207 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006208 switch (ar->scan.state) {
6209 case ATH10K_SCAN_IDLE:
6210 reinit_completion(&ar->scan.started);
6211 reinit_completion(&ar->scan.completed);
6212 reinit_completion(&ar->scan.on_channel);
6213 ar->scan.state = ATH10K_SCAN_STARTING;
6214 ar->scan.is_roc = true;
6215 ar->scan.vdev_id = arvif->vdev_id;
6216 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006217 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006218 ret = 0;
6219 break;
6220 case ATH10K_SCAN_STARTING:
6221 case ATH10K_SCAN_RUNNING:
6222 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006223 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006224 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006225 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006226 spin_unlock_bh(&ar->data_lock);
6227
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006228 if (ret)
6229 goto exit;
6230
Michal Kaziorfcf98442015-03-31 11:03:47 +00006231 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006232
Kalle Valo5e3dd152013-06-12 20:52:10 +03006233 memset(&arg, 0, sizeof(arg));
6234 ath10k_wmi_start_scan_init(ar, &arg);
6235 arg.vdev_id = arvif->vdev_id;
6236 arg.scan_id = ATH10K_SCAN_ID;
6237 arg.n_channels = 1;
6238 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006239 arg.dwell_time_active = scan_time_msec;
6240 arg.dwell_time_passive = scan_time_msec;
6241 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006242 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6243 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006244 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006245
6246 ret = ath10k_start_scan(ar, &arg);
6247 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006248 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006249 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006250 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006251 spin_unlock_bh(&ar->data_lock);
6252 goto exit;
6253 }
6254
Kalle Valo14e105c2016-04-13 14:13:21 +03006255 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006256 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006257 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006258
6259 ret = ath10k_scan_stop(ar);
6260 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006261 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006262
Kalle Valo5e3dd152013-06-12 20:52:10 +03006263 ret = -ETIMEDOUT;
6264 goto exit;
6265 }
6266
Michal Kaziorfcf98442015-03-31 11:03:47 +00006267 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6268 msecs_to_jiffies(duration));
6269
Kalle Valo5e3dd152013-06-12 20:52:10 +03006270 ret = 0;
6271exit:
6272 mutex_unlock(&ar->conf_mutex);
6273 return ret;
6274}
6275
6276static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6277{
6278 struct ath10k *ar = hw->priv;
6279
6280 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006281
6282 spin_lock_bh(&ar->data_lock);
6283 ar->scan.roc_notify = false;
6284 spin_unlock_bh(&ar->data_lock);
6285
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006286 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006287
Kalle Valo5e3dd152013-06-12 20:52:10 +03006288 mutex_unlock(&ar->conf_mutex);
6289
Michal Kazior4eb2e162014-10-28 10:23:09 +01006290 cancel_delayed_work_sync(&ar->scan.timeout);
6291
Kalle Valo5e3dd152013-06-12 20:52:10 +03006292 return 0;
6293}
6294
6295/*
6296 * Both RTS and Fragmentation threshold are interface-specific
6297 * in ath10k, but device-specific in mac80211.
6298 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006299
6300static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6301{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006302 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006303 struct ath10k_vif *arvif;
6304 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006305
Michal Kaziorad088bf2013-10-16 15:44:46 +03006306 mutex_lock(&ar->conf_mutex);
6307 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006308 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006309 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006310
Michal Kaziorad088bf2013-10-16 15:44:46 +03006311 ret = ath10k_mac_set_rts(arvif, value);
6312 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006313 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006314 arvif->vdev_id, ret);
6315 break;
6316 }
6317 }
6318 mutex_unlock(&ar->conf_mutex);
6319
6320 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006321}
6322
Michal Kazior92092fe2015-08-03 11:16:43 +02006323static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6324{
6325 /* Even though there's a WMI enum for fragmentation threshold no known
6326 * firmware actually implements it. Moreover it is not possible to rely
6327 * frame fragmentation to mac80211 because firmware clears the "more
6328 * fragments" bit in frame control making it impossible for remote
6329 * devices to reassemble frames.
6330 *
6331 * Hence implement a dummy callback just to say fragmentation isn't
6332 * supported. This effectively prevents mac80211 from doing frame
6333 * fragmentation in software.
6334 */
6335 return -EOPNOTSUPP;
6336}
6337
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02006338static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6339 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006340{
6341 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02006342 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006343 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006344
6345 /* mac80211 doesn't care if we really xmit queued frames or not
6346 * we'll collect those frames either way if we stop/delete vdevs */
6347 if (drop)
6348 return;
6349
Michal Kazior548db542013-07-05 16:15:15 +03006350 mutex_lock(&ar->conf_mutex);
6351
Michal Kazioraffd3212013-07-16 09:54:35 +02006352 if (ar->state == ATH10K_STATE_WEDGED)
6353 goto skip;
6354
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006355 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006356 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006357
Michal Kazioredb82362013-07-05 16:15:14 +03006358 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006359 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006360 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006361
Michal Kazior7962b0d2014-10-28 10:34:38 +01006362 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6363 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6364 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006365
6366 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006367 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006368
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006369 if (time_left == 0 || skip)
6370 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6371 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03006372
Michal Kazioraffd3212013-07-16 09:54:35 +02006373skip:
Michal Kazior548db542013-07-05 16:15:15 +03006374 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006375}
6376
6377/* TODO: Implement this function properly
6378 * For now it is needed to reply to Probe Requests in IBSS mode.
6379 * Propably we need this information from FW.
6380 */
6381static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
6382{
6383 return 1;
6384}
6385
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006386static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
6387 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02006388{
6389 struct ath10k *ar = hw->priv;
6390
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006391 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
6392 return;
6393
Michal Kazioraffd3212013-07-16 09:54:35 +02006394 mutex_lock(&ar->conf_mutex);
6395
6396 /* If device failed to restart it will be in a different state, e.g.
6397 * ATH10K_STATE_WEDGED */
6398 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006399 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02006400 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01006401 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02006402 }
6403
6404 mutex_unlock(&ar->conf_mutex);
6405}
6406
Michal Kazior2e1dea42013-07-31 10:32:40 +02006407static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
6408 struct survey_info *survey)
6409{
6410 struct ath10k *ar = hw->priv;
6411 struct ieee80211_supported_band *sband;
6412 struct survey_info *ar_survey = &ar->survey[idx];
6413 int ret = 0;
6414
6415 mutex_lock(&ar->conf_mutex);
6416
6417 sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
6418 if (sband && idx >= sband->n_channels) {
6419 idx -= sband->n_channels;
6420 sband = NULL;
6421 }
6422
6423 if (!sband)
6424 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
6425
6426 if (!sband || idx >= sband->n_channels) {
6427 ret = -ENOENT;
6428 goto exit;
6429 }
6430
6431 spin_lock_bh(&ar->data_lock);
6432 memcpy(survey, ar_survey, sizeof(*survey));
6433 spin_unlock_bh(&ar->data_lock);
6434
6435 survey->channel = &sband->channels[idx];
6436
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03006437 if (ar->rx_channel == survey->channel)
6438 survey->filled |= SURVEY_INFO_IN_USE;
6439
Michal Kazior2e1dea42013-07-31 10:32:40 +02006440exit:
6441 mutex_unlock(&ar->conf_mutex);
6442 return ret;
6443}
6444
Michal Kazior3ae54222015-03-31 10:49:20 +00006445static bool
6446ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
6447 enum ieee80211_band band,
6448 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006449{
Michal Kazior3ae54222015-03-31 10:49:20 +00006450 int num_rates = 0;
6451 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006452
Michal Kazior3ae54222015-03-31 10:49:20 +00006453 num_rates += hweight32(mask->control[band].legacy);
6454
6455 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
6456 num_rates += hweight8(mask->control[band].ht_mcs[i]);
6457
6458 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
6459 num_rates += hweight16(mask->control[band].vht_mcs[i]);
6460
6461 return num_rates == 1;
6462}
6463
6464static bool
6465ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
6466 enum ieee80211_band band,
6467 const struct cfg80211_bitrate_mask *mask,
6468 int *nss)
6469{
6470 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6471 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6472 u8 ht_nss_mask = 0;
6473 u8 vht_nss_mask = 0;
6474 int i;
6475
6476 if (mask->control[band].legacy)
6477 return false;
6478
6479 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6480 if (mask->control[band].ht_mcs[i] == 0)
6481 continue;
6482 else if (mask->control[band].ht_mcs[i] ==
6483 sband->ht_cap.mcs.rx_mask[i])
6484 ht_nss_mask |= BIT(i);
6485 else
6486 return false;
6487 }
6488
6489 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6490 if (mask->control[band].vht_mcs[i] == 0)
6491 continue;
6492 else if (mask->control[band].vht_mcs[i] ==
6493 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6494 vht_nss_mask |= BIT(i);
6495 else
6496 return false;
6497 }
6498
6499 if (ht_nss_mask != vht_nss_mask)
6500 return false;
6501
6502 if (ht_nss_mask == 0)
6503 return false;
6504
6505 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6506 return false;
6507
6508 *nss = fls(ht_nss_mask);
6509
6510 return true;
6511}
6512
6513static int
6514ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
6515 enum ieee80211_band band,
6516 const struct cfg80211_bitrate_mask *mask,
6517 u8 *rate, u8 *nss)
6518{
6519 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6520 int rate_idx;
6521 int i;
6522 u16 bitrate;
6523 u8 preamble;
6524 u8 hw_rate;
6525
6526 if (hweight32(mask->control[band].legacy) == 1) {
6527 rate_idx = ffs(mask->control[band].legacy) - 1;
6528
6529 hw_rate = sband->bitrates[rate_idx].hw_value;
6530 bitrate = sband->bitrates[rate_idx].bitrate;
6531
6532 if (ath10k_mac_bitrate_is_cck(bitrate))
6533 preamble = WMI_RATE_PREAMBLE_CCK;
6534 else
6535 preamble = WMI_RATE_PREAMBLE_OFDM;
6536
6537 *nss = 1;
6538 *rate = preamble << 6 |
6539 (*nss - 1) << 4 |
6540 hw_rate << 0;
6541
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006542 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006543 }
6544
Michal Kazior3ae54222015-03-31 10:49:20 +00006545 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6546 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6547 *nss = i + 1;
6548 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6549 (*nss - 1) << 4 |
6550 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006551
Michal Kazior3ae54222015-03-31 10:49:20 +00006552 return 0;
6553 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006554 }
6555
Michal Kazior3ae54222015-03-31 10:49:20 +00006556 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6557 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6558 *nss = i + 1;
6559 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6560 (*nss - 1) << 4 |
6561 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006562
Michal Kazior3ae54222015-03-31 10:49:20 +00006563 return 0;
6564 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006565 }
6566
Michal Kazior3ae54222015-03-31 10:49:20 +00006567 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006568}
6569
Michal Kazior3ae54222015-03-31 10:49:20 +00006570static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306571 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006572{
6573 struct ath10k *ar = arvif->ar;
6574 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006575 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006576
Michal Kazior3ae54222015-03-31 10:49:20 +00006577 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006578
Michal Kazior3ae54222015-03-31 10:49:20 +00006579 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6580 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006581
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006582 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006583 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006584 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006585 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006586 rate, ret);
6587 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006588 }
6589
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006590 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006591 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006592 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006593 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6594 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006595 }
6596
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006597 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006598 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006599 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006600 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6601 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006602 }
6603
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306604 vdev_param = ar->wmi.vdev_param->ldpc;
6605 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6606 if (ret) {
6607 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6608 return ret;
6609 }
6610
Michal Kazior3ae54222015-03-31 10:49:20 +00006611 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006612}
6613
Michal Kazior45c9abc2015-04-21 20:42:58 +03006614static bool
6615ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
6616 enum ieee80211_band band,
6617 const struct cfg80211_bitrate_mask *mask)
6618{
6619 int i;
6620 u16 vht_mcs;
6621
6622 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6623 * to express all VHT MCS rate masks. Effectively only the following
6624 * ranges can be used: none, 0-7, 0-8 and 0-9.
6625 */
6626 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6627 vht_mcs = mask->control[band].vht_mcs[i];
6628
6629 switch (vht_mcs) {
6630 case 0:
6631 case BIT(8) - 1:
6632 case BIT(9) - 1:
6633 case BIT(10) - 1:
6634 break;
6635 default:
6636 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6637 return false;
6638 }
6639 }
6640
6641 return true;
6642}
6643
6644static void ath10k_mac_set_bitrate_mask_iter(void *data,
6645 struct ieee80211_sta *sta)
6646{
6647 struct ath10k_vif *arvif = data;
6648 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6649 struct ath10k *ar = arvif->ar;
6650
6651 if (arsta->arvif != arvif)
6652 return;
6653
6654 spin_lock_bh(&ar->data_lock);
6655 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
6656 spin_unlock_bh(&ar->data_lock);
6657
6658 ieee80211_queue_work(ar->hw, &arsta->update_wk);
6659}
6660
Michal Kazior3ae54222015-03-31 10:49:20 +00006661static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
6662 struct ieee80211_vif *vif,
6663 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006664{
6665 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006666 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006667 struct ath10k *ar = arvif->ar;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006668 enum ieee80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006669 const u8 *ht_mcs_mask;
6670 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00006671 u8 rate;
6672 u8 nss;
6673 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306674 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00006675 int single_nss;
6676 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006677
Michal Kazior500ff9f2015-03-31 10:26:21 +00006678 if (ath10k_mac_vif_chan(vif, &def))
6679 return -EPERM;
6680
Michal Kazior500ff9f2015-03-31 10:26:21 +00006681 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006682 ht_mcs_mask = mask->control[band].ht_mcs;
6683 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306684 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006685
Michal Kazior3ae54222015-03-31 10:49:20 +00006686 sgi = mask->control[band].gi;
6687 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006688 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006689
Michal Kazior3ae54222015-03-31 10:49:20 +00006690 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
6691 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
6692 &rate, &nss);
6693 if (ret) {
6694 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
6695 arvif->vdev_id, ret);
6696 return ret;
6697 }
6698 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
6699 &single_nss)) {
6700 rate = WMI_FIXED_RATE_NONE;
6701 nss = single_nss;
6702 } else {
6703 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006704 nss = min(ar->num_rf_chains,
6705 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6706 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6707
6708 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
6709 return -EINVAL;
6710
6711 mutex_lock(&ar->conf_mutex);
6712
6713 arvif->bitrate_mask = *mask;
6714 ieee80211_iterate_stations_atomic(ar->hw,
6715 ath10k_mac_set_bitrate_mask_iter,
6716 arvif);
6717
6718 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006719 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006720
6721 mutex_lock(&ar->conf_mutex);
6722
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306723 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006724 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006725 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
6726 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006727 goto exit;
6728 }
6729
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006730exit:
6731 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00006732
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006733 return ret;
6734}
6735
Michal Kazior9797feb2014-02-14 14:49:48 +01006736static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6737 struct ieee80211_vif *vif,
6738 struct ieee80211_sta *sta,
6739 u32 changed)
6740{
6741 struct ath10k *ar = hw->priv;
6742 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6743 u32 bw, smps;
6744
6745 spin_lock_bh(&ar->data_lock);
6746
Michal Kazior7aa7a722014-08-25 12:09:38 +02006747 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01006748 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
6749 sta->addr, changed, sta->bandwidth, sta->rx_nss,
6750 sta->smps_mode);
6751
6752 if (changed & IEEE80211_RC_BW_CHANGED) {
6753 bw = WMI_PEER_CHWIDTH_20MHZ;
6754
6755 switch (sta->bandwidth) {
6756 case IEEE80211_STA_RX_BW_20:
6757 bw = WMI_PEER_CHWIDTH_20MHZ;
6758 break;
6759 case IEEE80211_STA_RX_BW_40:
6760 bw = WMI_PEER_CHWIDTH_40MHZ;
6761 break;
6762 case IEEE80211_STA_RX_BW_80:
6763 bw = WMI_PEER_CHWIDTH_80MHZ;
6764 break;
6765 case IEEE80211_STA_RX_BW_160:
Masanari Iidad939be32015-02-27 23:52:31 +09006766 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006767 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006768 bw = WMI_PEER_CHWIDTH_20MHZ;
6769 break;
6770 }
6771
6772 arsta->bw = bw;
6773 }
6774
6775 if (changed & IEEE80211_RC_NSS_CHANGED)
6776 arsta->nss = sta->rx_nss;
6777
6778 if (changed & IEEE80211_RC_SMPS_CHANGED) {
6779 smps = WMI_PEER_SMPS_PS_NONE;
6780
6781 switch (sta->smps_mode) {
6782 case IEEE80211_SMPS_AUTOMATIC:
6783 case IEEE80211_SMPS_OFF:
6784 smps = WMI_PEER_SMPS_PS_NONE;
6785 break;
6786 case IEEE80211_SMPS_STATIC:
6787 smps = WMI_PEER_SMPS_STATIC;
6788 break;
6789 case IEEE80211_SMPS_DYNAMIC:
6790 smps = WMI_PEER_SMPS_DYNAMIC;
6791 break;
6792 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02006793 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006794 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006795 smps = WMI_PEER_SMPS_PS_NONE;
6796 break;
6797 }
6798
6799 arsta->smps = smps;
6800 }
6801
Michal Kazior9797feb2014-02-14 14:49:48 +01006802 arsta->changed |= changed;
6803
6804 spin_unlock_bh(&ar->data_lock);
6805
6806 ieee80211_queue_work(hw, &arsta->update_wk);
6807}
6808
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006809static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
6810{
6811 /*
6812 * FIXME: Return 0 for time being. Need to figure out whether FW
6813 * has the API to fetch 64-bit local TSF
6814 */
6815
6816 return 0;
6817}
6818
Peter Oh9f0b7e72016-04-04 16:19:14 -07006819static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
Kalle Valo4d165442016-04-13 14:14:16 +03006820 u64 tsf)
Peter Oh9f0b7e72016-04-04 16:19:14 -07006821{
6822 struct ath10k *ar = hw->priv;
6823 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6824 u32 tsf_offset, vdev_param = ar->wmi.vdev_param->set_tsf;
6825 int ret;
6826
6827 /* Workaround:
6828 *
6829 * Given tsf argument is entire TSF value, but firmware accepts
6830 * only TSF offset to current TSF.
6831 *
6832 * get_tsf function is used to get offset value, however since
6833 * ath10k_get_tsf is not implemented properly, it will return 0 always.
6834 * Luckily all the caller functions to set_tsf, as of now, also rely on
6835 * get_tsf function to get entire tsf value such get_tsf() + tsf_delta,
6836 * final tsf offset value to firmware will be arithmetically correct.
6837 */
6838 tsf_offset = tsf - ath10k_get_tsf(hw, vif);
6839 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
6840 vdev_param, tsf_offset);
6841 if (ret && ret != -EOPNOTSUPP)
6842 ath10k_warn(ar, "failed to set tsf offset: %d\n", ret);
6843}
6844
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006845static int ath10k_ampdu_action(struct ieee80211_hw *hw,
6846 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02006847 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006848{
Michal Kazior7aa7a722014-08-25 12:09:38 +02006849 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006850 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Sara Sharon50ea05e2015-12-30 16:06:04 +02006851 struct ieee80211_sta *sta = params->sta;
6852 enum ieee80211_ampdu_mlme_action action = params->action;
6853 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006854
Michal Kazior7aa7a722014-08-25 12:09:38 +02006855 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 +02006856 arvif->vdev_id, sta->addr, tid, action);
6857
6858 switch (action) {
6859 case IEEE80211_AMPDU_RX_START:
6860 case IEEE80211_AMPDU_RX_STOP:
6861 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
6862 * creation/removal. Do we need to verify this?
6863 */
6864 return 0;
6865 case IEEE80211_AMPDU_TX_START:
6866 case IEEE80211_AMPDU_TX_STOP_CONT:
6867 case IEEE80211_AMPDU_TX_STOP_FLUSH:
6868 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
6869 case IEEE80211_AMPDU_TX_OPERATIONAL:
6870 /* Firmware offloads Tx aggregation entirely so deny mac80211
6871 * Tx aggregation requests.
6872 */
6873 return -EOPNOTSUPP;
6874 }
6875
6876 return -EINVAL;
6877}
6878
Michal Kazior500ff9f2015-03-31 10:26:21 +00006879static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006880ath10k_mac_update_rx_channel(struct ath10k *ar,
6881 struct ieee80211_chanctx_conf *ctx,
6882 struct ieee80211_vif_chanctx_switch *vifs,
6883 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00006884{
6885 struct cfg80211_chan_def *def = NULL;
6886
6887 /* Both locks are required because ar->rx_channel is modified. This
6888 * allows readers to hold either lock.
6889 */
6890 lockdep_assert_held(&ar->conf_mutex);
6891 lockdep_assert_held(&ar->data_lock);
6892
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006893 WARN_ON(ctx && vifs);
6894 WARN_ON(vifs && n_vifs != 1);
6895
Michal Kazior500ff9f2015-03-31 10:26:21 +00006896 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
6897 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
6898 * ppdu on Rx may reduce performance on low-end systems. It should be
6899 * possible to make tables/hashmaps to speed the lookup up (be vary of
6900 * cpu data cache lines though regarding sizes) but to keep the initial
6901 * implementation simple and less intrusive fallback to the slow lookup
6902 * only for multi-channel cases. Single-channel cases will remain to
6903 * use the old channel derival and thus performance should not be
6904 * affected much.
6905 */
6906 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006907 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00006908 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03006909 ath10k_mac_get_any_chandef_iter,
6910 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006911
6912 if (vifs)
6913 def = &vifs[0].new_ctx->def;
6914
Michal Kazior500ff9f2015-03-31 10:26:21 +00006915 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05306916 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
6917 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
6918 /* During driver restart due to firmware assert, since mac80211
6919 * already has valid channel context for given radio, channel
6920 * context iteration return num_chanctx > 0. So fix rx_channel
6921 * when restart is in progress.
6922 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006923 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00006924 } else {
6925 ar->rx_channel = NULL;
6926 }
6927 rcu_read_unlock();
6928}
6929
Michal Kazior7be6d1b2015-09-03 10:44:51 +02006930static void
6931ath10k_mac_update_vif_chan(struct ath10k *ar,
6932 struct ieee80211_vif_chanctx_switch *vifs,
6933 int n_vifs)
6934{
6935 struct ath10k_vif *arvif;
6936 int ret;
6937 int i;
6938
6939 lockdep_assert_held(&ar->conf_mutex);
6940
6941 /* First stop monitor interface. Some FW versions crash if there's a
6942 * lone monitor interface.
6943 */
6944 if (ar->monitor_started)
6945 ath10k_monitor_stop(ar);
6946
6947 for (i = 0; i < n_vifs; i++) {
6948 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6949
6950 ath10k_dbg(ar, ATH10K_DBG_MAC,
6951 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
6952 arvif->vdev_id,
6953 vifs[i].old_ctx->def.chan->center_freq,
6954 vifs[i].new_ctx->def.chan->center_freq,
6955 vifs[i].old_ctx->def.width,
6956 vifs[i].new_ctx->def.width);
6957
6958 if (WARN_ON(!arvif->is_started))
6959 continue;
6960
6961 if (WARN_ON(!arvif->is_up))
6962 continue;
6963
6964 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
6965 if (ret) {
6966 ath10k_warn(ar, "failed to down vdev %d: %d\n",
6967 arvif->vdev_id, ret);
6968 continue;
6969 }
6970 }
6971
6972 /* All relevant vdevs are downed and associated channel resources
6973 * should be available for the channel switch now.
6974 */
6975
6976 spin_lock_bh(&ar->data_lock);
6977 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
6978 spin_unlock_bh(&ar->data_lock);
6979
6980 for (i = 0; i < n_vifs; i++) {
6981 arvif = ath10k_vif_to_arvif(vifs[i].vif);
6982
6983 if (WARN_ON(!arvif->is_started))
6984 continue;
6985
6986 if (WARN_ON(!arvif->is_up))
6987 continue;
6988
6989 ret = ath10k_mac_setup_bcn_tmpl(arvif);
6990 if (ret)
6991 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
6992 ret);
6993
6994 ret = ath10k_mac_setup_prb_tmpl(arvif);
6995 if (ret)
6996 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
6997 ret);
6998
6999 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7000 if (ret) {
7001 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7002 arvif->vdev_id, ret);
7003 continue;
7004 }
7005
7006 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7007 arvif->bssid);
7008 if (ret) {
7009 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7010 arvif->vdev_id, ret);
7011 continue;
7012 }
7013 }
7014
7015 ath10k_monitor_recalc(ar);
7016}
7017
Michal Kazior500ff9f2015-03-31 10:26:21 +00007018static int
7019ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7020 struct ieee80211_chanctx_conf *ctx)
7021{
7022 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007023
7024 ath10k_dbg(ar, ATH10K_DBG_MAC,
7025 "mac chanctx add freq %hu width %d ptr %p\n",
7026 ctx->def.chan->center_freq, ctx->def.width, ctx);
7027
7028 mutex_lock(&ar->conf_mutex);
7029
7030 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007031 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007032 spin_unlock_bh(&ar->data_lock);
7033
7034 ath10k_recalc_radar_detection(ar);
7035 ath10k_monitor_recalc(ar);
7036
7037 mutex_unlock(&ar->conf_mutex);
7038
7039 return 0;
7040}
7041
7042static void
7043ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7044 struct ieee80211_chanctx_conf *ctx)
7045{
7046 struct ath10k *ar = hw->priv;
7047
7048 ath10k_dbg(ar, ATH10K_DBG_MAC,
7049 "mac chanctx remove freq %hu width %d ptr %p\n",
7050 ctx->def.chan->center_freq, ctx->def.width, ctx);
7051
7052 mutex_lock(&ar->conf_mutex);
7053
7054 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007055 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007056 spin_unlock_bh(&ar->data_lock);
7057
7058 ath10k_recalc_radar_detection(ar);
7059 ath10k_monitor_recalc(ar);
7060
7061 mutex_unlock(&ar->conf_mutex);
7062}
7063
Michal Kazior9713e3d2015-09-03 10:44:52 +02007064struct ath10k_mac_change_chanctx_arg {
7065 struct ieee80211_chanctx_conf *ctx;
7066 struct ieee80211_vif_chanctx_switch *vifs;
7067 int n_vifs;
7068 int next_vif;
7069};
7070
7071static void
7072ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
7073 struct ieee80211_vif *vif)
7074{
7075 struct ath10k_mac_change_chanctx_arg *arg = data;
7076
7077 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
7078 return;
7079
7080 arg->n_vifs++;
7081}
7082
7083static void
7084ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
7085 struct ieee80211_vif *vif)
7086{
7087 struct ath10k_mac_change_chanctx_arg *arg = data;
7088 struct ieee80211_chanctx_conf *ctx;
7089
7090 ctx = rcu_access_pointer(vif->chanctx_conf);
7091 if (ctx != arg->ctx)
7092 return;
7093
7094 if (WARN_ON(arg->next_vif == arg->n_vifs))
7095 return;
7096
7097 arg->vifs[arg->next_vif].vif = vif;
7098 arg->vifs[arg->next_vif].old_ctx = ctx;
7099 arg->vifs[arg->next_vif].new_ctx = ctx;
7100 arg->next_vif++;
7101}
7102
Michal Kazior500ff9f2015-03-31 10:26:21 +00007103static void
7104ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7105 struct ieee80211_chanctx_conf *ctx,
7106 u32 changed)
7107{
7108 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007109 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007110
7111 mutex_lock(&ar->conf_mutex);
7112
7113 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007114 "mac chanctx change freq %hu width %d ptr %p changed %x\n",
7115 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007116
7117 /* This shouldn't really happen because channel switching should use
7118 * switch_vif_chanctx().
7119 */
7120 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7121 goto unlock;
7122
Michal Kazior9713e3d2015-09-03 10:44:52 +02007123 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7124 ieee80211_iterate_active_interfaces_atomic(
7125 hw,
7126 IEEE80211_IFACE_ITER_NORMAL,
7127 ath10k_mac_change_chanctx_cnt_iter,
7128 &arg);
7129 if (arg.n_vifs == 0)
7130 goto radar;
7131
7132 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7133 GFP_KERNEL);
7134 if (!arg.vifs)
7135 goto radar;
7136
7137 ieee80211_iterate_active_interfaces_atomic(
7138 hw,
7139 IEEE80211_IFACE_ITER_NORMAL,
7140 ath10k_mac_change_chanctx_fill_iter,
7141 &arg);
7142 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7143 kfree(arg.vifs);
7144 }
7145
7146radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007147 ath10k_recalc_radar_detection(ar);
7148
7149 /* FIXME: How to configure Rx chains properly? */
7150
7151 /* No other actions are actually necessary. Firmware maintains channel
7152 * definitions per vdev internally and there's no host-side channel
7153 * context abstraction to configure, e.g. channel width.
7154 */
7155
7156unlock:
7157 mutex_unlock(&ar->conf_mutex);
7158}
7159
7160static int
7161ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7162 struct ieee80211_vif *vif,
7163 struct ieee80211_chanctx_conf *ctx)
7164{
7165 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007166 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7167 int ret;
7168
7169 mutex_lock(&ar->conf_mutex);
7170
7171 ath10k_dbg(ar, ATH10K_DBG_MAC,
7172 "mac chanctx assign ptr %p vdev_id %i\n",
7173 ctx, arvif->vdev_id);
7174
7175 if (WARN_ON(arvif->is_started)) {
7176 mutex_unlock(&ar->conf_mutex);
7177 return -EBUSY;
7178 }
7179
Michal Kazior089ab7a2015-06-03 12:16:55 +02007180 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007181 if (ret) {
7182 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7183 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007184 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007185 goto err;
7186 }
7187
7188 arvif->is_started = true;
7189
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007190 ret = ath10k_mac_vif_setup_ps(arvif);
7191 if (ret) {
7192 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7193 arvif->vdev_id, ret);
7194 goto err_stop;
7195 }
7196
Michal Kazior500ff9f2015-03-31 10:26:21 +00007197 if (vif->type == NL80211_IFTYPE_MONITOR) {
7198 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7199 if (ret) {
7200 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7201 arvif->vdev_id, ret);
7202 goto err_stop;
7203 }
7204
7205 arvif->is_up = true;
7206 }
7207
7208 mutex_unlock(&ar->conf_mutex);
7209 return 0;
7210
7211err_stop:
7212 ath10k_vdev_stop(arvif);
7213 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007214 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007215
7216err:
7217 mutex_unlock(&ar->conf_mutex);
7218 return ret;
7219}
7220
7221static void
7222ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7223 struct ieee80211_vif *vif,
7224 struct ieee80211_chanctx_conf *ctx)
7225{
7226 struct ath10k *ar = hw->priv;
7227 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7228 int ret;
7229
7230 mutex_lock(&ar->conf_mutex);
7231
7232 ath10k_dbg(ar, ATH10K_DBG_MAC,
7233 "mac chanctx unassign ptr %p vdev_id %i\n",
7234 ctx, arvif->vdev_id);
7235
7236 WARN_ON(!arvif->is_started);
7237
7238 if (vif->type == NL80211_IFTYPE_MONITOR) {
7239 WARN_ON(!arvif->is_up);
7240
7241 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7242 if (ret)
7243 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7244 arvif->vdev_id, ret);
7245
7246 arvif->is_up = false;
7247 }
7248
7249 ret = ath10k_vdev_stop(arvif);
7250 if (ret)
7251 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7252 arvif->vdev_id, ret);
7253
7254 arvif->is_started = false;
7255
7256 mutex_unlock(&ar->conf_mutex);
7257}
7258
7259static int
7260ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7261 struct ieee80211_vif_chanctx_switch *vifs,
7262 int n_vifs,
7263 enum ieee80211_chanctx_switch_mode mode)
7264{
7265 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007266
7267 mutex_lock(&ar->conf_mutex);
7268
7269 ath10k_dbg(ar, ATH10K_DBG_MAC,
7270 "mac chanctx switch n_vifs %d mode %d\n",
7271 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007272 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007273
7274 mutex_unlock(&ar->conf_mutex);
7275 return 0;
7276}
7277
Kalle Valo5e3dd152013-06-12 20:52:10 +03007278static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01007279 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02007280 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007281 .start = ath10k_start,
7282 .stop = ath10k_stop,
7283 .config = ath10k_config,
7284 .add_interface = ath10k_add_interface,
7285 .remove_interface = ath10k_remove_interface,
7286 .configure_filter = ath10k_configure_filter,
7287 .bss_info_changed = ath10k_bss_info_changed,
7288 .hw_scan = ath10k_hw_scan,
7289 .cancel_hw_scan = ath10k_cancel_hw_scan,
7290 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02007291 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007292 .sta_state = ath10k_sta_state,
7293 .conf_tx = ath10k_conf_tx,
7294 .remain_on_channel = ath10k_remain_on_channel,
7295 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
7296 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02007297 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007298 .flush = ath10k_flush,
7299 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03007300 .set_antenna = ath10k_set_antenna,
7301 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007302 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02007303 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00007304 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01007305 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02007306 .get_tsf = ath10k_get_tsf,
Peter Oh9f0b7e72016-04-04 16:19:14 -07007307 .set_tsf = ath10k_set_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007308 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03007309 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7310 .get_et_stats = ath10k_debug_get_et_stats,
7311 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00007312 .add_chanctx = ath10k_mac_op_add_chanctx,
7313 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7314 .change_chanctx = ath10k_mac_op_change_chanctx,
7315 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7316 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7317 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Kalle Valo43d2a302014-09-10 18:23:30 +03007318
7319 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7320
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007321#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007322 .suspend = ath10k_wow_op_suspend,
7323 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007324#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007325#ifdef CONFIG_MAC80211_DEBUGFS
7326 .sta_add_debugfs = ath10k_sta_add_debugfs,
7327#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03007328};
7329
Kalle Valo5e3dd152013-06-12 20:52:10 +03007330#define CHAN2G(_channel, _freq, _flags) { \
7331 .band = IEEE80211_BAND_2GHZ, \
7332 .hw_value = (_channel), \
7333 .center_freq = (_freq), \
7334 .flags = (_flags), \
7335 .max_antenna_gain = 0, \
7336 .max_power = 30, \
7337}
7338
7339#define CHAN5G(_channel, _freq, _flags) { \
7340 .band = IEEE80211_BAND_5GHZ, \
7341 .hw_value = (_channel), \
7342 .center_freq = (_freq), \
7343 .flags = (_flags), \
7344 .max_antenna_gain = 0, \
7345 .max_power = 30, \
7346}
7347
7348static const struct ieee80211_channel ath10k_2ghz_channels[] = {
7349 CHAN2G(1, 2412, 0),
7350 CHAN2G(2, 2417, 0),
7351 CHAN2G(3, 2422, 0),
7352 CHAN2G(4, 2427, 0),
7353 CHAN2G(5, 2432, 0),
7354 CHAN2G(6, 2437, 0),
7355 CHAN2G(7, 2442, 0),
7356 CHAN2G(8, 2447, 0),
7357 CHAN2G(9, 2452, 0),
7358 CHAN2G(10, 2457, 0),
7359 CHAN2G(11, 2462, 0),
7360 CHAN2G(12, 2467, 0),
7361 CHAN2G(13, 2472, 0),
7362 CHAN2G(14, 2484, 0),
7363};
7364
7365static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02007366 CHAN5G(36, 5180, 0),
7367 CHAN5G(40, 5200, 0),
7368 CHAN5G(44, 5220, 0),
7369 CHAN5G(48, 5240, 0),
7370 CHAN5G(52, 5260, 0),
7371 CHAN5G(56, 5280, 0),
7372 CHAN5G(60, 5300, 0),
7373 CHAN5G(64, 5320, 0),
7374 CHAN5G(100, 5500, 0),
7375 CHAN5G(104, 5520, 0),
7376 CHAN5G(108, 5540, 0),
7377 CHAN5G(112, 5560, 0),
7378 CHAN5G(116, 5580, 0),
7379 CHAN5G(120, 5600, 0),
7380 CHAN5G(124, 5620, 0),
7381 CHAN5G(128, 5640, 0),
7382 CHAN5G(132, 5660, 0),
7383 CHAN5G(136, 5680, 0),
7384 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07007385 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02007386 CHAN5G(149, 5745, 0),
7387 CHAN5G(153, 5765, 0),
7388 CHAN5G(157, 5785, 0),
7389 CHAN5G(161, 5805, 0),
7390 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03007391};
7392
Michal Kaziore7b54192014-08-07 11:03:27 +02007393struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007394{
7395 struct ieee80211_hw *hw;
7396 struct ath10k *ar;
7397
Michal Kaziore7b54192014-08-07 11:03:27 +02007398 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007399 if (!hw)
7400 return NULL;
7401
7402 ar = hw->priv;
7403 ar->hw = hw;
7404
7405 return ar;
7406}
7407
7408void ath10k_mac_destroy(struct ath10k *ar)
7409{
7410 ieee80211_free_hw(ar->hw);
7411}
7412
7413static const struct ieee80211_iface_limit ath10k_if_limits[] = {
7414 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307415 .max = 8,
7416 .types = BIT(NL80211_IFTYPE_STATION)
7417 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02007418 },
7419 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307420 .max = 3,
7421 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02007422 },
7423 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307424 .max = 1,
7425 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01007426 },
7427 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307428 .max = 7,
7429 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007430#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307431 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007432#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02007433 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007434};
7435
Bartosz Markowskif2595092013-12-10 16:20:39 +01007436static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007437 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307438 .max = 8,
7439 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007440#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307441 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007442#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007443 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307444 {
7445 .max = 1,
7446 .types = BIT(NL80211_IFTYPE_STATION)
7447 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007448};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007449
7450static const struct ieee80211_iface_combination ath10k_if_comb[] = {
7451 {
7452 .limits = ath10k_if_limits,
7453 .n_limits = ARRAY_SIZE(ath10k_if_limits),
7454 .max_interfaces = 8,
7455 .num_different_channels = 1,
7456 .beacon_int_infra_match = true,
7457 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01007458};
7459
7460static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007461 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01007462 .limits = ath10k_10x_if_limits,
7463 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007464 .max_interfaces = 8,
7465 .num_different_channels = 1,
7466 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01007467#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007468 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7469 BIT(NL80211_CHAN_WIDTH_20) |
7470 BIT(NL80211_CHAN_WIDTH_40) |
7471 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007472#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01007473 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007474};
7475
Michal Kaziorcf327842015-03-31 10:26:25 +00007476static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
7477 {
7478 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02007479 .types = BIT(NL80211_IFTYPE_STATION),
7480 },
7481 {
7482 .max = 2,
7483 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007484#ifdef CONFIG_MAC80211_MESH
7485 BIT(NL80211_IFTYPE_MESH_POINT) |
7486#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00007487 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7488 BIT(NL80211_IFTYPE_P2P_GO),
7489 },
7490 {
7491 .max = 1,
7492 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7493 },
7494};
7495
Michal Kaziored25b112015-07-09 13:08:39 +02007496static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
7497 {
7498 .max = 2,
7499 .types = BIT(NL80211_IFTYPE_STATION),
7500 },
7501 {
7502 .max = 2,
7503 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
7504 },
7505 {
7506 .max = 1,
7507 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007508#ifdef CONFIG_MAC80211_MESH
7509 BIT(NL80211_IFTYPE_MESH_POINT) |
7510#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007511 BIT(NL80211_IFTYPE_P2P_GO),
7512 },
7513 {
7514 .max = 1,
7515 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7516 },
7517};
7518
Michal Kaziorcf327842015-03-31 10:26:25 +00007519static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7520 {
7521 .max = 1,
7522 .types = BIT(NL80211_IFTYPE_STATION),
7523 },
7524 {
7525 .max = 1,
7526 .types = BIT(NL80211_IFTYPE_ADHOC),
7527 },
7528};
7529
7530/* FIXME: This is not thouroughly tested. These combinations may over- or
7531 * underestimate hw/fw capabilities.
7532 */
7533static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7534 {
7535 .limits = ath10k_tlv_if_limit,
7536 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007537 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007538 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7539 },
7540 {
7541 .limits = ath10k_tlv_if_limit_ibss,
7542 .num_different_channels = 1,
7543 .max_interfaces = 2,
7544 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7545 },
7546};
7547
7548static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7549 {
7550 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007551 .num_different_channels = 1,
7552 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007553 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7554 },
7555 {
Michal Kaziored25b112015-07-09 13:08:39 +02007556 .limits = ath10k_tlv_qcs_if_limit,
7557 .num_different_channels = 2,
7558 .max_interfaces = 4,
7559 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7560 },
7561 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007562 .limits = ath10k_tlv_if_limit_ibss,
7563 .num_different_channels = 1,
7564 .max_interfaces = 2,
7565 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7566 },
7567};
7568
Raja Manicf36fef2015-06-22 20:22:25 +05307569static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
7570 {
7571 .max = 1,
7572 .types = BIT(NL80211_IFTYPE_STATION),
7573 },
7574 {
7575 .max = 16,
7576 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007577#ifdef CONFIG_MAC80211_MESH
7578 | BIT(NL80211_IFTYPE_MESH_POINT)
7579#endif
Raja Manicf36fef2015-06-22 20:22:25 +05307580 },
7581};
7582
7583static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
7584 {
7585 .limits = ath10k_10_4_if_limits,
7586 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
7587 .max_interfaces = 16,
7588 .num_different_channels = 1,
7589 .beacon_int_infra_match = true,
7590#ifdef CONFIG_ATH10K_DFS_CERTIFIED
7591 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7592 BIT(NL80211_CHAN_WIDTH_20) |
7593 BIT(NL80211_CHAN_WIDTH_40) |
7594 BIT(NL80211_CHAN_WIDTH_80),
7595#endif
7596 },
7597};
7598
Kalle Valo5e3dd152013-06-12 20:52:10 +03007599static void ath10k_get_arvif_iter(void *data, u8 *mac,
7600 struct ieee80211_vif *vif)
7601{
7602 struct ath10k_vif_iter *arvif_iter = data;
7603 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7604
7605 if (arvif->vdev_id == arvif_iter->vdev_id)
7606 arvif_iter->arvif = arvif;
7607}
7608
7609struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
7610{
7611 struct ath10k_vif_iter arvif_iter;
7612 u32 flags;
7613
7614 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
7615 arvif_iter.vdev_id = vdev_id;
7616
7617 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
7618 ieee80211_iterate_active_interfaces_atomic(ar->hw,
7619 flags,
7620 ath10k_get_arvif_iter,
7621 &arvif_iter);
7622 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007623 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007624 return NULL;
7625 }
7626
7627 return arvif_iter.arvif;
7628}
7629
7630int ath10k_mac_register(struct ath10k *ar)
7631{
Johannes Berg3cb10942015-01-22 21:38:45 +01007632 static const u32 cipher_suites[] = {
7633 WLAN_CIPHER_SUITE_WEP40,
7634 WLAN_CIPHER_SUITE_WEP104,
7635 WLAN_CIPHER_SUITE_TKIP,
7636 WLAN_CIPHER_SUITE_CCMP,
7637 WLAN_CIPHER_SUITE_AES_CMAC,
7638 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03007639 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007640 void *channels;
7641 int ret;
7642
7643 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
7644
7645 SET_IEEE80211_DEV(ar->hw, ar->dev);
7646
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00007647 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
7648 ARRAY_SIZE(ath10k_5ghz_channels)) !=
7649 ATH10K_NUM_CHANS);
7650
Kalle Valo5e3dd152013-06-12 20:52:10 +03007651 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
7652 channels = kmemdup(ath10k_2ghz_channels,
7653 sizeof(ath10k_2ghz_channels),
7654 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02007655 if (!channels) {
7656 ret = -ENOMEM;
7657 goto err_free;
7658 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007659
7660 band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
7661 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
7662 band->channels = channels;
7663 band->n_bitrates = ath10k_g_rates_size;
7664 band->bitrates = ath10k_g_rates;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007665
7666 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
7667 }
7668
7669 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
7670 channels = kmemdup(ath10k_5ghz_channels,
7671 sizeof(ath10k_5ghz_channels),
7672 GFP_KERNEL);
7673 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02007674 ret = -ENOMEM;
7675 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007676 }
7677
7678 band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
7679 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
7680 band->channels = channels;
7681 band->n_bitrates = ath10k_a_rates_size;
7682 band->bitrates = ath10k_a_rates;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007683 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
7684 }
7685
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05307686 ath10k_mac_setup_ht_vht_cap(ar);
7687
Kalle Valo5e3dd152013-06-12 20:52:10 +03007688 ar->hw->wiphy->interface_modes =
7689 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007690 BIT(NL80211_IFTYPE_AP) |
7691 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01007692
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05307693 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
7694 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03007695
Bartosz Markowskid3541812013-12-10 16:20:40 +01007696 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
7697 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01007698 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01007699 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7700 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007701
Johannes Berg30686bf2015-06-02 21:39:54 +02007702 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
7703 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
7704 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
7705 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
7706 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
7707 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
7708 ieee80211_hw_set(ar->hw, AP_LINK_PS);
7709 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02007710 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
7711 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
7712 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
7713 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
7714 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
7715 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007716
David Liuccec9032015-07-24 20:25:32 +03007717 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7718 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
7719
Eliad Peller0d8614b2014-09-10 14:07:36 +03007720 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00007721 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03007722
Kalle Valo5e3dd152013-06-12 20:52:10 +03007723 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03007724 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007725
7726 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02007727 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
7728 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007729 }
7730
7731 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
7732 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
7733
7734 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01007735 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02007736 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007737
Kalle Valo5e3dd152013-06-12 20:52:10 +03007738 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
7739
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02007740 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
7741 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
7742
7743 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
7744 * that userspace (e.g. wpa_supplicant/hostapd) can generate
7745 * correct Probe Responses. This is more of a hack advert..
7746 */
7747 ar->hw->wiphy->probe_resp_offload |=
7748 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
7749 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
7750 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
7751 }
7752
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03007753 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
7754 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7755
Kalle Valo5e3dd152013-06-12 20:52:10 +03007756 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01007757 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007758 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
7759
7760 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05307761 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
7762 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02007763
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01007764 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
7765
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007766 ret = ath10k_wow_init(ar);
7767 if (ret) {
7768 ath10k_warn(ar, "failed to init wow: %d\n", ret);
7769 goto err_free;
7770 }
7771
Janusz Dziedzicc7025342015-06-15 14:46:41 +03007772 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
7773
Kalle Valo5e3dd152013-06-12 20:52:10 +03007774 /*
7775 * on LL hardware queues are managed entirely by the FW
7776 * so we only advertise to mac we can do the queues thing
7777 */
Michal Kazior96d828d2015-03-31 10:26:23 +00007778 ar->hw->queues = IEEE80211_MAX_QUEUES;
7779
7780 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
7781 * something that vdev_ids can't reach so that we don't stop the queue
7782 * accidentally.
7783 */
7784 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007785
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007786 switch (ar->wmi.op_version) {
7787 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01007788 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
7789 ar->hw->wiphy->n_iface_combinations =
7790 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03007791 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007792 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00007793 case ATH10K_FW_WMI_OP_VERSION_TLV:
7794 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
7795 ar->hw->wiphy->iface_combinations =
7796 ath10k_tlv_qcs_if_comb;
7797 ar->hw->wiphy->n_iface_combinations =
7798 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
7799 } else {
7800 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
7801 ar->hw->wiphy->n_iface_combinations =
7802 ARRAY_SIZE(ath10k_tlv_if_comb);
7803 }
7804 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
7805 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007806 case ATH10K_FW_WMI_OP_VERSION_10_1:
7807 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02007808 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007809 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
7810 ar->hw->wiphy->n_iface_combinations =
7811 ARRAY_SIZE(ath10k_10x_if_comb);
7812 break;
Raja Mani9bd21322015-06-22 20:10:09 +05307813 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05307814 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
7815 ar->hw->wiphy->n_iface_combinations =
7816 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05307817 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007818 case ATH10K_FW_WMI_OP_VERSION_UNSET:
7819 case ATH10K_FW_WMI_OP_VERSION_MAX:
7820 WARN_ON(1);
7821 ret = -EINVAL;
7822 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01007823 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007824
David Liuccec9032015-07-24 20:25:32 +03007825 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7826 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02007827
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007828 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
7829 /* Init ath dfs pattern detector */
7830 ar->ath_common.debug_mask = ATH_DBG_DFS;
7831 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
7832 NL80211_DFS_UNSET);
7833
7834 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02007835 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007836 }
7837
Kalle Valo5e3dd152013-06-12 20:52:10 +03007838 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
7839 ath10k_reg_notifier);
7840 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007841 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007842 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007843 }
7844
Johannes Berg3cb10942015-01-22 21:38:45 +01007845 ar->hw->wiphy->cipher_suites = cipher_suites;
7846 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
7847
Kalle Valo5e3dd152013-06-12 20:52:10 +03007848 ret = ieee80211_register_hw(ar->hw);
7849 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007850 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007851 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007852 }
7853
7854 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
7855 ret = regulatory_hint(ar->hw->wiphy,
7856 ar->ath_common.regulatory.alpha2);
7857 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02007858 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007859 }
7860
7861 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02007862
7863err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03007864 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07007865
7866err_dfs_detector_exit:
7867 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7868 ar->dfs_detector->exit(ar->dfs_detector);
7869
Michal Kaziord6015b22013-07-22 14:13:30 +02007870err_free:
7871 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
7872 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
7873
Jeff Johnson0e339442015-10-08 09:15:53 -07007874 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007875 return ret;
7876}
7877
7878void ath10k_mac_unregister(struct ath10k *ar)
7879{
7880 ieee80211_unregister_hw(ar->hw);
7881
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007882 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7883 ar->dfs_detector->exit(ar->dfs_detector);
7884
Kalle Valo5e3dd152013-06-12 20:52:10 +03007885 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
7886 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
7887
7888 SET_IEEE80211_DEV(ar->hw, NULL);
7889}