blob: 590d7667c861121aeb80ace739234293b224e5ed [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>
Bartosz Markowski209b2a62016-09-28 15:11:58 +030022#include <linux/acpi.h>
Kalle Valo5e3dd152013-06-12 20:52:10 +030023
Michal Kazior8cd13ca2013-07-16 09:38:54 +020024#include "hif.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030025#include "core.h"
26#include "debug.h"
27#include "wmi.h"
28#include "htt.h"
29#include "txrx.h"
Kalle Valo43d2a302014-09-10 18:23:30 +030030#include "testmode.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020031#include "wmi.h"
Michal Kaziorb4aa5392015-03-31 10:26:24 +000032#include "wmi-tlv.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020033#include "wmi-ops.h"
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +020034#include "wow.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030035
Michal Kaziordcc33092015-03-30 09:51:54 +030036/*********/
37/* Rates */
38/*********/
39
Michal Kaziordcc33092015-03-30 09:51:54 +030040static struct ieee80211_rate ath10k_rates[] = {
Michal Kazior5528e032015-03-30 09:51:56 +030041 { .bitrate = 10,
42 .hw_value = ATH10K_HW_RATE_CCK_LP_1M },
43 { .bitrate = 20,
44 .hw_value = ATH10K_HW_RATE_CCK_LP_2M,
45 .hw_value_short = ATH10K_HW_RATE_CCK_SP_2M,
46 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
47 { .bitrate = 55,
48 .hw_value = ATH10K_HW_RATE_CCK_LP_5_5M,
49 .hw_value_short = ATH10K_HW_RATE_CCK_SP_5_5M,
50 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
51 { .bitrate = 110,
52 .hw_value = ATH10K_HW_RATE_CCK_LP_11M,
53 .hw_value_short = ATH10K_HW_RATE_CCK_SP_11M,
54 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
Michal Kazior5653b392015-03-30 09:51:54 +030055
Michal Kazioraf001482015-03-30 09:51:56 +030056 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
57 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
58 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
59 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
60 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
61 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
62 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
63 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
Michal Kaziordcc33092015-03-30 09:51:54 +030064};
65
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +030066static struct ieee80211_rate ath10k_rates_rev2[] = {
67 { .bitrate = 10,
68 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_1M },
69 { .bitrate = 20,
70 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_2M,
71 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_2M,
72 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
73 { .bitrate = 55,
74 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
75 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
76 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
77 { .bitrate = 110,
78 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_11M,
79 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_11M,
80 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
81
82 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
83 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
84 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
85 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
86 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
87 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
88 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
89 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
90};
91
Michal Kazior8d7aa6b2015-03-30 09:51:57 +030092#define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
93
94#define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
95#define ath10k_a_rates_size (ARRAY_SIZE(ath10k_rates) - \
96 ATH10K_MAC_FIRST_OFDM_RATE_IDX)
Michal Kaziordcc33092015-03-30 09:51:54 +030097#define ath10k_g_rates (ath10k_rates + 0)
98#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
99
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +0300100#define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
101#define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
102
Michal Kazior486017c2015-03-30 09:51:54 +0300103static bool ath10k_mac_bitrate_is_cck(int bitrate)
104{
105 switch (bitrate) {
106 case 10:
107 case 20:
108 case 55:
109 case 110:
110 return true;
111 }
112
113 return false;
114}
115
116static u8 ath10k_mac_bitrate_to_rate(int bitrate)
117{
118 return DIV_ROUND_UP(bitrate, 5) |
119 (ath10k_mac_bitrate_is_cck(bitrate) ? BIT(7) : 0);
120}
121
Michal Kazior5528e032015-03-30 09:51:56 +0300122u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
Yanbo Li4b7f3532015-11-12 10:36:10 -0800123 u8 hw_rate, bool cck)
Michal Kazior5528e032015-03-30 09:51:56 +0300124{
125 const struct ieee80211_rate *rate;
126 int i;
127
128 for (i = 0; i < sband->n_bitrates; i++) {
129 rate = &sband->bitrates[i];
130
Yanbo Li4b7f3532015-11-12 10:36:10 -0800131 if (ath10k_mac_bitrate_is_cck(rate->bitrate) != cck)
132 continue;
133
Michal Kazior5528e032015-03-30 09:51:56 +0300134 if (rate->hw_value == hw_rate)
135 return i;
136 else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
137 rate->hw_value_short == hw_rate)
138 return i;
139 }
140
141 return 0;
142}
143
Michal Kazior01cebe12015-03-30 09:51:56 +0300144u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
145 u32 bitrate)
146{
147 int i;
148
149 for (i = 0; i < sband->n_bitrates; i++)
150 if (sband->bitrates[i].bitrate == bitrate)
151 return i;
152
153 return 0;
154}
155
Michal Kazior3ae54222015-03-31 10:49:20 +0000156static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
157{
158 switch ((mcs_map >> (2 * nss)) & 0x3) {
159 case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;
160 case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;
161 case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;
162 }
163 return 0;
164}
165
Michal Kazior45c9abc2015-04-21 20:42:58 +0300166static u32
167ath10k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
168{
169 int nss;
170
171 for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--)
172 if (ht_mcs_mask[nss])
173 return nss + 1;
174
175 return 1;
176}
177
178static u32
179ath10k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
180{
181 int nss;
182
183 for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--)
184 if (vht_mcs_mask[nss])
185 return nss + 1;
186
187 return 1;
188}
Kalle Valo5e3dd152013-06-12 20:52:10 +0300189
Raja Mani7e247a92016-04-12 20:15:53 +0530190int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val)
191{
192 enum wmi_host_platform_type platform_type;
193 int ret;
194
195 if (test_bit(WMI_SERVICE_TX_MODE_DYNAMIC, ar->wmi.svc_map))
196 platform_type = WMI_HOST_PLATFORM_LOW_PERF;
197 else
198 platform_type = WMI_HOST_PLATFORM_HIGH_PERF;
199
200 ret = ath10k_wmi_ext_resource_config(ar, platform_type, val);
201
202 if (ret && ret != -EOPNOTSUPP) {
203 ath10k_warn(ar, "failed to configure ext resource: %d\n", ret);
204 return ret;
205 }
206
207 return 0;
208}
209
Kalle Valo5e3dd152013-06-12 20:52:10 +0300210/**********/
211/* Crypto */
212/**********/
213
214static int ath10k_send_key(struct ath10k_vif *arvif,
215 struct ieee80211_key_conf *key,
216 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100217 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300218{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200219 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300220 struct wmi_vdev_install_key_arg arg = {
221 .vdev_id = arvif->vdev_id,
222 .key_idx = key->keyidx,
223 .key_len = key->keylen,
224 .key_data = key->key,
Michal Kazior370e5672015-02-18 14:02:26 +0100225 .key_flags = flags,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300226 .macaddr = macaddr,
227 };
228
Michal Kazior548db542013-07-05 16:15:15 +0300229 lockdep_assert_held(&arvif->ar->conf_mutex);
230
Kalle Valo5e3dd152013-06-12 20:52:10 +0300231 switch (key->cipher) {
232 case WLAN_CIPHER_SUITE_CCMP:
233 arg.key_cipher = WMI_CIPHER_AES_CCM;
Marek Kwaczynskie4e82e92015-01-24 12:14:53 +0200234 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300235 break;
236 case WLAN_CIPHER_SUITE_TKIP:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300237 arg.key_cipher = WMI_CIPHER_TKIP;
238 arg.key_txmic_len = 8;
239 arg.key_rxmic_len = 8;
240 break;
241 case WLAN_CIPHER_SUITE_WEP40:
242 case WLAN_CIPHER_SUITE_WEP104:
243 arg.key_cipher = WMI_CIPHER_WEP;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300244 break;
Johannes Berg3cb10942015-01-22 21:38:45 +0100245 case WLAN_CIPHER_SUITE_AES_CMAC:
Bartosz Markowskid7131c02015-03-10 14:32:19 +0100246 WARN_ON(1);
247 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300248 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200249 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300250 return -EOPNOTSUPP;
251 }
252
Kalle Valob9e284e2015-10-05 17:56:35 +0300253 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
David Liuccec9032015-07-24 20:25:32 +0300254 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
David Liuccec9032015-07-24 20:25:32 +0300255
Kalle Valo5e3dd152013-06-12 20:52:10 +0300256 if (cmd == DISABLE_KEY) {
257 arg.key_cipher = WMI_CIPHER_NONE;
258 arg.key_data = NULL;
259 }
260
261 return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
262}
263
264static int ath10k_install_key(struct ath10k_vif *arvif,
265 struct ieee80211_key_conf *key,
266 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100267 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300268{
269 struct ath10k *ar = arvif->ar;
270 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300271 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300272
Michal Kazior548db542013-07-05 16:15:15 +0300273 lockdep_assert_held(&ar->conf_mutex);
274
Wolfram Sang16735d02013-11-14 14:32:02 -0800275 reinit_completion(&ar->install_key_done);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300276
David Liuccec9032015-07-24 20:25:32 +0300277 if (arvif->nohwcrypt)
278 return 1;
279
Michal Kazior370e5672015-02-18 14:02:26 +0100280 ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300281 if (ret)
282 return ret;
283
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300284 time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);
285 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300286 return -ETIMEDOUT;
287
288 return 0;
289}
290
291static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
292 const u8 *addr)
293{
294 struct ath10k *ar = arvif->ar;
295 struct ath10k_peer *peer;
296 int ret;
297 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100298 u32 flags;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300299
300 lockdep_assert_held(&ar->conf_mutex);
301
Michal Kazior8674d902015-08-13 14:10:46 +0200302 if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP &&
Peter Oh7c97b722015-12-03 09:50:55 -0800303 arvif->vif->type != NL80211_IFTYPE_ADHOC &&
304 arvif->vif->type != NL80211_IFTYPE_MESH_POINT))
Michal Kazior8674d902015-08-13 14:10:46 +0200305 return -EINVAL;
306
Kalle Valo5e3dd152013-06-12 20:52:10 +0300307 spin_lock_bh(&ar->data_lock);
308 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
309 spin_unlock_bh(&ar->data_lock);
310
311 if (!peer)
312 return -ENOENT;
313
314 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
315 if (arvif->wep_keys[i] == NULL)
316 continue;
Michal Kazior370e5672015-02-18 14:02:26 +0100317
Michal Kazior8674d902015-08-13 14:10:46 +0200318 switch (arvif->vif->type) {
319 case NL80211_IFTYPE_AP:
320 flags = WMI_KEY_PAIRWISE;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300321
Michal Kazior8674d902015-08-13 14:10:46 +0200322 if (arvif->def_wep_key_idx == i)
323 flags |= WMI_KEY_TX_USAGE;
Michal Kaziorce90b272015-04-10 13:23:21 +0000324
Michal Kazior8674d902015-08-13 14:10:46 +0200325 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
326 SET_KEY, addr, flags);
327 if (ret < 0)
328 return ret;
329 break;
330 case NL80211_IFTYPE_ADHOC:
331 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
332 SET_KEY, addr,
333 WMI_KEY_PAIRWISE);
334 if (ret < 0)
335 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300336
Michal Kazior8674d902015-08-13 14:10:46 +0200337 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
338 SET_KEY, addr, WMI_KEY_GROUP);
339 if (ret < 0)
340 return ret;
341 break;
342 default:
343 WARN_ON(1);
344 return -EINVAL;
345 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300346
Sujith Manoharanae167132014-11-25 11:46:59 +0530347 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300348 peer->keys[i] = arvif->wep_keys[i];
Sujith Manoharanae167132014-11-25 11:46:59 +0530349 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300350 }
351
Michal Kaziorce90b272015-04-10 13:23:21 +0000352 /* In some cases (notably with static WEP IBSS with multiple keys)
353 * multicast Tx becomes broken. Both pairwise and groupwise keys are
354 * installed already. Using WMI_KEY_TX_USAGE in different combinations
355 * didn't seem help. Using def_keyid vdev parameter seems to be
356 * effective so use that.
357 *
358 * FIXME: Revisit. Perhaps this can be done in a less hacky way.
359 */
Michal Kazior8674d902015-08-13 14:10:46 +0200360 if (arvif->vif->type != NL80211_IFTYPE_ADHOC)
361 return 0;
362
Michal Kaziorce90b272015-04-10 13:23:21 +0000363 if (arvif->def_wep_key_idx == -1)
364 return 0;
365
366 ret = ath10k_wmi_vdev_set_param(arvif->ar,
367 arvif->vdev_id,
368 arvif->ar->wmi.vdev_param->def_keyid,
369 arvif->def_wep_key_idx);
370 if (ret) {
371 ath10k_warn(ar, "failed to re-set def wpa key idxon vdev %i: %d\n",
372 arvif->vdev_id, ret);
373 return ret;
374 }
375
Kalle Valo5e3dd152013-06-12 20:52:10 +0300376 return 0;
377}
378
379static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
380 const u8 *addr)
381{
382 struct ath10k *ar = arvif->ar;
383 struct ath10k_peer *peer;
384 int first_errno = 0;
385 int ret;
386 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100387 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300388
389 lockdep_assert_held(&ar->conf_mutex);
390
391 spin_lock_bh(&ar->data_lock);
392 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
393 spin_unlock_bh(&ar->data_lock);
394
395 if (!peer)
396 return -ENOENT;
397
398 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
399 if (peer->keys[i] == NULL)
400 continue;
401
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200402 /* key flags are not required to delete the key */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300403 ret = ath10k_install_key(arvif, peer->keys[i],
Michal Kazior370e5672015-02-18 14:02:26 +0100404 DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300405 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300406 first_errno = ret;
407
David Liuccec9032015-07-24 20:25:32 +0300408 if (ret < 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200409 ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300410 i, ret);
411
Sujith Manoharanae167132014-11-25 11:46:59 +0530412 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300413 peer->keys[i] = NULL;
Sujith Manoharanae167132014-11-25 11:46:59 +0530414 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300415 }
416
417 return first_errno;
418}
419
Sujith Manoharan504f6cd2014-11-25 11:46:58 +0530420bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
421 u8 keyidx)
422{
423 struct ath10k_peer *peer;
424 int i;
425
426 lockdep_assert_held(&ar->data_lock);
427
428 /* We don't know which vdev this peer belongs to,
429 * since WMI doesn't give us that information.
430 *
431 * FIXME: multi-bss needs to be handled.
432 */
433 peer = ath10k_peer_find(ar, 0, addr);
434 if (!peer)
435 return false;
436
437 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
438 if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)
439 return true;
440 }
441
442 return false;
443}
444
Kalle Valo5e3dd152013-06-12 20:52:10 +0300445static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
446 struct ieee80211_key_conf *key)
447{
448 struct ath10k *ar = arvif->ar;
449 struct ath10k_peer *peer;
450 u8 addr[ETH_ALEN];
451 int first_errno = 0;
452 int ret;
453 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100454 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300455
456 lockdep_assert_held(&ar->conf_mutex);
457
458 for (;;) {
459 /* since ath10k_install_key we can't hold data_lock all the
460 * time, so we try to remove the keys incrementally */
461 spin_lock_bh(&ar->data_lock);
462 i = 0;
463 list_for_each_entry(peer, &ar->peers, list) {
464 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
465 if (peer->keys[i] == key) {
Kalle Valob25f32c2014-09-14 12:50:49 +0300466 ether_addr_copy(addr, peer->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300467 peer->keys[i] = NULL;
468 break;
469 }
470 }
471
472 if (i < ARRAY_SIZE(peer->keys))
473 break;
474 }
475 spin_unlock_bh(&ar->data_lock);
476
477 if (i == ARRAY_SIZE(peer->keys))
478 break;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200479 /* key flags are not required to delete the key */
Michal Kazior370e5672015-02-18 14:02:26 +0100480 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300481 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300482 first_errno = ret;
483
484 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200485 ath10k_warn(ar, "failed to remove key for %pM: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +0200486 addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300487 }
488
489 return first_errno;
490}
491
Michal Kaziorad325cb2015-02-18 14:02:27 +0100492static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
493 struct ieee80211_key_conf *key)
494{
495 struct ath10k *ar = arvif->ar;
496 struct ath10k_peer *peer;
497 int ret;
498
499 lockdep_assert_held(&ar->conf_mutex);
500
501 list_for_each_entry(peer, &ar->peers, list) {
Kalle Valoc178da52016-04-13 14:13:49 +0300502 if (ether_addr_equal(peer->addr, arvif->vif->addr))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100503 continue;
504
Kalle Valoc178da52016-04-13 14:13:49 +0300505 if (ether_addr_equal(peer->addr, arvif->bssid))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100506 continue;
507
508 if (peer->keys[key->keyidx] == key)
509 continue;
510
511 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
512 arvif->vdev_id, key->keyidx);
513
514 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
515 if (ret) {
516 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
517 arvif->vdev_id, peer->addr, ret);
518 return ret;
519 }
520 }
521
522 return 0;
523}
524
Kalle Valo5e3dd152013-06-12 20:52:10 +0300525/*********************/
526/* General utilities */
527/*********************/
528
529static inline enum wmi_phy_mode
530chan_to_phymode(const struct cfg80211_chan_def *chandef)
531{
532 enum wmi_phy_mode phymode = MODE_UNKNOWN;
533
534 switch (chandef->chan->band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +0200535 case NL80211_BAND_2GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300536 switch (chandef->width) {
537 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800538 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
539 phymode = MODE_11B;
540 else
541 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300542 break;
543 case NL80211_CHAN_WIDTH_20:
544 phymode = MODE_11NG_HT20;
545 break;
546 case NL80211_CHAN_WIDTH_40:
547 phymode = MODE_11NG_HT40;
548 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400549 case NL80211_CHAN_WIDTH_5:
550 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300551 case NL80211_CHAN_WIDTH_80:
552 case NL80211_CHAN_WIDTH_80P80:
553 case NL80211_CHAN_WIDTH_160:
554 phymode = MODE_UNKNOWN;
555 break;
556 }
557 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +0200558 case NL80211_BAND_5GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300559 switch (chandef->width) {
560 case NL80211_CHAN_WIDTH_20_NOHT:
561 phymode = MODE_11A;
562 break;
563 case NL80211_CHAN_WIDTH_20:
564 phymode = MODE_11NA_HT20;
565 break;
566 case NL80211_CHAN_WIDTH_40:
567 phymode = MODE_11NA_HT40;
568 break;
569 case NL80211_CHAN_WIDTH_80:
570 phymode = MODE_11AC_VHT80;
571 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400572 case NL80211_CHAN_WIDTH_5:
573 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300574 case NL80211_CHAN_WIDTH_80P80:
575 case NL80211_CHAN_WIDTH_160:
576 phymode = MODE_UNKNOWN;
577 break;
578 }
579 break;
580 default:
581 break;
582 }
583
584 WARN_ON(phymode == MODE_UNKNOWN);
585 return phymode;
586}
587
588static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
589{
590/*
591 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
592 * 0 for no restriction
593 * 1 for 1/4 us
594 * 2 for 1/2 us
595 * 3 for 1 us
596 * 4 for 2 us
597 * 5 for 4 us
598 * 6 for 8 us
599 * 7 for 16 us
600 */
601 switch (mpdudensity) {
602 case 0:
603 return 0;
604 case 1:
605 case 2:
606 case 3:
607 /* Our lower layer calculations limit our precision to
608 1 microsecond */
609 return 1;
610 case 4:
611 return 2;
612 case 5:
613 return 4;
614 case 6:
615 return 8;
616 case 7:
617 return 16;
618 default:
619 return 0;
620 }
621}
622
Michal Kazior500ff9f2015-03-31 10:26:21 +0000623int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
624 struct cfg80211_chan_def *def)
625{
626 struct ieee80211_chanctx_conf *conf;
627
628 rcu_read_lock();
629 conf = rcu_dereference(vif->chanctx_conf);
630 if (!conf) {
631 rcu_read_unlock();
632 return -ENOENT;
633 }
634
635 *def = conf->def;
636 rcu_read_unlock();
637
638 return 0;
639}
640
641static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,
642 struct ieee80211_chanctx_conf *conf,
643 void *data)
644{
645 int *num = data;
646
647 (*num)++;
648}
649
650static int ath10k_mac_num_chanctxs(struct ath10k *ar)
651{
652 int num = 0;
653
654 ieee80211_iter_chan_contexts_atomic(ar->hw,
655 ath10k_mac_num_chanctxs_iter,
656 &num);
657
658 return num;
659}
660
661static void
662ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
663 struct ieee80211_chanctx_conf *conf,
664 void *data)
665{
666 struct cfg80211_chan_def **def = data;
667
668 *def = &conf->def;
669}
670
Michal Kazior69427262016-03-06 16:14:30 +0200671static int ath10k_peer_create(struct ath10k *ar,
672 struct ieee80211_vif *vif,
673 struct ieee80211_sta *sta,
674 u32 vdev_id,
675 const u8 *addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300676 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300677{
Michal Kaziore04cafb2015-08-05 12:15:24 +0200678 struct ath10k_vif *arvif;
Michal Kazior69427262016-03-06 16:14:30 +0200679 struct ath10k_peer *peer;
Michal Kaziore04cafb2015-08-05 12:15:24 +0200680 int num_peers = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300681 int ret;
682
683 lockdep_assert_held(&ar->conf_mutex);
684
Michal Kaziore04cafb2015-08-05 12:15:24 +0200685 num_peers = ar->num_peers;
686
687 /* Each vdev consumes a peer entry as well */
688 list_for_each_entry(arvif, &ar->arvifs, list)
689 num_peers++;
690
691 if (num_peers >= ar->max_num_peers)
Michal Kaziorcfd10612014-11-25 15:16:05 +0100692 return -ENOBUFS;
693
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300694 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800695 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200696 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200697 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300698 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800699 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300700
701 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800702 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200703 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200704 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300705 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800706 }
Michal Kazior292a7532014-11-25 15:16:04 +0100707
Michal Kazior69427262016-03-06 16:14:30 +0200708 spin_lock_bh(&ar->data_lock);
709
710 peer = ath10k_peer_find(ar, vdev_id, addr);
711 if (!peer) {
Ben Greearfee48cf2016-04-01 14:12:12 -0700712 spin_unlock_bh(&ar->data_lock);
Michal Kazior69427262016-03-06 16:14:30 +0200713 ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n",
714 addr, vdev_id);
715 ath10k_wmi_peer_delete(ar, vdev_id, addr);
Michal Kazior69427262016-03-06 16:14:30 +0200716 return -ENOENT;
717 }
718
719 peer->vif = vif;
720 peer->sta = sta;
721
722 spin_unlock_bh(&ar->data_lock);
723
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100724 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300725
726 return 0;
727}
728
Kalle Valo5a13e762014-01-20 11:01:46 +0200729static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
730{
731 struct ath10k *ar = arvif->ar;
732 u32 param;
733 int ret;
734
735 param = ar->wmi.pdev_param->sta_kickout_th;
736 ret = ath10k_wmi_pdev_set_param(ar, param,
737 ATH10K_KICKOUT_THRESHOLD);
738 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200739 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200740 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200741 return ret;
742 }
743
744 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
745 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
746 ATH10K_KEEPALIVE_MIN_IDLE);
747 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200748 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200749 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200750 return ret;
751 }
752
753 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
754 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
755 ATH10K_KEEPALIVE_MAX_IDLE);
756 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200757 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200758 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200759 return ret;
760 }
761
762 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
763 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
764 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
765 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200766 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200767 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200768 return ret;
769 }
770
771 return 0;
772}
773
Vivek Natarajanacab6402014-11-26 09:06:12 +0200774static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200775{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200776 struct ath10k *ar = arvif->ar;
777 u32 vdev_param;
778
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200779 vdev_param = ar->wmi.vdev_param->rts_threshold;
780 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200781}
782
Kalle Valo5e3dd152013-06-12 20:52:10 +0300783static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
784{
785 int ret;
786
787 lockdep_assert_held(&ar->conf_mutex);
788
789 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
790 if (ret)
791 return ret;
792
793 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
794 if (ret)
795 return ret;
796
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100797 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100798
Kalle Valo5e3dd152013-06-12 20:52:10 +0300799 return 0;
800}
801
802static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
803{
804 struct ath10k_peer *peer, *tmp;
Michal Kazior69427262016-03-06 16:14:30 +0200805 int peer_id;
Ben Greear6d68f792016-06-30 15:23:53 +0300806 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300807
808 lockdep_assert_held(&ar->conf_mutex);
809
810 spin_lock_bh(&ar->data_lock);
811 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
812 if (peer->vdev_id != vdev_id)
813 continue;
814
Michal Kazior7aa7a722014-08-25 12:09:38 +0200815 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300816 peer->addr, vdev_id);
817
Michal Kazior69427262016-03-06 16:14:30 +0200818 for_each_set_bit(peer_id, peer->peer_ids,
819 ATH10K_MAX_NUM_PEER_IDS) {
820 ar->peer_map[peer_id] = NULL;
821 }
822
Ben Greear6d68f792016-06-30 15:23:53 +0300823 /* Double check that peer is properly un-referenced from
824 * the peer_map
825 */
826 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
827 if (ar->peer_map[i] == peer) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +0530828 ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
Ben Greear6d68f792016-06-30 15:23:53 +0300829 peer->addr, peer, i);
830 ar->peer_map[i] = NULL;
831 }
832 }
833
Kalle Valo5e3dd152013-06-12 20:52:10 +0300834 list_del(&peer->list);
835 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100836 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300837 }
838 spin_unlock_bh(&ar->data_lock);
839}
840
Michal Kaziora96d7742013-07-16 09:38:56 +0200841static void ath10k_peer_cleanup_all(struct ath10k *ar)
842{
843 struct ath10k_peer *peer, *tmp;
Ben Greear6d68f792016-06-30 15:23:53 +0300844 int i;
Michal Kaziora96d7742013-07-16 09:38:56 +0200845
846 lockdep_assert_held(&ar->conf_mutex);
847
848 spin_lock_bh(&ar->data_lock);
849 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
850 list_del(&peer->list);
851 kfree(peer);
852 }
Ben Greear6d68f792016-06-30 15:23:53 +0300853
854 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
855 ar->peer_map[i] = NULL;
856
Michal Kaziora96d7742013-07-16 09:38:56 +0200857 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100858
859 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100860 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200861}
862
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300863static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
864 struct ieee80211_sta *sta,
865 enum wmi_tdls_peer_state state)
866{
867 int ret;
868 struct wmi_tdls_peer_update_cmd_arg arg = {};
869 struct wmi_tdls_peer_capab_arg cap = {};
870 struct wmi_channel_arg chan_arg = {};
871
872 lockdep_assert_held(&ar->conf_mutex);
873
874 arg.vdev_id = vdev_id;
875 arg.peer_state = state;
876 ether_addr_copy(arg.addr, sta->addr);
877
878 cap.peer_max_sp = sta->max_sp;
879 cap.peer_uapsd_queues = sta->uapsd_queues;
880
881 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
882 !sta->tdls_initiator)
883 cap.is_peer_responder = 1;
884
885 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
886 if (ret) {
887 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
888 arg.addr, vdev_id, ret);
889 return ret;
890 }
891
892 return 0;
893}
894
Kalle Valo5e3dd152013-06-12 20:52:10 +0300895/************************/
896/* Interface management */
897/************************/
898
Michal Kazior64badcb2014-09-18 11:18:02 +0300899void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
900{
901 struct ath10k *ar = arvif->ar;
902
903 lockdep_assert_held(&ar->data_lock);
904
905 if (!arvif->beacon)
906 return;
907
908 if (!arvif->beacon_buf)
909 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
910 arvif->beacon->len, DMA_TO_DEVICE);
911
Michal Kazioraf213192015-01-29 14:29:52 +0200912 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
913 arvif->beacon_state != ATH10K_BEACON_SENT))
914 return;
915
Michal Kazior64badcb2014-09-18 11:18:02 +0300916 dev_kfree_skb_any(arvif->beacon);
917
918 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200919 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300920}
921
922static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
923{
924 struct ath10k *ar = arvif->ar;
925
926 lockdep_assert_held(&ar->data_lock);
927
928 ath10k_mac_vif_beacon_free(arvif);
929
930 if (arvif->beacon_buf) {
931 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
932 arvif->beacon_buf, arvif->beacon_paddr);
933 arvif->beacon_buf = NULL;
934 }
935}
936
Kalle Valo5e3dd152013-06-12 20:52:10 +0300937static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
938{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300939 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300940
Michal Kazior548db542013-07-05 16:15:15 +0300941 lockdep_assert_held(&ar->conf_mutex);
942
Michal Kazior7962b0d2014-10-28 10:34:38 +0100943 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
944 return -ESHUTDOWN;
945
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300946 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
947 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
948 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300949 return -ETIMEDOUT;
950
951 return 0;
952}
953
Michal Kazior1bbc0972014-04-08 09:45:47 +0300954static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300955{
Michal Kazior500ff9f2015-03-31 10:26:21 +0000956 struct cfg80211_chan_def *chandef = NULL;
Maninder Singh19be9e92015-07-16 09:25:33 +0530957 struct ieee80211_channel *channel = NULL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300958 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300959 int ret = 0;
960
961 lockdep_assert_held(&ar->conf_mutex);
962
Michal Kazior500ff9f2015-03-31 10:26:21 +0000963 ieee80211_iter_chan_contexts_atomic(ar->hw,
964 ath10k_mac_get_any_chandef_iter,
965 &chandef);
966 if (WARN_ON_ONCE(!chandef))
967 return -ENOENT;
968
969 channel = chandef->chan;
970
Kalle Valo5e3dd152013-06-12 20:52:10 +0300971 arg.vdev_id = vdev_id;
972 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +0100973 arg.channel.band_center_freq1 = chandef->center_freq1;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300974
975 /* TODO setup this dynamically, what in case we
976 don't have any vifs? */
Michal Kaziorc930f742014-01-23 11:38:25 +0100977 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200978 arg.channel.chan_radar =
979 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300980
Michal Kazior89c5c842013-10-23 04:02:13 -0700981 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -0700982 arg.channel.max_power = channel->max_power * 2;
983 arg.channel.max_reg_power = channel->max_reg_power * 2;
984 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300985
Michal Kazior7962b0d2014-10-28 10:34:38 +0100986 reinit_completion(&ar->vdev_setup_done);
987
Kalle Valo5e3dd152013-06-12 20:52:10 +0300988 ret = ath10k_wmi_vdev_start(ar, &arg);
989 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200990 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200991 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300992 return ret;
993 }
994
995 ret = ath10k_vdev_setup_sync(ar);
996 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +0200997 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200998 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300999 return ret;
1000 }
1001
1002 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
1003 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001004 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001005 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001006 goto vdev_stop;
1007 }
1008
1009 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001010
Michal Kazior7aa7a722014-08-25 12:09:38 +02001011 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001012 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001013 return 0;
1014
1015vdev_stop:
1016 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1017 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001018 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001019 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001020
1021 return ret;
1022}
1023
Michal Kazior1bbc0972014-04-08 09:45:47 +03001024static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001025{
1026 int ret = 0;
1027
1028 lockdep_assert_held(&ar->conf_mutex);
1029
Marek Puzyniak52fa0192013-09-24 14:06:24 +02001030 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
1031 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001032 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001033 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001034
Michal Kazior7962b0d2014-10-28 10:34:38 +01001035 reinit_completion(&ar->vdev_setup_done);
1036
Kalle Valo5e3dd152013-06-12 20:52:10 +03001037 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1038 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001039 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001040 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001041
1042 ret = ath10k_vdev_setup_sync(ar);
1043 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +02001044 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001045 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001046
Michal Kazior7aa7a722014-08-25 12:09:38 +02001047 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001048 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001049 return ret;
1050}
1051
Michal Kazior1bbc0972014-04-08 09:45:47 +03001052static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001053{
1054 int bit, ret = 0;
1055
1056 lockdep_assert_held(&ar->conf_mutex);
1057
Ben Greeara9aefb32014-08-12 11:02:19 +03001058 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001059 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03001060 return -ENOMEM;
1061 }
1062
Ben Greear16c11172014-09-23 14:17:16 -07001063 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +03001064
Ben Greear16c11172014-09-23 14:17:16 -07001065 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001066
1067 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
1068 WMI_VDEV_TYPE_MONITOR,
1069 0, ar->mac_addr);
1070 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001071 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001072 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +03001073 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001074 }
1075
Ben Greear16c11172014-09-23 14:17:16 -07001076 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +02001077 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001078 ar->monitor_vdev_id);
1079
Kalle Valo5e3dd152013-06-12 20:52:10 +03001080 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001081}
1082
Michal Kazior1bbc0972014-04-08 09:45:47 +03001083static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001084{
1085 int ret = 0;
1086
1087 lockdep_assert_held(&ar->conf_mutex);
1088
Kalle Valo5e3dd152013-06-12 20:52:10 +03001089 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
1090 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001091 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001092 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001093 return ret;
1094 }
1095
Ben Greear16c11172014-09-23 14:17:16 -07001096 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001097
Michal Kazior7aa7a722014-08-25 12:09:38 +02001098 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001099 ar->monitor_vdev_id);
1100 return ret;
1101}
1102
Michal Kazior1bbc0972014-04-08 09:45:47 +03001103static int ath10k_monitor_start(struct ath10k *ar)
1104{
1105 int ret;
1106
1107 lockdep_assert_held(&ar->conf_mutex);
1108
Michal Kazior1bbc0972014-04-08 09:45:47 +03001109 ret = ath10k_monitor_vdev_create(ar);
1110 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001111 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001112 return ret;
1113 }
1114
1115 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
1116 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001117 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001118 ath10k_monitor_vdev_delete(ar);
1119 return ret;
1120 }
1121
1122 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001123 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +03001124
1125 return 0;
1126}
1127
Michal Kazior19337472014-08-28 12:58:16 +02001128static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +03001129{
1130 int ret;
1131
1132 lockdep_assert_held(&ar->conf_mutex);
1133
Michal Kazior1bbc0972014-04-08 09:45:47 +03001134 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001135 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001136 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001137 return ret;
1138 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001139
1140 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001141 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001142 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001143 return ret;
1144 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001145
1146 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001147 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +02001148
1149 return 0;
1150}
1151
Michal Kazior500ff9f2015-03-31 10:26:21 +00001152static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1153{
1154 int num_ctx;
1155
1156 /* At least one chanctx is required to derive a channel to start
1157 * monitor vdev on.
1158 */
1159 num_ctx = ath10k_mac_num_chanctxs(ar);
1160 if (num_ctx == 0)
1161 return false;
1162
1163 /* If there's already an existing special monitor interface then don't
1164 * bother creating another monitor vdev.
1165 */
1166 if (ar->monitor_arvif)
1167 return false;
1168
1169 return ar->monitor ||
Manoharan, Rajkumar705d7aa2016-11-23 16:58:11 +02001170 (!test_bit(ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST,
1171 ar->running_fw->fw_file.fw_features) &&
1172 (ar->filter_flags & FIF_OTHER_BSS)) ||
Michal Kazior500ff9f2015-03-31 10:26:21 +00001173 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1174}
1175
1176static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1177{
1178 int num_ctx;
1179
1180 num_ctx = ath10k_mac_num_chanctxs(ar);
1181
1182 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1183 * shouldn't allow this but make sure to prevent handling the following
1184 * case anyway since multi-channel DFS hasn't been tested at all.
1185 */
1186 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1187 return false;
1188
1189 return true;
1190}
1191
Michal Kazior19337472014-08-28 12:58:16 +02001192static int ath10k_monitor_recalc(struct ath10k *ar)
1193{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001194 bool needed;
1195 bool allowed;
1196 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001197
1198 lockdep_assert_held(&ar->conf_mutex);
1199
Michal Kazior500ff9f2015-03-31 10:26:21 +00001200 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1201 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001202
1203 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001204 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1205 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001206
Michal Kazior500ff9f2015-03-31 10:26:21 +00001207 if (WARN_ON(needed && !allowed)) {
1208 if (ar->monitor_started) {
1209 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1210
1211 ret = ath10k_monitor_stop(ar);
1212 if (ret)
Kalle Valo2a995082015-10-05 17:56:37 +03001213 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",
1214 ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001215 /* not serious */
1216 }
1217
1218 return -EPERM;
1219 }
1220
1221 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001222 return 0;
1223
Michal Kazior500ff9f2015-03-31 10:26:21 +00001224 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001225 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001226 else
1227 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001228}
1229
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02001230static bool ath10k_mac_can_set_cts_prot(struct ath10k_vif *arvif)
1231{
1232 struct ath10k *ar = arvif->ar;
1233
1234 lockdep_assert_held(&ar->conf_mutex);
1235
1236 if (!arvif->is_started) {
1237 ath10k_dbg(ar, ATH10K_DBG_MAC, "defer cts setup, vdev is not ready yet\n");
1238 return false;
1239 }
1240
1241 return true;
1242}
1243
1244static int ath10k_mac_set_cts_prot(struct ath10k_vif *arvif)
1245{
1246 struct ath10k *ar = arvif->ar;
1247 u32 vdev_param;
1248
1249 lockdep_assert_held(&ar->conf_mutex);
1250
1251 vdev_param = ar->wmi.vdev_param->protection_mode;
1252
1253 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_protection %d\n",
1254 arvif->vdev_id, arvif->use_cts_prot);
1255
1256 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1257 arvif->use_cts_prot ? 1 : 0);
1258}
1259
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001260static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1261{
1262 struct ath10k *ar = arvif->ar;
1263 u32 vdev_param, rts_cts = 0;
1264
1265 lockdep_assert_held(&ar->conf_mutex);
1266
1267 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1268
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001269 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001270
1271 if (arvif->num_legacy_stations > 0)
1272 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1273 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001274 else
1275 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1276 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001277
Bartosz Markowski86176902016-12-15 11:23:24 +02001278 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d recalc rts/cts prot %d\n",
1279 arvif->vdev_id, rts_cts);
1280
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001281 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1282 rts_cts);
1283}
1284
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001285static int ath10k_start_cac(struct ath10k *ar)
1286{
1287 int ret;
1288
1289 lockdep_assert_held(&ar->conf_mutex);
1290
1291 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1292
Michal Kazior19337472014-08-28 12:58:16 +02001293 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001294 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001295 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001296 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1297 return ret;
1298 }
1299
Michal Kazior7aa7a722014-08-25 12:09:38 +02001300 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001301 ar->monitor_vdev_id);
1302
1303 return 0;
1304}
1305
1306static int ath10k_stop_cac(struct ath10k *ar)
1307{
1308 lockdep_assert_held(&ar->conf_mutex);
1309
1310 /* CAC is not running - do nothing */
1311 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1312 return 0;
1313
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001314 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001315 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001316
Michal Kazior7aa7a722014-08-25 12:09:38 +02001317 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001318
1319 return 0;
1320}
1321
Michal Kazior500ff9f2015-03-31 10:26:21 +00001322static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1323 struct ieee80211_chanctx_conf *conf,
1324 void *data)
1325{
1326 bool *ret = data;
1327
1328 if (!*ret && conf->radar_enabled)
1329 *ret = true;
1330}
1331
1332static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1333{
1334 bool has_radar = false;
1335
1336 ieee80211_iter_chan_contexts_atomic(ar->hw,
1337 ath10k_mac_has_radar_iter,
1338 &has_radar);
1339
1340 return has_radar;
1341}
1342
Michal Kaziord6500972014-04-08 09:56:09 +03001343static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001344{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001345 int ret;
1346
1347 lockdep_assert_held(&ar->conf_mutex);
1348
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001349 ath10k_stop_cac(ar);
1350
Michal Kazior500ff9f2015-03-31 10:26:21 +00001351 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001352 return;
1353
Michal Kaziord6500972014-04-08 09:56:09 +03001354 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001355 return;
1356
1357 ret = ath10k_start_cac(ar);
1358 if (ret) {
1359 /*
1360 * Not possible to start CAC on current channel so starting
1361 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1362 * by indicating that radar was detected.
1363 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001364 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001365 ieee80211_radar_detected(ar->hw);
1366 }
1367}
1368
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301369static int ath10k_vdev_stop(struct ath10k_vif *arvif)
Michal Kazior72654fa2014-04-08 09:56:09 +03001370{
1371 struct ath10k *ar = arvif->ar;
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301372 int ret;
1373
1374 lockdep_assert_held(&ar->conf_mutex);
1375
1376 reinit_completion(&ar->vdev_setup_done);
1377
1378 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1379 if (ret) {
1380 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1381 arvif->vdev_id, ret);
1382 return ret;
1383 }
1384
1385 ret = ath10k_vdev_setup_sync(ar);
1386 if (ret) {
1387 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
1388 arvif->vdev_id, ret);
1389 return ret;
1390 }
1391
1392 WARN_ON(ar->num_started_vdevs == 0);
1393
1394 if (ar->num_started_vdevs != 0) {
1395 ar->num_started_vdevs--;
1396 ath10k_recalc_radar_detection(ar);
1397 }
1398
1399 return ret;
1400}
1401
Michal Kazior500ff9f2015-03-31 10:26:21 +00001402static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1403 const struct cfg80211_chan_def *chandef,
1404 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001405{
1406 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001407 struct wmi_vdev_start_request_arg arg = {};
1408 int ret = 0;
1409
1410 lockdep_assert_held(&ar->conf_mutex);
1411
1412 reinit_completion(&ar->vdev_setup_done);
1413
1414 arg.vdev_id = arvif->vdev_id;
1415 arg.dtim_period = arvif->dtim_period;
1416 arg.bcn_intval = arvif->beacon_interval;
1417
1418 arg.channel.freq = chandef->chan->center_freq;
1419 arg.channel.band_center_freq1 = chandef->center_freq1;
1420 arg.channel.mode = chan_to_phymode(chandef);
1421
1422 arg.channel.min_power = 0;
1423 arg.channel.max_power = chandef->chan->max_power * 2;
1424 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1425 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1426
1427 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1428 arg.ssid = arvif->u.ap.ssid;
1429 arg.ssid_len = arvif->u.ap.ssid_len;
1430 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1431
1432 /* For now allow DFS for AP mode */
1433 arg.channel.chan_radar =
1434 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1435 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1436 arg.ssid = arvif->vif->bss_conf.ssid;
1437 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1438 }
1439
Michal Kazior7aa7a722014-08-25 12:09:38 +02001440 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001441 "mac vdev %d start center_freq %d phymode %s\n",
1442 arg.vdev_id, arg.channel.freq,
1443 ath10k_wmi_phymode_str(arg.channel.mode));
1444
Michal Kaziordc55e302014-07-29 12:53:36 +03001445 if (restart)
1446 ret = ath10k_wmi_vdev_restart(ar, &arg);
1447 else
1448 ret = ath10k_wmi_vdev_start(ar, &arg);
1449
Michal Kazior72654fa2014-04-08 09:56:09 +03001450 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001451 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001452 arg.vdev_id, ret);
1453 return ret;
1454 }
1455
1456 ret = ath10k_vdev_setup_sync(ar);
1457 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001458 ath10k_warn(ar,
1459 "failed to synchronize setup for vdev %i restart %d: %d\n",
1460 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001461 return ret;
1462 }
1463
Michal Kaziord6500972014-04-08 09:56:09 +03001464 ar->num_started_vdevs++;
1465 ath10k_recalc_radar_detection(ar);
1466
Michal Kazior72654fa2014-04-08 09:56:09 +03001467 return ret;
1468}
1469
Michal Kazior500ff9f2015-03-31 10:26:21 +00001470static int ath10k_vdev_start(struct ath10k_vif *arvif,
1471 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001472{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001473 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001474}
1475
Michal Kazior500ff9f2015-03-31 10:26:21 +00001476static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1477 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001478{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001479 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kazior72654fa2014-04-08 09:56:09 +03001480}
1481
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001482static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1483 struct sk_buff *bcn)
1484{
1485 struct ath10k *ar = arvif->ar;
1486 struct ieee80211_mgmt *mgmt;
1487 const u8 *p2p_ie;
1488 int ret;
1489
Peter Oh08c27be2016-01-28 13:54:09 -08001490 if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001491 return 0;
1492
1493 mgmt = (void *)bcn->data;
1494 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1495 mgmt->u.beacon.variable,
1496 bcn->len - (mgmt->u.beacon.variable -
1497 bcn->data));
1498 if (!p2p_ie)
1499 return -ENOENT;
1500
1501 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1502 if (ret) {
1503 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1504 arvif->vdev_id, ret);
1505 return ret;
1506 }
1507
1508 return 0;
1509}
1510
1511static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1512 u8 oui_type, size_t ie_offset)
1513{
1514 size_t len;
1515 const u8 *next;
1516 const u8 *end;
1517 u8 *ie;
1518
1519 if (WARN_ON(skb->len < ie_offset))
1520 return -EINVAL;
1521
1522 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1523 skb->data + ie_offset,
1524 skb->len - ie_offset);
1525 if (!ie)
1526 return -ENOENT;
1527
1528 len = ie[1] + 2;
1529 end = skb->data + skb->len;
1530 next = ie + len;
1531
1532 if (WARN_ON(next > end))
1533 return -EINVAL;
1534
1535 memmove(ie, next, end - next);
1536 skb_trim(skb, skb->len - len);
1537
1538 return 0;
1539}
1540
1541static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1542{
1543 struct ath10k *ar = arvif->ar;
1544 struct ieee80211_hw *hw = ar->hw;
1545 struct ieee80211_vif *vif = arvif->vif;
1546 struct ieee80211_mutable_offsets offs = {};
1547 struct sk_buff *bcn;
1548 int ret;
1549
1550 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1551 return 0;
1552
Michal Kazior81a9a172015-03-05 16:02:17 +02001553 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1554 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1555 return 0;
1556
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001557 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1558 if (!bcn) {
1559 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1560 return -EPERM;
1561 }
1562
1563 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1564 if (ret) {
1565 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1566 kfree_skb(bcn);
1567 return ret;
1568 }
1569
1570 /* P2P IE is inserted by firmware automatically (as configured above)
1571 * so remove it from the base beacon template to avoid duplicate P2P
1572 * IEs in beacon frames.
1573 */
1574 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1575 offsetof(struct ieee80211_mgmt,
1576 u.beacon.variable));
1577
1578 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1579 0, NULL, 0);
1580 kfree_skb(bcn);
1581
1582 if (ret) {
1583 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1584 ret);
1585 return ret;
1586 }
1587
1588 return 0;
1589}
1590
1591static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1592{
1593 struct ath10k *ar = arvif->ar;
1594 struct ieee80211_hw *hw = ar->hw;
1595 struct ieee80211_vif *vif = arvif->vif;
1596 struct sk_buff *prb;
1597 int ret;
1598
1599 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1600 return 0;
1601
Michal Kazior81a9a172015-03-05 16:02:17 +02001602 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1603 return 0;
1604
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001605 prb = ieee80211_proberesp_get(hw, vif);
1606 if (!prb) {
1607 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1608 return -EPERM;
1609 }
1610
1611 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1612 kfree_skb(prb);
1613
1614 if (ret) {
1615 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1616 ret);
1617 return ret;
1618 }
1619
1620 return 0;
1621}
1622
Michal Kazior500ff9f2015-03-31 10:26:21 +00001623static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1624{
1625 struct ath10k *ar = arvif->ar;
1626 struct cfg80211_chan_def def;
1627 int ret;
1628
1629 /* When originally vdev is started during assign_vif_chanctx() some
1630 * information is missing, notably SSID. Firmware revisions with beacon
1631 * offloading require the SSID to be provided during vdev (re)start to
1632 * handle hidden SSID properly.
1633 *
1634 * Vdev restart must be done after vdev has been both started and
1635 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1636 * deliver vdev restart response event causing timeouts during vdev
1637 * syncing in ath10k.
1638 *
1639 * Note: The vdev down/up and template reinstallation could be skipped
1640 * since only wmi-tlv firmware are known to have beacon offload and
1641 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1642 * response delivery. It's probably more robust to keep it as is.
1643 */
1644 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1645 return 0;
1646
1647 if (WARN_ON(!arvif->is_started))
1648 return -EINVAL;
1649
1650 if (WARN_ON(!arvif->is_up))
1651 return -EINVAL;
1652
1653 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1654 return -EINVAL;
1655
1656 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1657 if (ret) {
1658 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1659 arvif->vdev_id, ret);
1660 return ret;
1661 }
1662
1663 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1664 * firmware will crash upon vdev up.
1665 */
1666
1667 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1668 if (ret) {
1669 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1670 return ret;
1671 }
1672
1673 ret = ath10k_mac_setup_prb_tmpl(arvif);
1674 if (ret) {
1675 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1676 return ret;
1677 }
1678
1679 ret = ath10k_vdev_restart(arvif, &def);
1680 if (ret) {
1681 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1682 arvif->vdev_id, ret);
1683 return ret;
1684 }
1685
1686 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1687 arvif->bssid);
1688 if (ret) {
1689 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1690 arvif->vdev_id, ret);
1691 return ret;
1692 }
1693
1694 return 0;
1695}
1696
Kalle Valo5e3dd152013-06-12 20:52:10 +03001697static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001698 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001699{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001700 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001701 int ret = 0;
1702
Michal Kazior548db542013-07-05 16:15:15 +03001703 lockdep_assert_held(&arvif->ar->conf_mutex);
1704
Kalle Valo5e3dd152013-06-12 20:52:10 +03001705 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001706 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1707 if (ret)
1708 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1709 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001710
Michal Kaziorc930f742014-01-23 11:38:25 +01001711 arvif->is_up = false;
1712
Michal Kazior748afc42014-01-23 12:48:21 +01001713 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001714 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001715 spin_unlock_bh(&arvif->ar->data_lock);
1716
Kalle Valo5e3dd152013-06-12 20:52:10 +03001717 return;
1718 }
1719
1720 arvif->tx_seq_no = 0x1000;
1721
Michal Kaziorc930f742014-01-23 11:38:25 +01001722 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001723 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001724
1725 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1726 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001727 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001728 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001729 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001730 return;
1731 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001732
Michal Kaziorc930f742014-01-23 11:38:25 +01001733 arvif->is_up = true;
1734
Michal Kazior500ff9f2015-03-31 10:26:21 +00001735 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1736 if (ret) {
1737 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1738 arvif->vdev_id, ret);
1739 return;
1740 }
1741
Michal Kazior7aa7a722014-08-25 12:09:38 +02001742 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001743}
1744
1745static void ath10k_control_ibss(struct ath10k_vif *arvif,
1746 struct ieee80211_bss_conf *info,
1747 const u8 self_peer[ETH_ALEN])
1748{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001749 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001750 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001751 int ret = 0;
1752
Michal Kazior548db542013-07-05 16:15:15 +03001753 lockdep_assert_held(&arvif->ar->conf_mutex);
1754
Kalle Valo5e3dd152013-06-12 20:52:10 +03001755 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001756 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001757 return;
1758
Joe Perches93803b32015-03-02 19:54:49 -08001759 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001760
1761 return;
1762 }
1763
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001764 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1765 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001766 ATH10K_DEFAULT_ATIM);
1767 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001768 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001769 arvif->vdev_id, ret);
1770}
1771
Michal Kazior9f9b5742014-12-12 12:41:36 +01001772static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1773{
1774 struct ath10k *ar = arvif->ar;
1775 u32 param;
1776 u32 value;
1777 int ret;
1778
1779 lockdep_assert_held(&arvif->ar->conf_mutex);
1780
1781 if (arvif->u.sta.uapsd)
1782 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1783 else
1784 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1785
1786 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1787 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1788 if (ret) {
1789 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1790 value, arvif->vdev_id, ret);
1791 return ret;
1792 }
1793
1794 return 0;
1795}
1796
1797static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1798{
1799 struct ath10k *ar = arvif->ar;
1800 u32 param;
1801 u32 value;
1802 int ret;
1803
1804 lockdep_assert_held(&arvif->ar->conf_mutex);
1805
1806 if (arvif->u.sta.uapsd)
1807 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1808 else
1809 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1810
1811 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1812 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1813 param, value);
1814 if (ret) {
1815 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1816 value, arvif->vdev_id, ret);
1817 return ret;
1818 }
1819
1820 return 0;
1821}
1822
Michal Kazior424f2632015-07-09 13:08:35 +02001823static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001824{
1825 struct ath10k_vif *arvif;
1826 int num = 0;
1827
1828 lockdep_assert_held(&ar->conf_mutex);
1829
1830 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001831 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001832 num++;
1833
1834 return num;
1835}
1836
Michal Kaziorad088bf2013-10-16 15:44:46 +03001837static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001838{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001839 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001840 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001841 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001842 enum wmi_sta_powersave_param param;
1843 enum wmi_sta_ps_mode psmode;
1844 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001845 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001846 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001847
Michal Kazior548db542013-07-05 16:15:15 +03001848 lockdep_assert_held(&arvif->ar->conf_mutex);
1849
Michal Kaziorad088bf2013-10-16 15:44:46 +03001850 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1851 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001852
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001853 enable_ps = arvif->ps;
1854
Michal Kazior424f2632015-07-09 13:08:35 +02001855 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001856 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
Kalle Valoc4cdf752016-04-20 19:45:18 +03001857 ar->running_fw->fw_file.fw_features)) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001858 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1859 arvif->vdev_id);
1860 enable_ps = false;
1861 }
1862
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001863 if (!arvif->is_started) {
1864 /* mac80211 can update vif powersave state while disconnected.
1865 * Firmware doesn't behave nicely and consumes more power than
1866 * necessary if PS is disabled on a non-started vdev. Hence
1867 * force-enable PS for non-running vdevs.
1868 */
1869 psmode = WMI_STA_PS_MODE_ENABLED;
1870 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001871 psmode = WMI_STA_PS_MODE_ENABLED;
1872 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1873
Michal Kazior526549a2014-12-12 12:41:37 +01001874 ps_timeout = conf->dynamic_ps_timeout;
1875 if (ps_timeout == 0) {
1876 /* Firmware doesn't like 0 */
1877 ps_timeout = ieee80211_tu_to_usec(
1878 vif->bss_conf.beacon_int) / 1000;
1879 }
1880
Michal Kaziorad088bf2013-10-16 15:44:46 +03001881 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001882 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001883 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001884 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001885 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001886 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001887 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001888 } else {
1889 psmode = WMI_STA_PS_MODE_DISABLED;
1890 }
1891
Michal Kazior7aa7a722014-08-25 12:09:38 +02001892 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001893 arvif->vdev_id, psmode ? "enable" : "disable");
1894
Michal Kaziorad088bf2013-10-16 15:44:46 +03001895 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1896 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001897 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001898 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001899 return ret;
1900 }
1901
1902 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001903}
1904
Michal Kazior46725b152015-01-28 09:57:49 +02001905static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1906{
1907 struct ath10k *ar = arvif->ar;
1908 struct wmi_sta_keepalive_arg arg = {};
1909 int ret;
1910
1911 lockdep_assert_held(&arvif->ar->conf_mutex);
1912
1913 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1914 return 0;
1915
1916 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1917 return 0;
1918
1919 /* Some firmware revisions have a bug and ignore the `enabled` field.
1920 * Instead use the interval to disable the keepalive.
1921 */
1922 arg.vdev_id = arvif->vdev_id;
1923 arg.enabled = 1;
1924 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1925 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1926
1927 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1928 if (ret) {
1929 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1930 arvif->vdev_id, ret);
1931 return ret;
1932 }
1933
1934 return 0;
1935}
1936
Michal Kazior81a9a172015-03-05 16:02:17 +02001937static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1938{
1939 struct ath10k *ar = arvif->ar;
1940 struct ieee80211_vif *vif = arvif->vif;
1941 int ret;
1942
Michal Kazior8513d952015-03-09 14:19:24 +01001943 lockdep_assert_held(&arvif->ar->conf_mutex);
1944
1945 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1946 return;
1947
Michal Kazior81a9a172015-03-05 16:02:17 +02001948 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1949 return;
1950
1951 if (!vif->csa_active)
1952 return;
1953
1954 if (!arvif->is_up)
1955 return;
1956
1957 if (!ieee80211_csa_is_complete(vif)) {
1958 ieee80211_csa_update_counter(vif);
1959
1960 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1961 if (ret)
1962 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1963 ret);
1964
1965 ret = ath10k_mac_setup_prb_tmpl(arvif);
1966 if (ret)
1967 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1968 ret);
1969 } else {
1970 ieee80211_csa_finish(vif);
1971 }
1972}
1973
1974static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1975{
1976 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1977 ap_csa_work);
1978 struct ath10k *ar = arvif->ar;
1979
1980 mutex_lock(&ar->conf_mutex);
1981 ath10k_mac_vif_ap_csa_count_down(arvif);
1982 mutex_unlock(&ar->conf_mutex);
1983}
1984
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001985static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1986 struct ieee80211_vif *vif)
1987{
1988 struct sk_buff *skb = data;
1989 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1990 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1991
1992 if (vif->type != NL80211_IFTYPE_STATION)
1993 return;
1994
1995 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1996 return;
1997
1998 cancel_delayed_work(&arvif->connection_loss_work);
1999}
2000
2001void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
2002{
2003 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2004 IEEE80211_IFACE_ITER_NORMAL,
2005 ath10k_mac_handle_beacon_iter,
2006 skb);
2007}
2008
2009static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
2010 struct ieee80211_vif *vif)
2011{
2012 u32 *vdev_id = data;
2013 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2014 struct ath10k *ar = arvif->ar;
2015 struct ieee80211_hw *hw = ar->hw;
2016
2017 if (arvif->vdev_id != *vdev_id)
2018 return;
2019
2020 if (!arvif->is_up)
2021 return;
2022
2023 ieee80211_beacon_loss(vif);
2024
2025 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
2026 * (done by mac80211) succeeds but beacons do not resume then it
2027 * doesn't make sense to continue operation. Queue connection loss work
2028 * which can be cancelled when beacon is received.
2029 */
2030 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
2031 ATH10K_CONNECTION_LOSS_HZ);
2032}
2033
2034void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
2035{
2036 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2037 IEEE80211_IFACE_ITER_NORMAL,
2038 ath10k_mac_handle_beacon_miss_iter,
2039 &vdev_id);
2040}
2041
2042static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
2043{
2044 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
2045 connection_loss_work.work);
2046 struct ieee80211_vif *vif = arvif->vif;
2047
2048 if (!arvif->is_up)
2049 return;
2050
2051 ieee80211_connection_loss(vif);
2052}
2053
Kalle Valo5e3dd152013-06-12 20:52:10 +03002054/**********************/
2055/* Station management */
2056/**********************/
2057
Michal Kazior590922a2014-10-21 10:10:29 +03002058static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
2059 struct ieee80211_vif *vif)
2060{
2061 /* Some firmware revisions have unstable STA powersave when listen
2062 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
2063 * generate NullFunc frames properly even if buffered frames have been
2064 * indicated in Beacon TIM. Firmware would seldom wake up to pull
2065 * buffered frames. Often pinging the device from AP would simply fail.
2066 *
2067 * As a workaround set it to 1.
2068 */
2069 if (vif->type == NL80211_IFTYPE_STATION)
2070 return 1;
2071
2072 return ar->hw->conf.listen_interval;
2073}
2074
Kalle Valo5e3dd152013-06-12 20:52:10 +03002075static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002076 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002077 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002078 struct wmi_peer_assoc_complete_arg *arg)
2079{
Michal Kazior590922a2014-10-21 10:10:29 +03002080 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorc51880e2015-03-30 09:51:57 +03002081 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03002082
Michal Kazior548db542013-07-05 16:15:15 +03002083 lockdep_assert_held(&ar->conf_mutex);
2084
Michal Kaziorc51880e2015-03-30 09:51:57 +03002085 if (vif->type == NL80211_IFTYPE_STATION)
2086 aid = vif->bss_conf.aid;
2087 else
2088 aid = sta->aid;
2089
Kalle Valob25f32c2014-09-14 12:50:49 +03002090 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002091 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002092 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002093 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03002094 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002095 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03002096 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002097}
2098
2099static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002100 struct ieee80211_vif *vif,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002101 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002102 struct wmi_peer_assoc_complete_arg *arg)
2103{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002104 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002105 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002106 struct cfg80211_bss *bss;
2107 const u8 *rsnie = NULL;
2108 const u8 *wpaie = NULL;
2109
Michal Kazior548db542013-07-05 16:15:15 +03002110 lockdep_assert_held(&ar->conf_mutex);
2111
Michal Kazior500ff9f2015-03-31 10:26:21 +00002112 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2113 return;
2114
2115 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
2116 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002117 if (bss) {
2118 const struct cfg80211_bss_ies *ies;
2119
2120 rcu_read_lock();
2121 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
2122
2123 ies = rcu_dereference(bss->ies);
2124
2125 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03002126 WLAN_OUI_TYPE_MICROSOFT_WPA,
2127 ies->data,
2128 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002129 rcu_read_unlock();
2130 cfg80211_put_bss(ar->hw->wiphy, bss);
2131 }
2132
2133 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2134 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002135 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002136 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002137 }
2138
2139 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002140 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002141 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002142 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002143
2144 if (sta->mfp &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03002145 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT,
2146 ar->running_fw->fw_file.fw_features)) {
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002147 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002148 }
2149}
2150
2151static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002152 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002153 struct ieee80211_sta *sta,
2154 struct wmi_peer_assoc_complete_arg *arg)
2155{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002156 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002157 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002158 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002159 const struct ieee80211_supported_band *sband;
2160 const struct ieee80211_rate *rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002161 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002162 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002163 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002164 int i;
2165
Michal Kazior548db542013-07-05 16:15:15 +03002166 lockdep_assert_held(&ar->conf_mutex);
2167
Michal Kazior500ff9f2015-03-31 10:26:21 +00002168 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2169 return;
2170
Michal Kazior45c9abc2015-04-21 20:42:58 +03002171 band = def.chan->band;
2172 sband = ar->hw->wiphy->bands[band];
2173 ratemask = sta->supp_rates[band];
2174 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002175 rates = sband->bitrates;
2176
2177 rateset->num_rates = 0;
2178
2179 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2180 if (!(ratemask & 1))
2181 continue;
2182
Michal Kazior486017c2015-03-30 09:51:54 +03002183 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2184 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002185 rateset->num_rates++;
2186 }
2187}
2188
Michal Kazior45c9abc2015-04-21 20:42:58 +03002189static bool
2190ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2191{
2192 int nss;
2193
2194 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2195 if (ht_mcs_mask[nss])
2196 return false;
2197
2198 return true;
2199}
2200
2201static bool
2202ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2203{
2204 int nss;
2205
2206 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2207 if (vht_mcs_mask[nss])
2208 return false;
2209
2210 return true;
2211}
2212
Kalle Valo5e3dd152013-06-12 20:52:10 +03002213static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002214 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002215 struct ieee80211_sta *sta,
2216 struct wmi_peer_assoc_complete_arg *arg)
2217{
2218 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002219 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2220 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002221 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002222 const u8 *ht_mcs_mask;
2223 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002224 int i, n;
2225 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002226 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002227
Michal Kazior548db542013-07-05 16:15:15 +03002228 lockdep_assert_held(&ar->conf_mutex);
2229
Michal Kazior45c9abc2015-04-21 20:42:58 +03002230 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2231 return;
2232
Kalle Valo5e3dd152013-06-12 20:52:10 +03002233 if (!ht_cap->ht_supported)
2234 return;
2235
Michal Kazior45c9abc2015-04-21 20:42:58 +03002236 band = def.chan->band;
2237 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2238 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2239
2240 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2241 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2242 return;
2243
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002244 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002245 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2246 ht_cap->ampdu_factor)) - 1;
2247
2248 arg->peer_mpdu_density =
2249 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2250
2251 arg->peer_ht_caps = ht_cap->cap;
2252 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2253
2254 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002255 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002256
2257 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002258 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002259 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2260 }
2261
Michal Kazior45c9abc2015-04-21 20:42:58 +03002262 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2263 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2264 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002265
Michal Kazior45c9abc2015-04-21 20:42:58 +03002266 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2267 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2268 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002269
2270 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2271 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002272 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002273 }
2274
2275 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002276 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2277 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2278 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2279 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002280 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002281 }
2282
Kalle Valo5e3dd152013-06-12 20:52:10 +03002283 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2284 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2285 else if (ht_cap->mcs.rx_mask[1])
2286 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2287
Michal Kazior45c9abc2015-04-21 20:42:58 +03002288 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2289 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2290 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2291 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002292 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002293 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002294
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002295 /*
2296 * This is a workaround for HT-enabled STAs which break the spec
2297 * and have no HT capabilities RX mask (no HT RX MCS map).
2298 *
2299 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2300 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2301 *
2302 * Firmware asserts if such situation occurs.
2303 */
2304 if (n == 0) {
2305 arg->peer_ht_rates.num_rates = 8;
2306 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2307 arg->peer_ht_rates.rates[i] = i;
2308 } else {
2309 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002310 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002311 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002312
Michal Kazior7aa7a722014-08-25 12:09:38 +02002313 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002314 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002315 arg->peer_ht_rates.num_rates,
2316 arg->peer_num_spatial_streams);
2317}
2318
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002319static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2320 struct ath10k_vif *arvif,
2321 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002322{
2323 u32 uapsd = 0;
2324 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002325 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002326
Michal Kazior548db542013-07-05 16:15:15 +03002327 lockdep_assert_held(&ar->conf_mutex);
2328
Kalle Valo5e3dd152013-06-12 20:52:10 +03002329 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002330 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002331 sta->uapsd_queues, sta->max_sp);
2332
Kalle Valo5e3dd152013-06-12 20:52:10 +03002333 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2334 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2335 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2336 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2337 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2338 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2339 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2340 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2341 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2342 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2343 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2344 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2345
Kalle Valo5e3dd152013-06-12 20:52:10 +03002346 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2347 max_sp = sta->max_sp;
2348
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002349 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2350 sta->addr,
2351 WMI_AP_PS_PEER_PARAM_UAPSD,
2352 uapsd);
2353 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002354 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002355 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002356 return ret;
2357 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002358
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002359 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2360 sta->addr,
2361 WMI_AP_PS_PEER_PARAM_MAX_SP,
2362 max_sp);
2363 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002364 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002365 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002366 return ret;
2367 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002368
2369 /* TODO setup this based on STA listen interval and
2370 beacon interval. Currently we don't know
2371 sta->listen_interval - mac80211 patch required.
2372 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002373 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002374 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2375 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002376 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002377 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002378 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002379 return ret;
2380 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002381 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002382
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002383 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002384}
2385
Michal Kazior45c9abc2015-04-21 20:42:58 +03002386static u16
2387ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2388 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2389{
2390 int idx_limit;
2391 int nss;
2392 u16 mcs_map;
2393 u16 mcs;
2394
2395 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2396 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2397 vht_mcs_limit[nss];
2398
2399 if (mcs_map)
2400 idx_limit = fls(mcs_map) - 1;
2401 else
2402 idx_limit = -1;
2403
2404 switch (idx_limit) {
2405 case 0: /* fall through */
2406 case 1: /* fall through */
2407 case 2: /* fall through */
2408 case 3: /* fall through */
2409 case 4: /* fall through */
2410 case 5: /* fall through */
2411 case 6: /* fall through */
2412 default:
2413 /* see ath10k_mac_can_set_bitrate_mask() */
2414 WARN_ON(1);
2415 /* fall through */
2416 case -1:
2417 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2418 break;
2419 case 7:
2420 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2421 break;
2422 case 8:
2423 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2424 break;
2425 case 9:
2426 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2427 break;
2428 }
2429
2430 tx_mcs_set &= ~(0x3 << (nss * 2));
2431 tx_mcs_set |= mcs << (nss * 2);
2432 }
2433
2434 return tx_mcs_set;
2435}
2436
Kalle Valo5e3dd152013-06-12 20:52:10 +03002437static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002438 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002439 struct ieee80211_sta *sta,
2440 struct wmi_peer_assoc_complete_arg *arg)
2441{
2442 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002443 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002444 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002445 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002446 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002447 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002448
Michal Kazior500ff9f2015-03-31 10:26:21 +00002449 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2450 return;
2451
Kalle Valo5e3dd152013-06-12 20:52:10 +03002452 if (!vht_cap->vht_supported)
2453 return;
2454
Michal Kazior45c9abc2015-04-21 20:42:58 +03002455 band = def.chan->band;
2456 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2457
2458 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2459 return;
2460
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002461 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002462
Johannes Berg57fbcce2016-04-12 15:56:15 +02002463 if (def.chan->band == NL80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002464 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002465
Kalle Valo5e3dd152013-06-12 20:52:10 +03002466 arg->peer_vht_caps = vht_cap->cap;
2467
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002468 ampdu_factor = (vht_cap->cap &
2469 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2470 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2471
2472 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2473 * zero in VHT IE. Using it would result in degraded throughput.
2474 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2475 * it if VHT max_mpdu is smaller. */
2476 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2477 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2478 ampdu_factor)) - 1);
2479
Kalle Valo5e3dd152013-06-12 20:52:10 +03002480 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002481 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002482
2483 arg->peer_vht_rates.rx_max_rate =
2484 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2485 arg->peer_vht_rates.rx_mcs_set =
2486 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2487 arg->peer_vht_rates.tx_max_rate =
2488 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002489 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2490 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002491
Michal Kazior7aa7a722014-08-25 12:09:38 +02002492 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002493 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002494}
2495
2496static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002497 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002498 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002499 struct wmi_peer_assoc_complete_arg *arg)
2500{
Michal Kazior590922a2014-10-21 10:10:29 +03002501 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2502
Kalle Valo5e3dd152013-06-12 20:52:10 +03002503 switch (arvif->vdev_type) {
2504 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002505 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002506 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002507
2508 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002509 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002510 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2511 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002512 break;
2513 case WMI_VDEV_TYPE_STA:
Michal Kazior590922a2014-10-21 10:10:29 +03002514 if (vif->bss_conf.qos)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002515 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002516 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002517 case WMI_VDEV_TYPE_IBSS:
2518 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002519 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002520 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002521 default:
2522 break;
2523 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002524
2525 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002526 sta->addr, !!(arg->peer_flags &
2527 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002528}
2529
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002530static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002531{
Johannes Berg57fbcce2016-04-12 15:56:15 +02002532 return sta->supp_rates[NL80211_BAND_2GHZ] >>
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002533 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002534}
2535
Kalle Valo5e3dd152013-06-12 20:52:10 +03002536static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002537 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002538 struct ieee80211_sta *sta,
2539 struct wmi_peer_assoc_complete_arg *arg)
2540{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002541 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002542 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002543 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002544 const u8 *ht_mcs_mask;
2545 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002546 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2547
Michal Kazior500ff9f2015-03-31 10:26:21 +00002548 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2549 return;
2550
Michal Kazior45c9abc2015-04-21 20:42:58 +03002551 band = def.chan->band;
2552 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2553 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2554
2555 switch (band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02002556 case NL80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002557 if (sta->vht_cap.vht_supported &&
2558 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002559 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2560 phymode = MODE_11AC_VHT40;
2561 else
2562 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002563 } else if (sta->ht_cap.ht_supported &&
2564 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002565 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2566 phymode = MODE_11NG_HT40;
2567 else
2568 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002569 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002570 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002571 } else {
2572 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002573 }
2574
2575 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002576 case NL80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002577 /*
2578 * Check VHT first.
2579 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002580 if (sta->vht_cap.vht_supported &&
2581 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002582 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2583 phymode = MODE_11AC_VHT80;
2584 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2585 phymode = MODE_11AC_VHT40;
2586 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2587 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002588 } else if (sta->ht_cap.ht_supported &&
2589 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2590 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002591 phymode = MODE_11NA_HT40;
2592 else
2593 phymode = MODE_11NA_HT20;
2594 } else {
2595 phymode = MODE_11A;
2596 }
2597
2598 break;
2599 default:
2600 break;
2601 }
2602
Michal Kazior7aa7a722014-08-25 12:09:38 +02002603 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002604 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002605
Kalle Valo5e3dd152013-06-12 20:52:10 +03002606 arg->peer_phymode = phymode;
2607 WARN_ON(phymode == MODE_UNKNOWN);
2608}
2609
Kalle Valob9ada652013-10-16 15:44:46 +03002610static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002611 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002612 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002613 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002614{
Michal Kazior548db542013-07-05 16:15:15 +03002615 lockdep_assert_held(&ar->conf_mutex);
2616
Kalle Valob9ada652013-10-16 15:44:46 +03002617 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002618
Michal Kazior590922a2014-10-21 10:10:29 +03002619 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002620 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002621 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002622 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002623 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002624 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2625 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002626
Kalle Valob9ada652013-10-16 15:44:46 +03002627 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002628}
2629
Michal Kazior90046f52014-02-14 14:45:51 +01002630static const u32 ath10k_smps_map[] = {
2631 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2632 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2633 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2634 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2635};
2636
2637static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2638 const u8 *addr,
2639 const struct ieee80211_sta_ht_cap *ht_cap)
2640{
2641 int smps;
2642
2643 if (!ht_cap->ht_supported)
2644 return 0;
2645
2646 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2647 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2648
2649 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2650 return -EINVAL;
2651
2652 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2653 WMI_PEER_SMPS_STATE,
2654 ath10k_smps_map[smps]);
2655}
2656
Michal Kazior139e1702015-02-15 16:50:42 +02002657static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2658 struct ieee80211_vif *vif,
2659 struct ieee80211_sta_vht_cap vht_cap)
2660{
2661 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2662 int ret;
2663 u32 param;
2664 u32 value;
2665
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302666 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2667 return 0;
2668
Michal Kazior139e1702015-02-15 16:50:42 +02002669 if (!(ar->vht_cap_info &
2670 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2671 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2672 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2673 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2674 return 0;
2675
2676 param = ar->wmi.vdev_param->txbf;
2677 value = 0;
2678
2679 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2680 return 0;
2681
2682 /* The following logic is correct. If a remote STA advertises support
2683 * for being a beamformer then we should enable us being a beamformee.
2684 */
2685
2686 if (ar->vht_cap_info &
2687 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2688 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2689 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2690 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2691
2692 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2693 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2694 }
2695
2696 if (ar->vht_cap_info &
2697 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2698 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2699 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2700 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2701
2702 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2703 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2704 }
2705
2706 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2707 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2708
2709 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2710 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2711
2712 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2713 if (ret) {
2714 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2715 value, ret);
2716 return ret;
2717 }
2718
2719 return 0;
2720}
2721
Kalle Valo5e3dd152013-06-12 20:52:10 +03002722/* can be called only in mac80211 callbacks due to `key_count` usage */
2723static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2724 struct ieee80211_vif *vif,
2725 struct ieee80211_bss_conf *bss_conf)
2726{
2727 struct ath10k *ar = hw->priv;
2728 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002729 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002730 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002731 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002732 struct ieee80211_sta *ap_sta;
2733 int ret;
2734
Michal Kazior548db542013-07-05 16:15:15 +03002735 lockdep_assert_held(&ar->conf_mutex);
2736
Michal Kazior077efc82014-10-21 10:10:29 +03002737 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2738 arvif->vdev_id, arvif->bssid, arvif->aid);
2739
Kalle Valo5e3dd152013-06-12 20:52:10 +03002740 rcu_read_lock();
2741
2742 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2743 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002744 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002745 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002746 rcu_read_unlock();
2747 return;
2748 }
2749
Michal Kazior90046f52014-02-14 14:45:51 +01002750 /* ap_sta must be accessed only within rcu section which must be left
2751 * before calling ath10k_setup_peer_smps() which might sleep. */
2752 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002753 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002754
Michal Kazior590922a2014-10-21 10:10:29 +03002755 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002756 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002757 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002758 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002759 rcu_read_unlock();
2760 return;
2761 }
2762
2763 rcu_read_unlock();
2764
Kalle Valob9ada652013-10-16 15:44:46 +03002765 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2766 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002767 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002768 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002769 return;
2770 }
2771
Michal Kazior90046f52014-02-14 14:45:51 +01002772 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2773 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002774 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002775 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002776 return;
2777 }
2778
Michal Kazior139e1702015-02-15 16:50:42 +02002779 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2780 if (ret) {
2781 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2782 arvif->vdev_id, bss_conf->bssid, ret);
2783 return;
2784 }
2785
Michal Kazior7aa7a722014-08-25 12:09:38 +02002786 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002787 "mac vdev %d up (associated) bssid %pM aid %d\n",
2788 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2789
Michal Kazior077efc82014-10-21 10:10:29 +03002790 WARN_ON(arvif->is_up);
2791
Michal Kaziorc930f742014-01-23 11:38:25 +01002792 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002793 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002794
2795 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2796 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002797 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002798 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002799 return;
2800 }
2801
2802 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002803
2804 /* Workaround: Some firmware revisions (tested with qca6174
2805 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2806 * poked with peer param command.
2807 */
2808 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2809 WMI_PEER_DUMMY_VAR, 1);
2810 if (ret) {
2811 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2812 arvif->bssid, arvif->vdev_id, ret);
2813 return;
2814 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002815}
2816
Kalle Valo5e3dd152013-06-12 20:52:10 +03002817static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2818 struct ieee80211_vif *vif)
2819{
2820 struct ath10k *ar = hw->priv;
2821 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002822 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002823 int ret;
2824
Michal Kazior548db542013-07-05 16:15:15 +03002825 lockdep_assert_held(&ar->conf_mutex);
2826
Michal Kazior077efc82014-10-21 10:10:29 +03002827 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2828 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002829
Kalle Valo5e3dd152013-06-12 20:52:10 +03002830 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002831 if (ret)
Ben Greearaa66ba02016-09-26 21:56:25 +03002832 ath10k_warn(ar, "failed to down vdev %i: %d\n",
Michal Kazior077efc82014-10-21 10:10:29 +03002833 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002834
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002835 arvif->def_wep_key_idx = -1;
2836
Michal Kazior139e1702015-02-15 16:50:42 +02002837 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2838 if (ret) {
2839 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2840 arvif->vdev_id, ret);
2841 return;
2842 }
2843
Michal Kaziorc930f742014-01-23 11:38:25 +01002844 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002845
2846 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002847}
2848
Michal Kazior590922a2014-10-21 10:10:29 +03002849static int ath10k_station_assoc(struct ath10k *ar,
2850 struct ieee80211_vif *vif,
2851 struct ieee80211_sta *sta,
2852 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002853{
Michal Kazior590922a2014-10-21 10:10:29 +03002854 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002855 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002856 int ret = 0;
2857
Michal Kazior548db542013-07-05 16:15:15 +03002858 lockdep_assert_held(&ar->conf_mutex);
2859
Michal Kazior590922a2014-10-21 10:10:29 +03002860 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002861 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002862 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002863 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002864 return ret;
2865 }
2866
2867 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2868 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002869 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002870 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002871 return ret;
2872 }
2873
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002874 /* Re-assoc is run only to update supported rates for given station. It
2875 * doesn't make much sense to reconfigure the peer completely.
2876 */
2877 if (!reassoc) {
2878 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2879 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002880 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002881 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002882 arvif->vdev_id, ret);
2883 return ret;
2884 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002885
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002886 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2887 if (ret) {
2888 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2889 sta->addr, arvif->vdev_id, ret);
2890 return ret;
2891 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002892
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002893 if (!sta->wme) {
2894 arvif->num_legacy_stations++;
2895 ret = ath10k_recalc_rtscts_prot(arvif);
2896 if (ret) {
2897 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2898 arvif->vdev_id, ret);
2899 return ret;
2900 }
2901 }
2902
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002903 /* Plumb cached keys only for static WEP */
2904 if (arvif->def_wep_key_idx != -1) {
2905 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2906 if (ret) {
2907 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2908 arvif->vdev_id, ret);
2909 return ret;
2910 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002911 }
2912 }
2913
Kalle Valo5e3dd152013-06-12 20:52:10 +03002914 return ret;
2915}
2916
Michal Kazior590922a2014-10-21 10:10:29 +03002917static int ath10k_station_disassoc(struct ath10k *ar,
2918 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002919 struct ieee80211_sta *sta)
2920{
Michal Kazior590922a2014-10-21 10:10:29 +03002921 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002922 int ret = 0;
2923
2924 lockdep_assert_held(&ar->conf_mutex);
2925
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002926 if (!sta->wme) {
2927 arvif->num_legacy_stations--;
2928 ret = ath10k_recalc_rtscts_prot(arvif);
2929 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002930 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002931 arvif->vdev_id, ret);
2932 return ret;
2933 }
2934 }
2935
Kalle Valo5e3dd152013-06-12 20:52:10 +03002936 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2937 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002938 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002939 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002940 return ret;
2941 }
2942
2943 return ret;
2944}
2945
2946/**************/
2947/* Regulatory */
2948/**************/
2949
2950static int ath10k_update_channel_list(struct ath10k *ar)
2951{
2952 struct ieee80211_hw *hw = ar->hw;
2953 struct ieee80211_supported_band **bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002954 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002955 struct ieee80211_channel *channel;
2956 struct wmi_scan_chan_list_arg arg = {0};
2957 struct wmi_channel_arg *ch;
2958 bool passive;
2959 int len;
2960 int ret;
2961 int i;
2962
Michal Kazior548db542013-07-05 16:15:15 +03002963 lockdep_assert_held(&ar->conf_mutex);
2964
Kalle Valo5e3dd152013-06-12 20:52:10 +03002965 bands = hw->wiphy->bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002966 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002967 if (!bands[band])
2968 continue;
2969
2970 for (i = 0; i < bands[band]->n_channels; i++) {
2971 if (bands[band]->channels[i].flags &
2972 IEEE80211_CHAN_DISABLED)
2973 continue;
2974
2975 arg.n_channels++;
2976 }
2977 }
2978
2979 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2980 arg.channels = kzalloc(len, GFP_KERNEL);
2981 if (!arg.channels)
2982 return -ENOMEM;
2983
2984 ch = arg.channels;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002985 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002986 if (!bands[band])
2987 continue;
2988
2989 for (i = 0; i < bands[band]->n_channels; i++) {
2990 channel = &bands[band]->channels[i];
2991
2992 if (channel->flags & IEEE80211_CHAN_DISABLED)
2993 continue;
2994
Eduardo Abinader98029772016-06-30 15:23:55 +03002995 ch->allow_ht = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002996
2997 /* FIXME: when should we really allow VHT? */
2998 ch->allow_vht = true;
2999
3000 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02003001 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003002
3003 ch->ht40plus =
3004 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
3005
Marek Puzyniake8a50f82013-11-20 09:59:47 +02003006 ch->chan_radar =
3007 !!(channel->flags & IEEE80211_CHAN_RADAR);
3008
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02003009 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003010 ch->passive = passive;
3011
3012 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02003013 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07003014 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07003015 ch->max_power = channel->max_power * 2;
3016 ch->max_reg_power = channel->max_reg_power * 2;
3017 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003018 ch->reg_class_id = 0; /* FIXME */
3019
3020 /* FIXME: why use only legacy modes, why not any
3021 * HT/VHT modes? Would that even make any
3022 * difference? */
Johannes Berg57fbcce2016-04-12 15:56:15 +02003023 if (channel->band == NL80211_BAND_2GHZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003024 ch->mode = MODE_11G;
3025 else
3026 ch->mode = MODE_11A;
3027
3028 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
3029 continue;
3030
Michal Kazior7aa7a722014-08-25 12:09:38 +02003031 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03003032 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
3033 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003034 ch->freq, ch->max_power, ch->max_reg_power,
3035 ch->max_antenna_gain, ch->mode);
3036
3037 ch++;
3038 }
3039 }
3040
3041 ret = ath10k_wmi_scan_chan_list(ar, &arg);
3042 kfree(arg.channels);
3043
3044 return ret;
3045}
3046
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003047static enum wmi_dfs_region
3048ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
3049{
3050 switch (dfs_region) {
3051 case NL80211_DFS_UNSET:
3052 return WMI_UNINIT_DFS_DOMAIN;
3053 case NL80211_DFS_FCC:
3054 return WMI_FCC_DFS_DOMAIN;
3055 case NL80211_DFS_ETSI:
3056 return WMI_ETSI_DFS_DOMAIN;
3057 case NL80211_DFS_JP:
3058 return WMI_MKK4_DFS_DOMAIN;
3059 }
3060 return WMI_UNINIT_DFS_DOMAIN;
3061}
3062
Michal Kaziorf7843d72013-07-16 09:38:52 +02003063static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003064{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003065 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003066 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003067 enum wmi_dfs_region wmi_dfs_reg;
3068 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003069
Michal Kaziorf7843d72013-07-16 09:38:52 +02003070 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003071
3072 ret = ath10k_update_channel_list(ar);
3073 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003074 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003075
3076 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003077
Masahiro Yamada97f26452016-08-03 13:45:50 -07003078 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003079 nl_dfs_reg = ar->dfs_detector->region;
3080 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
3081 } else {
3082 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
3083 }
3084
Kalle Valo5e3dd152013-06-12 20:52:10 +03003085 /* Target allows setting up per-band regdomain but ath_common provides
3086 * a combined one only */
3087 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02003088 regpair->reg_domain,
3089 regpair->reg_domain, /* 2ghz */
3090 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003091 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003092 regpair->reg_5ghz_ctl,
3093 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003094 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003095 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02003096}
Michal Kazior548db542013-07-05 16:15:15 +03003097
Michal Kaziorf7843d72013-07-16 09:38:52 +02003098static void ath10k_reg_notifier(struct wiphy *wiphy,
3099 struct regulatory_request *request)
3100{
3101 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
3102 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003103 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003104
3105 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3106
Masahiro Yamada97f26452016-08-03 13:45:50 -07003107 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003108 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003109 request->dfs_region);
3110 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3111 request->dfs_region);
3112 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003113 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003114 request->dfs_region);
3115 }
3116
Michal Kaziorf7843d72013-07-16 09:38:52 +02003117 mutex_lock(&ar->conf_mutex);
3118 if (ar->state == ATH10K_STATE_ON)
3119 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003120 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003121}
3122
3123/***************/
3124/* TX handlers */
3125/***************/
3126
Michal Kaziora30c7d02016-03-06 16:14:23 +02003127enum ath10k_mac_tx_path {
3128 ATH10K_MAC_TX_HTT,
3129 ATH10K_MAC_TX_HTT_MGMT,
3130 ATH10K_MAC_TX_WMI_MGMT,
3131 ATH10K_MAC_TX_UNKNOWN,
3132};
3133
Michal Kazior96d828d2015-03-31 10:26:23 +00003134void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3135{
3136 lockdep_assert_held(&ar->htt.tx_lock);
3137
3138 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3139 ar->tx_paused |= BIT(reason);
3140 ieee80211_stop_queues(ar->hw);
3141}
3142
3143static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3144 struct ieee80211_vif *vif)
3145{
3146 struct ath10k *ar = data;
3147 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3148
3149 if (arvif->tx_paused)
3150 return;
3151
3152 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3153}
3154
3155void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3156{
3157 lockdep_assert_held(&ar->htt.tx_lock);
3158
3159 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3160 ar->tx_paused &= ~BIT(reason);
3161
3162 if (ar->tx_paused)
3163 return;
3164
3165 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3166 IEEE80211_IFACE_ITER_RESUME_ALL,
3167 ath10k_mac_tx_unlock_iter,
3168 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003169
3170 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003171}
3172
3173void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3174{
3175 struct ath10k *ar = arvif->ar;
3176
3177 lockdep_assert_held(&ar->htt.tx_lock);
3178
3179 WARN_ON(reason >= BITS_PER_LONG);
3180 arvif->tx_paused |= BIT(reason);
3181 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3182}
3183
3184void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3185{
3186 struct ath10k *ar = arvif->ar;
3187
3188 lockdep_assert_held(&ar->htt.tx_lock);
3189
3190 WARN_ON(reason >= BITS_PER_LONG);
3191 arvif->tx_paused &= ~BIT(reason);
3192
3193 if (ar->tx_paused)
3194 return;
3195
3196 if (arvif->tx_paused)
3197 return;
3198
3199 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3200}
3201
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003202static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3203 enum wmi_tlv_tx_pause_id pause_id,
3204 enum wmi_tlv_tx_pause_action action)
3205{
3206 struct ath10k *ar = arvif->ar;
3207
3208 lockdep_assert_held(&ar->htt.tx_lock);
3209
Michal Kazioracd0b272015-07-09 13:08:38 +02003210 switch (action) {
3211 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3212 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003213 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003214 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3215 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3216 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003217 default:
Bartosz Markowski209b2a62016-09-28 15:11:58 +03003218 ath10k_dbg(ar, ATH10K_DBG_BOOT,
3219 "received unknown tx pause action %d on vdev %i, ignoring\n",
Michal Kazioracd0b272015-07-09 13:08:38 +02003220 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003221 break;
3222 }
3223}
3224
3225struct ath10k_mac_tx_pause {
3226 u32 vdev_id;
3227 enum wmi_tlv_tx_pause_id pause_id;
3228 enum wmi_tlv_tx_pause_action action;
3229};
3230
3231static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3232 struct ieee80211_vif *vif)
3233{
3234 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3235 struct ath10k_mac_tx_pause *arg = data;
3236
Michal Kazioracd0b272015-07-09 13:08:38 +02003237 if (arvif->vdev_id != arg->vdev_id)
3238 return;
3239
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003240 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3241}
3242
Michal Kazioracd0b272015-07-09 13:08:38 +02003243void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3244 enum wmi_tlv_tx_pause_id pause_id,
3245 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003246{
3247 struct ath10k_mac_tx_pause arg = {
3248 .vdev_id = vdev_id,
3249 .pause_id = pause_id,
3250 .action = action,
3251 };
3252
3253 spin_lock_bh(&ar->htt.tx_lock);
3254 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3255 IEEE80211_IFACE_ITER_RESUME_ALL,
3256 ath10k_mac_handle_tx_pause_iter,
3257 &arg);
3258 spin_unlock_bh(&ar->htt.tx_lock);
3259}
3260
Michal Kaziord740d8f2015-03-30 09:51:51 +03003261static enum ath10k_hw_txrx_mode
Michal Kazior6a2636d2015-11-18 06:59:16 +01003262ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3263 struct ieee80211_vif *vif,
3264 struct ieee80211_sta *sta,
3265 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003266{
3267 const struct ieee80211_hdr *hdr = (void *)skb->data;
3268 __le16 fc = hdr->frame_control;
3269
3270 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3271 return ATH10K_HW_TXRX_RAW;
3272
3273 if (ieee80211_is_mgmt(fc))
3274 return ATH10K_HW_TXRX_MGMT;
3275
3276 /* Workaround:
3277 *
3278 * NullFunc frames are mostly used to ping if a client or AP are still
3279 * reachable and responsive. This implies tx status reports must be
3280 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3281 * come to a conclusion that the other end disappeared and tear down
3282 * BSS connection or it can never disconnect from BSS/client (which is
3283 * the case).
3284 *
3285 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3286 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3287 * which seems to deliver correct tx reports for NullFunc frames. The
3288 * downside of using it is it ignores client powersave state so it can
3289 * end up disconnecting sleeping clients in AP mode. It should fix STA
3290 * mode though because AP don't sleep.
3291 */
3292 if (ar->htt.target_version_major < 3 &&
3293 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03003294 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3295 ar->running_fw->fw_file.fw_features))
Michal Kaziord740d8f2015-03-30 09:51:51 +03003296 return ATH10K_HW_TXRX_MGMT;
3297
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003298 /* Workaround:
3299 *
3300 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3301 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3302 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003303 *
3304 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003305 */
3306 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3307 return ATH10K_HW_TXRX_ETHERNET;
3308
David Liuccec9032015-07-24 20:25:32 +03003309 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3310 return ATH10K_HW_TXRX_RAW;
3311
Michal Kaziord740d8f2015-03-30 09:51:51 +03003312 return ATH10K_HW_TXRX_NATIVE_WIFI;
3313}
3314
David Liuccec9032015-07-24 20:25:32 +03003315static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003316 struct sk_buff *skb)
3317{
3318 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3319 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003320 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3321 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003322
3323 if (!ieee80211_has_protected(hdr->frame_control))
3324 return false;
3325
David Liuccec9032015-07-24 20:25:32 +03003326 if ((info->flags & mask) == mask)
3327 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003328
David Liuccec9032015-07-24 20:25:32 +03003329 if (vif)
3330 return !ath10k_vif_to_arvif(vif)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003331
David Liuccec9032015-07-24 20:25:32 +03003332 return true;
3333}
3334
Michal Kazior4b604552014-07-21 21:03:09 +03003335/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3336 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003337 */
Michal Kazior4b604552014-07-21 21:03:09 +03003338static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003339{
3340 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003341 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003342 u8 *qos_ctl;
3343
3344 if (!ieee80211_is_data_qos(hdr->frame_control))
3345 return;
3346
3347 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003348 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3349 skb->data, (void *)qos_ctl - (void *)skb->data);
3350 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003351
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003352 /* Some firmware revisions don't handle sending QoS NullFunc well.
3353 * These frames are mainly used for CQM purposes so it doesn't really
3354 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003355 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003356 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003357 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003358 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003359
3360 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003361}
3362
Michal Kaziord740d8f2015-03-30 09:51:51 +03003363static void ath10k_tx_h_8023(struct sk_buff *skb)
3364{
3365 struct ieee80211_hdr *hdr;
3366 struct rfc1042_hdr *rfc1042;
3367 struct ethhdr *eth;
3368 size_t hdrlen;
3369 u8 da[ETH_ALEN];
3370 u8 sa[ETH_ALEN];
3371 __be16 type;
3372
3373 hdr = (void *)skb->data;
3374 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3375 rfc1042 = (void *)skb->data + hdrlen;
3376
3377 ether_addr_copy(da, ieee80211_get_DA(hdr));
3378 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3379 type = rfc1042->snap_type;
3380
3381 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3382 skb_push(skb, sizeof(*eth));
3383
3384 eth = (void *)skb->data;
3385 ether_addr_copy(eth->h_dest, da);
3386 ether_addr_copy(eth->h_source, sa);
3387 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003388}
3389
Michal Kazior4b604552014-07-21 21:03:09 +03003390static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3391 struct ieee80211_vif *vif,
3392 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003393{
3394 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003395 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3396
3397 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003398 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003399 return;
3400
3401 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3402 spin_lock_bh(&ar->data_lock);
3403 if (arvif->u.ap.noa_data)
3404 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3405 GFP_ATOMIC))
3406 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3407 arvif->u.ap.noa_data,
3408 arvif->u.ap.noa_len);
3409 spin_unlock_bh(&ar->data_lock);
3410 }
3411}
3412
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003413static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3414 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003415 struct ieee80211_txq *txq,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003416 struct sk_buff *skb)
3417{
3418 struct ieee80211_hdr *hdr = (void *)skb->data;
3419 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3420
3421 cb->flags = 0;
3422 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3423 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3424
3425 if (ieee80211_is_mgmt(hdr->frame_control))
3426 cb->flags |= ATH10K_SKB_F_MGMT;
3427
3428 if (ieee80211_is_data_qos(hdr->frame_control))
3429 cb->flags |= ATH10K_SKB_F_QOS;
3430
3431 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003432 cb->txq = txq;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003433}
3434
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303435bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003436{
3437 /* FIXME: Not really sure since when the behaviour changed. At some
3438 * point new firmware stopped requiring creation of peer entries for
3439 * offchannel tx (and actually creating them causes issues with wmi-htc
3440 * tx credit replenishment and reliability). Assuming it's at least 3.4
3441 * because that's when the `freq` was introduced to TX_FRM HTT command.
3442 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303443 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303444 ar->htt.target_version_minor >= 4 &&
Kalle Valo77561f92016-04-20 19:45:47 +03003445 ar->running_fw->fw_file.htt_op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003446}
3447
Michal Kaziord740d8f2015-03-30 09:51:51 +03003448static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003449{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003450 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003451 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003452
Michal Kaziord740d8f2015-03-30 09:51:51 +03003453 spin_lock_bh(&ar->data_lock);
3454
3455 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3456 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3457 ret = -ENOSPC;
3458 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003459 }
3460
Michal Kaziord740d8f2015-03-30 09:51:51 +03003461 __skb_queue_tail(q, skb);
3462 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3463
3464unlock:
3465 spin_unlock_bh(&ar->data_lock);
3466
3467 return ret;
3468}
3469
Michal Kaziora30c7d02016-03-06 16:14:23 +02003470static enum ath10k_mac_tx_path
3471ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3472 struct sk_buff *skb,
3473 enum ath10k_hw_txrx_mode txmode)
3474{
3475 switch (txmode) {
3476 case ATH10K_HW_TXRX_RAW:
3477 case ATH10K_HW_TXRX_NATIVE_WIFI:
3478 case ATH10K_HW_TXRX_ETHERNET:
3479 return ATH10K_MAC_TX_HTT;
3480 case ATH10K_HW_TXRX_MGMT:
3481 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Kalle Valoc4cdf752016-04-20 19:45:18 +03003482 ar->running_fw->fw_file.fw_features))
Michal Kaziora30c7d02016-03-06 16:14:23 +02003483 return ATH10K_MAC_TX_WMI_MGMT;
3484 else if (ar->htt.target_version_major >= 3)
3485 return ATH10K_MAC_TX_HTT;
3486 else
3487 return ATH10K_MAC_TX_HTT_MGMT;
3488 }
3489
3490 return ATH10K_MAC_TX_UNKNOWN;
3491}
3492
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003493static int ath10k_mac_tx_submit(struct ath10k *ar,
3494 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003495 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003496 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003497{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003498 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003499 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003500
3501 switch (txpath) {
3502 case ATH10K_MAC_TX_HTT:
Michal Kazior8a933962015-11-18 06:59:17 +01003503 ret = ath10k_htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003504 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003505 case ATH10K_MAC_TX_HTT_MGMT:
3506 ret = ath10k_htt_mgmt_tx(htt, skb);
3507 break;
3508 case ATH10K_MAC_TX_WMI_MGMT:
3509 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3510 break;
3511 case ATH10K_MAC_TX_UNKNOWN:
3512 WARN_ON_ONCE(1);
3513 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003514 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003515 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003516
3517 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003518 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3519 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003520 ieee80211_free_txskb(ar->hw, skb);
3521 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003522
3523 return ret;
3524}
3525
3526/* This function consumes the sk_buff regardless of return value as far as
3527 * caller is concerned so no freeing is necessary afterwards.
3528 */
3529static int ath10k_mac_tx(struct ath10k *ar,
3530 struct ieee80211_vif *vif,
3531 struct ieee80211_sta *sta,
3532 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003533 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003534 struct sk_buff *skb)
3535{
3536 struct ieee80211_hw *hw = ar->hw;
3537 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3538 int ret;
3539
3540 /* We should disable CCK RATE due to P2P */
3541 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3542 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3543
3544 switch (txmode) {
3545 case ATH10K_HW_TXRX_MGMT:
3546 case ATH10K_HW_TXRX_NATIVE_WIFI:
3547 ath10k_tx_h_nwifi(hw, skb);
3548 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3549 ath10k_tx_h_seq_no(vif, skb);
3550 break;
3551 case ATH10K_HW_TXRX_ETHERNET:
3552 ath10k_tx_h_8023(skb);
3553 break;
3554 case ATH10K_HW_TXRX_RAW:
3555 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3556 WARN_ON_ONCE(1);
3557 ieee80211_free_txskb(hw, skb);
3558 return -ENOTSUPP;
3559 }
3560 }
3561
3562 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3563 if (!ath10k_mac_tx_frm_has_freq(ar)) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303564 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %pK\n",
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003565 skb);
3566
3567 skb_queue_tail(&ar->offchan_tx_queue, skb);
3568 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3569 return 0;
3570 }
3571 }
3572
Michal Kazior6421969f2016-03-06 16:14:25 +02003573 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003574 if (ret) {
3575 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3576 return ret;
3577 }
3578
3579 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003580}
3581
3582void ath10k_offchan_tx_purge(struct ath10k *ar)
3583{
3584 struct sk_buff *skb;
3585
3586 for (;;) {
3587 skb = skb_dequeue(&ar->offchan_tx_queue);
3588 if (!skb)
3589 break;
3590
3591 ieee80211_free_txskb(ar->hw, skb);
3592 }
3593}
3594
3595void ath10k_offchan_tx_work(struct work_struct *work)
3596{
3597 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3598 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003599 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003600 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003601 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003602 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003603 struct ieee80211_vif *vif;
3604 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003605 struct sk_buff *skb;
3606 const u8 *peer_addr;
3607 int vdev_id;
3608 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003609 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003610 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003611
3612 /* FW requirement: We must create a peer before FW will send out
3613 * an offchannel frame. Otherwise the frame will be stuck and
3614 * never transmitted. We delete the peer upon tx completion.
3615 * It is unlikely that a peer for offchannel tx will already be
3616 * present. However it may be in some rare cases so account for that.
3617 * Otherwise we might remove a legitimate peer and break stuff. */
3618
3619 for (;;) {
3620 skb = skb_dequeue(&ar->offchan_tx_queue);
3621 if (!skb)
3622 break;
3623
3624 mutex_lock(&ar->conf_mutex);
3625
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303626 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003627 skb);
3628
3629 hdr = (struct ieee80211_hdr *)skb->data;
3630 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003631
3632 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003633 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003634 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3635 spin_unlock_bh(&ar->data_lock);
3636
3637 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003638 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003639 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003640 peer_addr, vdev_id);
3641
3642 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003643 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3644 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003645 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003646 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003647 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003648 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003649 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003650 }
3651
3652 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003653 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003654 ar->offchan_tx_skb = skb;
3655 spin_unlock_bh(&ar->data_lock);
3656
Michal Kazior8a933962015-11-18 06:59:17 +01003657 /* It's safe to access vif and sta - conf_mutex guarantees that
3658 * sta_state() and remove_interface() are locked exclusively
3659 * out wrt to this offchannel worker.
3660 */
3661 arvif = ath10k_get_arvif(ar, vdev_id);
3662 if (arvif) {
3663 vif = arvif->vif;
3664 sta = ieee80211_find_sta(vif, peer_addr);
3665 } else {
3666 vif = NULL;
3667 sta = NULL;
3668 }
3669
3670 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003671 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003672
Michal Kazior6421969f2016-03-06 16:14:25 +02003673 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003674 if (ret) {
3675 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3676 ret);
3677 /* not serious */
3678 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003679
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003680 time_left =
3681 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3682 if (time_left == 0)
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303683 ath10k_warn(ar, "timed out waiting for offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003684 skb);
3685
Michal Kazioradaeed72015-08-05 12:15:23 +02003686 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003687 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3688 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003689 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003690 peer_addr, vdev_id, ret);
3691 }
3692
3693 mutex_unlock(&ar->conf_mutex);
3694 }
3695}
3696
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003697void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3698{
3699 struct sk_buff *skb;
3700
3701 for (;;) {
3702 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3703 if (!skb)
3704 break;
3705
3706 ieee80211_free_txskb(ar->hw, skb);
3707 }
3708}
3709
3710void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3711{
3712 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3713 struct sk_buff *skb;
3714 int ret;
3715
3716 for (;;) {
3717 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3718 if (!skb)
3719 break;
3720
3721 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003722 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003723 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003724 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003725 ieee80211_free_txskb(ar->hw, skb);
3726 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003727 }
3728}
3729
Michal Kazior29946872016-03-06 16:14:34 +02003730static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3731{
Bob Copelanda66cd732016-06-29 19:29:25 +03003732 struct ath10k_txq *artxq;
Michal Kazior29946872016-03-06 16:14:34 +02003733
3734 if (!txq)
3735 return;
3736
Bob Copelanda66cd732016-06-29 19:29:25 +03003737 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003738 INIT_LIST_HEAD(&artxq->list);
3739}
3740
3741static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3742{
Bob Copelanda66cd732016-06-29 19:29:25 +03003743 struct ath10k_txq *artxq;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003744 struct ath10k_skb_cb *cb;
3745 struct sk_buff *msdu;
3746 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003747
3748 if (!txq)
3749 return;
3750
Bob Copelanda66cd732016-06-29 19:29:25 +03003751 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003752 spin_lock_bh(&ar->txqs_lock);
3753 if (!list_empty(&artxq->list))
3754 list_del_init(&artxq->list);
3755 spin_unlock_bh(&ar->txqs_lock);
Michal Kaziordd4717b2016-03-06 16:14:39 +02003756
3757 spin_lock_bh(&ar->htt.tx_lock);
3758 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3759 cb = ATH10K_SKB_CB(msdu);
3760 if (cb->txq == txq)
3761 cb->txq = NULL;
3762 }
3763 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003764}
3765
Michal Kazior426e10e2016-03-06 16:14:43 +02003766struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
3767 u16 peer_id,
3768 u8 tid)
3769{
3770 struct ath10k_peer *peer;
3771
3772 lockdep_assert_held(&ar->data_lock);
3773
3774 peer = ar->peer_map[peer_id];
3775 if (!peer)
3776 return NULL;
3777
3778 if (peer->sta)
3779 return peer->sta->txq[tid];
3780 else if (peer->vif)
3781 return peer->vif->txq;
3782 else
3783 return NULL;
3784}
3785
Michal Kazior29946872016-03-06 16:14:34 +02003786static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3787 struct ieee80211_txq *txq)
3788{
Michal Kazior426e10e2016-03-06 16:14:43 +02003789 struct ath10k *ar = hw->priv;
3790 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3791
3792 /* No need to get locks */
3793
3794 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3795 return true;
3796
3797 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3798 return true;
3799
3800 if (artxq->num_fw_queued < artxq->num_push_allowed)
3801 return true;
3802
3803 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003804}
3805
Michal Kazior426e10e2016-03-06 16:14:43 +02003806int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3807 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02003808{
Michal Kazior29946872016-03-06 16:14:34 +02003809 struct ath10k *ar = hw->priv;
3810 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003811 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003812 struct ieee80211_vif *vif = txq->vif;
3813 struct ieee80211_sta *sta = txq->sta;
3814 enum ath10k_hw_txrx_mode txmode;
3815 enum ath10k_mac_tx_path txpath;
3816 struct sk_buff *skb;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303817 struct ieee80211_hdr *hdr;
Michal Kazior426e10e2016-03-06 16:14:43 +02003818 size_t skb_len;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303819 bool is_mgmt, is_presp;
Michal Kazior29946872016-03-06 16:14:34 +02003820 int ret;
3821
3822 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303823 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003824 spin_unlock_bh(&ar->htt.tx_lock);
3825
3826 if (ret)
3827 return ret;
3828
3829 skb = ieee80211_tx_dequeue(hw, txq);
3830 if (!skb) {
3831 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303832 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003833 spin_unlock_bh(&ar->htt.tx_lock);
3834
3835 return -ENOENT;
3836 }
3837
Michal Kaziordd4717b2016-03-06 16:14:39 +02003838 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Michal Kazior29946872016-03-06 16:14:34 +02003839
Michal Kazior426e10e2016-03-06 16:14:43 +02003840 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02003841 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
3842 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303843 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
3844
3845 if (is_mgmt) {
3846 hdr = (struct ieee80211_hdr *)skb->data;
3847 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
3848
3849 spin_lock_bh(&ar->htt.tx_lock);
3850 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
3851
3852 if (ret) {
3853 ath10k_htt_tx_dec_pending(htt);
3854 spin_unlock_bh(&ar->htt.tx_lock);
3855 return ret;
3856 }
3857 spin_unlock_bh(&ar->htt.tx_lock);
3858 }
Michal Kazior29946872016-03-06 16:14:34 +02003859
3860 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
3861 if (unlikely(ret)) {
3862 ath10k_warn(ar, "failed to push frame: %d\n", ret);
3863
3864 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303865 ath10k_htt_tx_dec_pending(htt);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303866 if (is_mgmt)
3867 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003868 spin_unlock_bh(&ar->htt.tx_lock);
3869
3870 return ret;
3871 }
3872
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003873 spin_lock_bh(&ar->htt.tx_lock);
3874 artxq->num_fw_queued++;
3875 spin_unlock_bh(&ar->htt.tx_lock);
3876
Michal Kazior426e10e2016-03-06 16:14:43 +02003877 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003878}
3879
3880void ath10k_mac_tx_push_pending(struct ath10k *ar)
3881{
3882 struct ieee80211_hw *hw = ar->hw;
3883 struct ieee80211_txq *txq;
3884 struct ath10k_txq *artxq;
3885 struct ath10k_txq *last;
3886 int ret;
3887 int max;
3888
Michal Kazior7a0adc82016-05-23 23:12:45 +03003889 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
3890 return;
3891
Michal Kazior29946872016-03-06 16:14:34 +02003892 spin_lock_bh(&ar->txqs_lock);
3893 rcu_read_lock();
3894
3895 last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
3896 while (!list_empty(&ar->txqs)) {
3897 artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
3898 txq = container_of((void *)artxq, struct ieee80211_txq,
3899 drv_priv);
3900
3901 /* Prevent aggressive sta/tid taking over tx queue */
3902 max = 16;
Michal Kazior750eeed2016-03-17 10:51:05 +01003903 ret = 0;
3904 while (ath10k_mac_tx_can_push(hw, txq) && max--) {
Michal Kazior29946872016-03-06 16:14:34 +02003905 ret = ath10k_mac_tx_push_txq(hw, txq);
3906 if (ret < 0)
3907 break;
3908 }
3909
3910 list_del_init(&artxq->list);
Michal Kazior9d71d472016-03-17 10:51:04 +01003911 if (ret != -ENOENT)
3912 list_add_tail(&artxq->list, &ar->txqs);
3913
Michal Kaziorc1a43d92016-03-06 16:14:36 +02003914 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02003915
Michal Kazior9d71d472016-03-17 10:51:04 +01003916 if (artxq == last || (ret < 0 && ret != -ENOENT))
Michal Kazior29946872016-03-06 16:14:34 +02003917 break;
Michal Kazior29946872016-03-06 16:14:34 +02003918 }
3919
3920 rcu_read_unlock();
3921 spin_unlock_bh(&ar->txqs_lock);
3922}
3923
Kalle Valo5e3dd152013-06-12 20:52:10 +03003924/************/
3925/* Scanning */
3926/************/
3927
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003928void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003929{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003930 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003931
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003932 switch (ar->scan.state) {
3933 case ATH10K_SCAN_IDLE:
3934 break;
3935 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01003936 case ATH10K_SCAN_ABORTING:
Avraham Stern7947d3e2016-07-05 15:23:12 +03003937 if (!ar->scan.is_roc) {
3938 struct cfg80211_scan_info info = {
3939 .aborted = (ar->scan.state ==
3940 ATH10K_SCAN_ABORTING),
3941 };
3942
3943 ieee80211_scan_completed(ar->hw, &info);
3944 } else if (ar->scan.roc_notify) {
Michal Kaziord710e752015-07-09 13:08:36 +02003945 ieee80211_remain_on_channel_expired(ar->hw);
Avraham Stern7947d3e2016-07-05 15:23:12 +03003946 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003947 /* fall through */
3948 case ATH10K_SCAN_STARTING:
3949 ar->scan.state = ATH10K_SCAN_IDLE;
3950 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01003951 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003952 ath10k_offchan_tx_purge(ar);
3953 cancel_delayed_work(&ar->scan.timeout);
Daniel Wagner881ed542016-08-18 15:12:06 +02003954 complete(&ar->scan.completed);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003955 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003956 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003957}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003958
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003959void ath10k_scan_finish(struct ath10k *ar)
3960{
3961 spin_lock_bh(&ar->data_lock);
3962 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003963 spin_unlock_bh(&ar->data_lock);
3964}
3965
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003966static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003967{
3968 struct wmi_stop_scan_arg arg = {
3969 .req_id = 1, /* FIXME */
3970 .req_type = WMI_SCAN_STOP_ONE,
3971 .u.scan_id = ATH10K_SCAN_ID,
3972 };
3973 int ret;
3974
3975 lockdep_assert_held(&ar->conf_mutex);
3976
Kalle Valo5e3dd152013-06-12 20:52:10 +03003977 ret = ath10k_wmi_stop_scan(ar, &arg);
3978 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003979 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003980 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003981 }
3982
Kalle Valo14e105c2016-04-13 14:13:21 +03003983 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003984 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003985 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003986 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003987 } else if (ret > 0) {
3988 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003989 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003990
3991out:
3992 /* Scan state should be updated upon scan completion but in case
3993 * firmware fails to deliver the event (for whatever reason) it is
3994 * desired to clean up scan state anyway. Firmware may have just
3995 * dropped the scan completion event delivery due to transport pipe
3996 * being overflown with data and/or it can recover on its own before
3997 * next scan request is submitted.
3998 */
3999 spin_lock_bh(&ar->data_lock);
4000 if (ar->scan.state != ATH10K_SCAN_IDLE)
4001 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004002 spin_unlock_bh(&ar->data_lock);
4003
4004 return ret;
4005}
4006
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004007static void ath10k_scan_abort(struct ath10k *ar)
4008{
4009 int ret;
4010
4011 lockdep_assert_held(&ar->conf_mutex);
4012
4013 spin_lock_bh(&ar->data_lock);
4014
4015 switch (ar->scan.state) {
4016 case ATH10K_SCAN_IDLE:
4017 /* This can happen if timeout worker kicked in and called
4018 * abortion while scan completion was being processed.
4019 */
4020 break;
4021 case ATH10K_SCAN_STARTING:
4022 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02004023 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004024 ath10k_scan_state_str(ar->scan.state),
4025 ar->scan.state);
4026 break;
4027 case ATH10K_SCAN_RUNNING:
4028 ar->scan.state = ATH10K_SCAN_ABORTING;
4029 spin_unlock_bh(&ar->data_lock);
4030
4031 ret = ath10k_scan_stop(ar);
4032 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004033 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004034
4035 spin_lock_bh(&ar->data_lock);
4036 break;
4037 }
4038
4039 spin_unlock_bh(&ar->data_lock);
4040}
4041
4042void ath10k_scan_timeout_work(struct work_struct *work)
4043{
4044 struct ath10k *ar = container_of(work, struct ath10k,
4045 scan.timeout.work);
4046
4047 mutex_lock(&ar->conf_mutex);
4048 ath10k_scan_abort(ar);
4049 mutex_unlock(&ar->conf_mutex);
4050}
4051
Kalle Valo5e3dd152013-06-12 20:52:10 +03004052static int ath10k_start_scan(struct ath10k *ar,
4053 const struct wmi_start_scan_arg *arg)
4054{
4055 int ret;
4056
4057 lockdep_assert_held(&ar->conf_mutex);
4058
4059 ret = ath10k_wmi_start_scan(ar, arg);
4060 if (ret)
4061 return ret;
4062
Kalle Valo14e105c2016-04-13 14:13:21 +03004063 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004064 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004065 ret = ath10k_scan_stop(ar);
4066 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004067 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004068
4069 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004070 }
4071
Ben Greear2f9eec02015-02-15 16:50:38 +02004072 /* If we failed to start the scan, return error code at
4073 * this point. This is probably due to some issue in the
4074 * firmware, but no need to wedge the driver due to that...
4075 */
4076 spin_lock_bh(&ar->data_lock);
4077 if (ar->scan.state == ATH10K_SCAN_IDLE) {
4078 spin_unlock_bh(&ar->data_lock);
4079 return -EINVAL;
4080 }
4081 spin_unlock_bh(&ar->data_lock);
4082
Kalle Valo5e3dd152013-06-12 20:52:10 +03004083 return 0;
4084}
4085
4086/**********************/
4087/* mac80211 callbacks */
4088/**********************/
4089
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004090static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4091 struct ieee80211_tx_control *control,
4092 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004093{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004094 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02004095 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03004096 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4097 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004098 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02004099 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02004100 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01004101 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02004102 enum ath10k_mac_tx_path txpath;
4103 bool is_htt;
4104 bool is_mgmt;
4105 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004106 int ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004107
Michal Kaziordd4717b2016-03-06 16:14:39 +02004108 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004109
Michal Kazior8a933962015-11-18 06:59:17 +01004110 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004111 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
4112 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
4113 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304114 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004115
Michal Kazior6421969f2016-03-06 16:14:25 +02004116 if (is_htt) {
4117 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004118 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4119
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304120 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004121 if (ret) {
4122 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4123 ret);
4124 spin_unlock_bh(&ar->htt.tx_lock);
4125 ieee80211_free_txskb(ar->hw, skb);
4126 return;
4127 }
4128
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304129 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4130 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304131 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4132 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304133 ath10k_htt_tx_dec_pending(htt);
4134 spin_unlock_bh(&ar->htt.tx_lock);
4135 ieee80211_free_txskb(ar->hw, skb);
4136 return;
4137 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004138 spin_unlock_bh(&ar->htt.tx_lock);
4139 }
4140
4141 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
4142 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004143 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004144 if (is_htt) {
4145 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304146 ath10k_htt_tx_dec_pending(htt);
4147 if (is_mgmt)
4148 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004149 spin_unlock_bh(&ar->htt.tx_lock);
4150 }
4151 return;
4152 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004153}
4154
Michal Kazior29946872016-03-06 16:14:34 +02004155static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4156 struct ieee80211_txq *txq)
4157{
4158 struct ath10k *ar = hw->priv;
4159 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304160 struct ieee80211_txq *f_txq;
4161 struct ath10k_txq *f_artxq;
4162 int ret = 0;
4163 int max = 16;
Michal Kazior29946872016-03-06 16:14:34 +02004164
Michal Kazior750eeed2016-03-17 10:51:05 +01004165 spin_lock_bh(&ar->txqs_lock);
4166 if (list_empty(&artxq->list))
4167 list_add_tail(&artxq->list, &ar->txqs);
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304168
4169 f_artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
4170 f_txq = container_of((void *)f_artxq, struct ieee80211_txq, drv_priv);
4171 list_del_init(&f_artxq->list);
4172
4173 while (ath10k_mac_tx_can_push(hw, f_txq) && max--) {
4174 ret = ath10k_mac_tx_push_txq(hw, f_txq);
4175 if (ret)
4176 break;
4177 }
4178 if (ret != -ENOENT)
4179 list_add_tail(&f_artxq->list, &ar->txqs);
Michal Kazior750eeed2016-03-17 10:51:05 +01004180 spin_unlock_bh(&ar->txqs_lock);
Michal Kazior29946872016-03-06 16:14:34 +02004181
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304182 ath10k_htt_tx_txq_update(hw, f_txq);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004183 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02004184}
4185
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004186/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004187void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004188{
4189 /* make sure rcu-protected mac80211 tx path itself is drained */
4190 synchronize_net();
4191
4192 ath10k_offchan_tx_purge(ar);
4193 ath10k_mgmt_over_wmi_tx_purge(ar);
4194
4195 cancel_work_sync(&ar->offchan_tx_work);
4196 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4197}
4198
Michal Kazioraffd3212013-07-16 09:54:35 +02004199void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004200{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004201 struct ath10k_vif *arvif;
4202
Michal Kazior818bdd12013-07-16 09:38:57 +02004203 lockdep_assert_held(&ar->conf_mutex);
4204
Michal Kazior19337472014-08-28 12:58:16 +02004205 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4206 ar->filter_flags = 0;
4207 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004208 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004209
4210 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004211 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004212
4213 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004214 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004215
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004216 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004217 ath10k_peer_cleanup_all(ar);
4218 ath10k_core_stop(ar);
4219 ath10k_hif_power_down(ar);
4220
4221 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004222 list_for_each_entry(arvif, &ar->arvifs, list)
4223 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004224 spin_unlock_bh(&ar->data_lock);
4225}
4226
Ben Greear46acf7bb2014-05-16 17:15:38 +03004227static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4228{
4229 struct ath10k *ar = hw->priv;
4230
4231 mutex_lock(&ar->conf_mutex);
4232
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304233 *tx_ant = ar->cfg_tx_chainmask;
4234 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03004235
4236 mutex_unlock(&ar->conf_mutex);
4237
4238 return 0;
4239}
4240
Ben Greear5572a952014-11-24 16:22:10 +02004241static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4242{
4243 /* It is not clear that allowing gaps in chainmask
4244 * is helpful. Probably it will not do what user
4245 * is hoping for, so warn in that case.
4246 */
4247 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4248 return;
4249
4250 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4251 dbg, cm);
4252}
4253
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304254static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4255{
4256 int nsts = ar->vht_cap_info;
4257
4258 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4259 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4260
4261 /* If firmware does not deliver to host number of space-time
4262 * streams supported, assume it support up to 4 BF STS and return
4263 * the value for VHT CAP: nsts-1)
4264 */
4265 if (nsts == 0)
4266 return 3;
4267
4268 return nsts;
4269}
4270
4271static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4272{
4273 int sound_dim = ar->vht_cap_info;
4274
4275 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4276 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4277
4278 /* If the sounding dimension is not advertised by the firmware,
4279 * let's use a default value of 1
4280 */
4281 if (sound_dim == 0)
4282 return 1;
4283
4284 return sound_dim;
4285}
4286
4287static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4288{
4289 struct ieee80211_sta_vht_cap vht_cap = {0};
4290 u16 mcs_map;
4291 u32 val;
4292 int i;
4293
4294 vht_cap.vht_supported = 1;
4295 vht_cap.cap = ar->vht_cap_info;
4296
4297 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4298 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4299 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4300 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4301 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4302
4303 vht_cap.cap |= val;
4304 }
4305
4306 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4307 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4308 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4309 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4310 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4311
4312 vht_cap.cap |= val;
4313 }
4314
4315 mcs_map = 0;
4316 for (i = 0; i < 8; i++) {
4317 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4318 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4319 else
4320 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4321 }
4322
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004323 if (ar->cfg_tx_chainmask <= 1)
4324 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4325
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304326 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4327 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4328
4329 return vht_cap;
4330}
4331
4332static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4333{
4334 int i;
4335 struct ieee80211_sta_ht_cap ht_cap = {0};
4336
4337 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4338 return ht_cap;
4339
4340 ht_cap.ht_supported = 1;
4341 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4342 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4343 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4344 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004345 ht_cap.cap |=
4346 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304347
4348 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4349 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4350
4351 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4352 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4353
4354 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4355 u32 smps;
4356
4357 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4358 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4359
4360 ht_cap.cap |= smps;
4361 }
4362
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004363 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304364 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4365
4366 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4367 u32 stbc;
4368
4369 stbc = ar->ht_cap_info;
4370 stbc &= WMI_HT_CAP_RX_STBC;
4371 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4372 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4373 stbc &= IEEE80211_HT_CAP_RX_STBC;
4374
4375 ht_cap.cap |= stbc;
4376 }
4377
4378 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
4379 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4380
4381 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4382 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4383
4384 /* max AMSDU is implicitly taken from vht_cap_info */
4385 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4386 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4387
4388 for (i = 0; i < ar->num_rf_chains; i++) {
4389 if (ar->cfg_rx_chainmask & BIT(i))
4390 ht_cap.mcs.rx_mask[i] = 0xFF;
4391 }
4392
4393 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4394
4395 return ht_cap;
4396}
4397
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304398static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4399{
4400 struct ieee80211_supported_band *band;
4401 struct ieee80211_sta_vht_cap vht_cap;
4402 struct ieee80211_sta_ht_cap ht_cap;
4403
4404 ht_cap = ath10k_get_ht_cap(ar);
4405 vht_cap = ath10k_create_vht_cap(ar);
4406
4407 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004408 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304409 band->ht_cap = ht_cap;
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304410 }
4411 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004412 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304413 band->ht_cap = ht_cap;
4414 band->vht_cap = vht_cap;
4415 }
4416}
4417
Ben Greear46acf7bb2014-05-16 17:15:38 +03004418static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4419{
4420 int ret;
4421
4422 lockdep_assert_held(&ar->conf_mutex);
4423
Ben Greear5572a952014-11-24 16:22:10 +02004424 ath10k_check_chain_mask(ar, tx_ant, "tx");
4425 ath10k_check_chain_mask(ar, rx_ant, "rx");
4426
Ben Greear46acf7bb2014-05-16 17:15:38 +03004427 ar->cfg_tx_chainmask = tx_ant;
4428 ar->cfg_rx_chainmask = rx_ant;
4429
4430 if ((ar->state != ATH10K_STATE_ON) &&
4431 (ar->state != ATH10K_STATE_RESTARTED))
4432 return 0;
4433
4434 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4435 tx_ant);
4436 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004437 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03004438 ret, tx_ant);
4439 return ret;
4440 }
4441
4442 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4443 rx_ant);
4444 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004445 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7bb2014-05-16 17:15:38 +03004446 ret, rx_ant);
4447 return ret;
4448 }
4449
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304450 /* Reload HT/VHT capability */
4451 ath10k_mac_setup_ht_vht_cap(ar);
4452
Ben Greear46acf7bb2014-05-16 17:15:38 +03004453 return 0;
4454}
4455
4456static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4457{
4458 struct ath10k *ar = hw->priv;
4459 int ret;
4460
4461 mutex_lock(&ar->conf_mutex);
4462 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4463 mutex_unlock(&ar->conf_mutex);
4464 return ret;
4465}
4466
Kalle Valo5e3dd152013-06-12 20:52:10 +03004467static int ath10k_start(struct ieee80211_hw *hw)
4468{
4469 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304470 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004471 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004472
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004473 /*
4474 * This makes sense only when restarting hw. It is harmless to call
Mohammed Shafi Shajakhan6dfdbfc2016-04-26 14:41:36 +03004475 * unconditionally. This is necessary to make sure no HTT/WMI tx
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004476 * commands will be submitted while restarting.
4477 */
4478 ath10k_drain_tx(ar);
4479
Michal Kazior548db542013-07-05 16:15:15 +03004480 mutex_lock(&ar->conf_mutex);
4481
Michal Kaziorc5058f52014-05-26 12:46:03 +03004482 switch (ar->state) {
4483 case ATH10K_STATE_OFF:
4484 ar->state = ATH10K_STATE_ON;
4485 break;
4486 case ATH10K_STATE_RESTARTING:
Michal Kaziorc5058f52014-05-26 12:46:03 +03004487 ar->state = ATH10K_STATE_RESTARTED;
4488 break;
4489 case ATH10K_STATE_ON:
4490 case ATH10K_STATE_RESTARTED:
4491 case ATH10K_STATE_WEDGED:
4492 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004493 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004494 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004495 case ATH10K_STATE_UTF:
4496 ret = -EBUSY;
4497 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004498 }
4499
4500 ret = ath10k_hif_power_up(ar);
4501 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004502 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004503 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004504 }
4505
Kalle Valo7ebf7212016-04-20 19:44:51 +03004506 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
4507 &ar->normal_mode_fw);
Michal Kazior818bdd12013-07-16 09:38:57 +02004508 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004509 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004510 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004511 }
4512
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304513 param = ar->wmi.pdev_param->pmf_qos;
4514 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004515 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004516 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004517 goto err_core_stop;
4518 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004519
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304520 param = ar->wmi.pdev_param->dynamic_bw;
4521 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004522 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004523 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004524 goto err_core_stop;
4525 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004526
Michal Kaziorcf327842015-03-31 10:26:25 +00004527 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4528 ret = ath10k_wmi_adaptive_qcs(ar, true);
4529 if (ret) {
4530 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4531 ret);
4532 goto err_core_stop;
4533 }
4534 }
4535
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004536 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304537 param = ar->wmi.pdev_param->burst_enable;
4538 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004539 if (ret) {
4540 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4541 goto err_core_stop;
4542 }
4543 }
4544
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304545 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7bb2014-05-16 17:15:38 +03004546
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004547 /*
4548 * By default FW set ARP frames ac to voice (6). In that case ARP
4549 * exchange is not working properly for UAPSD enabled AP. ARP requests
4550 * which arrives with access category 0 are processed by network stack
4551 * and send back with access category 0, but FW changes access category
4552 * to 6. Set ARP frames access category to best effort (0) solves
4553 * this problem.
4554 */
4555
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304556 param = ar->wmi.pdev_param->arp_ac_override;
4557 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004558 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004559 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004560 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004561 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004562 }
4563
Maharaja62f77f02015-10-21 11:49:18 +03004564 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
Kalle Valoc4cdf752016-04-20 19:45:18 +03004565 ar->running_fw->fw_file.fw_features)) {
Maharaja62f77f02015-10-21 11:49:18 +03004566 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4567 WMI_CCA_DETECT_LEVEL_AUTO,
4568 WMI_CCA_DETECT_MARGIN_AUTO);
4569 if (ret) {
4570 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4571 ret);
4572 goto err_core_stop;
4573 }
4574 }
4575
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304576 param = ar->wmi.pdev_param->ani_enable;
4577 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304578 if (ret) {
4579 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4580 ret);
4581 goto err_core_stop;
4582 }
4583
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304584 ar->ani_enabled = true;
4585
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304586 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304587 param = ar->wmi.pdev_param->peer_stats_update_period;
4588 ret = ath10k_wmi_pdev_set_param(ar, param,
4589 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4590 if (ret) {
4591 ath10k_warn(ar,
4592 "failed to set peer stats period : %d\n",
4593 ret);
4594 goto err_core_stop;
4595 }
4596 }
4597
Rajkumar Manoharan39136242016-05-27 20:15:59 +05304598 param = ar->wmi.pdev_param->enable_btcoex;
4599 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
4600 test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
4601 ar->running_fw->fw_file.fw_features)) {
4602 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4603 if (ret) {
4604 ath10k_warn(ar,
4605 "failed to set btcoex param: %d\n", ret);
4606 goto err_core_stop;
4607 }
4608 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
4609 }
4610
Michal Kaziord6500972014-04-08 09:56:09 +03004611 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004612 ath10k_regd_update(ar);
4613
Simon Wunderlich855aed12014-08-02 09:12:54 +03004614 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304615 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004616
Michal Kaziorae254432014-05-26 12:46:02 +03004617 mutex_unlock(&ar->conf_mutex);
4618 return 0;
4619
4620err_core_stop:
4621 ath10k_core_stop(ar);
4622
4623err_power_down:
4624 ath10k_hif_power_down(ar);
4625
4626err_off:
4627 ar->state = ATH10K_STATE_OFF;
4628
4629err:
Michal Kazior548db542013-07-05 16:15:15 +03004630 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004631 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004632}
4633
4634static void ath10k_stop(struct ieee80211_hw *hw)
4635{
4636 struct ath10k *ar = hw->priv;
4637
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004638 ath10k_drain_tx(ar);
4639
Michal Kazior548db542013-07-05 16:15:15 +03004640 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004641 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004642 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004643 ar->state = ATH10K_STATE_OFF;
4644 }
Michal Kazior548db542013-07-05 16:15:15 +03004645 mutex_unlock(&ar->conf_mutex);
4646
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004647 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004648 cancel_work_sync(&ar->restart_work);
4649}
4650
Michal Kaziorad088bf2013-10-16 15:44:46 +03004651static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004652{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004653 struct ath10k_vif *arvif;
4654 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004655
4656 lockdep_assert_held(&ar->conf_mutex);
4657
Michal Kaziorad088bf2013-10-16 15:44:46 +03004658 list_for_each_entry(arvif, &ar->arvifs, list) {
4659 ret = ath10k_mac_vif_setup_ps(arvif);
4660 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004661 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004662 break;
4663 }
4664 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004665
Michal Kaziorad088bf2013-10-16 15:44:46 +03004666 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004667}
4668
Michal Kazior7d9d5582014-10-21 10:40:15 +03004669static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4670{
4671 int ret;
4672 u32 param;
4673
4674 lockdep_assert_held(&ar->conf_mutex);
4675
4676 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4677
4678 param = ar->wmi.pdev_param->txpower_limit2g;
4679 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4680 if (ret) {
4681 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4682 txpower, ret);
4683 return ret;
4684 }
4685
4686 param = ar->wmi.pdev_param->txpower_limit5g;
4687 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4688 if (ret) {
4689 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4690 txpower, ret);
4691 return ret;
4692 }
4693
4694 return 0;
4695}
4696
4697static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4698{
4699 struct ath10k_vif *arvif;
4700 int ret, txpower = -1;
4701
4702 lockdep_assert_held(&ar->conf_mutex);
4703
4704 list_for_each_entry(arvif, &ar->arvifs, list) {
Ryan Hsu88407be2016-12-13 14:55:19 -08004705 if (arvif->txpower <= 0)
4706 continue;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004707
4708 if (txpower == -1)
4709 txpower = arvif->txpower;
4710 else
4711 txpower = min(txpower, arvif->txpower);
4712 }
4713
Ryan Hsu88407be2016-12-13 14:55:19 -08004714 if (txpower == -1)
4715 return 0;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004716
4717 ret = ath10k_mac_txpower_setup(ar, txpower);
4718 if (ret) {
4719 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4720 txpower, ret);
4721 return ret;
4722 }
4723
4724 return 0;
4725}
4726
Kalle Valo5e3dd152013-06-12 20:52:10 +03004727static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4728{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004729 struct ath10k *ar = hw->priv;
4730 struct ieee80211_conf *conf = &hw->conf;
4731 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004732
4733 mutex_lock(&ar->conf_mutex);
4734
Michal Kazioraffd3212013-07-16 09:54:35 +02004735 if (changed & IEEE80211_CONF_CHANGE_PS)
4736 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004737
4738 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004739 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4740 ret = ath10k_monitor_recalc(ar);
4741 if (ret)
4742 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004743 }
4744
4745 mutex_unlock(&ar->conf_mutex);
4746 return ret;
4747}
4748
Ben Greear5572a952014-11-24 16:22:10 +02004749static u32 get_nss_from_chainmask(u16 chain_mask)
4750{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05304751 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02004752 return 4;
4753 else if ((chain_mask & 0x7) == 0x7)
4754 return 3;
4755 else if ((chain_mask & 0x3) == 0x3)
4756 return 2;
4757 return 1;
4758}
4759
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304760static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4761{
4762 u32 value = 0;
4763 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004764 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004765 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304766
4767 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4768 return 0;
4769
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004770 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304771 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4772 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004773 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304774
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004775 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304776 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4777 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004778 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304779
4780 if (!value)
4781 return 0;
4782
4783 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4784 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4785
4786 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4787 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4788 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4789
4790 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4791 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4792
4793 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4794 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4795 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4796
4797 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4798 ar->wmi.vdev_param->txbf, value);
4799}
4800
Kalle Valo5e3dd152013-06-12 20:52:10 +03004801/*
4802 * TODO:
4803 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4804 * because we will send mgmt frames without CCK. This requirement
4805 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4806 * in the TX packet.
4807 */
4808static int ath10k_add_interface(struct ieee80211_hw *hw,
4809 struct ieee80211_vif *vif)
4810{
4811 struct ath10k *ar = hw->priv;
4812 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004813 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004814 enum wmi_sta_powersave_param param;
4815 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004816 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004817 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004818 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004819 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004820
Johannes Berg848955c2014-11-11 12:48:42 +01004821 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4822
Kalle Valo5e3dd152013-06-12 20:52:10 +03004823 mutex_lock(&ar->conf_mutex);
4824
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004825 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02004826 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004827
Kalle Valo5e3dd152013-06-12 20:52:10 +03004828 arvif->ar = ar;
4829 arvif->vif = vif;
4830
Ben Greeare63b33f2013-10-22 14:54:14 -07004831 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004832 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004833 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4834 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004835
Michal Kazior45c9abc2015-04-21 20:42:58 +03004836 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4837 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4838 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4839 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4840 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4841 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4842 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004843
Michal Kaziore04cafb2015-08-05 12:15:24 +02004844 if (ar->num_peers >= ar->max_num_peers) {
4845 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004846 ret = -ENOBUFS;
4847 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004848 }
4849
Ben Greeara9aefb32014-08-12 11:02:19 +03004850 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004851 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004852 ret = -EBUSY;
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004853 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004854 }
Ben Greear16c11172014-09-23 14:17:16 -07004855 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004856
Ben Greear16c11172014-09-23 14:17:16 -07004857 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4858 bit, ar->free_vdev_map);
4859
4860 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004861 arvif->vdev_subtype =
4862 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004863
Kalle Valo5e3dd152013-06-12 20:52:10 +03004864 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004865 case NL80211_IFTYPE_P2P_DEVICE:
4866 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004867 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4868 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01004869 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004870 case NL80211_IFTYPE_UNSPECIFIED:
4871 case NL80211_IFTYPE_STATION:
4872 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4873 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004874 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4875 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004876 break;
4877 case NL80211_IFTYPE_ADHOC:
4878 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4879 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004880 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08004881 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08004882 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4883 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08004884 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004885 ret = -EINVAL;
4886 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
4887 goto err;
4888 }
4889 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4890 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004891 case NL80211_IFTYPE_AP:
4892 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4893
4894 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004895 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4896 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004897 break;
4898 case NL80211_IFTYPE_MONITOR:
4899 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4900 break;
4901 default:
4902 WARN_ON(1);
4903 break;
4904 }
4905
Michal Kazior96d828d2015-03-31 10:26:23 +00004906 /* Using vdev_id as queue number will make it very easy to do per-vif
4907 * tx queue locking. This shouldn't wrap due to interface combinations
4908 * but do a modulo for correctness sake and prevent using offchannel tx
4909 * queues for regular vif tx.
4910 */
4911 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4912 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4913 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4914
Michal Kazior64badcb2014-09-18 11:18:02 +03004915 /* Some firmware revisions don't wait for beacon tx completion before
4916 * sending another SWBA event. This could lead to hardware using old
4917 * (freed) beacon data in some cases, e.g. tx credit starvation
4918 * combined with missed TBTT. This is very very rare.
4919 *
4920 * On non-IOMMU-enabled hosts this could be a possible security issue
4921 * because hw could beacon some random data on the air. On
4922 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4923 * device would crash.
4924 *
4925 * Since there are no beacon tx completions (implicit nor explicit)
4926 * propagated to host the only workaround for this is to allocate a
4927 * DMA-coherent buffer for a lifetime of a vif and use it for all
4928 * beacon tx commands. Worst case for this approach is some beacons may
4929 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4930 */
4931 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004932 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03004933 vif->type == NL80211_IFTYPE_AP) {
4934 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4935 IEEE80211_MAX_FRAME_LEN,
4936 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304937 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004938 if (!arvif->beacon_buf) {
4939 ret = -ENOMEM;
4940 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4941 ret);
4942 goto err;
4943 }
4944 }
David Liuccec9032015-07-24 20:25:32 +03004945 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
4946 arvif->nohwcrypt = true;
4947
4948 if (arvif->nohwcrypt &&
4949 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4950 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
4951 goto err;
4952 }
Michal Kazior64badcb2014-09-18 11:18:02 +03004953
4954 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4955 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4956 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004957
4958 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4959 arvif->vdev_subtype, vif->addr);
4960 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004961 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004962 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004963 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004964 }
4965
Ben Greear16c11172014-09-23 14:17:16 -07004966 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05304967 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03004968 list_add(&arvif->list, &ar->arvifs);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05304969 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004970
Michal Kazior46725b152015-01-28 09:57:49 +02004971 /* It makes no sense to have firmware do keepalives. mac80211 already
4972 * takes care of this with idle connection polling.
4973 */
4974 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004975 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02004976 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004977 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004978 goto err_vdev_delete;
4979 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004980
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004981 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004982
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004983 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4984 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004985 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004986 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004987 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004988 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004989 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03004990 goto err_vdev_delete;
4991 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004992
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05304993 /* Configuring number of spatial stream for monitor interface is causing
4994 * target assert in qca9888 and qca6174.
4995 */
4996 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02004997 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
4998
4999 vdev_param = ar->wmi.vdev_param->nss;
5000 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5001 nss);
5002 if (ret) {
5003 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
5004 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
5005 ret);
5006 goto err_vdev_delete;
5007 }
5008 }
5009
Michal Kaziore57e0572015-03-24 13:14:03 +00005010 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5011 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02005012 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
5013 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005014 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00005015 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005016 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005017 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005018 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005019
5020 spin_lock_bh(&ar->data_lock);
5021
5022 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
5023 if (!peer) {
5024 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5025 vif->addr, arvif->vdev_id);
5026 spin_unlock_bh(&ar->data_lock);
5027 ret = -ENOENT;
5028 goto err_peer_delete;
5029 }
5030
5031 arvif->peer_id = find_first_bit(peer->peer_ids,
5032 ATH10K_MAX_NUM_PEER_IDS);
5033
5034 spin_unlock_bh(&ar->data_lock);
5035 } else {
5036 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00005037 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01005038
Michal Kaziore57e0572015-03-24 13:14:03 +00005039 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02005040 ret = ath10k_mac_set_kickout(arvif);
5041 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005042 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005043 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02005044 goto err_peer_delete;
5045 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005046 }
5047
5048 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
5049 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
5050 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5051 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5052 param, value);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005053 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005054 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005055 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005056 goto err_peer_delete;
5057 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005058
Michal Kazior9f9b5742014-12-12 12:41:36 +01005059 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005060 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005061 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005062 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005063 goto err_peer_delete;
5064 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005065
Michal Kazior9f9b5742014-12-12 12:41:36 +01005066 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005067 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005068 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005069 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005070 goto err_peer_delete;
5071 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005072 }
5073
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305074 ret = ath10k_mac_set_txbf_conf(arvif);
5075 if (ret) {
5076 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
5077 arvif->vdev_id, ret);
5078 goto err_peer_delete;
5079 }
5080
Michal Kazior424121c2013-07-22 14:13:31 +02005081 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005082 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005083 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03005084 arvif->vdev_id, ret);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005085 goto err_peer_delete;
5086 }
Michal Kazior679c54a2013-07-05 16:15:04 +03005087
Michal Kazior7d9d5582014-10-21 10:40:15 +03005088 arvif->txpower = vif->bss_conf.txpower;
5089 ret = ath10k_mac_txpower_recalc(ar);
5090 if (ret) {
5091 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5092 goto err_peer_delete;
5093 }
5094
Michal Kazior500ff9f2015-03-31 10:26:21 +00005095 if (vif->type == NL80211_IFTYPE_MONITOR) {
5096 ar->monitor_arvif = arvif;
5097 ret = ath10k_monitor_recalc(ar);
5098 if (ret) {
5099 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5100 goto err_peer_delete;
5101 }
5102 }
5103
Michal Kazior6d2d51e2015-08-07 09:08:21 +02005104 spin_lock_bh(&ar->htt.tx_lock);
5105 if (!ar->tx_paused)
5106 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
5107 spin_unlock_bh(&ar->htt.tx_lock);
5108
Kalle Valo5e3dd152013-06-12 20:52:10 +03005109 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005110 return 0;
5111
5112err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00005113 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5114 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005115 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
5116
5117err_vdev_delete:
5118 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07005119 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305120 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005121 list_del(&arvif->list);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305122 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005123
5124err:
Michal Kazior64badcb2014-09-18 11:18:02 +03005125 if (arvif->beacon_buf) {
5126 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
5127 arvif->beacon_buf, arvif->beacon_paddr);
5128 arvif->beacon_buf = NULL;
5129 }
5130
Michal Kazior9dad14ae2013-10-16 15:44:45 +03005131 mutex_unlock(&ar->conf_mutex);
5132
Kalle Valo5e3dd152013-06-12 20:52:10 +03005133 return ret;
5134}
5135
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005136static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
5137{
5138 int i;
5139
5140 for (i = 0; i < BITS_PER_LONG; i++)
5141 ath10k_mac_vif_tx_unlock(arvif, i);
5142}
5143
Kalle Valo5e3dd152013-06-12 20:52:10 +03005144static void ath10k_remove_interface(struct ieee80211_hw *hw,
5145 struct ieee80211_vif *vif)
5146{
5147 struct ath10k *ar = hw->priv;
5148 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior69427262016-03-06 16:14:30 +02005149 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005150 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005151 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005152
Michal Kazior81a9a172015-03-05 16:02:17 +02005153 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005154 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005155
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305156 mutex_lock(&ar->conf_mutex);
5157
Michal Kaziored543882013-09-13 14:16:56 +02005158 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03005159 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02005160 spin_unlock_bh(&ar->data_lock);
5161
Simon Wunderlich855aed12014-08-02 09:12:54 +03005162 ret = ath10k_spectral_vif_stop(arvif);
5163 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005164 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005165 arvif->vdev_id, ret);
5166
Ben Greear16c11172014-09-23 14:17:16 -07005167 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305168 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005169 list_del(&arvif->list);
Vasanthakumar Thiagarajanebaa4b12016-10-10 19:51:18 +05305170 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005171
Michal Kaziore57e0572015-03-24 13:14:03 +00005172 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5173 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005174 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5175 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005176 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005177 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005178 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005179
5180 kfree(arvif->u.ap.noa_data);
5181 }
5182
Michal Kazior7aa7a722014-08-25 12:09:38 +02005183 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005184 arvif->vdev_id);
5185
Kalle Valo5e3dd152013-06-12 20:52:10 +03005186 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5187 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005188 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005189 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005190
Michal Kazior2c512052015-02-15 16:50:40 +02005191 /* Some firmware revisions don't notify host about self-peer removal
5192 * until after associated vdev is deleted.
5193 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005194 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5195 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005196 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5197 vif->addr);
5198 if (ret)
5199 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5200 arvif->vdev_id, ret);
5201
5202 spin_lock_bh(&ar->data_lock);
5203 ar->num_peers--;
5204 spin_unlock_bh(&ar->data_lock);
5205 }
5206
Michal Kazior69427262016-03-06 16:14:30 +02005207 spin_lock_bh(&ar->data_lock);
5208 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5209 peer = ar->peer_map[i];
5210 if (!peer)
5211 continue;
5212
5213 if (peer->vif == vif) {
5214 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5215 vif->addr, arvif->vdev_id);
5216 peer->vif = NULL;
5217 }
5218 }
5219 spin_unlock_bh(&ar->data_lock);
5220
Kalle Valo5e3dd152013-06-12 20:52:10 +03005221 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005222 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005223
Michal Kazior500ff9f2015-03-31 10:26:21 +00005224 if (vif->type == NL80211_IFTYPE_MONITOR) {
5225 ar->monitor_arvif = NULL;
5226 ret = ath10k_monitor_recalc(ar);
5227 if (ret)
5228 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5229 }
5230
Ryan Hsud679fa12016-12-22 14:31:46 -08005231 ret = ath10k_mac_txpower_recalc(ar);
5232 if (ret)
5233 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5234
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005235 spin_lock_bh(&ar->htt.tx_lock);
5236 ath10k_mac_vif_tx_unlock_all(arvif);
5237 spin_unlock_bh(&ar->htt.tx_lock);
5238
Michal Kazior29946872016-03-06 16:14:34 +02005239 ath10k_mac_txq_unref(ar, vif->txq);
5240
Kalle Valo5e3dd152013-06-12 20:52:10 +03005241 mutex_unlock(&ar->conf_mutex);
5242}
5243
5244/*
5245 * FIXME: Has to be verified.
5246 */
5247#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005248 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005249 FIF_CONTROL | \
5250 FIF_PSPOLL | \
5251 FIF_OTHER_BSS | \
5252 FIF_BCN_PRBRESP_PROMISC | \
5253 FIF_PROBE_REQ | \
5254 FIF_FCSFAIL)
5255
5256static void ath10k_configure_filter(struct ieee80211_hw *hw,
5257 unsigned int changed_flags,
5258 unsigned int *total_flags,
5259 u64 multicast)
5260{
5261 struct ath10k *ar = hw->priv;
5262 int ret;
5263
5264 mutex_lock(&ar->conf_mutex);
5265
5266 changed_flags &= SUPPORTED_FILTERS;
5267 *total_flags &= SUPPORTED_FILTERS;
5268 ar->filter_flags = *total_flags;
5269
Michal Kazior19337472014-08-28 12:58:16 +02005270 ret = ath10k_monitor_recalc(ar);
5271 if (ret)
Colin Ian King7f03d302016-08-26 19:08:52 +01005272 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005273
5274 mutex_unlock(&ar->conf_mutex);
5275}
5276
5277static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5278 struct ieee80211_vif *vif,
5279 struct ieee80211_bss_conf *info,
5280 u32 changed)
5281{
5282 struct ath10k *ar = hw->priv;
5283 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5284 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03005285 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005286
5287 mutex_lock(&ar->conf_mutex);
5288
5289 if (changed & BSS_CHANGED_IBSS)
5290 ath10k_control_ibss(arvif, info, vif->addr);
5291
5292 if (changed & BSS_CHANGED_BEACON_INT) {
5293 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005294 vdev_param = ar->wmi.vdev_param->beacon_interval;
5295 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005296 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005297 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005298 "mac vdev %d beacon_interval %d\n",
5299 arvif->vdev_id, arvif->beacon_interval);
5300
Kalle Valo5e3dd152013-06-12 20:52:10 +03005301 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005302 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005303 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005304 }
5305
5306 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005307 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005308 "vdev %d set beacon tx mode to staggered\n",
5309 arvif->vdev_id);
5310
Bartosz Markowski226a3392013-09-26 17:47:16 +02005311 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5312 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005313 WMI_BEACON_STAGGERED_MODE);
5314 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005315 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005316 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005317
5318 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5319 if (ret)
5320 ath10k_warn(ar, "failed to update beacon template: %d\n",
5321 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005322
5323 if (ieee80211_vif_is_mesh(vif)) {
5324 /* mesh doesn't use SSID but firmware needs it */
5325 strncpy(arvif->u.ap.ssid, "mesh",
5326 sizeof(arvif->u.ap.ssid));
5327 arvif->u.ap.ssid_len = 4;
5328 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005329 }
5330
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005331 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5332 ret = ath10k_mac_setup_prb_tmpl(arvif);
5333 if (ret)
5334 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5335 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005336 }
5337
Michal Kaziorba2479f2015-01-24 12:14:51 +02005338 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005339 arvif->dtim_period = info->dtim_period;
5340
Michal Kazior7aa7a722014-08-25 12:09:38 +02005341 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005342 "mac vdev %d dtim_period %d\n",
5343 arvif->vdev_id, arvif->dtim_period);
5344
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005345 vdev_param = ar->wmi.vdev_param->dtim_period;
5346 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005347 arvif->dtim_period);
5348 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005349 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005350 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005351 }
5352
5353 if (changed & BSS_CHANGED_SSID &&
5354 vif->type == NL80211_IFTYPE_AP) {
5355 arvif->u.ap.ssid_len = info->ssid_len;
5356 if (info->ssid_len)
5357 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5358 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5359 }
5360
Michal Kazior077efc82014-10-21 10:10:29 +03005361 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5362 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005363
5364 if (changed & BSS_CHANGED_BEACON_ENABLED)
5365 ath10k_control_beaconing(arvif, info);
5366
5367 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005368 arvif->use_cts_prot = info->use_cts_prot;
Kalle Valo60c3daa2013-09-08 17:56:07 +03005369
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005370 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005371 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005372 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005373 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005374
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02005375 if (ath10k_mac_can_set_cts_prot(arvif)) {
5376 ret = ath10k_mac_set_cts_prot(arvif);
5377 if (ret)
5378 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
5379 arvif->vdev_id, ret);
5380 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005381 }
5382
5383 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005384 if (info->use_short_slot)
5385 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5386
5387 else
5388 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5389
Michal Kazior7aa7a722014-08-25 12:09:38 +02005390 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005391 arvif->vdev_id, slottime);
5392
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005393 vdev_param = ar->wmi.vdev_param->slot_time;
5394 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005395 slottime);
5396 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005397 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005398 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005399 }
5400
5401 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005402 if (info->use_short_preamble)
5403 preamble = WMI_VDEV_PREAMBLE_SHORT;
5404 else
5405 preamble = WMI_VDEV_PREAMBLE_LONG;
5406
Michal Kazior7aa7a722014-08-25 12:09:38 +02005407 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005408 "mac vdev %d preamble %dn",
5409 arvif->vdev_id, preamble);
5410
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005411 vdev_param = ar->wmi.vdev_param->preamble;
5412 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005413 preamble);
5414 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005415 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005416 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005417 }
5418
5419 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005420 if (info->assoc) {
5421 /* Workaround: Make sure monitor vdev is not running
5422 * when associating to prevent some firmware revisions
5423 * (e.g. 10.1 and 10.2) from crashing.
5424 */
5425 if (ar->monitor_started)
5426 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005427 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005428 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005429 } else {
5430 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005431 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005432 }
5433
Michal Kazior7d9d5582014-10-21 10:40:15 +03005434 if (changed & BSS_CHANGED_TXPOWER) {
5435 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5436 arvif->vdev_id, info->txpower);
5437
5438 arvif->txpower = info->txpower;
5439 ret = ath10k_mac_txpower_recalc(ar);
5440 if (ret)
5441 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5442 }
5443
Michal Kaziorbf14e652014-12-12 12:41:38 +01005444 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005445 arvif->ps = vif->bss_conf.ps;
5446
5447 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005448 if (ret)
5449 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5450 arvif->vdev_id, ret);
5451 }
5452
Kalle Valo5e3dd152013-06-12 20:52:10 +03005453 mutex_unlock(&ar->conf_mutex);
5454}
5455
Benjamin Bergebee76f2016-09-28 15:11:58 +03005456static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, s16 value)
5457{
5458 struct ath10k *ar = hw->priv;
5459
5460 /* This function should never be called if setting the coverage class
5461 * is not supported on this hardware.
5462 */
5463 if (!ar->hw_params.hw_ops->set_coverage_class) {
5464 WARN_ON_ONCE(1);
5465 return;
5466 }
5467 ar->hw_params.hw_ops->set_coverage_class(ar, value);
5468}
5469
Kalle Valo5e3dd152013-06-12 20:52:10 +03005470static int ath10k_hw_scan(struct ieee80211_hw *hw,
5471 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005472 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005473{
5474 struct ath10k *ar = hw->priv;
5475 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02005476 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005477 struct wmi_start_scan_arg arg;
5478 int ret = 0;
5479 int i;
5480
5481 mutex_lock(&ar->conf_mutex);
5482
5483 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005484 switch (ar->scan.state) {
5485 case ATH10K_SCAN_IDLE:
5486 reinit_completion(&ar->scan.started);
5487 reinit_completion(&ar->scan.completed);
5488 ar->scan.state = ATH10K_SCAN_STARTING;
5489 ar->scan.is_roc = false;
5490 ar->scan.vdev_id = arvif->vdev_id;
5491 ret = 0;
5492 break;
5493 case ATH10K_SCAN_STARTING:
5494 case ATH10K_SCAN_RUNNING:
5495 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005496 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005497 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005498 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005499 spin_unlock_bh(&ar->data_lock);
5500
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005501 if (ret)
5502 goto exit;
5503
Kalle Valo5e3dd152013-06-12 20:52:10 +03005504 memset(&arg, 0, sizeof(arg));
5505 ath10k_wmi_start_scan_init(ar, &arg);
5506 arg.vdev_id = arvif->vdev_id;
5507 arg.scan_id = ATH10K_SCAN_ID;
5508
Kalle Valo5e3dd152013-06-12 20:52:10 +03005509 if (req->ie_len) {
5510 arg.ie_len = req->ie_len;
5511 memcpy(arg.ie, req->ie, arg.ie_len);
5512 }
5513
5514 if (req->n_ssids) {
5515 arg.n_ssids = req->n_ssids;
5516 for (i = 0; i < arg.n_ssids; i++) {
5517 arg.ssids[i].len = req->ssids[i].ssid_len;
5518 arg.ssids[i].ssid = req->ssids[i].ssid;
5519 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005520 } else {
5521 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005522 }
5523
5524 if (req->n_channels) {
5525 arg.n_channels = req->n_channels;
5526 for (i = 0; i < arg.n_channels; i++)
5527 arg.channels[i] = req->channels[i]->center_freq;
5528 }
5529
5530 ret = ath10k_start_scan(ar, &arg);
5531 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005532 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005533 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005534 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005535 spin_unlock_bh(&ar->data_lock);
5536 }
5537
Michal Kazior634349b2015-09-03 10:43:45 +02005538 /* Add a 200ms margin to account for event/command processing */
5539 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5540 msecs_to_jiffies(arg.max_scan_time +
5541 200));
5542
Kalle Valo5e3dd152013-06-12 20:52:10 +03005543exit:
5544 mutex_unlock(&ar->conf_mutex);
5545 return ret;
5546}
5547
5548static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5549 struct ieee80211_vif *vif)
5550{
5551 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005552
5553 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005554 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005555 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01005556
5557 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005558}
5559
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005560static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
5561 struct ath10k_vif *arvif,
5562 enum set_key_cmd cmd,
5563 struct ieee80211_key_conf *key)
5564{
5565 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
5566 int ret;
5567
5568 /* 10.1 firmware branch requires default key index to be set to group
5569 * key index after installing it. Otherwise FW/HW Txes corrupted
5570 * frames with multi-vif APs. This is not required for main firmware
5571 * branch (e.g. 636).
5572 *
Michal Kazior8461baf2015-04-10 13:23:22 +00005573 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
5574 *
5575 * FIXME: It remains unknown if this is required for multi-vif STA
5576 * interfaces on 10.1.
5577 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005578
Michal Kazior8461baf2015-04-10 13:23:22 +00005579 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
5580 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005581 return;
5582
5583 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
5584 return;
5585
5586 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
5587 return;
5588
5589 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5590 return;
5591
5592 if (cmd != SET_KEY)
5593 return;
5594
5595 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5596 key->keyidx);
5597 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005598 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005599 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005600}
5601
Kalle Valo5e3dd152013-06-12 20:52:10 +03005602static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5603 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5604 struct ieee80211_key_conf *key)
5605{
5606 struct ath10k *ar = hw->priv;
5607 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5608 struct ath10k_peer *peer;
5609 const u8 *peer_addr;
5610 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5611 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5612 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005613 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005614 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005615 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005616
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005617 /* this one needs to be done in software */
5618 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
5619 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005620
David Liuccec9032015-07-24 20:25:32 +03005621 if (arvif->nohwcrypt)
5622 return 1;
5623
Kalle Valo5e3dd152013-06-12 20:52:10 +03005624 if (key->keyidx > WMI_MAX_KEY_INDEX)
5625 return -ENOSPC;
5626
5627 mutex_lock(&ar->conf_mutex);
5628
5629 if (sta)
5630 peer_addr = sta->addr;
5631 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5632 peer_addr = vif->bss_conf.bssid;
5633 else
5634 peer_addr = vif->addr;
5635
5636 key->hw_key_idx = key->keyidx;
5637
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005638 if (is_wep) {
5639 if (cmd == SET_KEY)
5640 arvif->wep_keys[key->keyidx] = key;
5641 else
5642 arvif->wep_keys[key->keyidx] = NULL;
5643 }
5644
Kalle Valo5e3dd152013-06-12 20:52:10 +03005645 /* the peer should not disappear in mid-way (unless FW goes awry) since
5646 * we already hold conf_mutex. we just make sure its there now. */
5647 spin_lock_bh(&ar->data_lock);
5648 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5649 spin_unlock_bh(&ar->data_lock);
5650
5651 if (!peer) {
5652 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005653 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005654 peer_addr);
5655 ret = -EOPNOTSUPP;
5656 goto exit;
5657 } else {
5658 /* if the peer doesn't exist there is no key to disable
5659 * anymore */
5660 goto exit;
5661 }
5662 }
5663
Michal Kazior7cc45732015-03-09 14:24:17 +01005664 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5665 flags |= WMI_KEY_PAIRWISE;
5666 else
5667 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005668
Kalle Valo5e3dd152013-06-12 20:52:10 +03005669 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005670 if (cmd == DISABLE_KEY)
5671 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005672
Michal Kaziorad325cb2015-02-18 14:02:27 +01005673 /* When WEP keys are uploaded it's possible that there are
5674 * stations associated already (e.g. when merging) without any
5675 * keys. Static WEP needs an explicit per-peer key upload.
5676 */
5677 if (vif->type == NL80211_IFTYPE_ADHOC &&
5678 cmd == SET_KEY)
5679 ath10k_mac_vif_update_wep_key(arvif, key);
5680
Michal Kazior370e5672015-02-18 14:02:26 +01005681 /* 802.1x never sets the def_wep_key_idx so each set_key()
5682 * call changes default tx key.
5683 *
5684 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5685 * after first set_key().
5686 */
5687 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5688 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005689 }
5690
Michal Kazior370e5672015-02-18 14:02:26 +01005691 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005692 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005693 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005694 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005695 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005696 goto exit;
5697 }
5698
Michal Kazior29a10002015-04-10 13:05:58 +00005699 /* mac80211 sets static WEP keys as groupwise while firmware requires
5700 * them to be installed twice as both pairwise and groupwise.
5701 */
5702 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5703 flags2 = flags;
5704 flags2 &= ~WMI_KEY_GROUP;
5705 flags2 |= WMI_KEY_PAIRWISE;
5706
5707 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5708 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005709 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005710 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5711 arvif->vdev_id, peer_addr, ret);
5712 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5713 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005714 if (ret2) {
5715 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005716 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5717 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005718 }
Michal Kazior29a10002015-04-10 13:05:58 +00005719 goto exit;
5720 }
5721 }
5722
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005723 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5724
Kalle Valo5e3dd152013-06-12 20:52:10 +03005725 spin_lock_bh(&ar->data_lock);
5726 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5727 if (peer && cmd == SET_KEY)
5728 peer->keys[key->keyidx] = key;
5729 else if (peer && cmd == DISABLE_KEY)
5730 peer->keys[key->keyidx] = NULL;
5731 else if (peer == NULL)
5732 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005733 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005734 spin_unlock_bh(&ar->data_lock);
5735
5736exit:
5737 mutex_unlock(&ar->conf_mutex);
5738 return ret;
5739}
5740
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005741static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5742 struct ieee80211_vif *vif,
5743 int keyidx)
5744{
5745 struct ath10k *ar = hw->priv;
5746 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5747 int ret;
5748
5749 mutex_lock(&arvif->ar->conf_mutex);
5750
5751 if (arvif->ar->state != ATH10K_STATE_ON)
5752 goto unlock;
5753
5754 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5755 arvif->vdev_id, keyidx);
5756
5757 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5758 arvif->vdev_id,
5759 arvif->ar->wmi.vdev_param->def_keyid,
5760 keyidx);
5761
5762 if (ret) {
5763 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5764 arvif->vdev_id,
5765 ret);
5766 goto unlock;
5767 }
5768
5769 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005770
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005771unlock:
5772 mutex_unlock(&arvif->ar->conf_mutex);
5773}
5774
Michal Kazior9797feb2014-02-14 14:49:48 +01005775static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5776{
5777 struct ath10k *ar;
5778 struct ath10k_vif *arvif;
5779 struct ath10k_sta *arsta;
5780 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005781 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02005782 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005783 const u8 *ht_mcs_mask;
5784 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005785 u32 changed, bw, nss, smps;
5786 int err;
5787
5788 arsta = container_of(wk, struct ath10k_sta, update_wk);
5789 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5790 arvif = arsta->arvif;
5791 ar = arvif->ar;
5792
Michal Kazior45c9abc2015-04-21 20:42:58 +03005793 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5794 return;
5795
5796 band = def.chan->band;
5797 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5798 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5799
Michal Kazior9797feb2014-02-14 14:49:48 +01005800 spin_lock_bh(&ar->data_lock);
5801
5802 changed = arsta->changed;
5803 arsta->changed = 0;
5804
5805 bw = arsta->bw;
5806 nss = arsta->nss;
5807 smps = arsta->smps;
5808
5809 spin_unlock_bh(&ar->data_lock);
5810
5811 mutex_lock(&ar->conf_mutex);
5812
Michal Kazior45c9abc2015-04-21 20:42:58 +03005813 nss = max_t(u32, 1, nss);
5814 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
5815 ath10k_mac_max_vht_nss(vht_mcs_mask)));
5816
Michal Kazior9797feb2014-02-14 14:49:48 +01005817 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005818 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005819 sta->addr, bw);
5820
5821 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5822 WMI_PEER_CHAN_WIDTH, bw);
5823 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005824 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005825 sta->addr, bw, err);
5826 }
5827
5828 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005829 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005830 sta->addr, nss);
5831
5832 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5833 WMI_PEER_NSS, nss);
5834 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005835 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005836 sta->addr, nss, err);
5837 }
5838
5839 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005840 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005841 sta->addr, smps);
5842
5843 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5844 WMI_PEER_SMPS_STATE, smps);
5845 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005846 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005847 sta->addr, smps, err);
5848 }
5849
Janusz Dziedzic55884c02014-12-17 12:30:02 +02005850 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
5851 changed & IEEE80211_RC_NSS_CHANGED) {
5852 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005853 sta->addr);
5854
Michal Kazior590922a2014-10-21 10:10:29 +03005855 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005856 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005857 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005858 sta->addr);
5859 }
5860
Michal Kazior9797feb2014-02-14 14:49:48 +01005861 mutex_unlock(&ar->conf_mutex);
5862}
5863
Marek Puzyniak7c354242015-03-30 09:51:52 +03005864static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
5865 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005866{
5867 struct ath10k *ar = arvif->ar;
5868
5869 lockdep_assert_held(&ar->conf_mutex);
5870
Marek Puzyniak7c354242015-03-30 09:51:52 +03005871 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005872 return 0;
5873
5874 if (ar->num_stations >= ar->max_num_stations)
5875 return -ENOBUFS;
5876
5877 ar->num_stations++;
5878
5879 return 0;
5880}
5881
Marek Puzyniak7c354242015-03-30 09:51:52 +03005882static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
5883 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005884{
5885 struct ath10k *ar = arvif->ar;
5886
5887 lockdep_assert_held(&ar->conf_mutex);
5888
Marek Puzyniak7c354242015-03-30 09:51:52 +03005889 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005890 return;
5891
5892 ar->num_stations--;
5893}
5894
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005895struct ath10k_mac_tdls_iter_data {
5896 u32 num_tdls_stations;
5897 struct ieee80211_vif *curr_vif;
5898};
5899
5900static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5901 struct ieee80211_sta *sta)
5902{
5903 struct ath10k_mac_tdls_iter_data *iter_data = data;
5904 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5905 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5906
5907 if (sta->tdls && sta_vif == iter_data->curr_vif)
5908 iter_data->num_tdls_stations++;
5909}
5910
5911static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5912 struct ieee80211_vif *vif)
5913{
5914 struct ath10k_mac_tdls_iter_data data = {};
5915
5916 data.curr_vif = vif;
5917
5918 ieee80211_iterate_stations_atomic(hw,
5919 ath10k_mac_tdls_vif_stations_count_iter,
5920 &data);
5921 return data.num_tdls_stations;
5922}
5923
5924static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5925 struct ieee80211_vif *vif)
5926{
5927 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5928 int *num_tdls_vifs = data;
5929
5930 if (vif->type != NL80211_IFTYPE_STATION)
5931 return;
5932
5933 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5934 (*num_tdls_vifs)++;
5935}
5936
5937static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5938{
5939 int num_tdls_vifs = 0;
5940
5941 ieee80211_iterate_active_interfaces_atomic(hw,
5942 IEEE80211_IFACE_ITER_NORMAL,
5943 ath10k_mac_tdls_vifs_count_iter,
5944 &num_tdls_vifs);
5945 return num_tdls_vifs;
5946}
5947
Kalle Valo5e3dd152013-06-12 20:52:10 +03005948static int ath10k_sta_state(struct ieee80211_hw *hw,
5949 struct ieee80211_vif *vif,
5950 struct ieee80211_sta *sta,
5951 enum ieee80211_sta_state old_state,
5952 enum ieee80211_sta_state new_state)
5953{
5954 struct ath10k *ar = hw->priv;
5955 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005956 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005957 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005958 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02005959 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005960
Michal Kazior76f90022014-02-25 09:29:57 +02005961 if (old_state == IEEE80211_STA_NOTEXIST &&
5962 new_state == IEEE80211_STA_NONE) {
5963 memset(arsta, 0, sizeof(*arsta));
5964 arsta->arvif = arvif;
5965 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02005966
5967 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5968 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02005969 }
5970
Michal Kazior9797feb2014-02-14 14:49:48 +01005971 /* cancel must be done outside the mutex to avoid deadlock */
5972 if ((old_state == IEEE80211_STA_NONE &&
5973 new_state == IEEE80211_STA_NOTEXIST))
5974 cancel_work_sync(&arsta->update_wk);
5975
Kalle Valo5e3dd152013-06-12 20:52:10 +03005976 mutex_lock(&ar->conf_mutex);
5977
5978 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005979 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005980 /*
5981 * New station addition.
5982 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005983 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5984 u32 num_tdls_stations;
5985 u32 num_tdls_vifs;
5986
Michal Kaziorcfd10612014-11-25 15:16:05 +01005987 ath10k_dbg(ar, ATH10K_DBG_MAC,
5988 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5989 arvif->vdev_id, sta->addr,
5990 ar->num_stations + 1, ar->max_num_stations,
5991 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005992
Marek Puzyniak7c354242015-03-30 09:51:52 +03005993 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005994 if (ret) {
5995 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5996 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005997 goto exit;
5998 }
5999
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006000 if (sta->tdls)
6001 peer_type = WMI_PEER_TYPE_TDLS;
6002
Michal Kazior69427262016-03-06 16:14:30 +02006003 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
6004 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01006005 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006006 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 -08006007 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03006008 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01006009 goto exit;
6010 }
Michal Kazior077efc82014-10-21 10:10:29 +03006011
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006012 spin_lock_bh(&ar->data_lock);
6013
6014 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
6015 if (!peer) {
6016 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
6017 vif->addr, arvif->vdev_id);
6018 spin_unlock_bh(&ar->data_lock);
6019 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6020 ath10k_mac_dec_num_stations(arvif, sta);
6021 ret = -ENOENT;
6022 goto exit;
6023 }
6024
6025 arsta->peer_id = find_first_bit(peer->peer_ids,
6026 ATH10K_MAX_NUM_PEER_IDS);
6027
6028 spin_unlock_bh(&ar->data_lock);
6029
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006030 if (!sta->tdls)
6031 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03006032
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006033 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
6034 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
6035
6036 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
6037 num_tdls_stations == 0) {
6038 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
6039 arvif->vdev_id, ar->max_num_tdls_vdevs);
6040 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6041 ath10k_mac_dec_num_stations(arvif, sta);
6042 ret = -ENOBUFS;
6043 goto exit;
6044 }
6045
6046 if (num_tdls_stations == 0) {
6047 /* This is the first tdls peer in current vif */
6048 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
6049
6050 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6051 state);
Michal Kazior077efc82014-10-21 10:10:29 +03006052 if (ret) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006053 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
Michal Kazior077efc82014-10-21 10:10:29 +03006054 arvif->vdev_id, ret);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006055 ath10k_peer_delete(ar, arvif->vdev_id,
6056 sta->addr);
6057 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006058 goto exit;
6059 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006060 }
Michal Kazior077efc82014-10-21 10:10:29 +03006061
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006062 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6063 WMI_TDLS_PEER_STATE_PEERING);
6064 if (ret) {
6065 ath10k_warn(ar,
6066 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
6067 sta->addr, arvif->vdev_id, ret);
6068 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6069 ath10k_mac_dec_num_stations(arvif, sta);
6070
6071 if (num_tdls_stations != 0)
6072 goto exit;
6073 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6074 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03006075 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006076 } else if ((old_state == IEEE80211_STA_NONE &&
6077 new_state == IEEE80211_STA_NOTEXIST)) {
6078 /*
6079 * Existing station deletion.
6080 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006081 ath10k_dbg(ar, ATH10K_DBG_MAC,
Ben Greear30404202016-08-18 18:26:35 -07006082 "mac vdev %d peer delete %pM sta %pK (sta gone)\n",
6083 arvif->vdev_id, sta->addr, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006084
Kalle Valo5e3dd152013-06-12 20:52:10 +03006085 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6086 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006087 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006088 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006089
Marek Puzyniak7c354242015-03-30 09:51:52 +03006090 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006091
Michal Kazior69427262016-03-06 16:14:30 +02006092 spin_lock_bh(&ar->data_lock);
6093 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
6094 peer = ar->peer_map[i];
6095 if (!peer)
6096 continue;
6097
6098 if (peer->sta == sta) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05306099 ath10k_warn(ar, "found sta peer %pM (ptr %pK id %d) entry on vdev %i after it was supposedly removed\n",
Ben Greeard0eeafa2016-06-30 15:23:59 +03006100 sta->addr, peer, i, arvif->vdev_id);
Michal Kazior69427262016-03-06 16:14:30 +02006101 peer->sta = NULL;
Ben Greeard0eeafa2016-06-30 15:23:59 +03006102
6103 /* Clean up the peer object as well since we
6104 * must have failed to do this above.
6105 */
6106 list_del(&peer->list);
6107 ar->peer_map[i] = NULL;
6108 kfree(peer);
6109 ar->num_peers--;
Michal Kazior69427262016-03-06 16:14:30 +02006110 }
6111 }
6112 spin_unlock_bh(&ar->data_lock);
6113
Michal Kazior29946872016-03-06 16:14:34 +02006114 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6115 ath10k_mac_txq_unref(ar, sta->txq[i]);
6116
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006117 if (!sta->tdls)
6118 goto exit;
6119
6120 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
6121 goto exit;
6122
6123 /* This was the last tdls peer in current vif */
6124 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6125 WMI_TDLS_DISABLE);
6126 if (ret) {
6127 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6128 arvif->vdev_id, ret);
6129 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006130 } else if (old_state == IEEE80211_STA_AUTH &&
6131 new_state == IEEE80211_STA_ASSOC &&
6132 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006133 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03006134 vif->type == NL80211_IFTYPE_ADHOC)) {
6135 /*
6136 * New association.
6137 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006138 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006139 sta->addr);
6140
Michal Kazior590922a2014-10-21 10:10:29 +03006141 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006142 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006143 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006144 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006145 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006146 new_state == IEEE80211_STA_AUTHORIZED &&
6147 sta->tdls) {
6148 /*
6149 * Tdls station authorized.
6150 */
6151 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
6152 sta->addr);
6153
6154 ret = ath10k_station_assoc(ar, vif, sta, false);
6155 if (ret) {
6156 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
6157 sta->addr, arvif->vdev_id, ret);
6158 goto exit;
6159 }
6160
6161 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6162 WMI_TDLS_PEER_STATE_CONNECTED);
6163 if (ret)
6164 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
6165 sta->addr, arvif->vdev_id, ret);
6166 } else if (old_state == IEEE80211_STA_ASSOC &&
6167 new_state == IEEE80211_STA_AUTH &&
6168 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006169 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006170 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006171 /*
6172 * Disassociation.
6173 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006174 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006175 sta->addr);
6176
Michal Kazior590922a2014-10-21 10:10:29 +03006177 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006178 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006179 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006180 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006181 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006182exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006183 mutex_unlock(&ar->conf_mutex);
6184 return ret;
6185}
6186
6187static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006188 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006189{
6190 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02006191 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6192 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006193 u32 value = 0;
6194 int ret = 0;
6195
Michal Kazior548db542013-07-05 16:15:15 +03006196 lockdep_assert_held(&ar->conf_mutex);
6197
Kalle Valo5e3dd152013-06-12 20:52:10 +03006198 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6199 return 0;
6200
6201 switch (ac) {
6202 case IEEE80211_AC_VO:
6203 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6204 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006205 prio = 7;
6206 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006207 break;
6208 case IEEE80211_AC_VI:
6209 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6210 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006211 prio = 5;
6212 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006213 break;
6214 case IEEE80211_AC_BE:
6215 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6216 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006217 prio = 2;
6218 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006219 break;
6220 case IEEE80211_AC_BK:
6221 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6222 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006223 prio = 0;
6224 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006225 break;
6226 }
6227
6228 if (enable)
6229 arvif->u.sta.uapsd |= value;
6230 else
6231 arvif->u.sta.uapsd &= ~value;
6232
6233 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6234 WMI_STA_PS_PARAM_UAPSD,
6235 arvif->u.sta.uapsd);
6236 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006237 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006238 goto exit;
6239 }
6240
6241 if (arvif->u.sta.uapsd)
6242 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6243 else
6244 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6245
6246 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6247 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6248 value);
6249 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006250 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006251
Michal Kazior9f9b5742014-12-12 12:41:36 +01006252 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6253 if (ret) {
6254 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6255 arvif->vdev_id, ret);
6256 return ret;
6257 }
6258
6259 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6260 if (ret) {
6261 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6262 arvif->vdev_id, ret);
6263 return ret;
6264 }
6265
Michal Kaziorb0e56152015-01-24 12:14:52 +02006266 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6267 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6268 /* Only userspace can make an educated decision when to send
6269 * trigger frame. The following effectively disables u-UAPSD
6270 * autotrigger in firmware (which is enabled by default
6271 * provided the autotrigger service is available).
6272 */
6273
6274 arg.wmm_ac = acc;
6275 arg.user_priority = prio;
6276 arg.service_interval = 0;
6277 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6278 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6279
6280 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6281 arvif->bssid, &arg, 1);
6282 if (ret) {
6283 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6284 ret);
6285 return ret;
6286 }
6287 }
6288
Kalle Valo5e3dd152013-06-12 20:52:10 +03006289exit:
6290 return ret;
6291}
6292
6293static int ath10k_conf_tx(struct ieee80211_hw *hw,
6294 struct ieee80211_vif *vif, u16 ac,
6295 const struct ieee80211_tx_queue_params *params)
6296{
6297 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01006298 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006299 struct wmi_wmm_params_arg *p = NULL;
6300 int ret;
6301
6302 mutex_lock(&ar->conf_mutex);
6303
6304 switch (ac) {
6305 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006306 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006307 break;
6308 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006309 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006310 break;
6311 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006312 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006313 break;
6314 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006315 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006316 break;
6317 }
6318
6319 if (WARN_ON(!p)) {
6320 ret = -EINVAL;
6321 goto exit;
6322 }
6323
6324 p->cwmin = params->cw_min;
6325 p->cwmax = params->cw_max;
6326 p->aifs = params->aifs;
6327
6328 /*
6329 * The channel time duration programmed in the HW is in absolute
6330 * microseconds, while mac80211 gives the txop in units of
6331 * 32 microseconds.
6332 */
6333 p->txop = params->txop * 32;
6334
Michal Kazior7fc979a2015-01-28 09:57:28 +02006335 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6336 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6337 &arvif->wmm_params);
6338 if (ret) {
6339 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6340 arvif->vdev_id, ret);
6341 goto exit;
6342 }
6343 } else {
6344 /* This won't work well with multi-interface cases but it's
6345 * better than nothing.
6346 */
6347 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6348 if (ret) {
6349 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6350 goto exit;
6351 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006352 }
6353
6354 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6355 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006356 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006357
6358exit:
6359 mutex_unlock(&ar->conf_mutex);
6360 return ret;
6361}
6362
Kalle Valo14e105c2016-04-13 14:13:21 +03006363#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006364
6365static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6366 struct ieee80211_vif *vif,
6367 struct ieee80211_channel *chan,
6368 int duration,
6369 enum ieee80211_roc_type type)
6370{
6371 struct ath10k *ar = hw->priv;
6372 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6373 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006374 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006375 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006376
6377 mutex_lock(&ar->conf_mutex);
6378
6379 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006380 switch (ar->scan.state) {
6381 case ATH10K_SCAN_IDLE:
6382 reinit_completion(&ar->scan.started);
6383 reinit_completion(&ar->scan.completed);
6384 reinit_completion(&ar->scan.on_channel);
6385 ar->scan.state = ATH10K_SCAN_STARTING;
6386 ar->scan.is_roc = true;
6387 ar->scan.vdev_id = arvif->vdev_id;
6388 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006389 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006390 ret = 0;
6391 break;
6392 case ATH10K_SCAN_STARTING:
6393 case ATH10K_SCAN_RUNNING:
6394 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006395 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006396 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006397 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006398 spin_unlock_bh(&ar->data_lock);
6399
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006400 if (ret)
6401 goto exit;
6402
Michal Kaziorfcf98442015-03-31 11:03:47 +00006403 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006404
Kalle Valo5e3dd152013-06-12 20:52:10 +03006405 memset(&arg, 0, sizeof(arg));
6406 ath10k_wmi_start_scan_init(ar, &arg);
6407 arg.vdev_id = arvif->vdev_id;
6408 arg.scan_id = ATH10K_SCAN_ID;
6409 arg.n_channels = 1;
6410 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006411 arg.dwell_time_active = scan_time_msec;
6412 arg.dwell_time_passive = scan_time_msec;
6413 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006414 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6415 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006416 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006417
6418 ret = ath10k_start_scan(ar, &arg);
6419 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006420 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006421 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006422 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006423 spin_unlock_bh(&ar->data_lock);
6424 goto exit;
6425 }
6426
Kalle Valo14e105c2016-04-13 14:13:21 +03006427 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006428 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006429 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006430
6431 ret = ath10k_scan_stop(ar);
6432 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006433 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006434
Kalle Valo5e3dd152013-06-12 20:52:10 +03006435 ret = -ETIMEDOUT;
6436 goto exit;
6437 }
6438
Michal Kaziorfcf98442015-03-31 11:03:47 +00006439 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6440 msecs_to_jiffies(duration));
6441
Kalle Valo5e3dd152013-06-12 20:52:10 +03006442 ret = 0;
6443exit:
6444 mutex_unlock(&ar->conf_mutex);
6445 return ret;
6446}
6447
6448static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6449{
6450 struct ath10k *ar = hw->priv;
6451
6452 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006453
6454 spin_lock_bh(&ar->data_lock);
6455 ar->scan.roc_notify = false;
6456 spin_unlock_bh(&ar->data_lock);
6457
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006458 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006459
Kalle Valo5e3dd152013-06-12 20:52:10 +03006460 mutex_unlock(&ar->conf_mutex);
6461
Michal Kazior4eb2e162014-10-28 10:23:09 +01006462 cancel_delayed_work_sync(&ar->scan.timeout);
6463
Kalle Valo5e3dd152013-06-12 20:52:10 +03006464 return 0;
6465}
6466
6467/*
6468 * Both RTS and Fragmentation threshold are interface-specific
6469 * in ath10k, but device-specific in mac80211.
6470 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006471
6472static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6473{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006474 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006475 struct ath10k_vif *arvif;
6476 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006477
Michal Kaziorad088bf2013-10-16 15:44:46 +03006478 mutex_lock(&ar->conf_mutex);
6479 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006480 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006481 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006482
Michal Kaziorad088bf2013-10-16 15:44:46 +03006483 ret = ath10k_mac_set_rts(arvif, value);
6484 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006485 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006486 arvif->vdev_id, ret);
6487 break;
6488 }
6489 }
6490 mutex_unlock(&ar->conf_mutex);
6491
6492 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006493}
6494
Michal Kazior92092fe2015-08-03 11:16:43 +02006495static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6496{
6497 /* Even though there's a WMI enum for fragmentation threshold no known
6498 * firmware actually implements it. Moreover it is not possible to rely
6499 * frame fragmentation to mac80211 because firmware clears the "more
6500 * fragments" bit in frame control making it impossible for remote
6501 * devices to reassemble frames.
6502 *
6503 * Hence implement a dummy callback just to say fragmentation isn't
6504 * supported. This effectively prevents mac80211 from doing frame
6505 * fragmentation in software.
6506 */
6507 return -EOPNOTSUPP;
6508}
6509
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02006510static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6511 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006512{
6513 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02006514 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006515 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006516
6517 /* mac80211 doesn't care if we really xmit queued frames or not
6518 * we'll collect those frames either way if we stop/delete vdevs */
6519 if (drop)
6520 return;
6521
Michal Kazior548db542013-07-05 16:15:15 +03006522 mutex_lock(&ar->conf_mutex);
6523
Michal Kazioraffd3212013-07-16 09:54:35 +02006524 if (ar->state == ATH10K_STATE_WEDGED)
6525 goto skip;
6526
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006527 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006528 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006529
Michal Kazioredb82362013-07-05 16:15:14 +03006530 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006531 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006532 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006533
Michal Kazior7962b0d2014-10-28 10:34:38 +01006534 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6535 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6536 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006537
6538 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006539 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006540
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006541 if (time_left == 0 || skip)
6542 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6543 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03006544
Michal Kazioraffd3212013-07-16 09:54:35 +02006545skip:
Michal Kazior548db542013-07-05 16:15:15 +03006546 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006547}
6548
6549/* TODO: Implement this function properly
6550 * For now it is needed to reply to Probe Requests in IBSS mode.
6551 * Propably we need this information from FW.
6552 */
6553static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
6554{
6555 return 1;
6556}
6557
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006558static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
6559 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02006560{
6561 struct ath10k *ar = hw->priv;
6562
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006563 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
6564 return;
6565
Michal Kazioraffd3212013-07-16 09:54:35 +02006566 mutex_lock(&ar->conf_mutex);
6567
6568 /* If device failed to restart it will be in a different state, e.g.
6569 * ATH10K_STATE_WEDGED */
6570 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006571 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02006572 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01006573 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02006574 }
6575
6576 mutex_unlock(&ar->conf_mutex);
6577}
6578
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306579static void
6580ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
6581 struct ieee80211_channel *channel)
6582{
6583 int ret;
6584 enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
6585
6586 lockdep_assert_held(&ar->conf_mutex);
6587
6588 if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
6589 (ar->rx_channel != channel))
6590 return;
6591
6592 if (ar->scan.state != ATH10K_SCAN_IDLE) {
6593 ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
6594 return;
6595 }
6596
6597 reinit_completion(&ar->bss_survey_done);
6598
6599 ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
6600 if (ret) {
6601 ath10k_warn(ar, "failed to send pdev bss chan info request\n");
6602 return;
6603 }
6604
6605 ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
6606 if (!ret) {
6607 ath10k_warn(ar, "bss channel survey timed out\n");
6608 return;
6609 }
6610}
6611
Michal Kazior2e1dea42013-07-31 10:32:40 +02006612static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
6613 struct survey_info *survey)
6614{
6615 struct ath10k *ar = hw->priv;
6616 struct ieee80211_supported_band *sband;
6617 struct survey_info *ar_survey = &ar->survey[idx];
6618 int ret = 0;
6619
6620 mutex_lock(&ar->conf_mutex);
6621
Johannes Berg57fbcce2016-04-12 15:56:15 +02006622 sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006623 if (sband && idx >= sband->n_channels) {
6624 idx -= sband->n_channels;
6625 sband = NULL;
6626 }
6627
6628 if (!sband)
Johannes Berg57fbcce2016-04-12 15:56:15 +02006629 sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006630
6631 if (!sband || idx >= sband->n_channels) {
6632 ret = -ENOENT;
6633 goto exit;
6634 }
6635
Ashok Raj Nagarajan77eb3d62016-09-02 10:59:53 +05306636 ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306637
Michal Kazior2e1dea42013-07-31 10:32:40 +02006638 spin_lock_bh(&ar->data_lock);
6639 memcpy(survey, ar_survey, sizeof(*survey));
6640 spin_unlock_bh(&ar->data_lock);
6641
6642 survey->channel = &sband->channels[idx];
6643
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03006644 if (ar->rx_channel == survey->channel)
6645 survey->filled |= SURVEY_INFO_IN_USE;
6646
Michal Kazior2e1dea42013-07-31 10:32:40 +02006647exit:
6648 mutex_unlock(&ar->conf_mutex);
6649 return ret;
6650}
6651
Michal Kazior3ae54222015-03-31 10:49:20 +00006652static bool
6653ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006654 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006655 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006656{
Michal Kazior3ae54222015-03-31 10:49:20 +00006657 int num_rates = 0;
6658 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006659
Michal Kazior3ae54222015-03-31 10:49:20 +00006660 num_rates += hweight32(mask->control[band].legacy);
6661
6662 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
6663 num_rates += hweight8(mask->control[band].ht_mcs[i]);
6664
6665 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
6666 num_rates += hweight16(mask->control[band].vht_mcs[i]);
6667
6668 return num_rates == 1;
6669}
6670
6671static bool
6672ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006673 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006674 const struct cfg80211_bitrate_mask *mask,
6675 int *nss)
6676{
6677 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6678 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6679 u8 ht_nss_mask = 0;
6680 u8 vht_nss_mask = 0;
6681 int i;
6682
6683 if (mask->control[band].legacy)
6684 return false;
6685
6686 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6687 if (mask->control[band].ht_mcs[i] == 0)
6688 continue;
6689 else if (mask->control[band].ht_mcs[i] ==
6690 sband->ht_cap.mcs.rx_mask[i])
6691 ht_nss_mask |= BIT(i);
6692 else
6693 return false;
6694 }
6695
6696 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6697 if (mask->control[band].vht_mcs[i] == 0)
6698 continue;
6699 else if (mask->control[band].vht_mcs[i] ==
6700 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6701 vht_nss_mask |= BIT(i);
6702 else
6703 return false;
6704 }
6705
6706 if (ht_nss_mask != vht_nss_mask)
6707 return false;
6708
6709 if (ht_nss_mask == 0)
6710 return false;
6711
6712 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6713 return false;
6714
6715 *nss = fls(ht_nss_mask);
6716
6717 return true;
6718}
6719
6720static int
6721ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006722 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006723 const struct cfg80211_bitrate_mask *mask,
6724 u8 *rate, u8 *nss)
6725{
6726 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6727 int rate_idx;
6728 int i;
6729 u16 bitrate;
6730 u8 preamble;
6731 u8 hw_rate;
6732
6733 if (hweight32(mask->control[band].legacy) == 1) {
6734 rate_idx = ffs(mask->control[band].legacy) - 1;
6735
6736 hw_rate = sband->bitrates[rate_idx].hw_value;
6737 bitrate = sband->bitrates[rate_idx].bitrate;
6738
6739 if (ath10k_mac_bitrate_is_cck(bitrate))
6740 preamble = WMI_RATE_PREAMBLE_CCK;
6741 else
6742 preamble = WMI_RATE_PREAMBLE_OFDM;
6743
6744 *nss = 1;
6745 *rate = preamble << 6 |
6746 (*nss - 1) << 4 |
6747 hw_rate << 0;
6748
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006749 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006750 }
6751
Michal Kazior3ae54222015-03-31 10:49:20 +00006752 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6753 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6754 *nss = i + 1;
6755 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6756 (*nss - 1) << 4 |
6757 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006758
Michal Kazior3ae54222015-03-31 10:49:20 +00006759 return 0;
6760 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006761 }
6762
Michal Kazior3ae54222015-03-31 10:49:20 +00006763 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6764 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6765 *nss = i + 1;
6766 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6767 (*nss - 1) << 4 |
6768 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006769
Michal Kazior3ae54222015-03-31 10:49:20 +00006770 return 0;
6771 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006772 }
6773
Michal Kazior3ae54222015-03-31 10:49:20 +00006774 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006775}
6776
Michal Kazior3ae54222015-03-31 10:49:20 +00006777static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306778 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006779{
6780 struct ath10k *ar = arvif->ar;
6781 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006782 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006783
Michal Kazior3ae54222015-03-31 10:49:20 +00006784 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006785
Michal Kazior3ae54222015-03-31 10:49:20 +00006786 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6787 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006788
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006789 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006790 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006791 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006792 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006793 rate, ret);
6794 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006795 }
6796
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006797 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006798 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006799 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006800 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6801 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006802 }
6803
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006804 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006805 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006806 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006807 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6808 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006809 }
6810
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306811 vdev_param = ar->wmi.vdev_param->ldpc;
6812 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6813 if (ret) {
6814 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6815 return ret;
6816 }
6817
Michal Kazior3ae54222015-03-31 10:49:20 +00006818 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006819}
6820
Michal Kazior45c9abc2015-04-21 20:42:58 +03006821static bool
6822ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006823 enum nl80211_band band,
Michal Kazior45c9abc2015-04-21 20:42:58 +03006824 const struct cfg80211_bitrate_mask *mask)
6825{
6826 int i;
6827 u16 vht_mcs;
6828
6829 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6830 * to express all VHT MCS rate masks. Effectively only the following
6831 * ranges can be used: none, 0-7, 0-8 and 0-9.
6832 */
6833 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6834 vht_mcs = mask->control[band].vht_mcs[i];
6835
6836 switch (vht_mcs) {
6837 case 0:
6838 case BIT(8) - 1:
6839 case BIT(9) - 1:
6840 case BIT(10) - 1:
6841 break;
6842 default:
6843 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6844 return false;
6845 }
6846 }
6847
6848 return true;
6849}
6850
6851static void ath10k_mac_set_bitrate_mask_iter(void *data,
6852 struct ieee80211_sta *sta)
6853{
6854 struct ath10k_vif *arvif = data;
6855 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6856 struct ath10k *ar = arvif->ar;
6857
6858 if (arsta->arvif != arvif)
6859 return;
6860
6861 spin_lock_bh(&ar->data_lock);
6862 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
6863 spin_unlock_bh(&ar->data_lock);
6864
6865 ieee80211_queue_work(ar->hw, &arsta->update_wk);
6866}
6867
Michal Kazior3ae54222015-03-31 10:49:20 +00006868static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
6869 struct ieee80211_vif *vif,
6870 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006871{
6872 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006873 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006874 struct ath10k *ar = arvif->ar;
Johannes Berg57fbcce2016-04-12 15:56:15 +02006875 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006876 const u8 *ht_mcs_mask;
6877 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00006878 u8 rate;
6879 u8 nss;
6880 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306881 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00006882 int single_nss;
6883 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006884
Michal Kazior500ff9f2015-03-31 10:26:21 +00006885 if (ath10k_mac_vif_chan(vif, &def))
6886 return -EPERM;
6887
Michal Kazior500ff9f2015-03-31 10:26:21 +00006888 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006889 ht_mcs_mask = mask->control[band].ht_mcs;
6890 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306891 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006892
Michal Kazior3ae54222015-03-31 10:49:20 +00006893 sgi = mask->control[band].gi;
6894 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006895 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006896
Michal Kazior3ae54222015-03-31 10:49:20 +00006897 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
6898 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
6899 &rate, &nss);
6900 if (ret) {
6901 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
6902 arvif->vdev_id, ret);
6903 return ret;
6904 }
6905 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
6906 &single_nss)) {
6907 rate = WMI_FIXED_RATE_NONE;
6908 nss = single_nss;
6909 } else {
6910 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006911 nss = min(ar->num_rf_chains,
6912 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6913 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6914
6915 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
6916 return -EINVAL;
6917
6918 mutex_lock(&ar->conf_mutex);
6919
6920 arvif->bitrate_mask = *mask;
6921 ieee80211_iterate_stations_atomic(ar->hw,
6922 ath10k_mac_set_bitrate_mask_iter,
6923 arvif);
6924
6925 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006926 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006927
6928 mutex_lock(&ar->conf_mutex);
6929
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306930 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006931 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006932 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
6933 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006934 goto exit;
6935 }
6936
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006937exit:
6938 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00006939
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006940 return ret;
6941}
6942
Michal Kazior9797feb2014-02-14 14:49:48 +01006943static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6944 struct ieee80211_vif *vif,
6945 struct ieee80211_sta *sta,
6946 u32 changed)
6947{
6948 struct ath10k *ar = hw->priv;
6949 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6950 u32 bw, smps;
6951
6952 spin_lock_bh(&ar->data_lock);
6953
Michal Kazior7aa7a722014-08-25 12:09:38 +02006954 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01006955 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
6956 sta->addr, changed, sta->bandwidth, sta->rx_nss,
6957 sta->smps_mode);
6958
6959 if (changed & IEEE80211_RC_BW_CHANGED) {
6960 bw = WMI_PEER_CHWIDTH_20MHZ;
6961
6962 switch (sta->bandwidth) {
6963 case IEEE80211_STA_RX_BW_20:
6964 bw = WMI_PEER_CHWIDTH_20MHZ;
6965 break;
6966 case IEEE80211_STA_RX_BW_40:
6967 bw = WMI_PEER_CHWIDTH_40MHZ;
6968 break;
6969 case IEEE80211_STA_RX_BW_80:
6970 bw = WMI_PEER_CHWIDTH_80MHZ;
6971 break;
6972 case IEEE80211_STA_RX_BW_160:
Masanari Iidad939be32015-02-27 23:52:31 +09006973 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006974 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006975 bw = WMI_PEER_CHWIDTH_20MHZ;
6976 break;
6977 }
6978
6979 arsta->bw = bw;
6980 }
6981
6982 if (changed & IEEE80211_RC_NSS_CHANGED)
6983 arsta->nss = sta->rx_nss;
6984
6985 if (changed & IEEE80211_RC_SMPS_CHANGED) {
6986 smps = WMI_PEER_SMPS_PS_NONE;
6987
6988 switch (sta->smps_mode) {
6989 case IEEE80211_SMPS_AUTOMATIC:
6990 case IEEE80211_SMPS_OFF:
6991 smps = WMI_PEER_SMPS_PS_NONE;
6992 break;
6993 case IEEE80211_SMPS_STATIC:
6994 smps = WMI_PEER_SMPS_STATIC;
6995 break;
6996 case IEEE80211_SMPS_DYNAMIC:
6997 smps = WMI_PEER_SMPS_DYNAMIC;
6998 break;
6999 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02007000 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02007001 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01007002 smps = WMI_PEER_SMPS_PS_NONE;
7003 break;
7004 }
7005
7006 arsta->smps = smps;
7007 }
7008
Michal Kazior9797feb2014-02-14 14:49:48 +01007009 arsta->changed |= changed;
7010
7011 spin_unlock_bh(&ar->data_lock);
7012
7013 ieee80211_queue_work(hw, &arsta->update_wk);
7014}
7015
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007016static void ath10k_offset_tsf(struct ieee80211_hw *hw,
7017 struct ieee80211_vif *vif, s64 tsf_offset)
Peter Oh9f0b7e72016-04-04 16:19:14 -07007018{
7019 struct ath10k *ar = hw->priv;
7020 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007021 u32 offset, vdev_param;
Peter Oh9f0b7e72016-04-04 16:19:14 -07007022 int ret;
7023
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007024 if (tsf_offset < 0) {
7025 vdev_param = ar->wmi.vdev_param->dec_tsf;
7026 offset = -tsf_offset;
7027 } else {
7028 vdev_param = ar->wmi.vdev_param->inc_tsf;
7029 offset = tsf_offset;
7030 }
7031
Peter Oh9f0b7e72016-04-04 16:19:14 -07007032 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007033 vdev_param, offset);
7034
Peter Oh9f0b7e72016-04-04 16:19:14 -07007035 if (ret && ret != -EOPNOTSUPP)
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007036 ath10k_warn(ar, "failed to set tsf offset %d cmd %d: %d\n",
7037 offset, vdev_param, ret);
Peter Oh9f0b7e72016-04-04 16:19:14 -07007038}
7039
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007040static int ath10k_ampdu_action(struct ieee80211_hw *hw,
7041 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02007042 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007043{
Michal Kazior7aa7a722014-08-25 12:09:38 +02007044 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007045 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Sara Sharon50ea05e2015-12-30 16:06:04 +02007046 struct ieee80211_sta *sta = params->sta;
7047 enum ieee80211_ampdu_mlme_action action = params->action;
7048 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007049
Michal Kazior7aa7a722014-08-25 12:09:38 +02007050 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 +02007051 arvif->vdev_id, sta->addr, tid, action);
7052
7053 switch (action) {
7054 case IEEE80211_AMPDU_RX_START:
7055 case IEEE80211_AMPDU_RX_STOP:
7056 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
7057 * creation/removal. Do we need to verify this?
7058 */
7059 return 0;
7060 case IEEE80211_AMPDU_TX_START:
7061 case IEEE80211_AMPDU_TX_STOP_CONT:
7062 case IEEE80211_AMPDU_TX_STOP_FLUSH:
7063 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
7064 case IEEE80211_AMPDU_TX_OPERATIONAL:
7065 /* Firmware offloads Tx aggregation entirely so deny mac80211
7066 * Tx aggregation requests.
7067 */
7068 return -EOPNOTSUPP;
7069 }
7070
7071 return -EINVAL;
7072}
7073
Michal Kazior500ff9f2015-03-31 10:26:21 +00007074static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007075ath10k_mac_update_rx_channel(struct ath10k *ar,
7076 struct ieee80211_chanctx_conf *ctx,
7077 struct ieee80211_vif_chanctx_switch *vifs,
7078 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00007079{
7080 struct cfg80211_chan_def *def = NULL;
7081
7082 /* Both locks are required because ar->rx_channel is modified. This
7083 * allows readers to hold either lock.
7084 */
7085 lockdep_assert_held(&ar->conf_mutex);
7086 lockdep_assert_held(&ar->data_lock);
7087
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007088 WARN_ON(ctx && vifs);
7089 WARN_ON(vifs && n_vifs != 1);
7090
Michal Kazior500ff9f2015-03-31 10:26:21 +00007091 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
7092 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
7093 * ppdu on Rx may reduce performance on low-end systems. It should be
7094 * possible to make tables/hashmaps to speed the lookup up (be vary of
7095 * cpu data cache lines though regarding sizes) but to keep the initial
7096 * implementation simple and less intrusive fallback to the slow lookup
7097 * only for multi-channel cases. Single-channel cases will remain to
7098 * use the old channel derival and thus performance should not be
7099 * affected much.
7100 */
7101 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007102 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00007103 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03007104 ath10k_mac_get_any_chandef_iter,
7105 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007106
7107 if (vifs)
7108 def = &vifs[0].new_ctx->def;
7109
Michal Kazior500ff9f2015-03-31 10:26:21 +00007110 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05307111 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
7112 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
7113 /* During driver restart due to firmware assert, since mac80211
7114 * already has valid channel context for given radio, channel
7115 * context iteration return num_chanctx > 0. So fix rx_channel
7116 * when restart is in progress.
7117 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007118 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007119 } else {
7120 ar->rx_channel = NULL;
7121 }
7122 rcu_read_unlock();
7123}
7124
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007125static void
7126ath10k_mac_update_vif_chan(struct ath10k *ar,
7127 struct ieee80211_vif_chanctx_switch *vifs,
7128 int n_vifs)
7129{
7130 struct ath10k_vif *arvif;
7131 int ret;
7132 int i;
7133
7134 lockdep_assert_held(&ar->conf_mutex);
7135
7136 /* First stop monitor interface. Some FW versions crash if there's a
7137 * lone monitor interface.
7138 */
7139 if (ar->monitor_started)
7140 ath10k_monitor_stop(ar);
7141
7142 for (i = 0; i < n_vifs; i++) {
7143 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7144
7145 ath10k_dbg(ar, ATH10K_DBG_MAC,
7146 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
7147 arvif->vdev_id,
7148 vifs[i].old_ctx->def.chan->center_freq,
7149 vifs[i].new_ctx->def.chan->center_freq,
7150 vifs[i].old_ctx->def.width,
7151 vifs[i].new_ctx->def.width);
7152
7153 if (WARN_ON(!arvif->is_started))
7154 continue;
7155
7156 if (WARN_ON(!arvif->is_up))
7157 continue;
7158
7159 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7160 if (ret) {
7161 ath10k_warn(ar, "failed to down vdev %d: %d\n",
7162 arvif->vdev_id, ret);
7163 continue;
7164 }
7165 }
7166
7167 /* All relevant vdevs are downed and associated channel resources
7168 * should be available for the channel switch now.
7169 */
7170
7171 spin_lock_bh(&ar->data_lock);
7172 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
7173 spin_unlock_bh(&ar->data_lock);
7174
7175 for (i = 0; i < n_vifs; i++) {
7176 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7177
7178 if (WARN_ON(!arvif->is_started))
7179 continue;
7180
7181 if (WARN_ON(!arvif->is_up))
7182 continue;
7183
7184 ret = ath10k_mac_setup_bcn_tmpl(arvif);
7185 if (ret)
7186 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
7187 ret);
7188
7189 ret = ath10k_mac_setup_prb_tmpl(arvif);
7190 if (ret)
7191 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
7192 ret);
7193
7194 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7195 if (ret) {
7196 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7197 arvif->vdev_id, ret);
7198 continue;
7199 }
7200
7201 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7202 arvif->bssid);
7203 if (ret) {
7204 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7205 arvif->vdev_id, ret);
7206 continue;
7207 }
7208 }
7209
7210 ath10k_monitor_recalc(ar);
7211}
7212
Michal Kazior500ff9f2015-03-31 10:26:21 +00007213static int
7214ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7215 struct ieee80211_chanctx_conf *ctx)
7216{
7217 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007218
7219 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307220 "mac chanctx add freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007221 ctx->def.chan->center_freq, ctx->def.width, ctx);
7222
7223 mutex_lock(&ar->conf_mutex);
7224
7225 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007226 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007227 spin_unlock_bh(&ar->data_lock);
7228
7229 ath10k_recalc_radar_detection(ar);
7230 ath10k_monitor_recalc(ar);
7231
7232 mutex_unlock(&ar->conf_mutex);
7233
7234 return 0;
7235}
7236
7237static void
7238ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7239 struct ieee80211_chanctx_conf *ctx)
7240{
7241 struct ath10k *ar = hw->priv;
7242
7243 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307244 "mac chanctx remove freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007245 ctx->def.chan->center_freq, ctx->def.width, ctx);
7246
7247 mutex_lock(&ar->conf_mutex);
7248
7249 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007250 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007251 spin_unlock_bh(&ar->data_lock);
7252
7253 ath10k_recalc_radar_detection(ar);
7254 ath10k_monitor_recalc(ar);
7255
7256 mutex_unlock(&ar->conf_mutex);
7257}
7258
Michal Kazior9713e3d2015-09-03 10:44:52 +02007259struct ath10k_mac_change_chanctx_arg {
7260 struct ieee80211_chanctx_conf *ctx;
7261 struct ieee80211_vif_chanctx_switch *vifs;
7262 int n_vifs;
7263 int next_vif;
7264};
7265
7266static void
7267ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
7268 struct ieee80211_vif *vif)
7269{
7270 struct ath10k_mac_change_chanctx_arg *arg = data;
7271
7272 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
7273 return;
7274
7275 arg->n_vifs++;
7276}
7277
7278static void
7279ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
7280 struct ieee80211_vif *vif)
7281{
7282 struct ath10k_mac_change_chanctx_arg *arg = data;
7283 struct ieee80211_chanctx_conf *ctx;
7284
7285 ctx = rcu_access_pointer(vif->chanctx_conf);
7286 if (ctx != arg->ctx)
7287 return;
7288
7289 if (WARN_ON(arg->next_vif == arg->n_vifs))
7290 return;
7291
7292 arg->vifs[arg->next_vif].vif = vif;
7293 arg->vifs[arg->next_vif].old_ctx = ctx;
7294 arg->vifs[arg->next_vif].new_ctx = ctx;
7295 arg->next_vif++;
7296}
7297
Michal Kazior500ff9f2015-03-31 10:26:21 +00007298static void
7299ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7300 struct ieee80211_chanctx_conf *ctx,
7301 u32 changed)
7302{
7303 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007304 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007305
7306 mutex_lock(&ar->conf_mutex);
7307
7308 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307309 "mac chanctx change freq %hu width %d ptr %pK changed %x\n",
Michal Kazior089ab7a2015-06-03 12:16:55 +02007310 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007311
7312 /* This shouldn't really happen because channel switching should use
7313 * switch_vif_chanctx().
7314 */
7315 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7316 goto unlock;
7317
Michal Kazior9713e3d2015-09-03 10:44:52 +02007318 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7319 ieee80211_iterate_active_interfaces_atomic(
7320 hw,
7321 IEEE80211_IFACE_ITER_NORMAL,
7322 ath10k_mac_change_chanctx_cnt_iter,
7323 &arg);
7324 if (arg.n_vifs == 0)
7325 goto radar;
7326
7327 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7328 GFP_KERNEL);
7329 if (!arg.vifs)
7330 goto radar;
7331
7332 ieee80211_iterate_active_interfaces_atomic(
7333 hw,
7334 IEEE80211_IFACE_ITER_NORMAL,
7335 ath10k_mac_change_chanctx_fill_iter,
7336 &arg);
7337 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7338 kfree(arg.vifs);
7339 }
7340
7341radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007342 ath10k_recalc_radar_detection(ar);
7343
7344 /* FIXME: How to configure Rx chains properly? */
7345
7346 /* No other actions are actually necessary. Firmware maintains channel
7347 * definitions per vdev internally and there's no host-side channel
7348 * context abstraction to configure, e.g. channel width.
7349 */
7350
7351unlock:
7352 mutex_unlock(&ar->conf_mutex);
7353}
7354
7355static int
7356ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7357 struct ieee80211_vif *vif,
7358 struct ieee80211_chanctx_conf *ctx)
7359{
7360 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007361 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7362 int ret;
7363
7364 mutex_lock(&ar->conf_mutex);
7365
7366 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307367 "mac chanctx assign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007368 ctx, arvif->vdev_id);
7369
7370 if (WARN_ON(arvif->is_started)) {
7371 mutex_unlock(&ar->conf_mutex);
7372 return -EBUSY;
7373 }
7374
Michal Kazior089ab7a2015-06-03 12:16:55 +02007375 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007376 if (ret) {
7377 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7378 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007379 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007380 goto err;
7381 }
7382
7383 arvif->is_started = true;
7384
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007385 ret = ath10k_mac_vif_setup_ps(arvif);
7386 if (ret) {
7387 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7388 arvif->vdev_id, ret);
7389 goto err_stop;
7390 }
7391
Michal Kazior500ff9f2015-03-31 10:26:21 +00007392 if (vif->type == NL80211_IFTYPE_MONITOR) {
7393 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7394 if (ret) {
7395 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7396 arvif->vdev_id, ret);
7397 goto err_stop;
7398 }
7399
7400 arvif->is_up = true;
7401 }
7402
Bartosz Markowski7cfe0452016-12-15 11:23:24 +02007403 if (ath10k_mac_can_set_cts_prot(arvif)) {
7404 ret = ath10k_mac_set_cts_prot(arvif);
7405 if (ret)
7406 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
7407 arvif->vdev_id, ret);
7408 }
7409
Michal Kazior500ff9f2015-03-31 10:26:21 +00007410 mutex_unlock(&ar->conf_mutex);
7411 return 0;
7412
7413err_stop:
7414 ath10k_vdev_stop(arvif);
7415 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007416 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007417
7418err:
7419 mutex_unlock(&ar->conf_mutex);
7420 return ret;
7421}
7422
7423static void
7424ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7425 struct ieee80211_vif *vif,
7426 struct ieee80211_chanctx_conf *ctx)
7427{
7428 struct ath10k *ar = hw->priv;
7429 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7430 int ret;
7431
7432 mutex_lock(&ar->conf_mutex);
7433
7434 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307435 "mac chanctx unassign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007436 ctx, arvif->vdev_id);
7437
7438 WARN_ON(!arvif->is_started);
7439
7440 if (vif->type == NL80211_IFTYPE_MONITOR) {
7441 WARN_ON(!arvif->is_up);
7442
7443 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7444 if (ret)
7445 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7446 arvif->vdev_id, ret);
7447
7448 arvif->is_up = false;
7449 }
7450
7451 ret = ath10k_vdev_stop(arvif);
7452 if (ret)
7453 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7454 arvif->vdev_id, ret);
7455
7456 arvif->is_started = false;
7457
7458 mutex_unlock(&ar->conf_mutex);
7459}
7460
7461static int
7462ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7463 struct ieee80211_vif_chanctx_switch *vifs,
7464 int n_vifs,
7465 enum ieee80211_chanctx_switch_mode mode)
7466{
7467 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007468
7469 mutex_lock(&ar->conf_mutex);
7470
7471 ath10k_dbg(ar, ATH10K_DBG_MAC,
7472 "mac chanctx switch n_vifs %d mode %d\n",
7473 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007474 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007475
7476 mutex_unlock(&ar->conf_mutex);
7477 return 0;
7478}
7479
Kalle Valo5e3dd152013-06-12 20:52:10 +03007480static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01007481 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02007482 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007483 .start = ath10k_start,
7484 .stop = ath10k_stop,
7485 .config = ath10k_config,
7486 .add_interface = ath10k_add_interface,
7487 .remove_interface = ath10k_remove_interface,
7488 .configure_filter = ath10k_configure_filter,
7489 .bss_info_changed = ath10k_bss_info_changed,
Benjamin Bergebee76f2016-09-28 15:11:58 +03007490 .set_coverage_class = ath10k_mac_op_set_coverage_class,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007491 .hw_scan = ath10k_hw_scan,
7492 .cancel_hw_scan = ath10k_cancel_hw_scan,
7493 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02007494 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007495 .sta_state = ath10k_sta_state,
7496 .conf_tx = ath10k_conf_tx,
7497 .remain_on_channel = ath10k_remain_on_channel,
7498 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
7499 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02007500 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007501 .flush = ath10k_flush,
7502 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7bb2014-05-16 17:15:38 +03007503 .set_antenna = ath10k_set_antenna,
7504 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007505 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02007506 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00007507 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01007508 .sta_rc_update = ath10k_sta_rc_update,
Pedersen, Thomas973324f2016-09-28 16:56:29 -07007509 .offset_tsf = ath10k_offset_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007510 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03007511 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7512 .get_et_stats = ath10k_debug_get_et_stats,
7513 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00007514 .add_chanctx = ath10k_mac_op_add_chanctx,
7515 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7516 .change_chanctx = ath10k_mac_op_change_chanctx,
7517 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7518 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7519 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Kalle Valo43d2a302014-09-10 18:23:30 +03007520
7521 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7522
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007523#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007524 .suspend = ath10k_wow_op_suspend,
7525 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007526#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007527#ifdef CONFIG_MAC80211_DEBUGFS
7528 .sta_add_debugfs = ath10k_sta_add_debugfs,
Mohammed Shafi Shajakhan120a1f02016-06-30 15:23:50 +03007529 .sta_statistics = ath10k_sta_statistics,
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007530#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03007531};
7532
Kalle Valo5e3dd152013-06-12 20:52:10 +03007533#define CHAN2G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007534 .band = NL80211_BAND_2GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007535 .hw_value = (_channel), \
7536 .center_freq = (_freq), \
7537 .flags = (_flags), \
7538 .max_antenna_gain = 0, \
7539 .max_power = 30, \
7540}
7541
7542#define CHAN5G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007543 .band = NL80211_BAND_5GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007544 .hw_value = (_channel), \
7545 .center_freq = (_freq), \
7546 .flags = (_flags), \
7547 .max_antenna_gain = 0, \
7548 .max_power = 30, \
7549}
7550
7551static const struct ieee80211_channel ath10k_2ghz_channels[] = {
7552 CHAN2G(1, 2412, 0),
7553 CHAN2G(2, 2417, 0),
7554 CHAN2G(3, 2422, 0),
7555 CHAN2G(4, 2427, 0),
7556 CHAN2G(5, 2432, 0),
7557 CHAN2G(6, 2437, 0),
7558 CHAN2G(7, 2442, 0),
7559 CHAN2G(8, 2447, 0),
7560 CHAN2G(9, 2452, 0),
7561 CHAN2G(10, 2457, 0),
7562 CHAN2G(11, 2462, 0),
7563 CHAN2G(12, 2467, 0),
7564 CHAN2G(13, 2472, 0),
7565 CHAN2G(14, 2484, 0),
7566};
7567
7568static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02007569 CHAN5G(36, 5180, 0),
7570 CHAN5G(40, 5200, 0),
7571 CHAN5G(44, 5220, 0),
7572 CHAN5G(48, 5240, 0),
7573 CHAN5G(52, 5260, 0),
7574 CHAN5G(56, 5280, 0),
7575 CHAN5G(60, 5300, 0),
7576 CHAN5G(64, 5320, 0),
7577 CHAN5G(100, 5500, 0),
7578 CHAN5G(104, 5520, 0),
7579 CHAN5G(108, 5540, 0),
7580 CHAN5G(112, 5560, 0),
7581 CHAN5G(116, 5580, 0),
7582 CHAN5G(120, 5600, 0),
7583 CHAN5G(124, 5620, 0),
7584 CHAN5G(128, 5640, 0),
7585 CHAN5G(132, 5660, 0),
7586 CHAN5G(136, 5680, 0),
7587 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07007588 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02007589 CHAN5G(149, 5745, 0),
7590 CHAN5G(153, 5765, 0),
7591 CHAN5G(157, 5785, 0),
7592 CHAN5G(161, 5805, 0),
7593 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03007594};
7595
Michal Kaziore7b54192014-08-07 11:03:27 +02007596struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007597{
7598 struct ieee80211_hw *hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007599 struct ieee80211_ops *ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007600 struct ath10k *ar;
7601
Michal Kazior4ca18072016-07-18 23:22:18 +03007602 ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);
7603 if (!ops)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007604 return NULL;
7605
Michal Kazior4ca18072016-07-18 23:22:18 +03007606 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);
7607 if (!hw) {
7608 kfree(ops);
7609 return NULL;
7610 }
7611
Kalle Valo5e3dd152013-06-12 20:52:10 +03007612 ar = hw->priv;
7613 ar->hw = hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007614 ar->ops = ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007615
7616 return ar;
7617}
7618
7619void ath10k_mac_destroy(struct ath10k *ar)
7620{
Michal Kazior4ca18072016-07-18 23:22:18 +03007621 struct ieee80211_ops *ops = ar->ops;
7622
Kalle Valo5e3dd152013-06-12 20:52:10 +03007623 ieee80211_free_hw(ar->hw);
Michal Kazior4ca18072016-07-18 23:22:18 +03007624 kfree(ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007625}
7626
7627static const struct ieee80211_iface_limit ath10k_if_limits[] = {
7628 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307629 .max = 8,
7630 .types = BIT(NL80211_IFTYPE_STATION)
7631 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02007632 },
7633 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307634 .max = 3,
7635 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02007636 },
7637 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307638 .max = 1,
7639 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01007640 },
7641 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307642 .max = 7,
7643 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007644#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307645 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007646#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02007647 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007648};
7649
Bartosz Markowskif2595092013-12-10 16:20:39 +01007650static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007651 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307652 .max = 8,
7653 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007654#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307655 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007656#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007657 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307658 {
7659 .max = 1,
7660 .types = BIT(NL80211_IFTYPE_STATION)
7661 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007662};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007663
7664static const struct ieee80211_iface_combination ath10k_if_comb[] = {
7665 {
7666 .limits = ath10k_if_limits,
7667 .n_limits = ARRAY_SIZE(ath10k_if_limits),
7668 .max_interfaces = 8,
7669 .num_different_channels = 1,
7670 .beacon_int_infra_match = true,
7671 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01007672};
7673
7674static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007675 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01007676 .limits = ath10k_10x_if_limits,
7677 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007678 .max_interfaces = 8,
7679 .num_different_channels = 1,
7680 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01007681#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007682 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7683 BIT(NL80211_CHAN_WIDTH_20) |
7684 BIT(NL80211_CHAN_WIDTH_40) |
7685 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007686#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01007687 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007688};
7689
Michal Kaziorcf327842015-03-31 10:26:25 +00007690static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
7691 {
7692 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02007693 .types = BIT(NL80211_IFTYPE_STATION),
7694 },
7695 {
7696 .max = 2,
7697 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007698#ifdef CONFIG_MAC80211_MESH
7699 BIT(NL80211_IFTYPE_MESH_POINT) |
7700#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00007701 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7702 BIT(NL80211_IFTYPE_P2P_GO),
7703 },
7704 {
7705 .max = 1,
7706 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7707 },
7708};
7709
Michal Kaziored25b112015-07-09 13:08:39 +02007710static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
7711 {
7712 .max = 2,
7713 .types = BIT(NL80211_IFTYPE_STATION),
7714 },
7715 {
7716 .max = 2,
7717 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
7718 },
7719 {
7720 .max = 1,
7721 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007722#ifdef CONFIG_MAC80211_MESH
7723 BIT(NL80211_IFTYPE_MESH_POINT) |
7724#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007725 BIT(NL80211_IFTYPE_P2P_GO),
7726 },
7727 {
7728 .max = 1,
7729 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7730 },
7731};
7732
Michal Kaziorcf327842015-03-31 10:26:25 +00007733static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7734 {
7735 .max = 1,
7736 .types = BIT(NL80211_IFTYPE_STATION),
7737 },
7738 {
7739 .max = 1,
7740 .types = BIT(NL80211_IFTYPE_ADHOC),
7741 },
7742};
7743
7744/* FIXME: This is not thouroughly tested. These combinations may over- or
7745 * underestimate hw/fw capabilities.
7746 */
7747static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7748 {
7749 .limits = ath10k_tlv_if_limit,
7750 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007751 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007752 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7753 },
7754 {
7755 .limits = ath10k_tlv_if_limit_ibss,
7756 .num_different_channels = 1,
7757 .max_interfaces = 2,
7758 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7759 },
7760};
7761
7762static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7763 {
7764 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007765 .num_different_channels = 1,
7766 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007767 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7768 },
7769 {
Michal Kaziored25b112015-07-09 13:08:39 +02007770 .limits = ath10k_tlv_qcs_if_limit,
7771 .num_different_channels = 2,
7772 .max_interfaces = 4,
7773 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7774 },
7775 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007776 .limits = ath10k_tlv_if_limit_ibss,
7777 .num_different_channels = 1,
7778 .max_interfaces = 2,
7779 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7780 },
7781};
7782
Raja Manicf36fef2015-06-22 20:22:25 +05307783static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
7784 {
7785 .max = 1,
7786 .types = BIT(NL80211_IFTYPE_STATION),
7787 },
7788 {
7789 .max = 16,
7790 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007791#ifdef CONFIG_MAC80211_MESH
7792 | BIT(NL80211_IFTYPE_MESH_POINT)
7793#endif
Raja Manicf36fef2015-06-22 20:22:25 +05307794 },
7795};
7796
7797static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
7798 {
7799 .limits = ath10k_10_4_if_limits,
7800 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
7801 .max_interfaces = 16,
7802 .num_different_channels = 1,
7803 .beacon_int_infra_match = true,
7804#ifdef CONFIG_ATH10K_DFS_CERTIFIED
7805 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7806 BIT(NL80211_CHAN_WIDTH_20) |
7807 BIT(NL80211_CHAN_WIDTH_40) |
7808 BIT(NL80211_CHAN_WIDTH_80),
7809#endif
7810 },
7811};
7812
Kalle Valo5e3dd152013-06-12 20:52:10 +03007813static void ath10k_get_arvif_iter(void *data, u8 *mac,
7814 struct ieee80211_vif *vif)
7815{
7816 struct ath10k_vif_iter *arvif_iter = data;
7817 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7818
7819 if (arvif->vdev_id == arvif_iter->vdev_id)
7820 arvif_iter->arvif = arvif;
7821}
7822
7823struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
7824{
7825 struct ath10k_vif_iter arvif_iter;
7826 u32 flags;
7827
7828 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
7829 arvif_iter.vdev_id = vdev_id;
7830
7831 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
7832 ieee80211_iterate_active_interfaces_atomic(ar->hw,
7833 flags,
7834 ath10k_get_arvif_iter,
7835 &arvif_iter);
7836 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007837 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007838 return NULL;
7839 }
7840
7841 return arvif_iter.arvif;
7842}
7843
Bartosz Markowski209b2a62016-09-28 15:11:58 +03007844#define WRD_METHOD "WRDD"
7845#define WRDD_WIFI (0x07)
7846
7847static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_object *wrdd)
7848{
7849 union acpi_object *mcc_pkg;
7850 union acpi_object *domain_type;
7851 union acpi_object *mcc_value;
7852 u32 i;
7853
7854 if (wrdd->type != ACPI_TYPE_PACKAGE ||
7855 wrdd->package.count < 2 ||
7856 wrdd->package.elements[0].type != ACPI_TYPE_INTEGER ||
7857 wrdd->package.elements[0].integer.value != 0) {
7858 ath10k_warn(ar, "ignoring malformed/unsupported wrdd structure\n");
7859 return 0;
7860 }
7861
7862 for (i = 1; i < wrdd->package.count; ++i) {
7863 mcc_pkg = &wrdd->package.elements[i];
7864
7865 if (mcc_pkg->type != ACPI_TYPE_PACKAGE)
7866 continue;
7867 if (mcc_pkg->package.count < 2)
7868 continue;
7869 if (mcc_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
7870 mcc_pkg->package.elements[1].type != ACPI_TYPE_INTEGER)
7871 continue;
7872
7873 domain_type = &mcc_pkg->package.elements[0];
7874 if (domain_type->integer.value != WRDD_WIFI)
7875 continue;
7876
7877 mcc_value = &mcc_pkg->package.elements[1];
7878 return mcc_value->integer.value;
7879 }
7880 return 0;
7881}
7882
7883static int ath10k_mac_get_wrdd_regulatory(struct ath10k *ar, u16 *rd)
7884{
7885 struct pci_dev __maybe_unused *pdev = to_pci_dev(ar->dev);
7886 acpi_handle root_handle;
7887 acpi_handle handle;
7888 struct acpi_buffer wrdd = {ACPI_ALLOCATE_BUFFER, NULL};
7889 acpi_status status;
7890 u32 alpha2_code;
7891 char alpha2[3];
7892
7893 root_handle = ACPI_HANDLE(&pdev->dev);
7894 if (!root_handle)
7895 return -EOPNOTSUPP;
7896
7897 status = acpi_get_handle(root_handle, (acpi_string)WRD_METHOD, &handle);
7898 if (ACPI_FAILURE(status)) {
7899 ath10k_dbg(ar, ATH10K_DBG_BOOT,
7900 "failed to get wrd method %d\n", status);
7901 return -EIO;
7902 }
7903
7904 status = acpi_evaluate_object(handle, NULL, NULL, &wrdd);
7905 if (ACPI_FAILURE(status)) {
7906 ath10k_dbg(ar, ATH10K_DBG_BOOT,
7907 "failed to call wrdc %d\n", status);
7908 return -EIO;
7909 }
7910
7911 alpha2_code = ath10k_mac_wrdd_get_mcc(ar, wrdd.pointer);
7912 kfree(wrdd.pointer);
7913 if (!alpha2_code)
7914 return -EIO;
7915
7916 alpha2[0] = (alpha2_code >> 8) & 0xff;
7917 alpha2[1] = (alpha2_code >> 0) & 0xff;
7918 alpha2[2] = '\0';
7919
7920 ath10k_dbg(ar, ATH10K_DBG_BOOT,
7921 "regulatory hint from WRDD (alpha2-code): %s\n", alpha2);
7922
7923 *rd = ath_regd_find_country_by_name(alpha2);
7924 if (*rd == 0xffff)
7925 return -EIO;
7926
7927 *rd |= COUNTRY_ERD_FLAG;
7928 return 0;
7929}
7930
7931static int ath10k_mac_init_rd(struct ath10k *ar)
7932{
7933 int ret;
7934 u16 rd;
7935
7936 ret = ath10k_mac_get_wrdd_regulatory(ar, &rd);
7937 if (ret) {
7938 ath10k_dbg(ar, ATH10K_DBG_BOOT,
7939 "fallback to eeprom programmed regulatory settings\n");
7940 rd = ar->hw_eeprom_rd;
7941 }
7942
7943 ar->ath_common.regulatory.current_rd = rd;
7944 return 0;
7945}
7946
Kalle Valo5e3dd152013-06-12 20:52:10 +03007947int ath10k_mac_register(struct ath10k *ar)
7948{
Johannes Berg3cb10942015-01-22 21:38:45 +01007949 static const u32 cipher_suites[] = {
7950 WLAN_CIPHER_SUITE_WEP40,
7951 WLAN_CIPHER_SUITE_WEP104,
7952 WLAN_CIPHER_SUITE_TKIP,
7953 WLAN_CIPHER_SUITE_CCMP,
7954 WLAN_CIPHER_SUITE_AES_CMAC,
7955 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03007956 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007957 void *channels;
7958 int ret;
7959
7960 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
7961
7962 SET_IEEE80211_DEV(ar->hw, ar->dev);
7963
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00007964 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
7965 ARRAY_SIZE(ath10k_5ghz_channels)) !=
7966 ATH10K_NUM_CHANS);
7967
Kalle Valo5e3dd152013-06-12 20:52:10 +03007968 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
7969 channels = kmemdup(ath10k_2ghz_channels,
7970 sizeof(ath10k_2ghz_channels),
7971 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02007972 if (!channels) {
7973 ret = -ENOMEM;
7974 goto err_free;
7975 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007976
Johannes Berg57fbcce2016-04-12 15:56:15 +02007977 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007978 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
7979 band->channels = channels;
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +03007980
7981 if (ar->hw_params.cck_rate_map_rev2) {
7982 band->n_bitrates = ath10k_g_rates_rev2_size;
7983 band->bitrates = ath10k_g_rates_rev2;
7984 } else {
7985 band->n_bitrates = ath10k_g_rates_size;
7986 band->bitrates = ath10k_g_rates;
7987 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007988
Johannes Berg57fbcce2016-04-12 15:56:15 +02007989 ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007990 }
7991
7992 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
7993 channels = kmemdup(ath10k_5ghz_channels,
7994 sizeof(ath10k_5ghz_channels),
7995 GFP_KERNEL);
7996 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02007997 ret = -ENOMEM;
7998 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007999 }
8000
Johannes Berg57fbcce2016-04-12 15:56:15 +02008001 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03008002 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
8003 band->channels = channels;
8004 band->n_bitrates = ath10k_a_rates_size;
8005 band->bitrates = ath10k_a_rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02008006 ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008007 }
8008
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05308009 ath10k_mac_setup_ht_vht_cap(ar);
8010
Kalle Valo5e3dd152013-06-12 20:52:10 +03008011 ar->hw->wiphy->interface_modes =
8012 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04008013 BIT(NL80211_IFTYPE_AP) |
8014 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01008015
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05308016 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
8017 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7bb2014-05-16 17:15:38 +03008018
Kalle Valoc4cdf752016-04-20 19:45:18 +03008019 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))
Bartosz Markowskid3541812013-12-10 16:20:40 +01008020 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01008021 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01008022 BIT(NL80211_IFTYPE_P2P_CLIENT) |
8023 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008024
Johannes Berg30686bf2015-06-02 21:39:54 +02008025 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
8026 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
8027 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
8028 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
8029 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
8030 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
8031 ieee80211_hw_set(ar->hw, AP_LINK_PS);
8032 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02008033 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
8034 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
8035 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
8036 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
8037 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
8038 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Sara Sharonf3fe4e92016-10-18 23:12:11 +03008039 ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
Rajkumar Manoharanff32eeb2016-09-06 12:38:41 +05308040 ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008041
David Liuccec9032015-07-24 20:25:32 +03008042 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8043 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
8044
Eliad Peller0d8614b2014-09-10 14:07:36 +03008045 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00008046 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03008047
Kalle Valo5e3dd152013-06-12 20:52:10 +03008048 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03008049 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008050
8051 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02008052 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
8053 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008054 }
8055
8056 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
8057 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
8058
8059 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01008060 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02008061 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008062
Kalle Valo5e3dd152013-06-12 20:52:10 +03008063 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
8064
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02008065 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
8066 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
8067
8068 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
8069 * that userspace (e.g. wpa_supplicant/hostapd) can generate
8070 * correct Probe Responses. This is more of a hack advert..
8071 */
8072 ar->hw->wiphy->probe_resp_offload |=
8073 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
8074 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
8075 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
8076 }
8077
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03008078 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
8079 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
8080
Kalle Valo5e3dd152013-06-12 20:52:10 +03008081 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01008082 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008083 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
8084
8085 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05308086 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
8087 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02008088
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01008089 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
8090
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02008091 ret = ath10k_wow_init(ar);
8092 if (ret) {
8093 ath10k_warn(ar, "failed to init wow: %d\n", ret);
8094 goto err_free;
8095 }
8096
Janusz Dziedzicc7025342015-06-15 14:46:41 +03008097 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
8098
Kalle Valo5e3dd152013-06-12 20:52:10 +03008099 /*
8100 * on LL hardware queues are managed entirely by the FW
8101 * so we only advertise to mac we can do the queues thing
8102 */
Michal Kazior96d828d2015-03-31 10:26:23 +00008103 ar->hw->queues = IEEE80211_MAX_QUEUES;
8104
8105 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
8106 * something that vdev_ids can't reach so that we don't stop the queue
8107 * accidentally.
8108 */
8109 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008110
Kalle Valobf3c13a2016-04-20 19:45:33 +03008111 switch (ar->running_fw->fw_file.wmi_op_version) {
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008112 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01008113 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
8114 ar->hw->wiphy->n_iface_combinations =
8115 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03008116 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008117 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00008118 case ATH10K_FW_WMI_OP_VERSION_TLV:
8119 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
8120 ar->hw->wiphy->iface_combinations =
8121 ath10k_tlv_qcs_if_comb;
8122 ar->hw->wiphy->n_iface_combinations =
8123 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
8124 } else {
8125 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
8126 ar->hw->wiphy->n_iface_combinations =
8127 ARRAY_SIZE(ath10k_tlv_if_comb);
8128 }
8129 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
8130 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008131 case ATH10K_FW_WMI_OP_VERSION_10_1:
8132 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02008133 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008134 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
8135 ar->hw->wiphy->n_iface_combinations =
8136 ARRAY_SIZE(ath10k_10x_if_comb);
8137 break;
Raja Mani9bd21322015-06-22 20:10:09 +05308138 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05308139 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
8140 ar->hw->wiphy->n_iface_combinations =
8141 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05308142 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008143 case ATH10K_FW_WMI_OP_VERSION_UNSET:
8144 case ATH10K_FW_WMI_OP_VERSION_MAX:
8145 WARN_ON(1);
8146 ret = -EINVAL;
8147 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01008148 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008149
David Liuccec9032015-07-24 20:25:32 +03008150 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8151 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02008152
Masahiro Yamada97f26452016-08-03 13:45:50 -07008153 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008154 /* Init ath dfs pattern detector */
8155 ar->ath_common.debug_mask = ATH_DBG_DFS;
8156 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
8157 NL80211_DFS_UNSET);
8158
8159 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02008160 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008161 }
8162
Michal Kazior4ca18072016-07-18 23:22:18 +03008163 /* Current wake_tx_queue implementation imposes a significant
8164 * performance penalty in some setups. The tx scheduling code needs
8165 * more work anyway so disable the wake_tx_queue unless firmware
8166 * supports the pull-push mechanism.
8167 */
8168 if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,
8169 ar->running_fw->fw_file.fw_features))
8170 ar->ops->wake_tx_queue = NULL;
8171
Bartosz Markowski209b2a62016-09-28 15:11:58 +03008172 ret = ath10k_mac_init_rd(ar);
8173 if (ret) {
8174 ath10k_err(ar, "failed to derive regdom: %d\n", ret);
8175 goto err_dfs_detector_exit;
8176 }
8177
Benjamin Bergebee76f2016-09-28 15:11:58 +03008178 /* Disable set_coverage_class for chipsets that do not support it. */
8179 if (!ar->hw_params.hw_ops->set_coverage_class)
8180 ar->ops->set_coverage_class = NULL;
8181
Kalle Valo5e3dd152013-06-12 20:52:10 +03008182 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
8183 ath10k_reg_notifier);
8184 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008185 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008186 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008187 }
8188
Johannes Berg3cb10942015-01-22 21:38:45 +01008189 ar->hw->wiphy->cipher_suites = cipher_suites;
8190 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
8191
Kalle Valo5e3dd152013-06-12 20:52:10 +03008192 ret = ieee80211_register_hw(ar->hw);
8193 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008194 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008195 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008196 }
8197
8198 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
8199 ret = regulatory_hint(ar->hw->wiphy,
8200 ar->ath_common.regulatory.alpha2);
8201 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02008202 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008203 }
8204
8205 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02008206
8207err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03008208 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07008209
8210err_dfs_detector_exit:
Masahiro Yamada97f26452016-08-03 13:45:50 -07008211 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Jeff Johnson0e339442015-10-08 09:15:53 -07008212 ar->dfs_detector->exit(ar->dfs_detector);
8213
Michal Kaziord6015b22013-07-22 14:13:30 +02008214err_free:
Johannes Berg57fbcce2016-04-12 15:56:15 +02008215 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8216 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Michal Kaziord6015b22013-07-22 14:13:30 +02008217
Jeff Johnson0e339442015-10-08 09:15:53 -07008218 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008219 return ret;
8220}
8221
8222void ath10k_mac_unregister(struct ath10k *ar)
8223{
8224 ieee80211_unregister_hw(ar->hw);
8225
Masahiro Yamada97f26452016-08-03 13:45:50 -07008226 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008227 ar->dfs_detector->exit(ar->dfs_detector);
8228
Johannes Berg57fbcce2016-04-12 15:56:15 +02008229 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8230 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008231
8232 SET_IEEE80211_DEV(ar->hw, NULL);
8233}