blob: fb632a454fc2cd74e5a5a69185e490aa8f32fa46 [file] [log] [blame]
Kalle Valo5e3dd152013-06-12 20:52:10 +03001/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include "mac.h"
19
20#include <net/mac80211.h>
21#include <linux/etherdevice.h>
22
Michal Kazior8cd13ca2013-07-16 09:38:54 +020023#include "hif.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030024#include "core.h"
25#include "debug.h"
26#include "wmi.h"
27#include "htt.h"
28#include "txrx.h"
Kalle Valo43d2a302014-09-10 18:23:30 +030029#include "testmode.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020030#include "wmi.h"
Michal Kaziorb4aa5392015-03-31 10:26:24 +000031#include "wmi-tlv.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020032#include "wmi-ops.h"
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +020033#include "wow.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030034
Michal Kaziordcc33092015-03-30 09:51:54 +030035/*********/
36/* Rates */
37/*********/
38
Michal Kaziordcc33092015-03-30 09:51:54 +030039static struct ieee80211_rate ath10k_rates[] = {
Michal Kazior5528e032015-03-30 09:51:56 +030040 { .bitrate = 10,
41 .hw_value = ATH10K_HW_RATE_CCK_LP_1M },
42 { .bitrate = 20,
43 .hw_value = ATH10K_HW_RATE_CCK_LP_2M,
44 .hw_value_short = ATH10K_HW_RATE_CCK_SP_2M,
45 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
46 { .bitrate = 55,
47 .hw_value = ATH10K_HW_RATE_CCK_LP_5_5M,
48 .hw_value_short = ATH10K_HW_RATE_CCK_SP_5_5M,
49 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
50 { .bitrate = 110,
51 .hw_value = ATH10K_HW_RATE_CCK_LP_11M,
52 .hw_value_short = ATH10K_HW_RATE_CCK_SP_11M,
53 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
Michal Kazior5653b392015-03-30 09:51:54 +030054
Michal Kazioraf001482015-03-30 09:51:56 +030055 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
56 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
57 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
58 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
59 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
60 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
61 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
62 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
Michal Kaziordcc33092015-03-30 09:51:54 +030063};
64
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +030065static struct ieee80211_rate ath10k_rates_rev2[] = {
66 { .bitrate = 10,
67 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_1M },
68 { .bitrate = 20,
69 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_2M,
70 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_2M,
71 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
72 { .bitrate = 55,
73 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
74 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
75 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
76 { .bitrate = 110,
77 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_11M,
78 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_11M,
79 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
80
81 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
82 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
83 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
84 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
85 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
86 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
87 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
88 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
89};
90
Michal Kazior8d7aa6b2015-03-30 09:51:57 +030091#define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
92
93#define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
94#define ath10k_a_rates_size (ARRAY_SIZE(ath10k_rates) - \
95 ATH10K_MAC_FIRST_OFDM_RATE_IDX)
Michal Kaziordcc33092015-03-30 09:51:54 +030096#define ath10k_g_rates (ath10k_rates + 0)
97#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
98
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +030099#define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
100#define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
101
Michal Kazior486017c2015-03-30 09:51:54 +0300102static bool ath10k_mac_bitrate_is_cck(int bitrate)
103{
104 switch (bitrate) {
105 case 10:
106 case 20:
107 case 55:
108 case 110:
109 return true;
110 }
111
112 return false;
113}
114
115static u8 ath10k_mac_bitrate_to_rate(int bitrate)
116{
117 return DIV_ROUND_UP(bitrate, 5) |
118 (ath10k_mac_bitrate_is_cck(bitrate) ? BIT(7) : 0);
119}
120
Michal Kazior5528e032015-03-30 09:51:56 +0300121u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
Yanbo Li4b7f3532015-11-12 10:36:10 -0800122 u8 hw_rate, bool cck)
Michal Kazior5528e032015-03-30 09:51:56 +0300123{
124 const struct ieee80211_rate *rate;
125 int i;
126
127 for (i = 0; i < sband->n_bitrates; i++) {
128 rate = &sband->bitrates[i];
129
Yanbo Li4b7f3532015-11-12 10:36:10 -0800130 if (ath10k_mac_bitrate_is_cck(rate->bitrate) != cck)
131 continue;
132
Michal Kazior5528e032015-03-30 09:51:56 +0300133 if (rate->hw_value == hw_rate)
134 return i;
135 else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
136 rate->hw_value_short == hw_rate)
137 return i;
138 }
139
140 return 0;
141}
142
Michal Kazior01cebe12015-03-30 09:51:56 +0300143u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
144 u32 bitrate)
145{
146 int i;
147
148 for (i = 0; i < sband->n_bitrates; i++)
149 if (sband->bitrates[i].bitrate == bitrate)
150 return i;
151
152 return 0;
153}
154
Michal Kazior3ae54222015-03-31 10:49:20 +0000155static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
156{
157 switch ((mcs_map >> (2 * nss)) & 0x3) {
158 case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;
159 case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;
160 case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;
161 }
162 return 0;
163}
164
Michal Kazior45c9abc2015-04-21 20:42:58 +0300165static u32
166ath10k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
167{
168 int nss;
169
170 for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--)
171 if (ht_mcs_mask[nss])
172 return nss + 1;
173
174 return 1;
175}
176
177static u32
178ath10k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
179{
180 int nss;
181
182 for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--)
183 if (vht_mcs_mask[nss])
184 return nss + 1;
185
186 return 1;
187}
Kalle Valo5e3dd152013-06-12 20:52:10 +0300188
Raja Mani7e247a92016-04-12 20:15:53 +0530189int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val)
190{
191 enum wmi_host_platform_type platform_type;
192 int ret;
193
194 if (test_bit(WMI_SERVICE_TX_MODE_DYNAMIC, ar->wmi.svc_map))
195 platform_type = WMI_HOST_PLATFORM_LOW_PERF;
196 else
197 platform_type = WMI_HOST_PLATFORM_HIGH_PERF;
198
199 ret = ath10k_wmi_ext_resource_config(ar, platform_type, val);
200
201 if (ret && ret != -EOPNOTSUPP) {
202 ath10k_warn(ar, "failed to configure ext resource: %d\n", ret);
203 return ret;
204 }
205
206 return 0;
207}
208
Kalle Valo5e3dd152013-06-12 20:52:10 +0300209/**********/
210/* Crypto */
211/**********/
212
213static int ath10k_send_key(struct ath10k_vif *arvif,
214 struct ieee80211_key_conf *key,
215 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100216 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300217{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200218 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300219 struct wmi_vdev_install_key_arg arg = {
220 .vdev_id = arvif->vdev_id,
221 .key_idx = key->keyidx,
222 .key_len = key->keylen,
223 .key_data = key->key,
Michal Kazior370e5672015-02-18 14:02:26 +0100224 .key_flags = flags,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300225 .macaddr = macaddr,
226 };
227
Michal Kazior548db542013-07-05 16:15:15 +0300228 lockdep_assert_held(&arvif->ar->conf_mutex);
229
Kalle Valo5e3dd152013-06-12 20:52:10 +0300230 switch (key->cipher) {
231 case WLAN_CIPHER_SUITE_CCMP:
232 arg.key_cipher = WMI_CIPHER_AES_CCM;
Marek Kwaczynskie4e82e92015-01-24 12:14:53 +0200233 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300234 break;
235 case WLAN_CIPHER_SUITE_TKIP:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300236 arg.key_cipher = WMI_CIPHER_TKIP;
237 arg.key_txmic_len = 8;
238 arg.key_rxmic_len = 8;
239 break;
240 case WLAN_CIPHER_SUITE_WEP40:
241 case WLAN_CIPHER_SUITE_WEP104:
242 arg.key_cipher = WMI_CIPHER_WEP;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300243 break;
Johannes Berg3cb10942015-01-22 21:38:45 +0100244 case WLAN_CIPHER_SUITE_AES_CMAC:
Bartosz Markowskid7131c02015-03-10 14:32:19 +0100245 WARN_ON(1);
246 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300247 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200248 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300249 return -EOPNOTSUPP;
250 }
251
Kalle Valob9e284e2015-10-05 17:56:35 +0300252 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
David Liuccec9032015-07-24 20:25:32 +0300253 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
David Liuccec9032015-07-24 20:25:32 +0300254
Kalle Valo5e3dd152013-06-12 20:52:10 +0300255 if (cmd == DISABLE_KEY) {
256 arg.key_cipher = WMI_CIPHER_NONE;
257 arg.key_data = NULL;
258 }
259
260 return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
261}
262
263static int ath10k_install_key(struct ath10k_vif *arvif,
264 struct ieee80211_key_conf *key,
265 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100266 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300267{
268 struct ath10k *ar = arvif->ar;
269 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300270 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300271
Michal Kazior548db542013-07-05 16:15:15 +0300272 lockdep_assert_held(&ar->conf_mutex);
273
Wolfram Sang16735d02013-11-14 14:32:02 -0800274 reinit_completion(&ar->install_key_done);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300275
David Liuccec9032015-07-24 20:25:32 +0300276 if (arvif->nohwcrypt)
277 return 1;
278
Michal Kazior370e5672015-02-18 14:02:26 +0100279 ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300280 if (ret)
281 return ret;
282
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300283 time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);
284 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300285 return -ETIMEDOUT;
286
287 return 0;
288}
289
290static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
291 const u8 *addr)
292{
293 struct ath10k *ar = arvif->ar;
294 struct ath10k_peer *peer;
295 int ret;
296 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100297 u32 flags;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300298
299 lockdep_assert_held(&ar->conf_mutex);
300
Michal Kazior8674d902015-08-13 14:10:46 +0200301 if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP &&
Peter Oh7c97b722015-12-03 09:50:55 -0800302 arvif->vif->type != NL80211_IFTYPE_ADHOC &&
303 arvif->vif->type != NL80211_IFTYPE_MESH_POINT))
Michal Kazior8674d902015-08-13 14:10:46 +0200304 return -EINVAL;
305
Kalle Valo5e3dd152013-06-12 20:52:10 +0300306 spin_lock_bh(&ar->data_lock);
307 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
308 spin_unlock_bh(&ar->data_lock);
309
310 if (!peer)
311 return -ENOENT;
312
313 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
314 if (arvif->wep_keys[i] == NULL)
315 continue;
Michal Kazior370e5672015-02-18 14:02:26 +0100316
Michal Kazior8674d902015-08-13 14:10:46 +0200317 switch (arvif->vif->type) {
318 case NL80211_IFTYPE_AP:
319 flags = WMI_KEY_PAIRWISE;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300320
Michal Kazior8674d902015-08-13 14:10:46 +0200321 if (arvif->def_wep_key_idx == i)
322 flags |= WMI_KEY_TX_USAGE;
Michal Kaziorce90b272015-04-10 13:23:21 +0000323
Michal Kazior8674d902015-08-13 14:10:46 +0200324 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
325 SET_KEY, addr, flags);
326 if (ret < 0)
327 return ret;
328 break;
329 case NL80211_IFTYPE_ADHOC:
330 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
331 SET_KEY, addr,
332 WMI_KEY_PAIRWISE);
333 if (ret < 0)
334 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300335
Michal Kazior8674d902015-08-13 14:10:46 +0200336 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
337 SET_KEY, addr, WMI_KEY_GROUP);
338 if (ret < 0)
339 return ret;
340 break;
341 default:
342 WARN_ON(1);
343 return -EINVAL;
344 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300345
Sujith Manoharanae167132014-11-25 11:46:59 +0530346 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300347 peer->keys[i] = arvif->wep_keys[i];
Sujith Manoharanae167132014-11-25 11:46:59 +0530348 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300349 }
350
Michal Kaziorce90b272015-04-10 13:23:21 +0000351 /* In some cases (notably with static WEP IBSS with multiple keys)
352 * multicast Tx becomes broken. Both pairwise and groupwise keys are
353 * installed already. Using WMI_KEY_TX_USAGE in different combinations
354 * didn't seem help. Using def_keyid vdev parameter seems to be
355 * effective so use that.
356 *
357 * FIXME: Revisit. Perhaps this can be done in a less hacky way.
358 */
Michal Kazior8674d902015-08-13 14:10:46 +0200359 if (arvif->vif->type != NL80211_IFTYPE_ADHOC)
360 return 0;
361
Michal Kaziorce90b272015-04-10 13:23:21 +0000362 if (arvif->def_wep_key_idx == -1)
363 return 0;
364
365 ret = ath10k_wmi_vdev_set_param(arvif->ar,
366 arvif->vdev_id,
367 arvif->ar->wmi.vdev_param->def_keyid,
368 arvif->def_wep_key_idx);
369 if (ret) {
370 ath10k_warn(ar, "failed to re-set def wpa key idxon vdev %i: %d\n",
371 arvif->vdev_id, ret);
372 return ret;
373 }
374
Kalle Valo5e3dd152013-06-12 20:52:10 +0300375 return 0;
376}
377
378static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
379 const u8 *addr)
380{
381 struct ath10k *ar = arvif->ar;
382 struct ath10k_peer *peer;
383 int first_errno = 0;
384 int ret;
385 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100386 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300387
388 lockdep_assert_held(&ar->conf_mutex);
389
390 spin_lock_bh(&ar->data_lock);
391 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
392 spin_unlock_bh(&ar->data_lock);
393
394 if (!peer)
395 return -ENOENT;
396
397 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
398 if (peer->keys[i] == NULL)
399 continue;
400
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200401 /* key flags are not required to delete the key */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300402 ret = ath10k_install_key(arvif, peer->keys[i],
Michal Kazior370e5672015-02-18 14:02:26 +0100403 DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300404 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300405 first_errno = ret;
406
David Liuccec9032015-07-24 20:25:32 +0300407 if (ret < 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200408 ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300409 i, ret);
410
Sujith Manoharanae167132014-11-25 11:46:59 +0530411 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300412 peer->keys[i] = NULL;
Sujith Manoharanae167132014-11-25 11:46:59 +0530413 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300414 }
415
416 return first_errno;
417}
418
Sujith Manoharan504f6cd2014-11-25 11:46:58 +0530419bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
420 u8 keyidx)
421{
422 struct ath10k_peer *peer;
423 int i;
424
425 lockdep_assert_held(&ar->data_lock);
426
427 /* We don't know which vdev this peer belongs to,
428 * since WMI doesn't give us that information.
429 *
430 * FIXME: multi-bss needs to be handled.
431 */
432 peer = ath10k_peer_find(ar, 0, addr);
433 if (!peer)
434 return false;
435
436 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
437 if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)
438 return true;
439 }
440
441 return false;
442}
443
Kalle Valo5e3dd152013-06-12 20:52:10 +0300444static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
445 struct ieee80211_key_conf *key)
446{
447 struct ath10k *ar = arvif->ar;
448 struct ath10k_peer *peer;
449 u8 addr[ETH_ALEN];
450 int first_errno = 0;
451 int ret;
452 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100453 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300454
455 lockdep_assert_held(&ar->conf_mutex);
456
457 for (;;) {
458 /* since ath10k_install_key we can't hold data_lock all the
459 * time, so we try to remove the keys incrementally */
460 spin_lock_bh(&ar->data_lock);
461 i = 0;
462 list_for_each_entry(peer, &ar->peers, list) {
463 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
464 if (peer->keys[i] == key) {
Kalle Valob25f32c2014-09-14 12:50:49 +0300465 ether_addr_copy(addr, peer->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300466 peer->keys[i] = NULL;
467 break;
468 }
469 }
470
471 if (i < ARRAY_SIZE(peer->keys))
472 break;
473 }
474 spin_unlock_bh(&ar->data_lock);
475
476 if (i == ARRAY_SIZE(peer->keys))
477 break;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200478 /* key flags are not required to delete the key */
Michal Kazior370e5672015-02-18 14:02:26 +0100479 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300480 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300481 first_errno = ret;
482
483 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200484 ath10k_warn(ar, "failed to remove key for %pM: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +0200485 addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300486 }
487
488 return first_errno;
489}
490
Michal Kaziorad325cb2015-02-18 14:02:27 +0100491static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
492 struct ieee80211_key_conf *key)
493{
494 struct ath10k *ar = arvif->ar;
495 struct ath10k_peer *peer;
496 int ret;
497
498 lockdep_assert_held(&ar->conf_mutex);
499
500 list_for_each_entry(peer, &ar->peers, list) {
Kalle Valoc178da52016-04-13 14:13:49 +0300501 if (ether_addr_equal(peer->addr, arvif->vif->addr))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100502 continue;
503
Kalle Valoc178da52016-04-13 14:13:49 +0300504 if (ether_addr_equal(peer->addr, arvif->bssid))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100505 continue;
506
507 if (peer->keys[key->keyidx] == key)
508 continue;
509
510 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
511 arvif->vdev_id, key->keyidx);
512
513 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
514 if (ret) {
515 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
516 arvif->vdev_id, peer->addr, ret);
517 return ret;
518 }
519 }
520
521 return 0;
522}
523
Kalle Valo5e3dd152013-06-12 20:52:10 +0300524/*********************/
525/* General utilities */
526/*********************/
527
528static inline enum wmi_phy_mode
529chan_to_phymode(const struct cfg80211_chan_def *chandef)
530{
531 enum wmi_phy_mode phymode = MODE_UNKNOWN;
532
533 switch (chandef->chan->band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +0200534 case NL80211_BAND_2GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300535 switch (chandef->width) {
536 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800537 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
538 phymode = MODE_11B;
539 else
540 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300541 break;
542 case NL80211_CHAN_WIDTH_20:
543 phymode = MODE_11NG_HT20;
544 break;
545 case NL80211_CHAN_WIDTH_40:
546 phymode = MODE_11NG_HT40;
547 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400548 case NL80211_CHAN_WIDTH_5:
549 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300550 case NL80211_CHAN_WIDTH_80:
551 case NL80211_CHAN_WIDTH_80P80:
552 case NL80211_CHAN_WIDTH_160:
553 phymode = MODE_UNKNOWN;
554 break;
555 }
556 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +0200557 case NL80211_BAND_5GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300558 switch (chandef->width) {
559 case NL80211_CHAN_WIDTH_20_NOHT:
560 phymode = MODE_11A;
561 break;
562 case NL80211_CHAN_WIDTH_20:
563 phymode = MODE_11NA_HT20;
564 break;
565 case NL80211_CHAN_WIDTH_40:
566 phymode = MODE_11NA_HT40;
567 break;
568 case NL80211_CHAN_WIDTH_80:
569 phymode = MODE_11AC_VHT80;
570 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400571 case NL80211_CHAN_WIDTH_5:
572 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300573 case NL80211_CHAN_WIDTH_80P80:
574 case NL80211_CHAN_WIDTH_160:
575 phymode = MODE_UNKNOWN;
576 break;
577 }
578 break;
579 default:
580 break;
581 }
582
583 WARN_ON(phymode == MODE_UNKNOWN);
584 return phymode;
585}
586
587static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
588{
589/*
590 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
591 * 0 for no restriction
592 * 1 for 1/4 us
593 * 2 for 1/2 us
594 * 3 for 1 us
595 * 4 for 2 us
596 * 5 for 4 us
597 * 6 for 8 us
598 * 7 for 16 us
599 */
600 switch (mpdudensity) {
601 case 0:
602 return 0;
603 case 1:
604 case 2:
605 case 3:
606 /* Our lower layer calculations limit our precision to
607 1 microsecond */
608 return 1;
609 case 4:
610 return 2;
611 case 5:
612 return 4;
613 case 6:
614 return 8;
615 case 7:
616 return 16;
617 default:
618 return 0;
619 }
620}
621
Michal Kazior500ff9f2015-03-31 10:26:21 +0000622int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
623 struct cfg80211_chan_def *def)
624{
625 struct ieee80211_chanctx_conf *conf;
626
627 rcu_read_lock();
628 conf = rcu_dereference(vif->chanctx_conf);
629 if (!conf) {
630 rcu_read_unlock();
631 return -ENOENT;
632 }
633
634 *def = conf->def;
635 rcu_read_unlock();
636
637 return 0;
638}
639
640static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,
641 struct ieee80211_chanctx_conf *conf,
642 void *data)
643{
644 int *num = data;
645
646 (*num)++;
647}
648
649static int ath10k_mac_num_chanctxs(struct ath10k *ar)
650{
651 int num = 0;
652
653 ieee80211_iter_chan_contexts_atomic(ar->hw,
654 ath10k_mac_num_chanctxs_iter,
655 &num);
656
657 return num;
658}
659
660static void
661ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
662 struct ieee80211_chanctx_conf *conf,
663 void *data)
664{
665 struct cfg80211_chan_def **def = data;
666
667 *def = &conf->def;
668}
669
Michal Kazior69427262016-03-06 16:14:30 +0200670static int ath10k_peer_create(struct ath10k *ar,
671 struct ieee80211_vif *vif,
672 struct ieee80211_sta *sta,
673 u32 vdev_id,
674 const u8 *addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300675 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300676{
Michal Kaziore04cafb2015-08-05 12:15:24 +0200677 struct ath10k_vif *arvif;
Michal Kazior69427262016-03-06 16:14:30 +0200678 struct ath10k_peer *peer;
Michal Kaziore04cafb2015-08-05 12:15:24 +0200679 int num_peers = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300680 int ret;
681
682 lockdep_assert_held(&ar->conf_mutex);
683
Michal Kaziore04cafb2015-08-05 12:15:24 +0200684 num_peers = ar->num_peers;
685
686 /* Each vdev consumes a peer entry as well */
687 list_for_each_entry(arvif, &ar->arvifs, list)
688 num_peers++;
689
690 if (num_peers >= ar->max_num_peers)
Michal Kaziorcfd10612014-11-25 15:16:05 +0100691 return -ENOBUFS;
692
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300693 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800694 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200695 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200696 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300697 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800698 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300699
700 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800701 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200702 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200703 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300704 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800705 }
Michal Kazior292a7532014-11-25 15:16:04 +0100706
Michal Kazior69427262016-03-06 16:14:30 +0200707 spin_lock_bh(&ar->data_lock);
708
709 peer = ath10k_peer_find(ar, vdev_id, addr);
710 if (!peer) {
Ben Greearfee48cf2016-04-01 14:12:12 -0700711 spin_unlock_bh(&ar->data_lock);
Michal Kazior69427262016-03-06 16:14:30 +0200712 ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n",
713 addr, vdev_id);
714 ath10k_wmi_peer_delete(ar, vdev_id, addr);
Michal Kazior69427262016-03-06 16:14:30 +0200715 return -ENOENT;
716 }
717
718 peer->vif = vif;
719 peer->sta = sta;
720
721 spin_unlock_bh(&ar->data_lock);
722
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100723 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300724
725 return 0;
726}
727
Kalle Valo5a13e762014-01-20 11:01:46 +0200728static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
729{
730 struct ath10k *ar = arvif->ar;
731 u32 param;
732 int ret;
733
734 param = ar->wmi.pdev_param->sta_kickout_th;
735 ret = ath10k_wmi_pdev_set_param(ar, param,
736 ATH10K_KICKOUT_THRESHOLD);
737 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200738 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200739 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200740 return ret;
741 }
742
743 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
744 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
745 ATH10K_KEEPALIVE_MIN_IDLE);
746 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200747 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200748 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200749 return ret;
750 }
751
752 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
753 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
754 ATH10K_KEEPALIVE_MAX_IDLE);
755 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200756 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200757 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200758 return ret;
759 }
760
761 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
762 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
763 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
764 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200765 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200766 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200767 return ret;
768 }
769
770 return 0;
771}
772
Vivek Natarajanacab6402014-11-26 09:06:12 +0200773static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200774{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200775 struct ath10k *ar = arvif->ar;
776 u32 vdev_param;
777
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200778 vdev_param = ar->wmi.vdev_param->rts_threshold;
779 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200780}
781
Kalle Valo5e3dd152013-06-12 20:52:10 +0300782static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
783{
784 int ret;
785
786 lockdep_assert_held(&ar->conf_mutex);
787
788 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
789 if (ret)
790 return ret;
791
792 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
793 if (ret)
794 return ret;
795
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100796 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100797
Kalle Valo5e3dd152013-06-12 20:52:10 +0300798 return 0;
799}
800
801static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
802{
803 struct ath10k_peer *peer, *tmp;
Michal Kazior69427262016-03-06 16:14:30 +0200804 int peer_id;
Ben Greear6d68f792016-06-30 15:23:53 +0300805 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300806
807 lockdep_assert_held(&ar->conf_mutex);
808
809 spin_lock_bh(&ar->data_lock);
810 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
811 if (peer->vdev_id != vdev_id)
812 continue;
813
Michal Kazior7aa7a722014-08-25 12:09:38 +0200814 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300815 peer->addr, vdev_id);
816
Michal Kazior69427262016-03-06 16:14:30 +0200817 for_each_set_bit(peer_id, peer->peer_ids,
818 ATH10K_MAX_NUM_PEER_IDS) {
819 ar->peer_map[peer_id] = NULL;
820 }
821
Ben Greear6d68f792016-06-30 15:23:53 +0300822 /* Double check that peer is properly un-referenced from
823 * the peer_map
824 */
825 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
826 if (ar->peer_map[i] == peer) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +0530827 ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
Ben Greear6d68f792016-06-30 15:23:53 +0300828 peer->addr, peer, i);
829 ar->peer_map[i] = NULL;
830 }
831 }
832
Kalle Valo5e3dd152013-06-12 20:52:10 +0300833 list_del(&peer->list);
834 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100835 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300836 }
837 spin_unlock_bh(&ar->data_lock);
838}
839
Michal Kaziora96d7742013-07-16 09:38:56 +0200840static void ath10k_peer_cleanup_all(struct ath10k *ar)
841{
842 struct ath10k_peer *peer, *tmp;
Ben Greear6d68f792016-06-30 15:23:53 +0300843 int i;
Michal Kaziora96d7742013-07-16 09:38:56 +0200844
845 lockdep_assert_held(&ar->conf_mutex);
846
847 spin_lock_bh(&ar->data_lock);
848 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
849 list_del(&peer->list);
850 kfree(peer);
851 }
Ben Greear6d68f792016-06-30 15:23:53 +0300852
853 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
854 ar->peer_map[i] = NULL;
855
Michal Kaziora96d7742013-07-16 09:38:56 +0200856 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100857
858 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100859 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200860}
861
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300862static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
863 struct ieee80211_sta *sta,
864 enum wmi_tdls_peer_state state)
865{
866 int ret;
867 struct wmi_tdls_peer_update_cmd_arg arg = {};
868 struct wmi_tdls_peer_capab_arg cap = {};
869 struct wmi_channel_arg chan_arg = {};
870
871 lockdep_assert_held(&ar->conf_mutex);
872
873 arg.vdev_id = vdev_id;
874 arg.peer_state = state;
875 ether_addr_copy(arg.addr, sta->addr);
876
877 cap.peer_max_sp = sta->max_sp;
878 cap.peer_uapsd_queues = sta->uapsd_queues;
879
880 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
881 !sta->tdls_initiator)
882 cap.is_peer_responder = 1;
883
884 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
885 if (ret) {
886 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
887 arg.addr, vdev_id, ret);
888 return ret;
889 }
890
891 return 0;
892}
893
Kalle Valo5e3dd152013-06-12 20:52:10 +0300894/************************/
895/* Interface management */
896/************************/
897
Michal Kazior64badcb2014-09-18 11:18:02 +0300898void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
899{
900 struct ath10k *ar = arvif->ar;
901
902 lockdep_assert_held(&ar->data_lock);
903
904 if (!arvif->beacon)
905 return;
906
907 if (!arvif->beacon_buf)
908 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
909 arvif->beacon->len, DMA_TO_DEVICE);
910
Michal Kazioraf213192015-01-29 14:29:52 +0200911 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
912 arvif->beacon_state != ATH10K_BEACON_SENT))
913 return;
914
Michal Kazior64badcb2014-09-18 11:18:02 +0300915 dev_kfree_skb_any(arvif->beacon);
916
917 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200918 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300919}
920
921static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
922{
923 struct ath10k *ar = arvif->ar;
924
925 lockdep_assert_held(&ar->data_lock);
926
927 ath10k_mac_vif_beacon_free(arvif);
928
929 if (arvif->beacon_buf) {
930 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
931 arvif->beacon_buf, arvif->beacon_paddr);
932 arvif->beacon_buf = NULL;
933 }
934}
935
Kalle Valo5e3dd152013-06-12 20:52:10 +0300936static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
937{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300938 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300939
Michal Kazior548db542013-07-05 16:15:15 +0300940 lockdep_assert_held(&ar->conf_mutex);
941
Michal Kazior7962b0d2014-10-28 10:34:38 +0100942 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
943 return -ESHUTDOWN;
944
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300945 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
946 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
947 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300948 return -ETIMEDOUT;
949
950 return 0;
951}
952
Michal Kazior1bbc0972014-04-08 09:45:47 +0300953static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300954{
Michal Kazior500ff9f2015-03-31 10:26:21 +0000955 struct cfg80211_chan_def *chandef = NULL;
Maninder Singh19be9e92015-07-16 09:25:33 +0530956 struct ieee80211_channel *channel = NULL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300957 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300958 int ret = 0;
959
960 lockdep_assert_held(&ar->conf_mutex);
961
Michal Kazior500ff9f2015-03-31 10:26:21 +0000962 ieee80211_iter_chan_contexts_atomic(ar->hw,
963 ath10k_mac_get_any_chandef_iter,
964 &chandef);
965 if (WARN_ON_ONCE(!chandef))
966 return -ENOENT;
967
968 channel = chandef->chan;
969
Kalle Valo5e3dd152013-06-12 20:52:10 +0300970 arg.vdev_id = vdev_id;
971 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +0100972 arg.channel.band_center_freq1 = chandef->center_freq1;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300973
974 /* TODO setup this dynamically, what in case we
975 don't have any vifs? */
Michal Kaziorc930f742014-01-23 11:38:25 +0100976 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200977 arg.channel.chan_radar =
978 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300979
Michal Kazior89c5c842013-10-23 04:02:13 -0700980 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -0700981 arg.channel.max_power = channel->max_power * 2;
982 arg.channel.max_reg_power = channel->max_reg_power * 2;
983 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300984
Michal Kazior7962b0d2014-10-28 10:34:38 +0100985 reinit_completion(&ar->vdev_setup_done);
986
Kalle Valo5e3dd152013-06-12 20:52:10 +0300987 ret = ath10k_wmi_vdev_start(ar, &arg);
988 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200989 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200990 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300991 return ret;
992 }
993
994 ret = ath10k_vdev_setup_sync(ar);
995 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +0200996 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200997 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300998 return ret;
999 }
1000
1001 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
1002 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001003 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001004 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001005 goto vdev_stop;
1006 }
1007
1008 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001009
Michal Kazior7aa7a722014-08-25 12:09:38 +02001010 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001011 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001012 return 0;
1013
1014vdev_stop:
1015 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1016 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001017 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001018 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001019
1020 return ret;
1021}
1022
Michal Kazior1bbc0972014-04-08 09:45:47 +03001023static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001024{
1025 int ret = 0;
1026
1027 lockdep_assert_held(&ar->conf_mutex);
1028
Marek Puzyniak52fa0192013-09-24 14:06:24 +02001029 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
1030 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001031 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001032 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001033
Michal Kazior7962b0d2014-10-28 10:34:38 +01001034 reinit_completion(&ar->vdev_setup_done);
1035
Kalle Valo5e3dd152013-06-12 20:52:10 +03001036 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1037 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001038 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001039 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001040
1041 ret = ath10k_vdev_setup_sync(ar);
1042 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +02001043 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001044 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001045
Michal Kazior7aa7a722014-08-25 12:09:38 +02001046 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001047 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001048 return ret;
1049}
1050
Michal Kazior1bbc0972014-04-08 09:45:47 +03001051static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001052{
1053 int bit, ret = 0;
1054
1055 lockdep_assert_held(&ar->conf_mutex);
1056
Ben Greeara9aefb32014-08-12 11:02:19 +03001057 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001058 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03001059 return -ENOMEM;
1060 }
1061
Ben Greear16c11172014-09-23 14:17:16 -07001062 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +03001063
Ben Greear16c11172014-09-23 14:17:16 -07001064 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001065
1066 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
1067 WMI_VDEV_TYPE_MONITOR,
1068 0, ar->mac_addr);
1069 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001070 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001071 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +03001072 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001073 }
1074
Ben Greear16c11172014-09-23 14:17:16 -07001075 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +02001076 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001077 ar->monitor_vdev_id);
1078
Kalle Valo5e3dd152013-06-12 20:52:10 +03001079 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001080}
1081
Michal Kazior1bbc0972014-04-08 09:45:47 +03001082static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001083{
1084 int ret = 0;
1085
1086 lockdep_assert_held(&ar->conf_mutex);
1087
Kalle Valo5e3dd152013-06-12 20:52:10 +03001088 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
1089 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001090 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001091 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001092 return ret;
1093 }
1094
Ben Greear16c11172014-09-23 14:17:16 -07001095 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001096
Michal Kazior7aa7a722014-08-25 12:09:38 +02001097 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001098 ar->monitor_vdev_id);
1099 return ret;
1100}
1101
Michal Kazior1bbc0972014-04-08 09:45:47 +03001102static int ath10k_monitor_start(struct ath10k *ar)
1103{
1104 int ret;
1105
1106 lockdep_assert_held(&ar->conf_mutex);
1107
Michal Kazior1bbc0972014-04-08 09:45:47 +03001108 ret = ath10k_monitor_vdev_create(ar);
1109 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001110 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001111 return ret;
1112 }
1113
1114 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
1115 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001116 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001117 ath10k_monitor_vdev_delete(ar);
1118 return ret;
1119 }
1120
1121 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001122 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +03001123
1124 return 0;
1125}
1126
Michal Kazior19337472014-08-28 12:58:16 +02001127static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +03001128{
1129 int ret;
1130
1131 lockdep_assert_held(&ar->conf_mutex);
1132
Michal Kazior1bbc0972014-04-08 09:45:47 +03001133 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001134 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001135 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001136 return ret;
1137 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001138
1139 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001140 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001141 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001142 return ret;
1143 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001144
1145 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001146 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +02001147
1148 return 0;
1149}
1150
Michal Kazior500ff9f2015-03-31 10:26:21 +00001151static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1152{
1153 int num_ctx;
1154
1155 /* At least one chanctx is required to derive a channel to start
1156 * monitor vdev on.
1157 */
1158 num_ctx = ath10k_mac_num_chanctxs(ar);
1159 if (num_ctx == 0)
1160 return false;
1161
1162 /* If there's already an existing special monitor interface then don't
1163 * bother creating another monitor vdev.
1164 */
1165 if (ar->monitor_arvif)
1166 return false;
1167
1168 return ar->monitor ||
Bob Copeland0d031c82015-09-09 12:47:34 -04001169 ar->filter_flags & FIF_OTHER_BSS ||
Michal Kazior500ff9f2015-03-31 10:26:21 +00001170 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1171}
1172
1173static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1174{
1175 int num_ctx;
1176
1177 num_ctx = ath10k_mac_num_chanctxs(ar);
1178
1179 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1180 * shouldn't allow this but make sure to prevent handling the following
1181 * case anyway since multi-channel DFS hasn't been tested at all.
1182 */
1183 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1184 return false;
1185
1186 return true;
1187}
1188
Michal Kazior19337472014-08-28 12:58:16 +02001189static int ath10k_monitor_recalc(struct ath10k *ar)
1190{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001191 bool needed;
1192 bool allowed;
1193 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001194
1195 lockdep_assert_held(&ar->conf_mutex);
1196
Michal Kazior500ff9f2015-03-31 10:26:21 +00001197 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1198 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001199
1200 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001201 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1202 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001203
Michal Kazior500ff9f2015-03-31 10:26:21 +00001204 if (WARN_ON(needed && !allowed)) {
1205 if (ar->monitor_started) {
1206 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1207
1208 ret = ath10k_monitor_stop(ar);
1209 if (ret)
Kalle Valo2a995082015-10-05 17:56:37 +03001210 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",
1211 ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001212 /* not serious */
1213 }
1214
1215 return -EPERM;
1216 }
1217
1218 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001219 return 0;
1220
Michal Kazior500ff9f2015-03-31 10:26:21 +00001221 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001222 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001223 else
1224 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001225}
1226
Bartosz Markowski83e48fc2016-12-15 11:23:24 +02001227static bool ath10k_mac_can_set_cts_prot(struct ath10k_vif *arvif)
1228{
1229 struct ath10k *ar = arvif->ar;
1230
1231 lockdep_assert_held(&ar->conf_mutex);
1232
1233 if (!arvif->is_started) {
1234 ath10k_dbg(ar, ATH10K_DBG_MAC, "defer cts setup, vdev is not ready yet\n");
1235 return false;
1236 }
1237
1238 return true;
1239}
1240
1241static int ath10k_mac_set_cts_prot(struct ath10k_vif *arvif)
1242{
1243 struct ath10k *ar = arvif->ar;
1244 u32 vdev_param;
1245
1246 lockdep_assert_held(&ar->conf_mutex);
1247
1248 vdev_param = ar->wmi.vdev_param->protection_mode;
1249
1250 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_protection %d\n",
1251 arvif->vdev_id, arvif->use_cts_prot);
1252
1253 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1254 arvif->use_cts_prot ? 1 : 0);
1255}
1256
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001257static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1258{
1259 struct ath10k *ar = arvif->ar;
1260 u32 vdev_param, rts_cts = 0;
1261
1262 lockdep_assert_held(&ar->conf_mutex);
1263
1264 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1265
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001266 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001267
1268 if (arvif->num_legacy_stations > 0)
1269 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1270 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001271 else
1272 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1273 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001274
1275 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1276 rts_cts);
1277}
1278
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001279static int ath10k_start_cac(struct ath10k *ar)
1280{
1281 int ret;
1282
1283 lockdep_assert_held(&ar->conf_mutex);
1284
1285 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1286
Michal Kazior19337472014-08-28 12:58:16 +02001287 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001288 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001289 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001290 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1291 return ret;
1292 }
1293
Michal Kazior7aa7a722014-08-25 12:09:38 +02001294 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001295 ar->monitor_vdev_id);
1296
1297 return 0;
1298}
1299
1300static int ath10k_stop_cac(struct ath10k *ar)
1301{
1302 lockdep_assert_held(&ar->conf_mutex);
1303
1304 /* CAC is not running - do nothing */
1305 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1306 return 0;
1307
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001308 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001309 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001310
Michal Kazior7aa7a722014-08-25 12:09:38 +02001311 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001312
1313 return 0;
1314}
1315
Michal Kazior500ff9f2015-03-31 10:26:21 +00001316static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1317 struct ieee80211_chanctx_conf *conf,
1318 void *data)
1319{
1320 bool *ret = data;
1321
1322 if (!*ret && conf->radar_enabled)
1323 *ret = true;
1324}
1325
1326static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1327{
1328 bool has_radar = false;
1329
1330 ieee80211_iter_chan_contexts_atomic(ar->hw,
1331 ath10k_mac_has_radar_iter,
1332 &has_radar);
1333
1334 return has_radar;
1335}
1336
Michal Kaziord6500972014-04-08 09:56:09 +03001337static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001338{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001339 int ret;
1340
1341 lockdep_assert_held(&ar->conf_mutex);
1342
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001343 ath10k_stop_cac(ar);
1344
Michal Kazior500ff9f2015-03-31 10:26:21 +00001345 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001346 return;
1347
Michal Kaziord6500972014-04-08 09:56:09 +03001348 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001349 return;
1350
1351 ret = ath10k_start_cac(ar);
1352 if (ret) {
1353 /*
1354 * Not possible to start CAC on current channel so starting
1355 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1356 * by indicating that radar was detected.
1357 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001358 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001359 ieee80211_radar_detected(ar->hw);
1360 }
1361}
1362
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301363static int ath10k_vdev_stop(struct ath10k_vif *arvif)
Michal Kazior72654fa2014-04-08 09:56:09 +03001364{
1365 struct ath10k *ar = arvif->ar;
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301366 int ret;
1367
1368 lockdep_assert_held(&ar->conf_mutex);
1369
1370 reinit_completion(&ar->vdev_setup_done);
1371
1372 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1373 if (ret) {
1374 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1375 arvif->vdev_id, ret);
1376 return ret;
1377 }
1378
1379 ret = ath10k_vdev_setup_sync(ar);
1380 if (ret) {
1381 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
1382 arvif->vdev_id, ret);
1383 return ret;
1384 }
1385
1386 WARN_ON(ar->num_started_vdevs == 0);
1387
1388 if (ar->num_started_vdevs != 0) {
1389 ar->num_started_vdevs--;
1390 ath10k_recalc_radar_detection(ar);
1391 }
1392
1393 return ret;
1394}
1395
Michal Kazior500ff9f2015-03-31 10:26:21 +00001396static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1397 const struct cfg80211_chan_def *chandef,
1398 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001399{
1400 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001401 struct wmi_vdev_start_request_arg arg = {};
1402 int ret = 0;
1403
1404 lockdep_assert_held(&ar->conf_mutex);
1405
1406 reinit_completion(&ar->vdev_setup_done);
1407
1408 arg.vdev_id = arvif->vdev_id;
1409 arg.dtim_period = arvif->dtim_period;
1410 arg.bcn_intval = arvif->beacon_interval;
1411
1412 arg.channel.freq = chandef->chan->center_freq;
1413 arg.channel.band_center_freq1 = chandef->center_freq1;
1414 arg.channel.mode = chan_to_phymode(chandef);
1415
1416 arg.channel.min_power = 0;
1417 arg.channel.max_power = chandef->chan->max_power * 2;
1418 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1419 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1420
1421 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1422 arg.ssid = arvif->u.ap.ssid;
1423 arg.ssid_len = arvif->u.ap.ssid_len;
1424 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1425
1426 /* For now allow DFS for AP mode */
1427 arg.channel.chan_radar =
1428 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1429 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1430 arg.ssid = arvif->vif->bss_conf.ssid;
1431 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1432 }
1433
Michal Kazior7aa7a722014-08-25 12:09:38 +02001434 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001435 "mac vdev %d start center_freq %d phymode %s\n",
1436 arg.vdev_id, arg.channel.freq,
1437 ath10k_wmi_phymode_str(arg.channel.mode));
1438
Michal Kaziordc55e302014-07-29 12:53:36 +03001439 if (restart)
1440 ret = ath10k_wmi_vdev_restart(ar, &arg);
1441 else
1442 ret = ath10k_wmi_vdev_start(ar, &arg);
1443
Michal Kazior72654fa2014-04-08 09:56:09 +03001444 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001445 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001446 arg.vdev_id, ret);
1447 return ret;
1448 }
1449
1450 ret = ath10k_vdev_setup_sync(ar);
1451 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001452 ath10k_warn(ar,
1453 "failed to synchronize setup for vdev %i restart %d: %d\n",
1454 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001455 return ret;
1456 }
1457
Michal Kaziord6500972014-04-08 09:56:09 +03001458 ar->num_started_vdevs++;
1459 ath10k_recalc_radar_detection(ar);
1460
Michal Kazior72654fa2014-04-08 09:56:09 +03001461 return ret;
1462}
1463
Michal Kazior500ff9f2015-03-31 10:26:21 +00001464static int ath10k_vdev_start(struct ath10k_vif *arvif,
1465 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001466{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001467 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001468}
1469
Michal Kazior500ff9f2015-03-31 10:26:21 +00001470static int ath10k_vdev_restart(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, true);
Michal Kazior72654fa2014-04-08 09:56:09 +03001474}
1475
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001476static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1477 struct sk_buff *bcn)
1478{
1479 struct ath10k *ar = arvif->ar;
1480 struct ieee80211_mgmt *mgmt;
1481 const u8 *p2p_ie;
1482 int ret;
1483
Peter Oh08c27be2016-01-28 13:54:09 -08001484 if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001485 return 0;
1486
1487 mgmt = (void *)bcn->data;
1488 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1489 mgmt->u.beacon.variable,
1490 bcn->len - (mgmt->u.beacon.variable -
1491 bcn->data));
1492 if (!p2p_ie)
1493 return -ENOENT;
1494
1495 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1496 if (ret) {
1497 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1498 arvif->vdev_id, ret);
1499 return ret;
1500 }
1501
1502 return 0;
1503}
1504
1505static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1506 u8 oui_type, size_t ie_offset)
1507{
1508 size_t len;
1509 const u8 *next;
1510 const u8 *end;
1511 u8 *ie;
1512
1513 if (WARN_ON(skb->len < ie_offset))
1514 return -EINVAL;
1515
1516 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1517 skb->data + ie_offset,
1518 skb->len - ie_offset);
1519 if (!ie)
1520 return -ENOENT;
1521
1522 len = ie[1] + 2;
1523 end = skb->data + skb->len;
1524 next = ie + len;
1525
1526 if (WARN_ON(next > end))
1527 return -EINVAL;
1528
1529 memmove(ie, next, end - next);
1530 skb_trim(skb, skb->len - len);
1531
1532 return 0;
1533}
1534
1535static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1536{
1537 struct ath10k *ar = arvif->ar;
1538 struct ieee80211_hw *hw = ar->hw;
1539 struct ieee80211_vif *vif = arvif->vif;
1540 struct ieee80211_mutable_offsets offs = {};
1541 struct sk_buff *bcn;
1542 int ret;
1543
1544 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1545 return 0;
1546
Michal Kazior81a9a172015-03-05 16:02:17 +02001547 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1548 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1549 return 0;
1550
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001551 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1552 if (!bcn) {
1553 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1554 return -EPERM;
1555 }
1556
1557 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1558 if (ret) {
1559 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1560 kfree_skb(bcn);
1561 return ret;
1562 }
1563
1564 /* P2P IE is inserted by firmware automatically (as configured above)
1565 * so remove it from the base beacon template to avoid duplicate P2P
1566 * IEs in beacon frames.
1567 */
1568 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1569 offsetof(struct ieee80211_mgmt,
1570 u.beacon.variable));
1571
1572 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1573 0, NULL, 0);
1574 kfree_skb(bcn);
1575
1576 if (ret) {
1577 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1578 ret);
1579 return ret;
1580 }
1581
1582 return 0;
1583}
1584
1585static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1586{
1587 struct ath10k *ar = arvif->ar;
1588 struct ieee80211_hw *hw = ar->hw;
1589 struct ieee80211_vif *vif = arvif->vif;
1590 struct sk_buff *prb;
1591 int ret;
1592
1593 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1594 return 0;
1595
Michal Kazior81a9a172015-03-05 16:02:17 +02001596 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1597 return 0;
1598
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001599 prb = ieee80211_proberesp_get(hw, vif);
1600 if (!prb) {
1601 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1602 return -EPERM;
1603 }
1604
1605 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1606 kfree_skb(prb);
1607
1608 if (ret) {
1609 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1610 ret);
1611 return ret;
1612 }
1613
1614 return 0;
1615}
1616
Michal Kazior500ff9f2015-03-31 10:26:21 +00001617static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1618{
1619 struct ath10k *ar = arvif->ar;
1620 struct cfg80211_chan_def def;
1621 int ret;
1622
1623 /* When originally vdev is started during assign_vif_chanctx() some
1624 * information is missing, notably SSID. Firmware revisions with beacon
1625 * offloading require the SSID to be provided during vdev (re)start to
1626 * handle hidden SSID properly.
1627 *
1628 * Vdev restart must be done after vdev has been both started and
1629 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1630 * deliver vdev restart response event causing timeouts during vdev
1631 * syncing in ath10k.
1632 *
1633 * Note: The vdev down/up and template reinstallation could be skipped
1634 * since only wmi-tlv firmware are known to have beacon offload and
1635 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1636 * response delivery. It's probably more robust to keep it as is.
1637 */
1638 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1639 return 0;
1640
1641 if (WARN_ON(!arvif->is_started))
1642 return -EINVAL;
1643
1644 if (WARN_ON(!arvif->is_up))
1645 return -EINVAL;
1646
1647 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1648 return -EINVAL;
1649
1650 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1651 if (ret) {
1652 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1653 arvif->vdev_id, ret);
1654 return ret;
1655 }
1656
1657 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1658 * firmware will crash upon vdev up.
1659 */
1660
1661 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1662 if (ret) {
1663 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1664 return ret;
1665 }
1666
1667 ret = ath10k_mac_setup_prb_tmpl(arvif);
1668 if (ret) {
1669 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1670 return ret;
1671 }
1672
1673 ret = ath10k_vdev_restart(arvif, &def);
1674 if (ret) {
1675 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1676 arvif->vdev_id, ret);
1677 return ret;
1678 }
1679
1680 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1681 arvif->bssid);
1682 if (ret) {
1683 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1684 arvif->vdev_id, ret);
1685 return ret;
1686 }
1687
1688 return 0;
1689}
1690
Kalle Valo5e3dd152013-06-12 20:52:10 +03001691static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001692 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001693{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001694 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001695 int ret = 0;
1696
Michal Kazior548db542013-07-05 16:15:15 +03001697 lockdep_assert_held(&arvif->ar->conf_mutex);
1698
Kalle Valo5e3dd152013-06-12 20:52:10 +03001699 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001700 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1701 if (ret)
1702 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1703 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001704
Michal Kaziorc930f742014-01-23 11:38:25 +01001705 arvif->is_up = false;
1706
Michal Kazior748afc42014-01-23 12:48:21 +01001707 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001708 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001709 spin_unlock_bh(&arvif->ar->data_lock);
1710
Kalle Valo5e3dd152013-06-12 20:52:10 +03001711 return;
1712 }
1713
1714 arvif->tx_seq_no = 0x1000;
1715
Michal Kaziorc930f742014-01-23 11:38:25 +01001716 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001717 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001718
1719 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1720 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001721 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001722 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001723 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001724 return;
1725 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001726
Michal Kaziorc930f742014-01-23 11:38:25 +01001727 arvif->is_up = true;
1728
Michal Kazior500ff9f2015-03-31 10:26:21 +00001729 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1730 if (ret) {
1731 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1732 arvif->vdev_id, ret);
1733 return;
1734 }
1735
Michal Kazior7aa7a722014-08-25 12:09:38 +02001736 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001737}
1738
1739static void ath10k_control_ibss(struct ath10k_vif *arvif,
1740 struct ieee80211_bss_conf *info,
1741 const u8 self_peer[ETH_ALEN])
1742{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001743 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001744 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001745 int ret = 0;
1746
Michal Kazior548db542013-07-05 16:15:15 +03001747 lockdep_assert_held(&arvif->ar->conf_mutex);
1748
Kalle Valo5e3dd152013-06-12 20:52:10 +03001749 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001750 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001751 return;
1752
Joe Perches93803b32015-03-02 19:54:49 -08001753 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001754
1755 return;
1756 }
1757
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001758 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1759 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001760 ATH10K_DEFAULT_ATIM);
1761 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001762 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001763 arvif->vdev_id, ret);
1764}
1765
Michal Kazior9f9b5742014-12-12 12:41:36 +01001766static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1767{
1768 struct ath10k *ar = arvif->ar;
1769 u32 param;
1770 u32 value;
1771 int ret;
1772
1773 lockdep_assert_held(&arvif->ar->conf_mutex);
1774
1775 if (arvif->u.sta.uapsd)
1776 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1777 else
1778 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1779
1780 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1781 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1782 if (ret) {
1783 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1784 value, arvif->vdev_id, ret);
1785 return ret;
1786 }
1787
1788 return 0;
1789}
1790
1791static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1792{
1793 struct ath10k *ar = arvif->ar;
1794 u32 param;
1795 u32 value;
1796 int ret;
1797
1798 lockdep_assert_held(&arvif->ar->conf_mutex);
1799
1800 if (arvif->u.sta.uapsd)
1801 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1802 else
1803 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1804
1805 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1806 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1807 param, value);
1808 if (ret) {
1809 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1810 value, arvif->vdev_id, ret);
1811 return ret;
1812 }
1813
1814 return 0;
1815}
1816
Michal Kazior424f2632015-07-09 13:08:35 +02001817static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001818{
1819 struct ath10k_vif *arvif;
1820 int num = 0;
1821
1822 lockdep_assert_held(&ar->conf_mutex);
1823
1824 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001825 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001826 num++;
1827
1828 return num;
1829}
1830
Michal Kaziorad088bf2013-10-16 15:44:46 +03001831static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001832{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001833 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001834 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001835 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001836 enum wmi_sta_powersave_param param;
1837 enum wmi_sta_ps_mode psmode;
1838 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001839 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001840 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001841
Michal Kazior548db542013-07-05 16:15:15 +03001842 lockdep_assert_held(&arvif->ar->conf_mutex);
1843
Michal Kaziorad088bf2013-10-16 15:44:46 +03001844 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1845 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001846
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001847 enable_ps = arvif->ps;
1848
Michal Kazior424f2632015-07-09 13:08:35 +02001849 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001850 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
Kalle Valoc4cdf752016-04-20 19:45:18 +03001851 ar->running_fw->fw_file.fw_features)) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001852 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1853 arvif->vdev_id);
1854 enable_ps = false;
1855 }
1856
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001857 if (!arvif->is_started) {
1858 /* mac80211 can update vif powersave state while disconnected.
1859 * Firmware doesn't behave nicely and consumes more power than
1860 * necessary if PS is disabled on a non-started vdev. Hence
1861 * force-enable PS for non-running vdevs.
1862 */
1863 psmode = WMI_STA_PS_MODE_ENABLED;
1864 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001865 psmode = WMI_STA_PS_MODE_ENABLED;
1866 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1867
Michal Kazior526549a2014-12-12 12:41:37 +01001868 ps_timeout = conf->dynamic_ps_timeout;
1869 if (ps_timeout == 0) {
1870 /* Firmware doesn't like 0 */
1871 ps_timeout = ieee80211_tu_to_usec(
1872 vif->bss_conf.beacon_int) / 1000;
1873 }
1874
Michal Kaziorad088bf2013-10-16 15:44:46 +03001875 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001876 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001877 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001878 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001879 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001880 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001881 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001882 } else {
1883 psmode = WMI_STA_PS_MODE_DISABLED;
1884 }
1885
Michal Kazior7aa7a722014-08-25 12:09:38 +02001886 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001887 arvif->vdev_id, psmode ? "enable" : "disable");
1888
Michal Kaziorad088bf2013-10-16 15:44:46 +03001889 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1890 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001891 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001892 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001893 return ret;
1894 }
1895
1896 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001897}
1898
Michal Kazior46725b12015-01-28 09:57:49 +02001899static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1900{
1901 struct ath10k *ar = arvif->ar;
1902 struct wmi_sta_keepalive_arg arg = {};
1903 int ret;
1904
1905 lockdep_assert_held(&arvif->ar->conf_mutex);
1906
1907 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1908 return 0;
1909
1910 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1911 return 0;
1912
1913 /* Some firmware revisions have a bug and ignore the `enabled` field.
1914 * Instead use the interval to disable the keepalive.
1915 */
1916 arg.vdev_id = arvif->vdev_id;
1917 arg.enabled = 1;
1918 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1919 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1920
1921 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1922 if (ret) {
1923 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1924 arvif->vdev_id, ret);
1925 return ret;
1926 }
1927
1928 return 0;
1929}
1930
Michal Kazior81a9a172015-03-05 16:02:17 +02001931static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1932{
1933 struct ath10k *ar = arvif->ar;
1934 struct ieee80211_vif *vif = arvif->vif;
1935 int ret;
1936
Michal Kazior8513d952015-03-09 14:19:24 +01001937 lockdep_assert_held(&arvif->ar->conf_mutex);
1938
1939 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1940 return;
1941
Michal Kazior81a9a172015-03-05 16:02:17 +02001942 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1943 return;
1944
1945 if (!vif->csa_active)
1946 return;
1947
1948 if (!arvif->is_up)
1949 return;
1950
1951 if (!ieee80211_csa_is_complete(vif)) {
1952 ieee80211_csa_update_counter(vif);
1953
1954 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1955 if (ret)
1956 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1957 ret);
1958
1959 ret = ath10k_mac_setup_prb_tmpl(arvif);
1960 if (ret)
1961 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1962 ret);
1963 } else {
1964 ieee80211_csa_finish(vif);
1965 }
1966}
1967
1968static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1969{
1970 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1971 ap_csa_work);
1972 struct ath10k *ar = arvif->ar;
1973
1974 mutex_lock(&ar->conf_mutex);
1975 ath10k_mac_vif_ap_csa_count_down(arvif);
1976 mutex_unlock(&ar->conf_mutex);
1977}
1978
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001979static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1980 struct ieee80211_vif *vif)
1981{
1982 struct sk_buff *skb = data;
1983 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1984 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1985
1986 if (vif->type != NL80211_IFTYPE_STATION)
1987 return;
1988
1989 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1990 return;
1991
1992 cancel_delayed_work(&arvif->connection_loss_work);
1993}
1994
1995void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
1996{
1997 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1998 IEEE80211_IFACE_ITER_NORMAL,
1999 ath10k_mac_handle_beacon_iter,
2000 skb);
2001}
2002
2003static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
2004 struct ieee80211_vif *vif)
2005{
2006 u32 *vdev_id = data;
2007 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2008 struct ath10k *ar = arvif->ar;
2009 struct ieee80211_hw *hw = ar->hw;
2010
2011 if (arvif->vdev_id != *vdev_id)
2012 return;
2013
2014 if (!arvif->is_up)
2015 return;
2016
2017 ieee80211_beacon_loss(vif);
2018
2019 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
2020 * (done by mac80211) succeeds but beacons do not resume then it
2021 * doesn't make sense to continue operation. Queue connection loss work
2022 * which can be cancelled when beacon is received.
2023 */
2024 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
2025 ATH10K_CONNECTION_LOSS_HZ);
2026}
2027
2028void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
2029{
2030 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2031 IEEE80211_IFACE_ITER_NORMAL,
2032 ath10k_mac_handle_beacon_miss_iter,
2033 &vdev_id);
2034}
2035
2036static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
2037{
2038 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
2039 connection_loss_work.work);
2040 struct ieee80211_vif *vif = arvif->vif;
2041
2042 if (!arvif->is_up)
2043 return;
2044
2045 ieee80211_connection_loss(vif);
2046}
2047
Kalle Valo5e3dd152013-06-12 20:52:10 +03002048/**********************/
2049/* Station management */
2050/**********************/
2051
Michal Kazior590922a2014-10-21 10:10:29 +03002052static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
2053 struct ieee80211_vif *vif)
2054{
2055 /* Some firmware revisions have unstable STA powersave when listen
2056 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
2057 * generate NullFunc frames properly even if buffered frames have been
2058 * indicated in Beacon TIM. Firmware would seldom wake up to pull
2059 * buffered frames. Often pinging the device from AP would simply fail.
2060 *
2061 * As a workaround set it to 1.
2062 */
2063 if (vif->type == NL80211_IFTYPE_STATION)
2064 return 1;
2065
2066 return ar->hw->conf.listen_interval;
2067}
2068
Kalle Valo5e3dd152013-06-12 20:52:10 +03002069static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002070 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002071 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002072 struct wmi_peer_assoc_complete_arg *arg)
2073{
Michal Kazior590922a2014-10-21 10:10:29 +03002074 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorc51880e2015-03-30 09:51:57 +03002075 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03002076
Michal Kazior548db542013-07-05 16:15:15 +03002077 lockdep_assert_held(&ar->conf_mutex);
2078
Michal Kaziorc51880e2015-03-30 09:51:57 +03002079 if (vif->type == NL80211_IFTYPE_STATION)
2080 aid = vif->bss_conf.aid;
2081 else
2082 aid = sta->aid;
2083
Kalle Valob25f32c2014-09-14 12:50:49 +03002084 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002085 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002086 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002087 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03002088 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002089 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03002090 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002091}
2092
2093static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002094 struct ieee80211_vif *vif,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002095 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002096 struct wmi_peer_assoc_complete_arg *arg)
2097{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002098 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002099 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002100 struct cfg80211_bss *bss;
2101 const u8 *rsnie = NULL;
2102 const u8 *wpaie = NULL;
2103
Michal Kazior548db542013-07-05 16:15:15 +03002104 lockdep_assert_held(&ar->conf_mutex);
2105
Michal Kazior500ff9f2015-03-31 10:26:21 +00002106 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2107 return;
2108
2109 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
2110 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002111 if (bss) {
2112 const struct cfg80211_bss_ies *ies;
2113
2114 rcu_read_lock();
2115 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
2116
2117 ies = rcu_dereference(bss->ies);
2118
2119 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03002120 WLAN_OUI_TYPE_MICROSOFT_WPA,
2121 ies->data,
2122 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002123 rcu_read_unlock();
2124 cfg80211_put_bss(ar->hw->wiphy, bss);
2125 }
2126
2127 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2128 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002129 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002130 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002131 }
2132
2133 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002134 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002135 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002136 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002137
2138 if (sta->mfp &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03002139 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT,
2140 ar->running_fw->fw_file.fw_features)) {
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002141 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002142 }
2143}
2144
2145static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002146 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002147 struct ieee80211_sta *sta,
2148 struct wmi_peer_assoc_complete_arg *arg)
2149{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002150 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002151 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002152 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002153 const struct ieee80211_supported_band *sband;
2154 const struct ieee80211_rate *rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002155 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002156 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002157 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002158 int i;
2159
Michal Kazior548db542013-07-05 16:15:15 +03002160 lockdep_assert_held(&ar->conf_mutex);
2161
Michal Kazior500ff9f2015-03-31 10:26:21 +00002162 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2163 return;
2164
Michal Kazior45c9abc2015-04-21 20:42:58 +03002165 band = def.chan->band;
2166 sband = ar->hw->wiphy->bands[band];
2167 ratemask = sta->supp_rates[band];
2168 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002169 rates = sband->bitrates;
2170
2171 rateset->num_rates = 0;
2172
2173 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2174 if (!(ratemask & 1))
2175 continue;
2176
Michal Kazior486017c2015-03-30 09:51:54 +03002177 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2178 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002179 rateset->num_rates++;
2180 }
2181}
2182
Michal Kazior45c9abc2015-04-21 20:42:58 +03002183static bool
2184ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2185{
2186 int nss;
2187
2188 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2189 if (ht_mcs_mask[nss])
2190 return false;
2191
2192 return true;
2193}
2194
2195static bool
2196ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2197{
2198 int nss;
2199
2200 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2201 if (vht_mcs_mask[nss])
2202 return false;
2203
2204 return true;
2205}
2206
Kalle Valo5e3dd152013-06-12 20:52:10 +03002207static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002208 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002209 struct ieee80211_sta *sta,
2210 struct wmi_peer_assoc_complete_arg *arg)
2211{
2212 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002213 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2214 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002215 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002216 const u8 *ht_mcs_mask;
2217 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002218 int i, n;
2219 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002220 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002221
Michal Kazior548db542013-07-05 16:15:15 +03002222 lockdep_assert_held(&ar->conf_mutex);
2223
Michal Kazior45c9abc2015-04-21 20:42:58 +03002224 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2225 return;
2226
Kalle Valo5e3dd152013-06-12 20:52:10 +03002227 if (!ht_cap->ht_supported)
2228 return;
2229
Michal Kazior45c9abc2015-04-21 20:42:58 +03002230 band = def.chan->band;
2231 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2232 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2233
2234 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2235 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2236 return;
2237
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002238 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002239 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2240 ht_cap->ampdu_factor)) - 1;
2241
2242 arg->peer_mpdu_density =
2243 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2244
2245 arg->peer_ht_caps = ht_cap->cap;
2246 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2247
2248 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002249 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002250
2251 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002252 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002253 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2254 }
2255
Michal Kazior45c9abc2015-04-21 20:42:58 +03002256 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2257 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2258 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002259
Michal Kazior45c9abc2015-04-21 20:42:58 +03002260 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2261 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2262 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002263
2264 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2265 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002266 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002267 }
2268
2269 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002270 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2271 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2272 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2273 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002274 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002275 }
2276
Kalle Valo5e3dd152013-06-12 20:52:10 +03002277 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2278 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2279 else if (ht_cap->mcs.rx_mask[1])
2280 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2281
Michal Kazior45c9abc2015-04-21 20:42:58 +03002282 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2283 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2284 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2285 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002286 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002287 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002288
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002289 /*
2290 * This is a workaround for HT-enabled STAs which break the spec
2291 * and have no HT capabilities RX mask (no HT RX MCS map).
2292 *
2293 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2294 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2295 *
2296 * Firmware asserts if such situation occurs.
2297 */
2298 if (n == 0) {
2299 arg->peer_ht_rates.num_rates = 8;
2300 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2301 arg->peer_ht_rates.rates[i] = i;
2302 } else {
2303 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002304 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002305 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002306
Michal Kazior7aa7a722014-08-25 12:09:38 +02002307 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002308 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002309 arg->peer_ht_rates.num_rates,
2310 arg->peer_num_spatial_streams);
2311}
2312
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002313static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2314 struct ath10k_vif *arvif,
2315 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002316{
2317 u32 uapsd = 0;
2318 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002319 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002320
Michal Kazior548db542013-07-05 16:15:15 +03002321 lockdep_assert_held(&ar->conf_mutex);
2322
Kalle Valo5e3dd152013-06-12 20:52:10 +03002323 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002324 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002325 sta->uapsd_queues, sta->max_sp);
2326
Kalle Valo5e3dd152013-06-12 20:52:10 +03002327 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2328 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2329 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2330 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2331 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2332 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2333 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2334 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2335 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2336 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2337 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2338 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2339
Kalle Valo5e3dd152013-06-12 20:52:10 +03002340 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2341 max_sp = sta->max_sp;
2342
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002343 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2344 sta->addr,
2345 WMI_AP_PS_PEER_PARAM_UAPSD,
2346 uapsd);
2347 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002348 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002349 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002350 return ret;
2351 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002352
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002353 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2354 sta->addr,
2355 WMI_AP_PS_PEER_PARAM_MAX_SP,
2356 max_sp);
2357 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002358 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002359 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002360 return ret;
2361 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002362
2363 /* TODO setup this based on STA listen interval and
2364 beacon interval. Currently we don't know
2365 sta->listen_interval - mac80211 patch required.
2366 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002367 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002368 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2369 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002370 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002371 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002372 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002373 return ret;
2374 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002375 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002376
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002377 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002378}
2379
Michal Kazior45c9abc2015-04-21 20:42:58 +03002380static u16
2381ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2382 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2383{
2384 int idx_limit;
2385 int nss;
2386 u16 mcs_map;
2387 u16 mcs;
2388
2389 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2390 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2391 vht_mcs_limit[nss];
2392
2393 if (mcs_map)
2394 idx_limit = fls(mcs_map) - 1;
2395 else
2396 idx_limit = -1;
2397
2398 switch (idx_limit) {
2399 case 0: /* fall through */
2400 case 1: /* fall through */
2401 case 2: /* fall through */
2402 case 3: /* fall through */
2403 case 4: /* fall through */
2404 case 5: /* fall through */
2405 case 6: /* fall through */
2406 default:
2407 /* see ath10k_mac_can_set_bitrate_mask() */
2408 WARN_ON(1);
2409 /* fall through */
2410 case -1:
2411 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2412 break;
2413 case 7:
2414 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2415 break;
2416 case 8:
2417 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2418 break;
2419 case 9:
2420 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2421 break;
2422 }
2423
2424 tx_mcs_set &= ~(0x3 << (nss * 2));
2425 tx_mcs_set |= mcs << (nss * 2);
2426 }
2427
2428 return tx_mcs_set;
2429}
2430
Kalle Valo5e3dd152013-06-12 20:52:10 +03002431static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002432 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002433 struct ieee80211_sta *sta,
2434 struct wmi_peer_assoc_complete_arg *arg)
2435{
2436 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002437 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002438 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002439 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002440 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002441 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002442
Michal Kazior500ff9f2015-03-31 10:26:21 +00002443 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2444 return;
2445
Kalle Valo5e3dd152013-06-12 20:52:10 +03002446 if (!vht_cap->vht_supported)
2447 return;
2448
Michal Kazior45c9abc2015-04-21 20:42:58 +03002449 band = def.chan->band;
2450 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2451
2452 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2453 return;
2454
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002455 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002456
Johannes Berg57fbcce2016-04-12 15:56:15 +02002457 if (def.chan->band == NL80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002458 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002459
Kalle Valo5e3dd152013-06-12 20:52:10 +03002460 arg->peer_vht_caps = vht_cap->cap;
2461
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002462 ampdu_factor = (vht_cap->cap &
2463 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2464 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2465
2466 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2467 * zero in VHT IE. Using it would result in degraded throughput.
2468 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2469 * it if VHT max_mpdu is smaller. */
2470 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2471 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2472 ampdu_factor)) - 1);
2473
Kalle Valo5e3dd152013-06-12 20:52:10 +03002474 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002475 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002476
2477 arg->peer_vht_rates.rx_max_rate =
2478 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2479 arg->peer_vht_rates.rx_mcs_set =
2480 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2481 arg->peer_vht_rates.tx_max_rate =
2482 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002483 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2484 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002485
Michal Kazior7aa7a722014-08-25 12:09:38 +02002486 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002487 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002488}
2489
2490static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002491 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002492 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002493 struct wmi_peer_assoc_complete_arg *arg)
2494{
Michal Kazior590922a2014-10-21 10:10:29 +03002495 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2496
Kalle Valo5e3dd152013-06-12 20:52:10 +03002497 switch (arvif->vdev_type) {
2498 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002499 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002500 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002501
2502 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002503 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002504 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2505 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002506 break;
2507 case WMI_VDEV_TYPE_STA:
Balaji Pothunooribb327722017-12-07 16:58:04 +02002508 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002509 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002510 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002511 case WMI_VDEV_TYPE_IBSS:
2512 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002513 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002514 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002515 default:
2516 break;
2517 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002518
2519 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002520 sta->addr, !!(arg->peer_flags &
2521 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002522}
2523
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002524static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002525{
Johannes Berg57fbcce2016-04-12 15:56:15 +02002526 return sta->supp_rates[NL80211_BAND_2GHZ] >>
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002527 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002528}
2529
Kalle Valo5e3dd152013-06-12 20:52:10 +03002530static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002531 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002532 struct ieee80211_sta *sta,
2533 struct wmi_peer_assoc_complete_arg *arg)
2534{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002535 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002536 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002537 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002538 const u8 *ht_mcs_mask;
2539 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002540 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2541
Michal Kazior500ff9f2015-03-31 10:26:21 +00002542 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2543 return;
2544
Michal Kazior45c9abc2015-04-21 20:42:58 +03002545 band = def.chan->band;
2546 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2547 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2548
2549 switch (band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02002550 case NL80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002551 if (sta->vht_cap.vht_supported &&
2552 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002553 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2554 phymode = MODE_11AC_VHT40;
2555 else
2556 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002557 } else if (sta->ht_cap.ht_supported &&
2558 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002559 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2560 phymode = MODE_11NG_HT40;
2561 else
2562 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002563 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002564 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002565 } else {
2566 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002567 }
2568
2569 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002570 case NL80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002571 /*
2572 * Check VHT first.
2573 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002574 if (sta->vht_cap.vht_supported &&
2575 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002576 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2577 phymode = MODE_11AC_VHT80;
2578 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2579 phymode = MODE_11AC_VHT40;
2580 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2581 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002582 } else if (sta->ht_cap.ht_supported &&
2583 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2584 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002585 phymode = MODE_11NA_HT40;
2586 else
2587 phymode = MODE_11NA_HT20;
2588 } else {
2589 phymode = MODE_11A;
2590 }
2591
2592 break;
2593 default:
2594 break;
2595 }
2596
Michal Kazior7aa7a722014-08-25 12:09:38 +02002597 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002598 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002599
Kalle Valo5e3dd152013-06-12 20:52:10 +03002600 arg->peer_phymode = phymode;
2601 WARN_ON(phymode == MODE_UNKNOWN);
2602}
2603
Kalle Valob9ada652013-10-16 15:44:46 +03002604static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002605 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002606 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002607 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002608{
Michal Kazior548db542013-07-05 16:15:15 +03002609 lockdep_assert_held(&ar->conf_mutex);
2610
Kalle Valob9ada652013-10-16 15:44:46 +03002611 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002612
Michal Kazior590922a2014-10-21 10:10:29 +03002613 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002614 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002615 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002616 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002617 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002618 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2619 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002620
Kalle Valob9ada652013-10-16 15:44:46 +03002621 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002622}
2623
Michal Kazior90046f52014-02-14 14:45:51 +01002624static const u32 ath10k_smps_map[] = {
2625 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2626 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2627 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2628 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2629};
2630
2631static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2632 const u8 *addr,
2633 const struct ieee80211_sta_ht_cap *ht_cap)
2634{
2635 int smps;
2636
2637 if (!ht_cap->ht_supported)
2638 return 0;
2639
2640 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2641 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2642
2643 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2644 return -EINVAL;
2645
2646 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2647 WMI_PEER_SMPS_STATE,
2648 ath10k_smps_map[smps]);
2649}
2650
Michal Kazior139e1702015-02-15 16:50:42 +02002651static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2652 struct ieee80211_vif *vif,
2653 struct ieee80211_sta_vht_cap vht_cap)
2654{
2655 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2656 int ret;
2657 u32 param;
2658 u32 value;
2659
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302660 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2661 return 0;
2662
Michal Kazior139e1702015-02-15 16:50:42 +02002663 if (!(ar->vht_cap_info &
2664 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2665 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2666 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2667 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2668 return 0;
2669
2670 param = ar->wmi.vdev_param->txbf;
2671 value = 0;
2672
2673 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2674 return 0;
2675
2676 /* The following logic is correct. If a remote STA advertises support
2677 * for being a beamformer then we should enable us being a beamformee.
2678 */
2679
2680 if (ar->vht_cap_info &
2681 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2682 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2683 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2684 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2685
2686 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2687 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2688 }
2689
2690 if (ar->vht_cap_info &
2691 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2692 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2693 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2694 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2695
2696 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2697 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2698 }
2699
2700 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2701 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2702
2703 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2704 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2705
2706 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2707 if (ret) {
2708 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2709 value, ret);
2710 return ret;
2711 }
2712
2713 return 0;
2714}
2715
Kalle Valo5e3dd152013-06-12 20:52:10 +03002716/* can be called only in mac80211 callbacks due to `key_count` usage */
2717static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2718 struct ieee80211_vif *vif,
2719 struct ieee80211_bss_conf *bss_conf)
2720{
2721 struct ath10k *ar = hw->priv;
2722 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002723 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002724 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002725 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002726 struct ieee80211_sta *ap_sta;
2727 int ret;
2728
Michal Kazior548db542013-07-05 16:15:15 +03002729 lockdep_assert_held(&ar->conf_mutex);
2730
Michal Kazior077efc82014-10-21 10:10:29 +03002731 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2732 arvif->vdev_id, arvif->bssid, arvif->aid);
2733
Kalle Valo5e3dd152013-06-12 20:52:10 +03002734 rcu_read_lock();
2735
2736 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2737 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002738 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002739 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002740 rcu_read_unlock();
2741 return;
2742 }
2743
Michal Kazior90046f52014-02-14 14:45:51 +01002744 /* ap_sta must be accessed only within rcu section which must be left
2745 * before calling ath10k_setup_peer_smps() which might sleep. */
2746 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002747 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002748
Michal Kazior590922a2014-10-21 10:10:29 +03002749 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002750 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002751 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002752 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002753 rcu_read_unlock();
2754 return;
2755 }
2756
2757 rcu_read_unlock();
2758
Kalle Valob9ada652013-10-16 15:44:46 +03002759 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2760 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002761 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002762 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002763 return;
2764 }
2765
Michal Kazior90046f52014-02-14 14:45:51 +01002766 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2767 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002768 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002769 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002770 return;
2771 }
2772
Michal Kazior139e1702015-02-15 16:50:42 +02002773 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2774 if (ret) {
2775 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2776 arvif->vdev_id, bss_conf->bssid, ret);
2777 return;
2778 }
2779
Michal Kazior7aa7a722014-08-25 12:09:38 +02002780 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002781 "mac vdev %d up (associated) bssid %pM aid %d\n",
2782 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2783
Michal Kazior077efc82014-10-21 10:10:29 +03002784 WARN_ON(arvif->is_up);
2785
Michal Kaziorc930f742014-01-23 11:38:25 +01002786 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002787 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002788
2789 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2790 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002791 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002792 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002793 return;
2794 }
2795
2796 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002797
2798 /* Workaround: Some firmware revisions (tested with qca6174
2799 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2800 * poked with peer param command.
2801 */
2802 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2803 WMI_PEER_DUMMY_VAR, 1);
2804 if (ret) {
2805 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2806 arvif->bssid, arvif->vdev_id, ret);
2807 return;
2808 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002809}
2810
Kalle Valo5e3dd152013-06-12 20:52:10 +03002811static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2812 struct ieee80211_vif *vif)
2813{
2814 struct ath10k *ar = hw->priv;
2815 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002816 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002817 int ret;
2818
Michal Kazior548db542013-07-05 16:15:15 +03002819 lockdep_assert_held(&ar->conf_mutex);
2820
Michal Kazior077efc82014-10-21 10:10:29 +03002821 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2822 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002823
Kalle Valo5e3dd152013-06-12 20:52:10 +03002824 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002825 if (ret)
Ben Greearaa66ba02016-09-26 21:56:25 +03002826 ath10k_warn(ar, "failed to down vdev %i: %d\n",
Michal Kazior077efc82014-10-21 10:10:29 +03002827 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002828
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002829 arvif->def_wep_key_idx = -1;
2830
Michal Kazior139e1702015-02-15 16:50:42 +02002831 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2832 if (ret) {
2833 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2834 arvif->vdev_id, ret);
2835 return;
2836 }
2837
Michal Kaziorc930f742014-01-23 11:38:25 +01002838 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002839
2840 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002841}
2842
Michal Kazior590922a2014-10-21 10:10:29 +03002843static int ath10k_station_assoc(struct ath10k *ar,
2844 struct ieee80211_vif *vif,
2845 struct ieee80211_sta *sta,
2846 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002847{
Michal Kazior590922a2014-10-21 10:10:29 +03002848 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002849 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002850 int ret = 0;
2851
Michal Kazior548db542013-07-05 16:15:15 +03002852 lockdep_assert_held(&ar->conf_mutex);
2853
Michal Kazior590922a2014-10-21 10:10:29 +03002854 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002855 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002856 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002857 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002858 return ret;
2859 }
2860
2861 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2862 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002863 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002864 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002865 return ret;
2866 }
2867
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002868 /* Re-assoc is run only to update supported rates for given station. It
2869 * doesn't make much sense to reconfigure the peer completely.
2870 */
2871 if (!reassoc) {
2872 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2873 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002874 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002875 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002876 arvif->vdev_id, ret);
2877 return ret;
2878 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002879
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002880 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2881 if (ret) {
2882 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2883 sta->addr, arvif->vdev_id, ret);
2884 return ret;
2885 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002886
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002887 if (!sta->wme) {
2888 arvif->num_legacy_stations++;
2889 ret = ath10k_recalc_rtscts_prot(arvif);
2890 if (ret) {
2891 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2892 arvif->vdev_id, ret);
2893 return ret;
2894 }
2895 }
2896
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002897 /* Plumb cached keys only for static WEP */
2898 if (arvif->def_wep_key_idx != -1) {
2899 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2900 if (ret) {
2901 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2902 arvif->vdev_id, ret);
2903 return ret;
2904 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002905 }
2906 }
2907
Kalle Valo5e3dd152013-06-12 20:52:10 +03002908 return ret;
2909}
2910
Michal Kazior590922a2014-10-21 10:10:29 +03002911static int ath10k_station_disassoc(struct ath10k *ar,
2912 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002913 struct ieee80211_sta *sta)
2914{
Michal Kazior590922a2014-10-21 10:10:29 +03002915 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002916 int ret = 0;
2917
2918 lockdep_assert_held(&ar->conf_mutex);
2919
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002920 if (!sta->wme) {
2921 arvif->num_legacy_stations--;
2922 ret = ath10k_recalc_rtscts_prot(arvif);
2923 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002924 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002925 arvif->vdev_id, ret);
2926 return ret;
2927 }
2928 }
2929
Kalle Valo5e3dd152013-06-12 20:52:10 +03002930 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2931 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002932 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002933 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002934 return ret;
2935 }
2936
2937 return ret;
2938}
2939
2940/**************/
2941/* Regulatory */
2942/**************/
2943
2944static int ath10k_update_channel_list(struct ath10k *ar)
2945{
2946 struct ieee80211_hw *hw = ar->hw;
2947 struct ieee80211_supported_band **bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002948 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002949 struct ieee80211_channel *channel;
2950 struct wmi_scan_chan_list_arg arg = {0};
2951 struct wmi_channel_arg *ch;
2952 bool passive;
2953 int len;
2954 int ret;
2955 int i;
2956
Michal Kazior548db542013-07-05 16:15:15 +03002957 lockdep_assert_held(&ar->conf_mutex);
2958
Kalle Valo5e3dd152013-06-12 20:52:10 +03002959 bands = hw->wiphy->bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002960 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002961 if (!bands[band])
2962 continue;
2963
2964 for (i = 0; i < bands[band]->n_channels; i++) {
2965 if (bands[band]->channels[i].flags &
2966 IEEE80211_CHAN_DISABLED)
2967 continue;
2968
2969 arg.n_channels++;
2970 }
2971 }
2972
2973 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2974 arg.channels = kzalloc(len, GFP_KERNEL);
2975 if (!arg.channels)
2976 return -ENOMEM;
2977
2978 ch = arg.channels;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002979 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002980 if (!bands[band])
2981 continue;
2982
2983 for (i = 0; i < bands[band]->n_channels; i++) {
2984 channel = &bands[band]->channels[i];
2985
2986 if (channel->flags & IEEE80211_CHAN_DISABLED)
2987 continue;
2988
Eduardo Abinader98029772016-06-30 15:23:55 +03002989 ch->allow_ht = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002990
2991 /* FIXME: when should we really allow VHT? */
2992 ch->allow_vht = true;
2993
2994 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002995 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002996
2997 ch->ht40plus =
2998 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2999
Marek Puzyniake8a50f82013-11-20 09:59:47 +02003000 ch->chan_radar =
3001 !!(channel->flags & IEEE80211_CHAN_RADAR);
3002
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02003003 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003004 ch->passive = passive;
3005
Sven Eckelmann7ffd72b2018-07-26 15:59:48 +02003006 /* the firmware is ignoring the "radar" flag of the
3007 * channel and is scanning actively using Probe Requests
3008 * on "Radar detection"/DFS channels which are not
3009 * marked as "available"
3010 */
3011 ch->passive |= ch->chan_radar;
3012
Kalle Valo5e3dd152013-06-12 20:52:10 +03003013 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02003014 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07003015 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07003016 ch->max_power = channel->max_power * 2;
3017 ch->max_reg_power = channel->max_reg_power * 2;
3018 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003019 ch->reg_class_id = 0; /* FIXME */
3020
3021 /* FIXME: why use only legacy modes, why not any
3022 * HT/VHT modes? Would that even make any
3023 * difference? */
Johannes Berg57fbcce2016-04-12 15:56:15 +02003024 if (channel->band == NL80211_BAND_2GHZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003025 ch->mode = MODE_11G;
3026 else
3027 ch->mode = MODE_11A;
3028
3029 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
3030 continue;
3031
Michal Kazior7aa7a722014-08-25 12:09:38 +02003032 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03003033 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
3034 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003035 ch->freq, ch->max_power, ch->max_reg_power,
3036 ch->max_antenna_gain, ch->mode);
3037
3038 ch++;
3039 }
3040 }
3041
3042 ret = ath10k_wmi_scan_chan_list(ar, &arg);
3043 kfree(arg.channels);
3044
3045 return ret;
3046}
3047
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003048static enum wmi_dfs_region
3049ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
3050{
3051 switch (dfs_region) {
3052 case NL80211_DFS_UNSET:
3053 return WMI_UNINIT_DFS_DOMAIN;
3054 case NL80211_DFS_FCC:
3055 return WMI_FCC_DFS_DOMAIN;
3056 case NL80211_DFS_ETSI:
3057 return WMI_ETSI_DFS_DOMAIN;
3058 case NL80211_DFS_JP:
3059 return WMI_MKK4_DFS_DOMAIN;
3060 }
3061 return WMI_UNINIT_DFS_DOMAIN;
3062}
3063
Michal Kaziorf7843d72013-07-16 09:38:52 +02003064static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003065{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003066 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003067 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003068 enum wmi_dfs_region wmi_dfs_reg;
3069 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003070
Michal Kaziorf7843d72013-07-16 09:38:52 +02003071 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003072
3073 ret = ath10k_update_channel_list(ar);
3074 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003075 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003076
3077 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003078
Masahiro Yamada97f26452016-08-03 13:45:50 -07003079 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003080 nl_dfs_reg = ar->dfs_detector->region;
3081 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
3082 } else {
3083 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
3084 }
3085
Kalle Valo5e3dd152013-06-12 20:52:10 +03003086 /* Target allows setting up per-band regdomain but ath_common provides
3087 * a combined one only */
3088 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02003089 regpair->reg_domain,
3090 regpair->reg_domain, /* 2ghz */
3091 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003092 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003093 regpair->reg_5ghz_ctl,
3094 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003095 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003096 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02003097}
Michal Kazior548db542013-07-05 16:15:15 +03003098
Michal Kaziorf7843d72013-07-16 09:38:52 +02003099static void ath10k_reg_notifier(struct wiphy *wiphy,
3100 struct regulatory_request *request)
3101{
3102 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
3103 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003104 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003105
3106 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3107
Masahiro Yamada97f26452016-08-03 13:45:50 -07003108 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003109 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003110 request->dfs_region);
3111 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3112 request->dfs_region);
3113 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003114 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003115 request->dfs_region);
3116 }
3117
Michal Kaziorf7843d72013-07-16 09:38:52 +02003118 mutex_lock(&ar->conf_mutex);
3119 if (ar->state == ATH10K_STATE_ON)
3120 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003121 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003122}
3123
3124/***************/
3125/* TX handlers */
3126/***************/
3127
Michal Kaziora30c7d02016-03-06 16:14:23 +02003128enum ath10k_mac_tx_path {
3129 ATH10K_MAC_TX_HTT,
3130 ATH10K_MAC_TX_HTT_MGMT,
3131 ATH10K_MAC_TX_WMI_MGMT,
3132 ATH10K_MAC_TX_UNKNOWN,
3133};
3134
Michal Kazior96d828d2015-03-31 10:26:23 +00003135void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3136{
3137 lockdep_assert_held(&ar->htt.tx_lock);
3138
3139 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3140 ar->tx_paused |= BIT(reason);
3141 ieee80211_stop_queues(ar->hw);
3142}
3143
3144static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3145 struct ieee80211_vif *vif)
3146{
3147 struct ath10k *ar = data;
3148 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3149
3150 if (arvif->tx_paused)
3151 return;
3152
3153 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3154}
3155
3156void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3157{
3158 lockdep_assert_held(&ar->htt.tx_lock);
3159
3160 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3161 ar->tx_paused &= ~BIT(reason);
3162
3163 if (ar->tx_paused)
3164 return;
3165
3166 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3167 IEEE80211_IFACE_ITER_RESUME_ALL,
3168 ath10k_mac_tx_unlock_iter,
3169 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003170
3171 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003172}
3173
3174void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3175{
3176 struct ath10k *ar = arvif->ar;
3177
3178 lockdep_assert_held(&ar->htt.tx_lock);
3179
3180 WARN_ON(reason >= BITS_PER_LONG);
3181 arvif->tx_paused |= BIT(reason);
3182 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3183}
3184
3185void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3186{
3187 struct ath10k *ar = arvif->ar;
3188
3189 lockdep_assert_held(&ar->htt.tx_lock);
3190
3191 WARN_ON(reason >= BITS_PER_LONG);
3192 arvif->tx_paused &= ~BIT(reason);
3193
3194 if (ar->tx_paused)
3195 return;
3196
3197 if (arvif->tx_paused)
3198 return;
3199
3200 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3201}
3202
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003203static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3204 enum wmi_tlv_tx_pause_id pause_id,
3205 enum wmi_tlv_tx_pause_action action)
3206{
3207 struct ath10k *ar = arvif->ar;
3208
3209 lockdep_assert_held(&ar->htt.tx_lock);
3210
Michal Kazioracd0b272015-07-09 13:08:38 +02003211 switch (action) {
3212 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3213 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003214 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003215 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3216 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3217 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003218 default:
Michal Kazioracd0b272015-07-09 13:08:38 +02003219 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
3220 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
Michal Kazior874b5ac2017-01-12 16:14:30 +01003778 if (peer->removed)
3779 return NULL;
3780
Michal Kazior426e10e2016-03-06 16:14:43 +02003781 if (peer->sta)
3782 return peer->sta->txq[tid];
3783 else if (peer->vif)
3784 return peer->vif->txq;
3785 else
3786 return NULL;
3787}
3788
Michal Kazior29946872016-03-06 16:14:34 +02003789static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3790 struct ieee80211_txq *txq)
3791{
Michal Kazior426e10e2016-03-06 16:14:43 +02003792 struct ath10k *ar = hw->priv;
3793 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3794
3795 /* No need to get locks */
3796
3797 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3798 return true;
3799
3800 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3801 return true;
3802
3803 if (artxq->num_fw_queued < artxq->num_push_allowed)
3804 return true;
3805
3806 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003807}
3808
Michal Kazior426e10e2016-03-06 16:14:43 +02003809int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3810 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02003811{
Michal Kazior29946872016-03-06 16:14:34 +02003812 struct ath10k *ar = hw->priv;
3813 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003814 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003815 struct ieee80211_vif *vif = txq->vif;
3816 struct ieee80211_sta *sta = txq->sta;
3817 enum ath10k_hw_txrx_mode txmode;
3818 enum ath10k_mac_tx_path txpath;
3819 struct sk_buff *skb;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303820 struct ieee80211_hdr *hdr;
Michal Kazior426e10e2016-03-06 16:14:43 +02003821 size_t skb_len;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303822 bool is_mgmt, is_presp;
Michal Kazior29946872016-03-06 16:14:34 +02003823 int ret;
3824
3825 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303826 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003827 spin_unlock_bh(&ar->htt.tx_lock);
3828
3829 if (ret)
3830 return ret;
3831
3832 skb = ieee80211_tx_dequeue(hw, txq);
3833 if (!skb) {
3834 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303835 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003836 spin_unlock_bh(&ar->htt.tx_lock);
3837
3838 return -ENOENT;
3839 }
3840
Michal Kaziordd4717b2016-03-06 16:14:39 +02003841 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Michal Kazior29946872016-03-06 16:14:34 +02003842
Michal Kazior426e10e2016-03-06 16:14:43 +02003843 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02003844 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
3845 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303846 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
3847
3848 if (is_mgmt) {
3849 hdr = (struct ieee80211_hdr *)skb->data;
3850 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
3851
3852 spin_lock_bh(&ar->htt.tx_lock);
3853 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
3854
3855 if (ret) {
3856 ath10k_htt_tx_dec_pending(htt);
3857 spin_unlock_bh(&ar->htt.tx_lock);
3858 return ret;
3859 }
3860 spin_unlock_bh(&ar->htt.tx_lock);
3861 }
Michal Kazior29946872016-03-06 16:14:34 +02003862
3863 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
3864 if (unlikely(ret)) {
3865 ath10k_warn(ar, "failed to push frame: %d\n", ret);
3866
3867 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303868 ath10k_htt_tx_dec_pending(htt);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303869 if (is_mgmt)
3870 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003871 spin_unlock_bh(&ar->htt.tx_lock);
3872
3873 return ret;
3874 }
3875
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003876 spin_lock_bh(&ar->htt.tx_lock);
3877 artxq->num_fw_queued++;
3878 spin_unlock_bh(&ar->htt.tx_lock);
3879
Michal Kazior426e10e2016-03-06 16:14:43 +02003880 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003881}
3882
3883void ath10k_mac_tx_push_pending(struct ath10k *ar)
3884{
3885 struct ieee80211_hw *hw = ar->hw;
3886 struct ieee80211_txq *txq;
3887 struct ath10k_txq *artxq;
3888 struct ath10k_txq *last;
3889 int ret;
3890 int max;
3891
Michal Kazior7a0adc82016-05-23 23:12:45 +03003892 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
3893 return;
3894
Michal Kazior29946872016-03-06 16:14:34 +02003895 spin_lock_bh(&ar->txqs_lock);
3896 rcu_read_lock();
3897
3898 last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
3899 while (!list_empty(&ar->txqs)) {
3900 artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
3901 txq = container_of((void *)artxq, struct ieee80211_txq,
3902 drv_priv);
3903
3904 /* Prevent aggressive sta/tid taking over tx queue */
3905 max = 16;
Michal Kazior750eeed2016-03-17 10:51:05 +01003906 ret = 0;
3907 while (ath10k_mac_tx_can_push(hw, txq) && max--) {
Michal Kazior29946872016-03-06 16:14:34 +02003908 ret = ath10k_mac_tx_push_txq(hw, txq);
3909 if (ret < 0)
3910 break;
3911 }
3912
3913 list_del_init(&artxq->list);
Michal Kazior9d71d472016-03-17 10:51:04 +01003914 if (ret != -ENOENT)
3915 list_add_tail(&artxq->list, &ar->txqs);
3916
Michal Kaziorc1a43d92016-03-06 16:14:36 +02003917 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02003918
Michal Kazior9d71d472016-03-17 10:51:04 +01003919 if (artxq == last || (ret < 0 && ret != -ENOENT))
Michal Kazior29946872016-03-06 16:14:34 +02003920 break;
Michal Kazior29946872016-03-06 16:14:34 +02003921 }
3922
3923 rcu_read_unlock();
3924 spin_unlock_bh(&ar->txqs_lock);
3925}
3926
Kalle Valo5e3dd152013-06-12 20:52:10 +03003927/************/
3928/* Scanning */
3929/************/
3930
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003931void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003932{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003933 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003934
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003935 switch (ar->scan.state) {
3936 case ATH10K_SCAN_IDLE:
3937 break;
3938 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01003939 case ATH10K_SCAN_ABORTING:
Avraham Stern7947d3e2016-07-05 15:23:12 +03003940 if (!ar->scan.is_roc) {
3941 struct cfg80211_scan_info info = {
3942 .aborted = (ar->scan.state ==
3943 ATH10K_SCAN_ABORTING),
3944 };
3945
3946 ieee80211_scan_completed(ar->hw, &info);
3947 } else if (ar->scan.roc_notify) {
Michal Kaziord710e752015-07-09 13:08:36 +02003948 ieee80211_remain_on_channel_expired(ar->hw);
Avraham Stern7947d3e2016-07-05 15:23:12 +03003949 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003950 /* fall through */
3951 case ATH10K_SCAN_STARTING:
3952 ar->scan.state = ATH10K_SCAN_IDLE;
3953 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01003954 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003955 ath10k_offchan_tx_purge(ar);
3956 cancel_delayed_work(&ar->scan.timeout);
Daniel Wagner881ed542016-08-18 15:12:06 +02003957 complete(&ar->scan.completed);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003958 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003959 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003960}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003961
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003962void ath10k_scan_finish(struct ath10k *ar)
3963{
3964 spin_lock_bh(&ar->data_lock);
3965 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003966 spin_unlock_bh(&ar->data_lock);
3967}
3968
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003969static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003970{
3971 struct wmi_stop_scan_arg arg = {
3972 .req_id = 1, /* FIXME */
3973 .req_type = WMI_SCAN_STOP_ONE,
3974 .u.scan_id = ATH10K_SCAN_ID,
3975 };
3976 int ret;
3977
3978 lockdep_assert_held(&ar->conf_mutex);
3979
Kalle Valo5e3dd152013-06-12 20:52:10 +03003980 ret = ath10k_wmi_stop_scan(ar, &arg);
3981 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003982 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003983 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003984 }
3985
Kalle Valo14e105c2016-04-13 14:13:21 +03003986 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003987 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003988 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003989 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003990 } else if (ret > 0) {
3991 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003992 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003993
3994out:
3995 /* Scan state should be updated upon scan completion but in case
3996 * firmware fails to deliver the event (for whatever reason) it is
3997 * desired to clean up scan state anyway. Firmware may have just
3998 * dropped the scan completion event delivery due to transport pipe
3999 * being overflown with data and/or it can recover on its own before
4000 * next scan request is submitted.
4001 */
4002 spin_lock_bh(&ar->data_lock);
4003 if (ar->scan.state != ATH10K_SCAN_IDLE)
4004 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004005 spin_unlock_bh(&ar->data_lock);
4006
4007 return ret;
4008}
4009
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004010static void ath10k_scan_abort(struct ath10k *ar)
4011{
4012 int ret;
4013
4014 lockdep_assert_held(&ar->conf_mutex);
4015
4016 spin_lock_bh(&ar->data_lock);
4017
4018 switch (ar->scan.state) {
4019 case ATH10K_SCAN_IDLE:
4020 /* This can happen if timeout worker kicked in and called
4021 * abortion while scan completion was being processed.
4022 */
4023 break;
4024 case ATH10K_SCAN_STARTING:
4025 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02004026 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004027 ath10k_scan_state_str(ar->scan.state),
4028 ar->scan.state);
4029 break;
4030 case ATH10K_SCAN_RUNNING:
4031 ar->scan.state = ATH10K_SCAN_ABORTING;
4032 spin_unlock_bh(&ar->data_lock);
4033
4034 ret = ath10k_scan_stop(ar);
4035 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004036 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004037
4038 spin_lock_bh(&ar->data_lock);
4039 break;
4040 }
4041
4042 spin_unlock_bh(&ar->data_lock);
4043}
4044
4045void ath10k_scan_timeout_work(struct work_struct *work)
4046{
4047 struct ath10k *ar = container_of(work, struct ath10k,
4048 scan.timeout.work);
4049
4050 mutex_lock(&ar->conf_mutex);
4051 ath10k_scan_abort(ar);
4052 mutex_unlock(&ar->conf_mutex);
4053}
4054
Kalle Valo5e3dd152013-06-12 20:52:10 +03004055static int ath10k_start_scan(struct ath10k *ar,
4056 const struct wmi_start_scan_arg *arg)
4057{
4058 int ret;
4059
4060 lockdep_assert_held(&ar->conf_mutex);
4061
4062 ret = ath10k_wmi_start_scan(ar, arg);
4063 if (ret)
4064 return ret;
4065
Kalle Valo14e105c2016-04-13 14:13:21 +03004066 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004067 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004068 ret = ath10k_scan_stop(ar);
4069 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004070 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004071
4072 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004073 }
4074
Ben Greear2f9eec02015-02-15 16:50:38 +02004075 /* If we failed to start the scan, return error code at
4076 * this point. This is probably due to some issue in the
4077 * firmware, but no need to wedge the driver due to that...
4078 */
4079 spin_lock_bh(&ar->data_lock);
4080 if (ar->scan.state == ATH10K_SCAN_IDLE) {
4081 spin_unlock_bh(&ar->data_lock);
4082 return -EINVAL;
4083 }
4084 spin_unlock_bh(&ar->data_lock);
4085
Kalle Valo5e3dd152013-06-12 20:52:10 +03004086 return 0;
4087}
4088
4089/**********************/
4090/* mac80211 callbacks */
4091/**********************/
4092
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004093static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4094 struct ieee80211_tx_control *control,
4095 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004096{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004097 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02004098 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03004099 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4100 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004101 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02004102 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02004103 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01004104 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02004105 enum ath10k_mac_tx_path txpath;
4106 bool is_htt;
4107 bool is_mgmt;
4108 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004109 int ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004110
Michal Kaziordd4717b2016-03-06 16:14:39 +02004111 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004112
Michal Kazior8a933962015-11-18 06:59:17 +01004113 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004114 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
4115 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
4116 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304117 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004118
Michal Kazior6421969f2016-03-06 16:14:25 +02004119 if (is_htt) {
4120 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004121 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4122
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304123 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004124 if (ret) {
4125 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4126 ret);
4127 spin_unlock_bh(&ar->htt.tx_lock);
4128 ieee80211_free_txskb(ar->hw, skb);
4129 return;
4130 }
4131
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304132 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4133 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304134 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4135 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304136 ath10k_htt_tx_dec_pending(htt);
4137 spin_unlock_bh(&ar->htt.tx_lock);
4138 ieee80211_free_txskb(ar->hw, skb);
4139 return;
4140 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004141 spin_unlock_bh(&ar->htt.tx_lock);
4142 }
4143
4144 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
4145 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004146 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004147 if (is_htt) {
4148 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304149 ath10k_htt_tx_dec_pending(htt);
4150 if (is_mgmt)
4151 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004152 spin_unlock_bh(&ar->htt.tx_lock);
4153 }
4154 return;
4155 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004156}
4157
Michal Kazior29946872016-03-06 16:14:34 +02004158static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4159 struct ieee80211_txq *txq)
4160{
4161 struct ath10k *ar = hw->priv;
4162 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304163 struct ieee80211_txq *f_txq;
4164 struct ath10k_txq *f_artxq;
4165 int ret = 0;
4166 int max = 16;
Michal Kazior29946872016-03-06 16:14:34 +02004167
Michal Kazior750eeed2016-03-17 10:51:05 +01004168 spin_lock_bh(&ar->txqs_lock);
4169 if (list_empty(&artxq->list))
4170 list_add_tail(&artxq->list, &ar->txqs);
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304171
4172 f_artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
4173 f_txq = container_of((void *)f_artxq, struct ieee80211_txq, drv_priv);
4174 list_del_init(&f_artxq->list);
4175
4176 while (ath10k_mac_tx_can_push(hw, f_txq) && max--) {
4177 ret = ath10k_mac_tx_push_txq(hw, f_txq);
4178 if (ret)
4179 break;
4180 }
4181 if (ret != -ENOENT)
4182 list_add_tail(&f_artxq->list, &ar->txqs);
Michal Kazior750eeed2016-03-17 10:51:05 +01004183 spin_unlock_bh(&ar->txqs_lock);
Michal Kazior29946872016-03-06 16:14:34 +02004184
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304185 ath10k_htt_tx_txq_update(hw, f_txq);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004186 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02004187}
4188
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004189/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004190void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004191{
4192 /* make sure rcu-protected mac80211 tx path itself is drained */
4193 synchronize_net();
4194
4195 ath10k_offchan_tx_purge(ar);
4196 ath10k_mgmt_over_wmi_tx_purge(ar);
4197
4198 cancel_work_sync(&ar->offchan_tx_work);
4199 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4200}
4201
Michal Kazioraffd3212013-07-16 09:54:35 +02004202void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004203{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004204 struct ath10k_vif *arvif;
4205
Michal Kazior818bdd12013-07-16 09:38:57 +02004206 lockdep_assert_held(&ar->conf_mutex);
4207
Michal Kazior19337472014-08-28 12:58:16 +02004208 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4209 ar->filter_flags = 0;
4210 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004211 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004212
4213 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004214 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004215
4216 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004217 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004218
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004219 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004220 ath10k_peer_cleanup_all(ar);
4221 ath10k_core_stop(ar);
4222 ath10k_hif_power_down(ar);
4223
4224 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004225 list_for_each_entry(arvif, &ar->arvifs, list)
4226 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004227 spin_unlock_bh(&ar->data_lock);
4228}
4229
Ben Greear46acf7b2014-05-16 17:15:38 +03004230static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4231{
4232 struct ath10k *ar = hw->priv;
4233
4234 mutex_lock(&ar->conf_mutex);
4235
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304236 *tx_ant = ar->cfg_tx_chainmask;
4237 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03004238
4239 mutex_unlock(&ar->conf_mutex);
4240
4241 return 0;
4242}
4243
Ben Greear5572a952014-11-24 16:22:10 +02004244static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4245{
4246 /* It is not clear that allowing gaps in chainmask
4247 * is helpful. Probably it will not do what user
4248 * is hoping for, so warn in that case.
4249 */
4250 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4251 return;
4252
4253 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4254 dbg, cm);
4255}
4256
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304257static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4258{
4259 int nsts = ar->vht_cap_info;
4260
4261 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4262 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4263
4264 /* If firmware does not deliver to host number of space-time
4265 * streams supported, assume it support up to 4 BF STS and return
4266 * the value for VHT CAP: nsts-1)
4267 */
4268 if (nsts == 0)
4269 return 3;
4270
4271 return nsts;
4272}
4273
4274static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4275{
4276 int sound_dim = ar->vht_cap_info;
4277
4278 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4279 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4280
4281 /* If the sounding dimension is not advertised by the firmware,
4282 * let's use a default value of 1
4283 */
4284 if (sound_dim == 0)
4285 return 1;
4286
4287 return sound_dim;
4288}
4289
4290static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4291{
4292 struct ieee80211_sta_vht_cap vht_cap = {0};
4293 u16 mcs_map;
4294 u32 val;
4295 int i;
4296
4297 vht_cap.vht_supported = 1;
4298 vht_cap.cap = ar->vht_cap_info;
4299
4300 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4301 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4302 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4303 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4304 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4305
4306 vht_cap.cap |= val;
4307 }
4308
4309 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4310 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4311 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4312 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4313 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4314
4315 vht_cap.cap |= val;
4316 }
4317
4318 mcs_map = 0;
4319 for (i = 0; i < 8; i++) {
4320 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4321 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4322 else
4323 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4324 }
4325
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004326 if (ar->cfg_tx_chainmask <= 1)
4327 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4328
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304329 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4330 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4331
4332 return vht_cap;
4333}
4334
4335static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4336{
4337 int i;
4338 struct ieee80211_sta_ht_cap ht_cap = {0};
4339
4340 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4341 return ht_cap;
4342
4343 ht_cap.ht_supported = 1;
4344 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4345 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4346 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4347 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004348 ht_cap.cap |=
4349 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304350
4351 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4352 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4353
4354 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4355 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4356
4357 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4358 u32 smps;
4359
4360 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4361 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4362
4363 ht_cap.cap |= smps;
4364 }
4365
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004366 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304367 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4368
4369 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4370 u32 stbc;
4371
4372 stbc = ar->ht_cap_info;
4373 stbc &= WMI_HT_CAP_RX_STBC;
4374 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4375 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4376 stbc &= IEEE80211_HT_CAP_RX_STBC;
4377
4378 ht_cap.cap |= stbc;
4379 }
4380
4381 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
4382 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4383
4384 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4385 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4386
4387 /* max AMSDU is implicitly taken from vht_cap_info */
4388 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4389 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4390
4391 for (i = 0; i < ar->num_rf_chains; i++) {
4392 if (ar->cfg_rx_chainmask & BIT(i))
4393 ht_cap.mcs.rx_mask[i] = 0xFF;
4394 }
4395
4396 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4397
4398 return ht_cap;
4399}
4400
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304401static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4402{
4403 struct ieee80211_supported_band *band;
4404 struct ieee80211_sta_vht_cap vht_cap;
4405 struct ieee80211_sta_ht_cap ht_cap;
4406
4407 ht_cap = ath10k_get_ht_cap(ar);
4408 vht_cap = ath10k_create_vht_cap(ar);
4409
4410 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004411 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304412 band->ht_cap = ht_cap;
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304413 }
4414 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004415 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304416 band->ht_cap = ht_cap;
4417 band->vht_cap = vht_cap;
4418 }
4419}
4420
Ben Greear46acf7b2014-05-16 17:15:38 +03004421static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4422{
4423 int ret;
4424
4425 lockdep_assert_held(&ar->conf_mutex);
4426
Ben Greear5572a952014-11-24 16:22:10 +02004427 ath10k_check_chain_mask(ar, tx_ant, "tx");
4428 ath10k_check_chain_mask(ar, rx_ant, "rx");
4429
Ben Greear46acf7b2014-05-16 17:15:38 +03004430 ar->cfg_tx_chainmask = tx_ant;
4431 ar->cfg_rx_chainmask = rx_ant;
4432
4433 if ((ar->state != ATH10K_STATE_ON) &&
4434 (ar->state != ATH10K_STATE_RESTARTED))
4435 return 0;
4436
4437 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4438 tx_ant);
4439 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004440 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004441 ret, tx_ant);
4442 return ret;
4443 }
4444
4445 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4446 rx_ant);
4447 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004448 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004449 ret, rx_ant);
4450 return ret;
4451 }
4452
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304453 /* Reload HT/VHT capability */
4454 ath10k_mac_setup_ht_vht_cap(ar);
4455
Ben Greear46acf7b2014-05-16 17:15:38 +03004456 return 0;
4457}
4458
4459static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4460{
4461 struct ath10k *ar = hw->priv;
4462 int ret;
4463
4464 mutex_lock(&ar->conf_mutex);
4465 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4466 mutex_unlock(&ar->conf_mutex);
4467 return ret;
4468}
4469
Kalle Valo5e3dd152013-06-12 20:52:10 +03004470static int ath10k_start(struct ieee80211_hw *hw)
4471{
4472 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304473 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004474 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004475
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004476 /*
4477 * This makes sense only when restarting hw. It is harmless to call
Mohammed Shafi Shajakhan6dfdbfc2016-04-26 14:41:36 +03004478 * unconditionally. This is necessary to make sure no HTT/WMI tx
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004479 * commands will be submitted while restarting.
4480 */
4481 ath10k_drain_tx(ar);
4482
Michal Kazior548db542013-07-05 16:15:15 +03004483 mutex_lock(&ar->conf_mutex);
4484
Michal Kaziorc5058f52014-05-26 12:46:03 +03004485 switch (ar->state) {
4486 case ATH10K_STATE_OFF:
4487 ar->state = ATH10K_STATE_ON;
4488 break;
4489 case ATH10K_STATE_RESTARTING:
Michal Kaziorc5058f52014-05-26 12:46:03 +03004490 ar->state = ATH10K_STATE_RESTARTED;
4491 break;
4492 case ATH10K_STATE_ON:
4493 case ATH10K_STATE_RESTARTED:
4494 case ATH10K_STATE_WEDGED:
4495 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004496 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004497 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004498 case ATH10K_STATE_UTF:
4499 ret = -EBUSY;
4500 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004501 }
4502
4503 ret = ath10k_hif_power_up(ar);
4504 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004505 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004506 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004507 }
4508
Kalle Valo7ebf7212016-04-20 19:44:51 +03004509 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
4510 &ar->normal_mode_fw);
Michal Kazior818bdd12013-07-16 09:38:57 +02004511 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004512 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004513 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004514 }
4515
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304516 param = ar->wmi.pdev_param->pmf_qos;
4517 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004518 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004519 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004520 goto err_core_stop;
4521 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004522
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304523 param = ar->wmi.pdev_param->dynamic_bw;
4524 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004525 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004526 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004527 goto err_core_stop;
4528 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004529
Michal Kaziorcf327842015-03-31 10:26:25 +00004530 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4531 ret = ath10k_wmi_adaptive_qcs(ar, true);
4532 if (ret) {
4533 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4534 ret);
4535 goto err_core_stop;
4536 }
4537 }
4538
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004539 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304540 param = ar->wmi.pdev_param->burst_enable;
4541 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004542 if (ret) {
4543 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4544 goto err_core_stop;
4545 }
4546 }
4547
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304548 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7b2014-05-16 17:15:38 +03004549
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004550 /*
4551 * By default FW set ARP frames ac to voice (6). In that case ARP
4552 * exchange is not working properly for UAPSD enabled AP. ARP requests
4553 * which arrives with access category 0 are processed by network stack
4554 * and send back with access category 0, but FW changes access category
4555 * to 6. Set ARP frames access category to best effort (0) solves
4556 * this problem.
4557 */
4558
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304559 param = ar->wmi.pdev_param->arp_ac_override;
4560 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004561 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004562 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004563 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004564 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004565 }
4566
Maharaja62f77f02015-10-21 11:49:18 +03004567 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
Kalle Valoc4cdf752016-04-20 19:45:18 +03004568 ar->running_fw->fw_file.fw_features)) {
Maharaja62f77f02015-10-21 11:49:18 +03004569 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4570 WMI_CCA_DETECT_LEVEL_AUTO,
4571 WMI_CCA_DETECT_MARGIN_AUTO);
4572 if (ret) {
4573 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4574 ret);
4575 goto err_core_stop;
4576 }
4577 }
4578
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304579 param = ar->wmi.pdev_param->ani_enable;
4580 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304581 if (ret) {
4582 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4583 ret);
4584 goto err_core_stop;
4585 }
4586
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304587 ar->ani_enabled = true;
4588
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304589 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304590 param = ar->wmi.pdev_param->peer_stats_update_period;
4591 ret = ath10k_wmi_pdev_set_param(ar, param,
4592 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4593 if (ret) {
4594 ath10k_warn(ar,
4595 "failed to set peer stats period : %d\n",
4596 ret);
4597 goto err_core_stop;
4598 }
4599 }
4600
Rajkumar Manoharan39136242016-05-27 20:15:59 +05304601 param = ar->wmi.pdev_param->enable_btcoex;
4602 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
4603 test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
4604 ar->running_fw->fw_file.fw_features)) {
4605 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4606 if (ret) {
4607 ath10k_warn(ar,
4608 "failed to set btcoex param: %d\n", ret);
4609 goto err_core_stop;
4610 }
4611 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
4612 }
4613
Michal Kaziord6500972014-04-08 09:56:09 +03004614 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004615 ath10k_regd_update(ar);
4616
Simon Wunderlich855aed12014-08-02 09:12:54 +03004617 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304618 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004619
Michal Kaziorae254432014-05-26 12:46:02 +03004620 mutex_unlock(&ar->conf_mutex);
4621 return 0;
4622
4623err_core_stop:
4624 ath10k_core_stop(ar);
4625
4626err_power_down:
4627 ath10k_hif_power_down(ar);
4628
4629err_off:
4630 ar->state = ATH10K_STATE_OFF;
4631
4632err:
Michal Kazior548db542013-07-05 16:15:15 +03004633 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004634 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004635}
4636
4637static void ath10k_stop(struct ieee80211_hw *hw)
4638{
4639 struct ath10k *ar = hw->priv;
4640
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004641 ath10k_drain_tx(ar);
4642
Michal Kazior548db542013-07-05 16:15:15 +03004643 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004644 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004645 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004646 ar->state = ATH10K_STATE_OFF;
4647 }
Michal Kazior548db542013-07-05 16:15:15 +03004648 mutex_unlock(&ar->conf_mutex);
4649
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004650 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004651 cancel_work_sync(&ar->restart_work);
4652}
4653
Michal Kaziorad088bf2013-10-16 15:44:46 +03004654static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004655{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004656 struct ath10k_vif *arvif;
4657 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004658
4659 lockdep_assert_held(&ar->conf_mutex);
4660
Michal Kaziorad088bf2013-10-16 15:44:46 +03004661 list_for_each_entry(arvif, &ar->arvifs, list) {
4662 ret = ath10k_mac_vif_setup_ps(arvif);
4663 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004664 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004665 break;
4666 }
4667 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004668
Michal Kaziorad088bf2013-10-16 15:44:46 +03004669 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004670}
4671
Michal Kazior7d9d5582014-10-21 10:40:15 +03004672static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4673{
4674 int ret;
4675 u32 param;
4676
4677 lockdep_assert_held(&ar->conf_mutex);
4678
4679 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4680
4681 param = ar->wmi.pdev_param->txpower_limit2g;
4682 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4683 if (ret) {
4684 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4685 txpower, ret);
4686 return ret;
4687 }
4688
4689 param = ar->wmi.pdev_param->txpower_limit5g;
4690 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4691 if (ret) {
4692 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4693 txpower, ret);
4694 return ret;
4695 }
4696
4697 return 0;
4698}
4699
4700static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4701{
4702 struct ath10k_vif *arvif;
4703 int ret, txpower = -1;
4704
4705 lockdep_assert_held(&ar->conf_mutex);
4706
4707 list_for_each_entry(arvif, &ar->arvifs, list) {
Ryan Hsu77bc3e92016-12-13 14:55:19 -08004708 if (arvif->txpower <= 0)
4709 continue;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004710
4711 if (txpower == -1)
4712 txpower = arvif->txpower;
4713 else
4714 txpower = min(txpower, arvif->txpower);
4715 }
4716
Ryan Hsu77bc3e92016-12-13 14:55:19 -08004717 if (txpower == -1)
4718 return 0;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004719
4720 ret = ath10k_mac_txpower_setup(ar, txpower);
4721 if (ret) {
4722 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4723 txpower, ret);
4724 return ret;
4725 }
4726
4727 return 0;
4728}
4729
Kalle Valo5e3dd152013-06-12 20:52:10 +03004730static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4731{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004732 struct ath10k *ar = hw->priv;
4733 struct ieee80211_conf *conf = &hw->conf;
4734 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004735
4736 mutex_lock(&ar->conf_mutex);
4737
Michal Kazioraffd3212013-07-16 09:54:35 +02004738 if (changed & IEEE80211_CONF_CHANGE_PS)
4739 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004740
4741 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004742 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4743 ret = ath10k_monitor_recalc(ar);
4744 if (ret)
4745 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004746 }
4747
4748 mutex_unlock(&ar->conf_mutex);
4749 return ret;
4750}
4751
Ben Greear5572a952014-11-24 16:22:10 +02004752static u32 get_nss_from_chainmask(u16 chain_mask)
4753{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05304754 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02004755 return 4;
4756 else if ((chain_mask & 0x7) == 0x7)
4757 return 3;
4758 else if ((chain_mask & 0x3) == 0x3)
4759 return 2;
4760 return 1;
4761}
4762
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304763static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4764{
4765 u32 value = 0;
4766 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004767 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004768 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304769
4770 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4771 return 0;
4772
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004773 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304774 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4775 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004776 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304777
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004778 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304779 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4780 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004781 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304782
4783 if (!value)
4784 return 0;
4785
4786 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4787 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4788
4789 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4790 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4791 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4792
4793 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4794 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4795
4796 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4797 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4798 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4799
4800 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4801 ar->wmi.vdev_param->txbf, value);
4802}
4803
Kalle Valo5e3dd152013-06-12 20:52:10 +03004804/*
4805 * TODO:
4806 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4807 * because we will send mgmt frames without CCK. This requirement
4808 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4809 * in the TX packet.
4810 */
4811static int ath10k_add_interface(struct ieee80211_hw *hw,
4812 struct ieee80211_vif *vif)
4813{
4814 struct ath10k *ar = hw->priv;
4815 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004816 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004817 enum wmi_sta_powersave_param param;
4818 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004819 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004820 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004821 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004822 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004823
Johannes Berg848955c2014-11-11 12:48:42 +01004824 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4825
Kalle Valo5e3dd152013-06-12 20:52:10 +03004826 mutex_lock(&ar->conf_mutex);
4827
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004828 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02004829 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004830
Kalle Valo5e3dd152013-06-12 20:52:10 +03004831 arvif->ar = ar;
4832 arvif->vif = vif;
4833
Ben Greeare63b33f2013-10-22 14:54:14 -07004834 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004835 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004836 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4837 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004838
Michal Kazior45c9abc2015-04-21 20:42:58 +03004839 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4840 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4841 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4842 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4843 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4844 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4845 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004846
Michal Kaziore04cafb2015-08-05 12:15:24 +02004847 if (ar->num_peers >= ar->max_num_peers) {
4848 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004849 ret = -ENOBUFS;
4850 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004851 }
4852
Ben Greeara9aefb32014-08-12 11:02:19 +03004853 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004854 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004855 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03004856 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004857 }
Ben Greear16c11172014-09-23 14:17:16 -07004858 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004859
Ben Greear16c11172014-09-23 14:17:16 -07004860 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4861 bit, ar->free_vdev_map);
4862
4863 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004864 arvif->vdev_subtype =
4865 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004866
Kalle Valo5e3dd152013-06-12 20:52:10 +03004867 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004868 case NL80211_IFTYPE_P2P_DEVICE:
4869 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004870 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4871 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01004872 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004873 case NL80211_IFTYPE_UNSPECIFIED:
4874 case NL80211_IFTYPE_STATION:
4875 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4876 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004877 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4878 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004879 break;
4880 case NL80211_IFTYPE_ADHOC:
4881 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4882 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004883 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08004884 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08004885 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4886 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08004887 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004888 ret = -EINVAL;
4889 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
4890 goto err;
4891 }
4892 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4893 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004894 case NL80211_IFTYPE_AP:
4895 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4896
4897 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004898 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4899 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004900 break;
4901 case NL80211_IFTYPE_MONITOR:
4902 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4903 break;
4904 default:
4905 WARN_ON(1);
4906 break;
4907 }
4908
Michal Kazior96d828d2015-03-31 10:26:23 +00004909 /* Using vdev_id as queue number will make it very easy to do per-vif
4910 * tx queue locking. This shouldn't wrap due to interface combinations
4911 * but do a modulo for correctness sake and prevent using offchannel tx
4912 * queues for regular vif tx.
4913 */
4914 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4915 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4916 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4917
Michal Kazior64badcb2014-09-18 11:18:02 +03004918 /* Some firmware revisions don't wait for beacon tx completion before
4919 * sending another SWBA event. This could lead to hardware using old
4920 * (freed) beacon data in some cases, e.g. tx credit starvation
4921 * combined with missed TBTT. This is very very rare.
4922 *
4923 * On non-IOMMU-enabled hosts this could be a possible security issue
4924 * because hw could beacon some random data on the air. On
4925 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4926 * device would crash.
4927 *
4928 * Since there are no beacon tx completions (implicit nor explicit)
4929 * propagated to host the only workaround for this is to allocate a
4930 * DMA-coherent buffer for a lifetime of a vif and use it for all
4931 * beacon tx commands. Worst case for this approach is some beacons may
4932 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4933 */
4934 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004935 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03004936 vif->type == NL80211_IFTYPE_AP) {
4937 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4938 IEEE80211_MAX_FRAME_LEN,
4939 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304940 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004941 if (!arvif->beacon_buf) {
4942 ret = -ENOMEM;
4943 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4944 ret);
4945 goto err;
4946 }
4947 }
David Liuccec9032015-07-24 20:25:32 +03004948 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
4949 arvif->nohwcrypt = true;
4950
4951 if (arvif->nohwcrypt &&
4952 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4953 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
4954 goto err;
4955 }
Michal Kazior64badcb2014-09-18 11:18:02 +03004956
4957 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4958 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4959 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004960
4961 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4962 arvif->vdev_subtype, vif->addr);
4963 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004964 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004965 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004966 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004967 }
4968
Ben Greear16c11172014-09-23 14:17:16 -07004969 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05304970 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03004971 list_add(&arvif->list, &ar->arvifs);
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05304972 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004973
Michal Kazior46725b12015-01-28 09:57:49 +02004974 /* It makes no sense to have firmware do keepalives. mac80211 already
4975 * takes care of this with idle connection polling.
4976 */
4977 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004978 if (ret) {
Michal Kazior46725b12015-01-28 09:57:49 +02004979 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004980 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004981 goto err_vdev_delete;
4982 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004983
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004984 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004985
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004986 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4987 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004988 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004989 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03004990 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004991 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004992 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004993 goto err_vdev_delete;
4994 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004995
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05304996 /* Configuring number of spatial stream for monitor interface is causing
4997 * target assert in qca9888 and qca6174.
4998 */
4999 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02005000 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
5001
5002 vdev_param = ar->wmi.vdev_param->nss;
5003 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5004 nss);
5005 if (ret) {
5006 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
5007 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
5008 ret);
5009 goto err_vdev_delete;
5010 }
5011 }
5012
Michal Kaziore57e0572015-03-24 13:14:03 +00005013 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5014 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02005015 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
5016 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005017 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00005018 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005019 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005020 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005021 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005022
5023 spin_lock_bh(&ar->data_lock);
5024
5025 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
5026 if (!peer) {
5027 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5028 vif->addr, arvif->vdev_id);
5029 spin_unlock_bh(&ar->data_lock);
5030 ret = -ENOENT;
5031 goto err_peer_delete;
5032 }
5033
5034 arvif->peer_id = find_first_bit(peer->peer_ids,
5035 ATH10K_MAX_NUM_PEER_IDS);
5036
5037 spin_unlock_bh(&ar->data_lock);
5038 } else {
5039 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00005040 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01005041
Michal Kaziore57e0572015-03-24 13:14:03 +00005042 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02005043 ret = ath10k_mac_set_kickout(arvif);
5044 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005045 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005046 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02005047 goto err_peer_delete;
5048 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005049 }
5050
5051 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
5052 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
5053 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5054 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5055 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005056 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005057 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005058 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005059 goto err_peer_delete;
5060 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005061
Michal Kazior9f9b5742014-12-12 12:41:36 +01005062 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005063 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005064 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005065 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005066 goto err_peer_delete;
5067 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005068
Michal Kazior9f9b5742014-12-12 12:41:36 +01005069 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005070 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005071 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005072 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005073 goto err_peer_delete;
5074 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005075 }
5076
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305077 ret = ath10k_mac_set_txbf_conf(arvif);
5078 if (ret) {
5079 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
5080 arvif->vdev_id, ret);
5081 goto err_peer_delete;
5082 }
5083
Michal Kazior424121c2013-07-22 14:13:31 +02005084 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005085 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005086 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03005087 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005088 goto err_peer_delete;
5089 }
Michal Kazior679c54a2013-07-05 16:15:04 +03005090
Michal Kazior7d9d5582014-10-21 10:40:15 +03005091 arvif->txpower = vif->bss_conf.txpower;
5092 ret = ath10k_mac_txpower_recalc(ar);
5093 if (ret) {
5094 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5095 goto err_peer_delete;
5096 }
5097
Michal Kazior500ff9f2015-03-31 10:26:21 +00005098 if (vif->type == NL80211_IFTYPE_MONITOR) {
5099 ar->monitor_arvif = arvif;
5100 ret = ath10k_monitor_recalc(ar);
5101 if (ret) {
5102 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5103 goto err_peer_delete;
5104 }
5105 }
5106
Michal Kazior6d2d51e2015-08-07 09:08:21 +02005107 spin_lock_bh(&ar->htt.tx_lock);
5108 if (!ar->tx_paused)
5109 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
5110 spin_unlock_bh(&ar->htt.tx_lock);
5111
Kalle Valo5e3dd152013-06-12 20:52:10 +03005112 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005113 return 0;
5114
5115err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00005116 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5117 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14a2013-10-16 15:44:45 +03005118 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
5119
5120err_vdev_delete:
5121 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07005122 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05305123 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005124 list_del(&arvif->list);
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05305125 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005126
5127err:
Michal Kazior64badcb2014-09-18 11:18:02 +03005128 if (arvif->beacon_buf) {
5129 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
5130 arvif->beacon_buf, arvif->beacon_paddr);
5131 arvif->beacon_buf = NULL;
5132 }
5133
Michal Kazior9dad14a2013-10-16 15:44:45 +03005134 mutex_unlock(&ar->conf_mutex);
5135
Kalle Valo5e3dd152013-06-12 20:52:10 +03005136 return ret;
5137}
5138
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005139static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
5140{
5141 int i;
5142
5143 for (i = 0; i < BITS_PER_LONG; i++)
5144 ath10k_mac_vif_tx_unlock(arvif, i);
5145}
5146
Kalle Valo5e3dd152013-06-12 20:52:10 +03005147static void ath10k_remove_interface(struct ieee80211_hw *hw,
5148 struct ieee80211_vif *vif)
5149{
5150 struct ath10k *ar = hw->priv;
5151 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior69427262016-03-06 16:14:30 +02005152 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005153 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005154 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005155
Michal Kazior81a9a172015-03-05 16:02:17 +02005156 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005157 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005158
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305159 mutex_lock(&ar->conf_mutex);
5160
Michal Kaziored543882013-09-13 14:16:56 +02005161 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03005162 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02005163 spin_unlock_bh(&ar->data_lock);
5164
Simon Wunderlich855aed12014-08-02 09:12:54 +03005165 ret = ath10k_spectral_vif_stop(arvif);
5166 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005167 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005168 arvif->vdev_id, ret);
5169
Ben Greear16c11172014-09-23 14:17:16 -07005170 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05305171 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005172 list_del(&arvif->list);
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05305173 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005174
Michal Kaziore57e0572015-03-24 13:14:03 +00005175 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5176 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005177 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5178 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005179 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005180 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005181 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005182
5183 kfree(arvif->u.ap.noa_data);
5184 }
5185
Michal Kazior7aa7a722014-08-25 12:09:38 +02005186 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005187 arvif->vdev_id);
5188
Kalle Valo5e3dd152013-06-12 20:52:10 +03005189 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5190 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005191 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005192 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005193
Michal Kazior2c512052015-02-15 16:50:40 +02005194 /* Some firmware revisions don't notify host about self-peer removal
5195 * until after associated vdev is deleted.
5196 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005197 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5198 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005199 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5200 vif->addr);
5201 if (ret)
5202 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5203 arvif->vdev_id, ret);
5204
5205 spin_lock_bh(&ar->data_lock);
5206 ar->num_peers--;
5207 spin_unlock_bh(&ar->data_lock);
5208 }
5209
Michal Kazior69427262016-03-06 16:14:30 +02005210 spin_lock_bh(&ar->data_lock);
5211 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5212 peer = ar->peer_map[i];
5213 if (!peer)
5214 continue;
5215
5216 if (peer->vif == vif) {
5217 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5218 vif->addr, arvif->vdev_id);
5219 peer->vif = NULL;
5220 }
5221 }
5222 spin_unlock_bh(&ar->data_lock);
5223
Kalle Valo5e3dd152013-06-12 20:52:10 +03005224 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005225 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005226
Michal Kazior500ff9f2015-03-31 10:26:21 +00005227 if (vif->type == NL80211_IFTYPE_MONITOR) {
5228 ar->monitor_arvif = NULL;
5229 ret = ath10k_monitor_recalc(ar);
5230 if (ret)
5231 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5232 }
5233
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005234 spin_lock_bh(&ar->htt.tx_lock);
5235 ath10k_mac_vif_tx_unlock_all(arvif);
5236 spin_unlock_bh(&ar->htt.tx_lock);
5237
Michal Kazior29946872016-03-06 16:14:34 +02005238 ath10k_mac_txq_unref(ar, vif->txq);
5239
Kalle Valo5e3dd152013-06-12 20:52:10 +03005240 mutex_unlock(&ar->conf_mutex);
5241}
5242
5243/*
5244 * FIXME: Has to be verified.
5245 */
5246#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005247 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005248 FIF_CONTROL | \
5249 FIF_PSPOLL | \
5250 FIF_OTHER_BSS | \
5251 FIF_BCN_PRBRESP_PROMISC | \
5252 FIF_PROBE_REQ | \
5253 FIF_FCSFAIL)
5254
5255static void ath10k_configure_filter(struct ieee80211_hw *hw,
5256 unsigned int changed_flags,
5257 unsigned int *total_flags,
5258 u64 multicast)
5259{
5260 struct ath10k *ar = hw->priv;
5261 int ret;
5262
5263 mutex_lock(&ar->conf_mutex);
5264
5265 changed_flags &= SUPPORTED_FILTERS;
5266 *total_flags &= SUPPORTED_FILTERS;
5267 ar->filter_flags = *total_flags;
5268
Michal Kazior19337472014-08-28 12:58:16 +02005269 ret = ath10k_monitor_recalc(ar);
5270 if (ret)
Colin Ian King7f03d302016-08-26 19:08:52 +01005271 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005272
5273 mutex_unlock(&ar->conf_mutex);
5274}
5275
5276static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5277 struct ieee80211_vif *vif,
5278 struct ieee80211_bss_conf *info,
5279 u32 changed)
5280{
5281 struct ath10k *ar = hw->priv;
5282 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5283 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03005284 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005285
5286 mutex_lock(&ar->conf_mutex);
5287
5288 if (changed & BSS_CHANGED_IBSS)
5289 ath10k_control_ibss(arvif, info, vif->addr);
5290
5291 if (changed & BSS_CHANGED_BEACON_INT) {
5292 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005293 vdev_param = ar->wmi.vdev_param->beacon_interval;
5294 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005295 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005296 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005297 "mac vdev %d beacon_interval %d\n",
5298 arvif->vdev_id, arvif->beacon_interval);
5299
Kalle Valo5e3dd152013-06-12 20:52:10 +03005300 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005301 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005302 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005303 }
5304
5305 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005306 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005307 "vdev %d set beacon tx mode to staggered\n",
5308 arvif->vdev_id);
5309
Bartosz Markowski226a3392013-09-26 17:47:16 +02005310 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5311 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005312 WMI_BEACON_STAGGERED_MODE);
5313 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005314 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005315 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005316
5317 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5318 if (ret)
5319 ath10k_warn(ar, "failed to update beacon template: %d\n",
5320 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005321
5322 if (ieee80211_vif_is_mesh(vif)) {
5323 /* mesh doesn't use SSID but firmware needs it */
5324 strncpy(arvif->u.ap.ssid, "mesh",
5325 sizeof(arvif->u.ap.ssid));
5326 arvif->u.ap.ssid_len = 4;
5327 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005328 }
5329
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005330 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5331 ret = ath10k_mac_setup_prb_tmpl(arvif);
5332 if (ret)
5333 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5334 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005335 }
5336
Michal Kaziorba2479f2015-01-24 12:14:51 +02005337 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005338 arvif->dtim_period = info->dtim_period;
5339
Michal Kazior7aa7a722014-08-25 12:09:38 +02005340 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005341 "mac vdev %d dtim_period %d\n",
5342 arvif->vdev_id, arvif->dtim_period);
5343
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005344 vdev_param = ar->wmi.vdev_param->dtim_period;
5345 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005346 arvif->dtim_period);
5347 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005348 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005349 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005350 }
5351
5352 if (changed & BSS_CHANGED_SSID &&
5353 vif->type == NL80211_IFTYPE_AP) {
5354 arvif->u.ap.ssid_len = info->ssid_len;
5355 if (info->ssid_len)
5356 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5357 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5358 }
5359
Michal Kazior077efc82014-10-21 10:10:29 +03005360 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5361 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005362
5363 if (changed & BSS_CHANGED_BEACON_ENABLED)
5364 ath10k_control_beaconing(arvif, info);
5365
5366 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005367 arvif->use_cts_prot = info->use_cts_prot;
Kalle Valo60c3daa2013-09-08 17:56:07 +03005368
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005369 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005370 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005371 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005372 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005373
Bartosz Markowski83e48fc2016-12-15 11:23:24 +02005374 if (ath10k_mac_can_set_cts_prot(arvif)) {
5375 ret = ath10k_mac_set_cts_prot(arvif);
5376 if (ret)
5377 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
5378 arvif->vdev_id, ret);
5379 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005380 }
5381
5382 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005383 if (info->use_short_slot)
5384 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5385
5386 else
5387 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5388
Michal Kazior7aa7a722014-08-25 12:09:38 +02005389 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005390 arvif->vdev_id, slottime);
5391
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005392 vdev_param = ar->wmi.vdev_param->slot_time;
5393 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005394 slottime);
5395 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005396 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005397 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005398 }
5399
5400 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005401 if (info->use_short_preamble)
5402 preamble = WMI_VDEV_PREAMBLE_SHORT;
5403 else
5404 preamble = WMI_VDEV_PREAMBLE_LONG;
5405
Michal Kazior7aa7a722014-08-25 12:09:38 +02005406 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005407 "mac vdev %d preamble %dn",
5408 arvif->vdev_id, preamble);
5409
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005410 vdev_param = ar->wmi.vdev_param->preamble;
5411 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005412 preamble);
5413 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005414 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005415 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005416 }
5417
5418 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005419 if (info->assoc) {
5420 /* Workaround: Make sure monitor vdev is not running
5421 * when associating to prevent some firmware revisions
5422 * (e.g. 10.1 and 10.2) from crashing.
5423 */
5424 if (ar->monitor_started)
5425 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005426 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005427 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005428 } else {
5429 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005430 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005431 }
5432
Michal Kazior7d9d5582014-10-21 10:40:15 +03005433 if (changed & BSS_CHANGED_TXPOWER) {
5434 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5435 arvif->vdev_id, info->txpower);
5436
5437 arvif->txpower = info->txpower;
5438 ret = ath10k_mac_txpower_recalc(ar);
5439 if (ret)
5440 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5441 }
5442
Michal Kaziorbf14e652014-12-12 12:41:38 +01005443 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005444 arvif->ps = vif->bss_conf.ps;
5445
5446 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005447 if (ret)
5448 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5449 arvif->vdev_id, ret);
5450 }
5451
Kalle Valo5e3dd152013-06-12 20:52:10 +03005452 mutex_unlock(&ar->conf_mutex);
5453}
5454
5455static int ath10k_hw_scan(struct ieee80211_hw *hw,
5456 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005457 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005458{
5459 struct ath10k *ar = hw->priv;
5460 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02005461 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005462 struct wmi_start_scan_arg arg;
5463 int ret = 0;
5464 int i;
5465
5466 mutex_lock(&ar->conf_mutex);
5467
5468 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005469 switch (ar->scan.state) {
5470 case ATH10K_SCAN_IDLE:
5471 reinit_completion(&ar->scan.started);
5472 reinit_completion(&ar->scan.completed);
5473 ar->scan.state = ATH10K_SCAN_STARTING;
5474 ar->scan.is_roc = false;
5475 ar->scan.vdev_id = arvif->vdev_id;
5476 ret = 0;
5477 break;
5478 case ATH10K_SCAN_STARTING:
5479 case ATH10K_SCAN_RUNNING:
5480 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005481 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005482 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005483 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005484 spin_unlock_bh(&ar->data_lock);
5485
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005486 if (ret)
5487 goto exit;
5488
Kalle Valo5e3dd152013-06-12 20:52:10 +03005489 memset(&arg, 0, sizeof(arg));
5490 ath10k_wmi_start_scan_init(ar, &arg);
5491 arg.vdev_id = arvif->vdev_id;
5492 arg.scan_id = ATH10K_SCAN_ID;
5493
Kalle Valo5e3dd152013-06-12 20:52:10 +03005494 if (req->ie_len) {
5495 arg.ie_len = req->ie_len;
5496 memcpy(arg.ie, req->ie, arg.ie_len);
5497 }
5498
5499 if (req->n_ssids) {
5500 arg.n_ssids = req->n_ssids;
5501 for (i = 0; i < arg.n_ssids; i++) {
5502 arg.ssids[i].len = req->ssids[i].ssid_len;
5503 arg.ssids[i].ssid = req->ssids[i].ssid;
5504 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005505 } else {
5506 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005507 }
5508
5509 if (req->n_channels) {
5510 arg.n_channels = req->n_channels;
5511 for (i = 0; i < arg.n_channels; i++)
5512 arg.channels[i] = req->channels[i]->center_freq;
5513 }
5514
5515 ret = ath10k_start_scan(ar, &arg);
5516 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005517 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005518 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005519 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005520 spin_unlock_bh(&ar->data_lock);
5521 }
5522
Michal Kazior634349b2015-09-03 10:43:45 +02005523 /* Add a 200ms margin to account for event/command processing */
5524 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5525 msecs_to_jiffies(arg.max_scan_time +
5526 200));
5527
Kalle Valo5e3dd152013-06-12 20:52:10 +03005528exit:
5529 mutex_unlock(&ar->conf_mutex);
5530 return ret;
5531}
5532
5533static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5534 struct ieee80211_vif *vif)
5535{
5536 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005537
5538 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005539 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005540 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01005541
5542 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005543}
5544
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005545static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
5546 struct ath10k_vif *arvif,
5547 enum set_key_cmd cmd,
5548 struct ieee80211_key_conf *key)
5549{
5550 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
5551 int ret;
5552
5553 /* 10.1 firmware branch requires default key index to be set to group
5554 * key index after installing it. Otherwise FW/HW Txes corrupted
5555 * frames with multi-vif APs. This is not required for main firmware
5556 * branch (e.g. 636).
5557 *
Michal Kazior8461baf2015-04-10 13:23:22 +00005558 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
5559 *
5560 * FIXME: It remains unknown if this is required for multi-vif STA
5561 * interfaces on 10.1.
5562 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005563
Michal Kazior8461baf2015-04-10 13:23:22 +00005564 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
5565 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005566 return;
5567
5568 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
5569 return;
5570
5571 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
5572 return;
5573
5574 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5575 return;
5576
5577 if (cmd != SET_KEY)
5578 return;
5579
5580 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5581 key->keyidx);
5582 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005583 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005584 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005585}
5586
Kalle Valo5e3dd152013-06-12 20:52:10 +03005587static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5588 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5589 struct ieee80211_key_conf *key)
5590{
5591 struct ath10k *ar = hw->priv;
5592 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5593 struct ath10k_peer *peer;
5594 const u8 *peer_addr;
5595 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5596 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5597 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005598 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005599 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005600 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005601
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005602 /* this one needs to be done in software */
5603 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
5604 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005605
David Liuccec9032015-07-24 20:25:32 +03005606 if (arvif->nohwcrypt)
5607 return 1;
5608
Kalle Valo5e3dd152013-06-12 20:52:10 +03005609 if (key->keyidx > WMI_MAX_KEY_INDEX)
5610 return -ENOSPC;
5611
5612 mutex_lock(&ar->conf_mutex);
5613
5614 if (sta)
5615 peer_addr = sta->addr;
5616 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5617 peer_addr = vif->bss_conf.bssid;
5618 else
5619 peer_addr = vif->addr;
5620
5621 key->hw_key_idx = key->keyidx;
5622
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005623 if (is_wep) {
5624 if (cmd == SET_KEY)
5625 arvif->wep_keys[key->keyidx] = key;
5626 else
5627 arvif->wep_keys[key->keyidx] = NULL;
5628 }
5629
Kalle Valo5e3dd152013-06-12 20:52:10 +03005630 /* the peer should not disappear in mid-way (unless FW goes awry) since
5631 * we already hold conf_mutex. we just make sure its there now. */
5632 spin_lock_bh(&ar->data_lock);
5633 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5634 spin_unlock_bh(&ar->data_lock);
5635
5636 if (!peer) {
5637 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005638 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005639 peer_addr);
5640 ret = -EOPNOTSUPP;
5641 goto exit;
5642 } else {
5643 /* if the peer doesn't exist there is no key to disable
5644 * anymore */
5645 goto exit;
5646 }
5647 }
5648
Michal Kazior7cc45732015-03-09 14:24:17 +01005649 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5650 flags |= WMI_KEY_PAIRWISE;
5651 else
5652 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005653
Kalle Valo5e3dd152013-06-12 20:52:10 +03005654 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005655 if (cmd == DISABLE_KEY)
5656 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005657
Michal Kaziorad325cb2015-02-18 14:02:27 +01005658 /* When WEP keys are uploaded it's possible that there are
5659 * stations associated already (e.g. when merging) without any
5660 * keys. Static WEP needs an explicit per-peer key upload.
5661 */
5662 if (vif->type == NL80211_IFTYPE_ADHOC &&
5663 cmd == SET_KEY)
5664 ath10k_mac_vif_update_wep_key(arvif, key);
5665
Michal Kazior370e5672015-02-18 14:02:26 +01005666 /* 802.1x never sets the def_wep_key_idx so each set_key()
5667 * call changes default tx key.
5668 *
5669 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5670 * after first set_key().
5671 */
5672 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5673 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005674 }
5675
Michal Kazior370e5672015-02-18 14:02:26 +01005676 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005677 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005678 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005679 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005680 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005681 goto exit;
5682 }
5683
Michal Kazior29a10002015-04-10 13:05:58 +00005684 /* mac80211 sets static WEP keys as groupwise while firmware requires
5685 * them to be installed twice as both pairwise and groupwise.
5686 */
5687 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5688 flags2 = flags;
5689 flags2 &= ~WMI_KEY_GROUP;
5690 flags2 |= WMI_KEY_PAIRWISE;
5691
5692 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5693 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005694 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005695 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5696 arvif->vdev_id, peer_addr, ret);
5697 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5698 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005699 if (ret2) {
5700 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005701 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5702 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005703 }
Michal Kazior29a10002015-04-10 13:05:58 +00005704 goto exit;
5705 }
5706 }
5707
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005708 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5709
Kalle Valo5e3dd152013-06-12 20:52:10 +03005710 spin_lock_bh(&ar->data_lock);
5711 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5712 if (peer && cmd == SET_KEY)
5713 peer->keys[key->keyidx] = key;
5714 else if (peer && cmd == DISABLE_KEY)
5715 peer->keys[key->keyidx] = NULL;
5716 else if (peer == NULL)
5717 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005718 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005719 spin_unlock_bh(&ar->data_lock);
5720
5721exit:
5722 mutex_unlock(&ar->conf_mutex);
5723 return ret;
5724}
5725
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005726static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5727 struct ieee80211_vif *vif,
5728 int keyidx)
5729{
5730 struct ath10k *ar = hw->priv;
5731 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5732 int ret;
5733
5734 mutex_lock(&arvif->ar->conf_mutex);
5735
5736 if (arvif->ar->state != ATH10K_STATE_ON)
5737 goto unlock;
5738
5739 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5740 arvif->vdev_id, keyidx);
5741
5742 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5743 arvif->vdev_id,
5744 arvif->ar->wmi.vdev_param->def_keyid,
5745 keyidx);
5746
5747 if (ret) {
5748 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5749 arvif->vdev_id,
5750 ret);
5751 goto unlock;
5752 }
5753
5754 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005755
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005756unlock:
5757 mutex_unlock(&arvif->ar->conf_mutex);
5758}
5759
Michal Kazior9797feb2014-02-14 14:49:48 +01005760static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5761{
5762 struct ath10k *ar;
5763 struct ath10k_vif *arvif;
5764 struct ath10k_sta *arsta;
5765 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005766 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02005767 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005768 const u8 *ht_mcs_mask;
5769 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005770 u32 changed, bw, nss, smps;
5771 int err;
5772
5773 arsta = container_of(wk, struct ath10k_sta, update_wk);
5774 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5775 arvif = arsta->arvif;
5776 ar = arvif->ar;
5777
Michal Kazior45c9abc2015-04-21 20:42:58 +03005778 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5779 return;
5780
5781 band = def.chan->band;
5782 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5783 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5784
Michal Kazior9797feb2014-02-14 14:49:48 +01005785 spin_lock_bh(&ar->data_lock);
5786
5787 changed = arsta->changed;
5788 arsta->changed = 0;
5789
5790 bw = arsta->bw;
5791 nss = arsta->nss;
5792 smps = arsta->smps;
5793
5794 spin_unlock_bh(&ar->data_lock);
5795
5796 mutex_lock(&ar->conf_mutex);
5797
Michal Kazior45c9abc2015-04-21 20:42:58 +03005798 nss = max_t(u32, 1, nss);
5799 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
5800 ath10k_mac_max_vht_nss(vht_mcs_mask)));
5801
Michal Kazior9797feb2014-02-14 14:49:48 +01005802 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005803 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005804 sta->addr, bw);
5805
5806 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5807 WMI_PEER_CHAN_WIDTH, bw);
5808 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005809 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005810 sta->addr, bw, err);
5811 }
5812
5813 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005814 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005815 sta->addr, nss);
5816
5817 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5818 WMI_PEER_NSS, nss);
5819 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005820 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005821 sta->addr, nss, err);
5822 }
5823
5824 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005825 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005826 sta->addr, smps);
5827
5828 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5829 WMI_PEER_SMPS_STATE, smps);
5830 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005831 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005832 sta->addr, smps, err);
5833 }
5834
Karthikeyan Periyasamy237b5a32018-03-27 11:25:29 +03005835 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
5836 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005837 sta->addr);
5838
Michal Kazior590922a2014-10-21 10:10:29 +03005839 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005840 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005841 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005842 sta->addr);
5843 }
5844
Michal Kazior9797feb2014-02-14 14:49:48 +01005845 mutex_unlock(&ar->conf_mutex);
5846}
5847
Marek Puzyniak7c354242015-03-30 09:51:52 +03005848static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
5849 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005850{
5851 struct ath10k *ar = arvif->ar;
5852
5853 lockdep_assert_held(&ar->conf_mutex);
5854
Marek Puzyniak7c354242015-03-30 09:51:52 +03005855 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005856 return 0;
5857
5858 if (ar->num_stations >= ar->max_num_stations)
5859 return -ENOBUFS;
5860
5861 ar->num_stations++;
5862
5863 return 0;
5864}
5865
Marek Puzyniak7c354242015-03-30 09:51:52 +03005866static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
5867 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005868{
5869 struct ath10k *ar = arvif->ar;
5870
5871 lockdep_assert_held(&ar->conf_mutex);
5872
Marek Puzyniak7c354242015-03-30 09:51:52 +03005873 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005874 return;
5875
5876 ar->num_stations--;
5877}
5878
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005879struct ath10k_mac_tdls_iter_data {
5880 u32 num_tdls_stations;
5881 struct ieee80211_vif *curr_vif;
5882};
5883
5884static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5885 struct ieee80211_sta *sta)
5886{
5887 struct ath10k_mac_tdls_iter_data *iter_data = data;
5888 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5889 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5890
5891 if (sta->tdls && sta_vif == iter_data->curr_vif)
5892 iter_data->num_tdls_stations++;
5893}
5894
5895static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5896 struct ieee80211_vif *vif)
5897{
5898 struct ath10k_mac_tdls_iter_data data = {};
5899
5900 data.curr_vif = vif;
5901
5902 ieee80211_iterate_stations_atomic(hw,
5903 ath10k_mac_tdls_vif_stations_count_iter,
5904 &data);
5905 return data.num_tdls_stations;
5906}
5907
5908static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5909 struct ieee80211_vif *vif)
5910{
5911 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5912 int *num_tdls_vifs = data;
5913
5914 if (vif->type != NL80211_IFTYPE_STATION)
5915 return;
5916
5917 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5918 (*num_tdls_vifs)++;
5919}
5920
5921static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5922{
5923 int num_tdls_vifs = 0;
5924
5925 ieee80211_iterate_active_interfaces_atomic(hw,
5926 IEEE80211_IFACE_ITER_NORMAL,
5927 ath10k_mac_tdls_vifs_count_iter,
5928 &num_tdls_vifs);
5929 return num_tdls_vifs;
5930}
5931
Kalle Valo5e3dd152013-06-12 20:52:10 +03005932static int ath10k_sta_state(struct ieee80211_hw *hw,
5933 struct ieee80211_vif *vif,
5934 struct ieee80211_sta *sta,
5935 enum ieee80211_sta_state old_state,
5936 enum ieee80211_sta_state new_state)
5937{
5938 struct ath10k *ar = hw->priv;
5939 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005940 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005941 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005942 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02005943 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005944
Michal Kazior76f90022014-02-25 09:29:57 +02005945 if (old_state == IEEE80211_STA_NOTEXIST &&
5946 new_state == IEEE80211_STA_NONE) {
5947 memset(arsta, 0, sizeof(*arsta));
5948 arsta->arvif = arvif;
5949 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02005950
5951 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5952 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02005953 }
5954
Michal Kazior9797feb2014-02-14 14:49:48 +01005955 /* cancel must be done outside the mutex to avoid deadlock */
5956 if ((old_state == IEEE80211_STA_NONE &&
5957 new_state == IEEE80211_STA_NOTEXIST))
5958 cancel_work_sync(&arsta->update_wk);
5959
Kalle Valo5e3dd152013-06-12 20:52:10 +03005960 mutex_lock(&ar->conf_mutex);
5961
5962 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005963 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005964 /*
5965 * New station addition.
5966 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005967 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5968 u32 num_tdls_stations;
5969 u32 num_tdls_vifs;
5970
Michal Kaziorcfd10612014-11-25 15:16:05 +01005971 ath10k_dbg(ar, ATH10K_DBG_MAC,
5972 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5973 arvif->vdev_id, sta->addr,
5974 ar->num_stations + 1, ar->max_num_stations,
5975 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005976
Marek Puzyniak7c354242015-03-30 09:51:52 +03005977 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005978 if (ret) {
5979 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5980 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005981 goto exit;
5982 }
5983
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005984 if (sta->tdls)
5985 peer_type = WMI_PEER_TYPE_TDLS;
5986
Michal Kazior69427262016-03-06 16:14:30 +02005987 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
5988 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005989 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005990 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 -08005991 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005992 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005993 goto exit;
5994 }
Michal Kazior077efc82014-10-21 10:10:29 +03005995
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005996 spin_lock_bh(&ar->data_lock);
5997
5998 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
5999 if (!peer) {
6000 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
6001 vif->addr, arvif->vdev_id);
6002 spin_unlock_bh(&ar->data_lock);
6003 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6004 ath10k_mac_dec_num_stations(arvif, sta);
6005 ret = -ENOENT;
6006 goto exit;
6007 }
6008
6009 arsta->peer_id = find_first_bit(peer->peer_ids,
6010 ATH10K_MAX_NUM_PEER_IDS);
6011
6012 spin_unlock_bh(&ar->data_lock);
6013
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006014 if (!sta->tdls)
6015 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03006016
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006017 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
6018 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
6019
6020 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
6021 num_tdls_stations == 0) {
6022 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
6023 arvif->vdev_id, ar->max_num_tdls_vdevs);
6024 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6025 ath10k_mac_dec_num_stations(arvif, sta);
6026 ret = -ENOBUFS;
6027 goto exit;
6028 }
6029
6030 if (num_tdls_stations == 0) {
6031 /* This is the first tdls peer in current vif */
6032 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
6033
6034 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6035 state);
Michal Kazior077efc82014-10-21 10:10:29 +03006036 if (ret) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006037 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
Michal Kazior077efc82014-10-21 10:10:29 +03006038 arvif->vdev_id, ret);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006039 ath10k_peer_delete(ar, arvif->vdev_id,
6040 sta->addr);
6041 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006042 goto exit;
6043 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006044 }
Michal Kazior077efc82014-10-21 10:10:29 +03006045
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006046 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6047 WMI_TDLS_PEER_STATE_PEERING);
6048 if (ret) {
6049 ath10k_warn(ar,
6050 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
6051 sta->addr, arvif->vdev_id, ret);
6052 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6053 ath10k_mac_dec_num_stations(arvif, sta);
6054
6055 if (num_tdls_stations != 0)
6056 goto exit;
6057 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6058 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03006059 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006060 } else if ((old_state == IEEE80211_STA_NONE &&
6061 new_state == IEEE80211_STA_NOTEXIST)) {
6062 /*
6063 * Existing station deletion.
6064 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006065 ath10k_dbg(ar, ATH10K_DBG_MAC,
Ben Greear30404202016-08-18 18:26:35 -07006066 "mac vdev %d peer delete %pM sta %pK (sta gone)\n",
6067 arvif->vdev_id, sta->addr, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006068
Manikanta Pubbisetty10318872017-11-06 13:39:31 +05306069 if (sta->tdls) {
6070 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id,
6071 sta,
6072 WMI_TDLS_PEER_STATE_TEARDOWN);
6073 if (ret)
6074 ath10k_warn(ar, "failed to update tdls peer state for %pM state %d: %i\n",
6075 sta->addr,
6076 WMI_TDLS_PEER_STATE_TEARDOWN, ret);
6077 }
6078
Kalle Valo5e3dd152013-06-12 20:52:10 +03006079 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6080 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006081 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006082 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006083
Marek Puzyniak7c354242015-03-30 09:51:52 +03006084 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006085
Michal Kazior69427262016-03-06 16:14:30 +02006086 spin_lock_bh(&ar->data_lock);
6087 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
6088 peer = ar->peer_map[i];
6089 if (!peer)
6090 continue;
6091
6092 if (peer->sta == sta) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05306093 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 +03006094 sta->addr, peer, i, arvif->vdev_id);
Michal Kazior69427262016-03-06 16:14:30 +02006095 peer->sta = NULL;
Ben Greeard0eeafa2016-06-30 15:23:59 +03006096
6097 /* Clean up the peer object as well since we
6098 * must have failed to do this above.
6099 */
6100 list_del(&peer->list);
6101 ar->peer_map[i] = NULL;
6102 kfree(peer);
6103 ar->num_peers--;
Michal Kazior69427262016-03-06 16:14:30 +02006104 }
6105 }
6106 spin_unlock_bh(&ar->data_lock);
6107
Michal Kazior29946872016-03-06 16:14:34 +02006108 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6109 ath10k_mac_txq_unref(ar, sta->txq[i]);
6110
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006111 if (!sta->tdls)
6112 goto exit;
6113
6114 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
6115 goto exit;
6116
6117 /* This was the last tdls peer in current vif */
6118 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6119 WMI_TDLS_DISABLE);
6120 if (ret) {
6121 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6122 arvif->vdev_id, ret);
6123 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006124 } else if (old_state == IEEE80211_STA_AUTH &&
6125 new_state == IEEE80211_STA_ASSOC &&
6126 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006127 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03006128 vif->type == NL80211_IFTYPE_ADHOC)) {
6129 /*
6130 * New association.
6131 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006132 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006133 sta->addr);
6134
Michal Kazior590922a2014-10-21 10:10:29 +03006135 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006136 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006137 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006138 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006139 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006140 new_state == IEEE80211_STA_AUTHORIZED &&
6141 sta->tdls) {
6142 /*
6143 * Tdls station authorized.
6144 */
6145 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
6146 sta->addr);
6147
6148 ret = ath10k_station_assoc(ar, vif, sta, false);
6149 if (ret) {
6150 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
6151 sta->addr, arvif->vdev_id, ret);
6152 goto exit;
6153 }
6154
6155 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6156 WMI_TDLS_PEER_STATE_CONNECTED);
6157 if (ret)
6158 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
6159 sta->addr, arvif->vdev_id, ret);
6160 } else if (old_state == IEEE80211_STA_ASSOC &&
6161 new_state == IEEE80211_STA_AUTH &&
6162 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006163 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006164 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006165 /*
6166 * Disassociation.
6167 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006168 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006169 sta->addr);
6170
Michal Kazior590922a2014-10-21 10:10:29 +03006171 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006172 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006173 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006174 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006175 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006176exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006177 mutex_unlock(&ar->conf_mutex);
6178 return ret;
6179}
6180
6181static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006182 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006183{
6184 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02006185 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6186 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006187 u32 value = 0;
6188 int ret = 0;
6189
Michal Kazior548db542013-07-05 16:15:15 +03006190 lockdep_assert_held(&ar->conf_mutex);
6191
Kalle Valo5e3dd152013-06-12 20:52:10 +03006192 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6193 return 0;
6194
6195 switch (ac) {
6196 case IEEE80211_AC_VO:
6197 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6198 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006199 prio = 7;
6200 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006201 break;
6202 case IEEE80211_AC_VI:
6203 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6204 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006205 prio = 5;
6206 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006207 break;
6208 case IEEE80211_AC_BE:
6209 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6210 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006211 prio = 2;
6212 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006213 break;
6214 case IEEE80211_AC_BK:
6215 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6216 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006217 prio = 0;
6218 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006219 break;
6220 }
6221
6222 if (enable)
6223 arvif->u.sta.uapsd |= value;
6224 else
6225 arvif->u.sta.uapsd &= ~value;
6226
6227 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6228 WMI_STA_PS_PARAM_UAPSD,
6229 arvif->u.sta.uapsd);
6230 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006231 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006232 goto exit;
6233 }
6234
6235 if (arvif->u.sta.uapsd)
6236 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6237 else
6238 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6239
6240 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6241 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6242 value);
6243 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006244 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006245
Michal Kazior9f9b5742014-12-12 12:41:36 +01006246 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6247 if (ret) {
6248 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6249 arvif->vdev_id, ret);
6250 return ret;
6251 }
6252
6253 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6254 if (ret) {
6255 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6256 arvif->vdev_id, ret);
6257 return ret;
6258 }
6259
Michal Kaziorb0e56152015-01-24 12:14:52 +02006260 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6261 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6262 /* Only userspace can make an educated decision when to send
6263 * trigger frame. The following effectively disables u-UAPSD
6264 * autotrigger in firmware (which is enabled by default
6265 * provided the autotrigger service is available).
6266 */
6267
6268 arg.wmm_ac = acc;
6269 arg.user_priority = prio;
6270 arg.service_interval = 0;
6271 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6272 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6273
6274 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6275 arvif->bssid, &arg, 1);
6276 if (ret) {
6277 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6278 ret);
6279 return ret;
6280 }
6281 }
6282
Kalle Valo5e3dd152013-06-12 20:52:10 +03006283exit:
6284 return ret;
6285}
6286
6287static int ath10k_conf_tx(struct ieee80211_hw *hw,
6288 struct ieee80211_vif *vif, u16 ac,
6289 const struct ieee80211_tx_queue_params *params)
6290{
6291 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01006292 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006293 struct wmi_wmm_params_arg *p = NULL;
6294 int ret;
6295
6296 mutex_lock(&ar->conf_mutex);
6297
6298 switch (ac) {
6299 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006300 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006301 break;
6302 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006303 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006304 break;
6305 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006306 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006307 break;
6308 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006309 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006310 break;
6311 }
6312
6313 if (WARN_ON(!p)) {
6314 ret = -EINVAL;
6315 goto exit;
6316 }
6317
6318 p->cwmin = params->cw_min;
6319 p->cwmax = params->cw_max;
6320 p->aifs = params->aifs;
6321
6322 /*
6323 * The channel time duration programmed in the HW is in absolute
6324 * microseconds, while mac80211 gives the txop in units of
6325 * 32 microseconds.
6326 */
6327 p->txop = params->txop * 32;
6328
Michal Kazior7fc979a2015-01-28 09:57:28 +02006329 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6330 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6331 &arvif->wmm_params);
6332 if (ret) {
6333 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6334 arvif->vdev_id, ret);
6335 goto exit;
6336 }
6337 } else {
6338 /* This won't work well with multi-interface cases but it's
6339 * better than nothing.
6340 */
6341 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6342 if (ret) {
6343 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6344 goto exit;
6345 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006346 }
6347
6348 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6349 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006350 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006351
6352exit:
6353 mutex_unlock(&ar->conf_mutex);
6354 return ret;
6355}
6356
Kalle Valo14e105c2016-04-13 14:13:21 +03006357#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006358
6359static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6360 struct ieee80211_vif *vif,
6361 struct ieee80211_channel *chan,
6362 int duration,
6363 enum ieee80211_roc_type type)
6364{
6365 struct ath10k *ar = hw->priv;
6366 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6367 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006368 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006369 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006370
6371 mutex_lock(&ar->conf_mutex);
6372
6373 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006374 switch (ar->scan.state) {
6375 case ATH10K_SCAN_IDLE:
6376 reinit_completion(&ar->scan.started);
6377 reinit_completion(&ar->scan.completed);
6378 reinit_completion(&ar->scan.on_channel);
6379 ar->scan.state = ATH10K_SCAN_STARTING;
6380 ar->scan.is_roc = true;
6381 ar->scan.vdev_id = arvif->vdev_id;
6382 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006383 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006384 ret = 0;
6385 break;
6386 case ATH10K_SCAN_STARTING:
6387 case ATH10K_SCAN_RUNNING:
6388 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006389 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006390 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006391 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006392 spin_unlock_bh(&ar->data_lock);
6393
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006394 if (ret)
6395 goto exit;
6396
Michal Kaziorfcf98442015-03-31 11:03:47 +00006397 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006398
Kalle Valo5e3dd152013-06-12 20:52:10 +03006399 memset(&arg, 0, sizeof(arg));
6400 ath10k_wmi_start_scan_init(ar, &arg);
6401 arg.vdev_id = arvif->vdev_id;
6402 arg.scan_id = ATH10K_SCAN_ID;
6403 arg.n_channels = 1;
6404 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006405 arg.dwell_time_active = scan_time_msec;
6406 arg.dwell_time_passive = scan_time_msec;
6407 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006408 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6409 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006410 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006411
6412 ret = ath10k_start_scan(ar, &arg);
6413 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006414 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006415 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006416 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006417 spin_unlock_bh(&ar->data_lock);
6418 goto exit;
6419 }
6420
Kalle Valo14e105c2016-04-13 14:13:21 +03006421 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006422 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006423 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006424
6425 ret = ath10k_scan_stop(ar);
6426 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006427 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006428
Kalle Valo5e3dd152013-06-12 20:52:10 +03006429 ret = -ETIMEDOUT;
6430 goto exit;
6431 }
6432
Michal Kaziorfcf98442015-03-31 11:03:47 +00006433 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6434 msecs_to_jiffies(duration));
6435
Kalle Valo5e3dd152013-06-12 20:52:10 +03006436 ret = 0;
6437exit:
6438 mutex_unlock(&ar->conf_mutex);
6439 return ret;
6440}
6441
6442static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6443{
6444 struct ath10k *ar = hw->priv;
6445
6446 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006447
6448 spin_lock_bh(&ar->data_lock);
6449 ar->scan.roc_notify = false;
6450 spin_unlock_bh(&ar->data_lock);
6451
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006452 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006453
Kalle Valo5e3dd152013-06-12 20:52:10 +03006454 mutex_unlock(&ar->conf_mutex);
6455
Michal Kazior4eb2e162014-10-28 10:23:09 +01006456 cancel_delayed_work_sync(&ar->scan.timeout);
6457
Kalle Valo5e3dd152013-06-12 20:52:10 +03006458 return 0;
6459}
6460
6461/*
6462 * Both RTS and Fragmentation threshold are interface-specific
6463 * in ath10k, but device-specific in mac80211.
6464 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006465
6466static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6467{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006468 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006469 struct ath10k_vif *arvif;
6470 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006471
Michal Kaziorad088bf2013-10-16 15:44:46 +03006472 mutex_lock(&ar->conf_mutex);
6473 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006474 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006475 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006476
Michal Kaziorad088bf2013-10-16 15:44:46 +03006477 ret = ath10k_mac_set_rts(arvif, value);
6478 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006479 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006480 arvif->vdev_id, ret);
6481 break;
6482 }
6483 }
6484 mutex_unlock(&ar->conf_mutex);
6485
6486 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006487}
6488
Michal Kazior92092fe2015-08-03 11:16:43 +02006489static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6490{
6491 /* Even though there's a WMI enum for fragmentation threshold no known
6492 * firmware actually implements it. Moreover it is not possible to rely
6493 * frame fragmentation to mac80211 because firmware clears the "more
6494 * fragments" bit in frame control making it impossible for remote
6495 * devices to reassemble frames.
6496 *
6497 * Hence implement a dummy callback just to say fragmentation isn't
6498 * supported. This effectively prevents mac80211 from doing frame
6499 * fragmentation in software.
6500 */
6501 return -EOPNOTSUPP;
6502}
6503
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02006504static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6505 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006506{
6507 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02006508 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006509 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006510
6511 /* mac80211 doesn't care if we really xmit queued frames or not
6512 * we'll collect those frames either way if we stop/delete vdevs */
6513 if (drop)
6514 return;
6515
Michal Kazior548db542013-07-05 16:15:15 +03006516 mutex_lock(&ar->conf_mutex);
6517
Michal Kazioraffd3212013-07-16 09:54:35 +02006518 if (ar->state == ATH10K_STATE_WEDGED)
6519 goto skip;
6520
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006521 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006522 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006523
Michal Kazioredb82362013-07-05 16:15:14 +03006524 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006525 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006526 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006527
Michal Kazior7962b0d2014-10-28 10:34:38 +01006528 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6529 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6530 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006531
6532 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006533 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006534
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006535 if (time_left == 0 || skip)
6536 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6537 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03006538
Michal Kazioraffd3212013-07-16 09:54:35 +02006539skip:
Michal Kazior548db542013-07-05 16:15:15 +03006540 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006541}
6542
6543/* TODO: Implement this function properly
6544 * For now it is needed to reply to Probe Requests in IBSS mode.
6545 * Propably we need this information from FW.
6546 */
6547static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
6548{
6549 return 1;
6550}
6551
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006552static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
6553 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02006554{
6555 struct ath10k *ar = hw->priv;
6556
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006557 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
6558 return;
6559
Michal Kazioraffd3212013-07-16 09:54:35 +02006560 mutex_lock(&ar->conf_mutex);
6561
6562 /* If device failed to restart it will be in a different state, e.g.
6563 * ATH10K_STATE_WEDGED */
6564 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006565 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02006566 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01006567 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02006568 }
6569
6570 mutex_unlock(&ar->conf_mutex);
6571}
6572
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306573static void
6574ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
6575 struct ieee80211_channel *channel)
6576{
6577 int ret;
6578 enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
6579
6580 lockdep_assert_held(&ar->conf_mutex);
6581
6582 if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
6583 (ar->rx_channel != channel))
6584 return;
6585
6586 if (ar->scan.state != ATH10K_SCAN_IDLE) {
6587 ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
6588 return;
6589 }
6590
6591 reinit_completion(&ar->bss_survey_done);
6592
6593 ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
6594 if (ret) {
6595 ath10k_warn(ar, "failed to send pdev bss chan info request\n");
6596 return;
6597 }
6598
6599 ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
6600 if (!ret) {
6601 ath10k_warn(ar, "bss channel survey timed out\n");
6602 return;
6603 }
6604}
6605
Michal Kazior2e1dea42013-07-31 10:32:40 +02006606static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
6607 struct survey_info *survey)
6608{
6609 struct ath10k *ar = hw->priv;
6610 struct ieee80211_supported_band *sband;
6611 struct survey_info *ar_survey = &ar->survey[idx];
6612 int ret = 0;
6613
6614 mutex_lock(&ar->conf_mutex);
6615
Johannes Berg57fbcce2016-04-12 15:56:15 +02006616 sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006617 if (sband && idx >= sband->n_channels) {
6618 idx -= sband->n_channels;
6619 sband = NULL;
6620 }
6621
6622 if (!sband)
Johannes Berg57fbcce2016-04-12 15:56:15 +02006623 sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006624
6625 if (!sband || idx >= sband->n_channels) {
6626 ret = -ENOENT;
6627 goto exit;
6628 }
6629
Ashok Raj Nagarajan77eb3d62016-09-02 10:59:53 +05306630 ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306631
Michal Kazior2e1dea42013-07-31 10:32:40 +02006632 spin_lock_bh(&ar->data_lock);
6633 memcpy(survey, ar_survey, sizeof(*survey));
6634 spin_unlock_bh(&ar->data_lock);
6635
6636 survey->channel = &sband->channels[idx];
6637
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03006638 if (ar->rx_channel == survey->channel)
6639 survey->filled |= SURVEY_INFO_IN_USE;
6640
Michal Kazior2e1dea42013-07-31 10:32:40 +02006641exit:
6642 mutex_unlock(&ar->conf_mutex);
6643 return ret;
6644}
6645
Michal Kazior3ae54222015-03-31 10:49:20 +00006646static bool
6647ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006648 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006649 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006650{
Michal Kazior3ae54222015-03-31 10:49:20 +00006651 int num_rates = 0;
6652 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006653
Michal Kazior3ae54222015-03-31 10:49:20 +00006654 num_rates += hweight32(mask->control[band].legacy);
6655
6656 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
6657 num_rates += hweight8(mask->control[band].ht_mcs[i]);
6658
6659 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
6660 num_rates += hweight16(mask->control[band].vht_mcs[i]);
6661
6662 return num_rates == 1;
6663}
6664
6665static bool
6666ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006667 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006668 const struct cfg80211_bitrate_mask *mask,
6669 int *nss)
6670{
6671 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6672 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6673 u8 ht_nss_mask = 0;
6674 u8 vht_nss_mask = 0;
6675 int i;
6676
6677 if (mask->control[band].legacy)
6678 return false;
6679
6680 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6681 if (mask->control[band].ht_mcs[i] == 0)
6682 continue;
6683 else if (mask->control[band].ht_mcs[i] ==
6684 sband->ht_cap.mcs.rx_mask[i])
6685 ht_nss_mask |= BIT(i);
6686 else
6687 return false;
6688 }
6689
6690 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6691 if (mask->control[band].vht_mcs[i] == 0)
6692 continue;
6693 else if (mask->control[band].vht_mcs[i] ==
6694 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6695 vht_nss_mask |= BIT(i);
6696 else
6697 return false;
6698 }
6699
6700 if (ht_nss_mask != vht_nss_mask)
6701 return false;
6702
6703 if (ht_nss_mask == 0)
6704 return false;
6705
6706 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6707 return false;
6708
6709 *nss = fls(ht_nss_mask);
6710
6711 return true;
6712}
6713
6714static int
6715ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006716 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006717 const struct cfg80211_bitrate_mask *mask,
6718 u8 *rate, u8 *nss)
6719{
6720 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6721 int rate_idx;
6722 int i;
6723 u16 bitrate;
6724 u8 preamble;
6725 u8 hw_rate;
6726
6727 if (hweight32(mask->control[band].legacy) == 1) {
6728 rate_idx = ffs(mask->control[band].legacy) - 1;
6729
6730 hw_rate = sband->bitrates[rate_idx].hw_value;
6731 bitrate = sband->bitrates[rate_idx].bitrate;
6732
6733 if (ath10k_mac_bitrate_is_cck(bitrate))
6734 preamble = WMI_RATE_PREAMBLE_CCK;
6735 else
6736 preamble = WMI_RATE_PREAMBLE_OFDM;
6737
6738 *nss = 1;
6739 *rate = preamble << 6 |
6740 (*nss - 1) << 4 |
6741 hw_rate << 0;
6742
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006743 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006744 }
6745
Michal Kazior3ae54222015-03-31 10:49:20 +00006746 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6747 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6748 *nss = i + 1;
6749 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6750 (*nss - 1) << 4 |
6751 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006752
Michal Kazior3ae54222015-03-31 10:49:20 +00006753 return 0;
6754 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006755 }
6756
Michal Kazior3ae54222015-03-31 10:49:20 +00006757 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6758 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6759 *nss = i + 1;
6760 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6761 (*nss - 1) << 4 |
6762 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006763
Michal Kazior3ae54222015-03-31 10:49:20 +00006764 return 0;
6765 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006766 }
6767
Michal Kazior3ae54222015-03-31 10:49:20 +00006768 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006769}
6770
Michal Kazior3ae54222015-03-31 10:49:20 +00006771static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306772 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006773{
6774 struct ath10k *ar = arvif->ar;
6775 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006776 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006777
Michal Kazior3ae54222015-03-31 10:49:20 +00006778 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006779
Michal Kazior3ae54222015-03-31 10:49:20 +00006780 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6781 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006782
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006783 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006784 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006785 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006786 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006787 rate, ret);
6788 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006789 }
6790
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006791 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006792 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006793 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006794 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6795 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006796 }
6797
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006798 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006799 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006800 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006801 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6802 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006803 }
6804
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306805 vdev_param = ar->wmi.vdev_param->ldpc;
6806 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6807 if (ret) {
6808 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6809 return ret;
6810 }
6811
Michal Kazior3ae54222015-03-31 10:49:20 +00006812 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006813}
6814
Michal Kazior45c9abc2015-04-21 20:42:58 +03006815static bool
6816ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006817 enum nl80211_band band,
Michal Kazior45c9abc2015-04-21 20:42:58 +03006818 const struct cfg80211_bitrate_mask *mask)
6819{
6820 int i;
6821 u16 vht_mcs;
6822
6823 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6824 * to express all VHT MCS rate masks. Effectively only the following
6825 * ranges can be used: none, 0-7, 0-8 and 0-9.
6826 */
6827 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6828 vht_mcs = mask->control[band].vht_mcs[i];
6829
6830 switch (vht_mcs) {
6831 case 0:
6832 case BIT(8) - 1:
6833 case BIT(9) - 1:
6834 case BIT(10) - 1:
6835 break;
6836 default:
6837 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6838 return false;
6839 }
6840 }
6841
6842 return true;
6843}
6844
6845static void ath10k_mac_set_bitrate_mask_iter(void *data,
6846 struct ieee80211_sta *sta)
6847{
6848 struct ath10k_vif *arvif = data;
6849 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6850 struct ath10k *ar = arvif->ar;
6851
6852 if (arsta->arvif != arvif)
6853 return;
6854
6855 spin_lock_bh(&ar->data_lock);
6856 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
6857 spin_unlock_bh(&ar->data_lock);
6858
6859 ieee80211_queue_work(ar->hw, &arsta->update_wk);
6860}
6861
Michal Kazior3ae54222015-03-31 10:49:20 +00006862static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
6863 struct ieee80211_vif *vif,
6864 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006865{
6866 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006867 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006868 struct ath10k *ar = arvif->ar;
Johannes Berg57fbcce2016-04-12 15:56:15 +02006869 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006870 const u8 *ht_mcs_mask;
6871 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00006872 u8 rate;
6873 u8 nss;
6874 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306875 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00006876 int single_nss;
6877 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006878
Michal Kazior500ff9f2015-03-31 10:26:21 +00006879 if (ath10k_mac_vif_chan(vif, &def))
6880 return -EPERM;
6881
Michal Kazior500ff9f2015-03-31 10:26:21 +00006882 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006883 ht_mcs_mask = mask->control[band].ht_mcs;
6884 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306885 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006886
Michal Kazior3ae54222015-03-31 10:49:20 +00006887 sgi = mask->control[band].gi;
6888 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006889 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006890
Michal Kazior3ae54222015-03-31 10:49:20 +00006891 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
6892 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
6893 &rate, &nss);
6894 if (ret) {
6895 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
6896 arvif->vdev_id, ret);
6897 return ret;
6898 }
6899 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
6900 &single_nss)) {
6901 rate = WMI_FIXED_RATE_NONE;
6902 nss = single_nss;
6903 } else {
6904 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006905 nss = min(ar->num_rf_chains,
6906 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6907 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6908
6909 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
6910 return -EINVAL;
6911
6912 mutex_lock(&ar->conf_mutex);
6913
6914 arvif->bitrate_mask = *mask;
6915 ieee80211_iterate_stations_atomic(ar->hw,
6916 ath10k_mac_set_bitrate_mask_iter,
6917 arvif);
6918
6919 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006920 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006921
6922 mutex_lock(&ar->conf_mutex);
6923
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306924 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006925 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006926 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
6927 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006928 goto exit;
6929 }
6930
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006931exit:
6932 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00006933
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006934 return ret;
6935}
6936
Michal Kazior9797feb2014-02-14 14:49:48 +01006937static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6938 struct ieee80211_vif *vif,
6939 struct ieee80211_sta *sta,
6940 u32 changed)
6941{
6942 struct ath10k *ar = hw->priv;
6943 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Karthikeyan Periyasamye63ff842018-03-12 17:09:40 +05306944 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6945 struct ath10k_peer *peer;
Michal Kazior9797feb2014-02-14 14:49:48 +01006946 u32 bw, smps;
6947
6948 spin_lock_bh(&ar->data_lock);
6949
Karthikeyan Periyasamye63ff842018-03-12 17:09:40 +05306950 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
6951 if (!peer) {
6952 spin_unlock_bh(&ar->data_lock);
6953 ath10k_warn(ar, "mac sta rc update failed to find peer %pM on vdev %i\n",
6954 sta->addr, arvif->vdev_id);
6955 return;
6956 }
6957
Michal Kazior7aa7a722014-08-25 12:09:38 +02006958 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01006959 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
6960 sta->addr, changed, sta->bandwidth, sta->rx_nss,
6961 sta->smps_mode);
6962
6963 if (changed & IEEE80211_RC_BW_CHANGED) {
6964 bw = WMI_PEER_CHWIDTH_20MHZ;
6965
6966 switch (sta->bandwidth) {
6967 case IEEE80211_STA_RX_BW_20:
6968 bw = WMI_PEER_CHWIDTH_20MHZ;
6969 break;
6970 case IEEE80211_STA_RX_BW_40:
6971 bw = WMI_PEER_CHWIDTH_40MHZ;
6972 break;
6973 case IEEE80211_STA_RX_BW_80:
6974 bw = WMI_PEER_CHWIDTH_80MHZ;
6975 break;
6976 case IEEE80211_STA_RX_BW_160:
Masanari Iidad939be32015-02-27 23:52:31 +09006977 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006978 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006979 bw = WMI_PEER_CHWIDTH_20MHZ;
6980 break;
6981 }
6982
6983 arsta->bw = bw;
6984 }
6985
6986 if (changed & IEEE80211_RC_NSS_CHANGED)
6987 arsta->nss = sta->rx_nss;
6988
6989 if (changed & IEEE80211_RC_SMPS_CHANGED) {
6990 smps = WMI_PEER_SMPS_PS_NONE;
6991
6992 switch (sta->smps_mode) {
6993 case IEEE80211_SMPS_AUTOMATIC:
6994 case IEEE80211_SMPS_OFF:
6995 smps = WMI_PEER_SMPS_PS_NONE;
6996 break;
6997 case IEEE80211_SMPS_STATIC:
6998 smps = WMI_PEER_SMPS_STATIC;
6999 break;
7000 case IEEE80211_SMPS_DYNAMIC:
7001 smps = WMI_PEER_SMPS_DYNAMIC;
7002 break;
7003 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02007004 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02007005 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01007006 smps = WMI_PEER_SMPS_PS_NONE;
7007 break;
7008 }
7009
7010 arsta->smps = smps;
7011 }
7012
Michal Kazior9797feb2014-02-14 14:49:48 +01007013 arsta->changed |= changed;
7014
7015 spin_unlock_bh(&ar->data_lock);
7016
7017 ieee80211_queue_work(hw, &arsta->update_wk);
7018}
7019
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02007020static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
7021{
7022 /*
7023 * FIXME: Return 0 for time being. Need to figure out whether FW
7024 * has the API to fetch 64-bit local TSF
7025 */
7026
7027 return 0;
7028}
7029
Peter Oh9f0b7e72016-04-04 16:19:14 -07007030static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
Kalle Valo4d165442016-04-13 14:14:16 +03007031 u64 tsf)
Peter Oh9f0b7e72016-04-04 16:19:14 -07007032{
7033 struct ath10k *ar = hw->priv;
7034 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7035 u32 tsf_offset, vdev_param = ar->wmi.vdev_param->set_tsf;
7036 int ret;
7037
7038 /* Workaround:
7039 *
7040 * Given tsf argument is entire TSF value, but firmware accepts
7041 * only TSF offset to current TSF.
7042 *
7043 * get_tsf function is used to get offset value, however since
7044 * ath10k_get_tsf is not implemented properly, it will return 0 always.
7045 * Luckily all the caller functions to set_tsf, as of now, also rely on
7046 * get_tsf function to get entire tsf value such get_tsf() + tsf_delta,
7047 * final tsf offset value to firmware will be arithmetically correct.
7048 */
7049 tsf_offset = tsf - ath10k_get_tsf(hw, vif);
7050 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
7051 vdev_param, tsf_offset);
7052 if (ret && ret != -EOPNOTSUPP)
7053 ath10k_warn(ar, "failed to set tsf offset: %d\n", ret);
7054}
7055
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007056static int ath10k_ampdu_action(struct ieee80211_hw *hw,
7057 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02007058 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007059{
Michal Kazior7aa7a722014-08-25 12:09:38 +02007060 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007061 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Sara Sharon50ea05e2015-12-30 16:06:04 +02007062 struct ieee80211_sta *sta = params->sta;
7063 enum ieee80211_ampdu_mlme_action action = params->action;
7064 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007065
Michal Kazior7aa7a722014-08-25 12:09:38 +02007066 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 +02007067 arvif->vdev_id, sta->addr, tid, action);
7068
7069 switch (action) {
7070 case IEEE80211_AMPDU_RX_START:
7071 case IEEE80211_AMPDU_RX_STOP:
7072 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
7073 * creation/removal. Do we need to verify this?
7074 */
7075 return 0;
7076 case IEEE80211_AMPDU_TX_START:
7077 case IEEE80211_AMPDU_TX_STOP_CONT:
7078 case IEEE80211_AMPDU_TX_STOP_FLUSH:
7079 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
7080 case IEEE80211_AMPDU_TX_OPERATIONAL:
7081 /* Firmware offloads Tx aggregation entirely so deny mac80211
7082 * Tx aggregation requests.
7083 */
7084 return -EOPNOTSUPP;
7085 }
7086
7087 return -EINVAL;
7088}
7089
Michal Kazior500ff9f2015-03-31 10:26:21 +00007090static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007091ath10k_mac_update_rx_channel(struct ath10k *ar,
7092 struct ieee80211_chanctx_conf *ctx,
7093 struct ieee80211_vif_chanctx_switch *vifs,
7094 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00007095{
7096 struct cfg80211_chan_def *def = NULL;
7097
7098 /* Both locks are required because ar->rx_channel is modified. This
7099 * allows readers to hold either lock.
7100 */
7101 lockdep_assert_held(&ar->conf_mutex);
7102 lockdep_assert_held(&ar->data_lock);
7103
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007104 WARN_ON(ctx && vifs);
Mohammed Shafi Shajakhan5d2db0d2017-03-08 13:52:06 +02007105 WARN_ON(vifs && !n_vifs);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007106
Michal Kazior500ff9f2015-03-31 10:26:21 +00007107 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
7108 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
7109 * ppdu on Rx may reduce performance on low-end systems. It should be
7110 * possible to make tables/hashmaps to speed the lookup up (be vary of
7111 * cpu data cache lines though regarding sizes) but to keep the initial
7112 * implementation simple and less intrusive fallback to the slow lookup
7113 * only for multi-channel cases. Single-channel cases will remain to
7114 * use the old channel derival and thus performance should not be
7115 * affected much.
7116 */
7117 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007118 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00007119 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03007120 ath10k_mac_get_any_chandef_iter,
7121 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007122
7123 if (vifs)
7124 def = &vifs[0].new_ctx->def;
7125
Michal Kazior500ff9f2015-03-31 10:26:21 +00007126 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05307127 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
7128 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
7129 /* During driver restart due to firmware assert, since mac80211
7130 * already has valid channel context for given radio, channel
7131 * context iteration return num_chanctx > 0. So fix rx_channel
7132 * when restart is in progress.
7133 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007134 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007135 } else {
7136 ar->rx_channel = NULL;
7137 }
7138 rcu_read_unlock();
7139}
7140
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007141static void
7142ath10k_mac_update_vif_chan(struct ath10k *ar,
7143 struct ieee80211_vif_chanctx_switch *vifs,
7144 int n_vifs)
7145{
7146 struct ath10k_vif *arvif;
7147 int ret;
7148 int i;
7149
7150 lockdep_assert_held(&ar->conf_mutex);
7151
7152 /* First stop monitor interface. Some FW versions crash if there's a
7153 * lone monitor interface.
7154 */
7155 if (ar->monitor_started)
7156 ath10k_monitor_stop(ar);
7157
7158 for (i = 0; i < n_vifs; i++) {
7159 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7160
7161 ath10k_dbg(ar, ATH10K_DBG_MAC,
7162 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
7163 arvif->vdev_id,
7164 vifs[i].old_ctx->def.chan->center_freq,
7165 vifs[i].new_ctx->def.chan->center_freq,
7166 vifs[i].old_ctx->def.width,
7167 vifs[i].new_ctx->def.width);
7168
7169 if (WARN_ON(!arvif->is_started))
7170 continue;
7171
7172 if (WARN_ON(!arvif->is_up))
7173 continue;
7174
7175 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7176 if (ret) {
7177 ath10k_warn(ar, "failed to down vdev %d: %d\n",
7178 arvif->vdev_id, ret);
7179 continue;
7180 }
7181 }
7182
7183 /* All relevant vdevs are downed and associated channel resources
7184 * should be available for the channel switch now.
7185 */
7186
7187 spin_lock_bh(&ar->data_lock);
7188 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
7189 spin_unlock_bh(&ar->data_lock);
7190
7191 for (i = 0; i < n_vifs; i++) {
7192 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7193
7194 if (WARN_ON(!arvif->is_started))
7195 continue;
7196
7197 if (WARN_ON(!arvif->is_up))
7198 continue;
7199
7200 ret = ath10k_mac_setup_bcn_tmpl(arvif);
7201 if (ret)
7202 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
7203 ret);
7204
7205 ret = ath10k_mac_setup_prb_tmpl(arvif);
7206 if (ret)
7207 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
7208 ret);
7209
7210 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7211 if (ret) {
7212 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7213 arvif->vdev_id, ret);
7214 continue;
7215 }
7216
7217 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7218 arvif->bssid);
7219 if (ret) {
7220 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7221 arvif->vdev_id, ret);
7222 continue;
7223 }
7224 }
7225
7226 ath10k_monitor_recalc(ar);
7227}
7228
Michal Kazior500ff9f2015-03-31 10:26:21 +00007229static int
7230ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7231 struct ieee80211_chanctx_conf *ctx)
7232{
7233 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007234
7235 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307236 "mac chanctx add freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007237 ctx->def.chan->center_freq, ctx->def.width, ctx);
7238
7239 mutex_lock(&ar->conf_mutex);
7240
7241 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007242 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007243 spin_unlock_bh(&ar->data_lock);
7244
7245 ath10k_recalc_radar_detection(ar);
7246 ath10k_monitor_recalc(ar);
7247
7248 mutex_unlock(&ar->conf_mutex);
7249
7250 return 0;
7251}
7252
7253static void
7254ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7255 struct ieee80211_chanctx_conf *ctx)
7256{
7257 struct ath10k *ar = hw->priv;
7258
7259 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307260 "mac chanctx remove freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007261 ctx->def.chan->center_freq, ctx->def.width, ctx);
7262
7263 mutex_lock(&ar->conf_mutex);
7264
7265 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007266 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007267 spin_unlock_bh(&ar->data_lock);
7268
7269 ath10k_recalc_radar_detection(ar);
7270 ath10k_monitor_recalc(ar);
7271
7272 mutex_unlock(&ar->conf_mutex);
7273}
7274
Michal Kazior9713e3d2015-09-03 10:44:52 +02007275struct ath10k_mac_change_chanctx_arg {
7276 struct ieee80211_chanctx_conf *ctx;
7277 struct ieee80211_vif_chanctx_switch *vifs;
7278 int n_vifs;
7279 int next_vif;
7280};
7281
7282static void
7283ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
7284 struct ieee80211_vif *vif)
7285{
7286 struct ath10k_mac_change_chanctx_arg *arg = data;
7287
7288 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
7289 return;
7290
7291 arg->n_vifs++;
7292}
7293
7294static void
7295ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
7296 struct ieee80211_vif *vif)
7297{
7298 struct ath10k_mac_change_chanctx_arg *arg = data;
7299 struct ieee80211_chanctx_conf *ctx;
7300
7301 ctx = rcu_access_pointer(vif->chanctx_conf);
7302 if (ctx != arg->ctx)
7303 return;
7304
7305 if (WARN_ON(arg->next_vif == arg->n_vifs))
7306 return;
7307
7308 arg->vifs[arg->next_vif].vif = vif;
7309 arg->vifs[arg->next_vif].old_ctx = ctx;
7310 arg->vifs[arg->next_vif].new_ctx = ctx;
7311 arg->next_vif++;
7312}
7313
Michal Kazior500ff9f2015-03-31 10:26:21 +00007314static void
7315ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7316 struct ieee80211_chanctx_conf *ctx,
7317 u32 changed)
7318{
7319 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007320 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007321
7322 mutex_lock(&ar->conf_mutex);
7323
7324 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307325 "mac chanctx change freq %hu width %d ptr %pK changed %x\n",
Michal Kazior089ab7a2015-06-03 12:16:55 +02007326 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007327
7328 /* This shouldn't really happen because channel switching should use
7329 * switch_vif_chanctx().
7330 */
7331 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7332 goto unlock;
7333
Michal Kazior9713e3d2015-09-03 10:44:52 +02007334 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7335 ieee80211_iterate_active_interfaces_atomic(
7336 hw,
7337 IEEE80211_IFACE_ITER_NORMAL,
7338 ath10k_mac_change_chanctx_cnt_iter,
7339 &arg);
7340 if (arg.n_vifs == 0)
7341 goto radar;
7342
7343 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7344 GFP_KERNEL);
7345 if (!arg.vifs)
7346 goto radar;
7347
7348 ieee80211_iterate_active_interfaces_atomic(
7349 hw,
7350 IEEE80211_IFACE_ITER_NORMAL,
7351 ath10k_mac_change_chanctx_fill_iter,
7352 &arg);
7353 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7354 kfree(arg.vifs);
7355 }
7356
7357radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007358 ath10k_recalc_radar_detection(ar);
7359
7360 /* FIXME: How to configure Rx chains properly? */
7361
7362 /* No other actions are actually necessary. Firmware maintains channel
7363 * definitions per vdev internally and there's no host-side channel
7364 * context abstraction to configure, e.g. channel width.
7365 */
7366
7367unlock:
7368 mutex_unlock(&ar->conf_mutex);
7369}
7370
7371static int
7372ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7373 struct ieee80211_vif *vif,
7374 struct ieee80211_chanctx_conf *ctx)
7375{
7376 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007377 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7378 int ret;
7379
7380 mutex_lock(&ar->conf_mutex);
7381
7382 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307383 "mac chanctx assign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007384 ctx, arvif->vdev_id);
7385
7386 if (WARN_ON(arvif->is_started)) {
7387 mutex_unlock(&ar->conf_mutex);
7388 return -EBUSY;
7389 }
7390
Michal Kazior089ab7a2015-06-03 12:16:55 +02007391 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007392 if (ret) {
7393 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7394 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007395 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007396 goto err;
7397 }
7398
7399 arvif->is_started = true;
7400
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007401 ret = ath10k_mac_vif_setup_ps(arvif);
7402 if (ret) {
7403 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7404 arvif->vdev_id, ret);
7405 goto err_stop;
7406 }
7407
Michal Kazior500ff9f2015-03-31 10:26:21 +00007408 if (vif->type == NL80211_IFTYPE_MONITOR) {
7409 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7410 if (ret) {
7411 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7412 arvif->vdev_id, ret);
7413 goto err_stop;
7414 }
7415
7416 arvif->is_up = true;
7417 }
7418
Bartosz Markowski83e48fc2016-12-15 11:23:24 +02007419 if (ath10k_mac_can_set_cts_prot(arvif)) {
7420 ret = ath10k_mac_set_cts_prot(arvif);
7421 if (ret)
7422 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
7423 arvif->vdev_id, ret);
7424 }
7425
Michal Kazior500ff9f2015-03-31 10:26:21 +00007426 mutex_unlock(&ar->conf_mutex);
7427 return 0;
7428
7429err_stop:
7430 ath10k_vdev_stop(arvif);
7431 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007432 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007433
7434err:
7435 mutex_unlock(&ar->conf_mutex);
7436 return ret;
7437}
7438
7439static void
7440ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7441 struct ieee80211_vif *vif,
7442 struct ieee80211_chanctx_conf *ctx)
7443{
7444 struct ath10k *ar = hw->priv;
7445 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7446 int ret;
7447
7448 mutex_lock(&ar->conf_mutex);
7449
7450 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307451 "mac chanctx unassign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007452 ctx, arvif->vdev_id);
7453
7454 WARN_ON(!arvif->is_started);
7455
7456 if (vif->type == NL80211_IFTYPE_MONITOR) {
7457 WARN_ON(!arvif->is_up);
7458
7459 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7460 if (ret)
7461 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7462 arvif->vdev_id, ret);
7463
7464 arvif->is_up = false;
7465 }
7466
7467 ret = ath10k_vdev_stop(arvif);
7468 if (ret)
7469 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7470 arvif->vdev_id, ret);
7471
7472 arvif->is_started = false;
7473
7474 mutex_unlock(&ar->conf_mutex);
7475}
7476
7477static int
7478ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7479 struct ieee80211_vif_chanctx_switch *vifs,
7480 int n_vifs,
7481 enum ieee80211_chanctx_switch_mode mode)
7482{
7483 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007484
7485 mutex_lock(&ar->conf_mutex);
7486
7487 ath10k_dbg(ar, ATH10K_DBG_MAC,
7488 "mac chanctx switch n_vifs %d mode %d\n",
7489 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007490 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007491
7492 mutex_unlock(&ar->conf_mutex);
7493 return 0;
7494}
7495
Michal Kazior874b5ac2017-01-12 16:14:30 +01007496static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,
7497 struct ieee80211_vif *vif,
7498 struct ieee80211_sta *sta)
7499{
7500 struct ath10k *ar;
7501 struct ath10k_peer *peer;
7502
7503 ar = hw->priv;
7504
7505 list_for_each_entry(peer, &ar->peers, list)
7506 if (peer->sta == sta)
7507 peer->removed = true;
7508}
7509
Kalle Valo5e3dd152013-06-12 20:52:10 +03007510static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01007511 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02007512 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007513 .start = ath10k_start,
7514 .stop = ath10k_stop,
7515 .config = ath10k_config,
7516 .add_interface = ath10k_add_interface,
7517 .remove_interface = ath10k_remove_interface,
7518 .configure_filter = ath10k_configure_filter,
7519 .bss_info_changed = ath10k_bss_info_changed,
7520 .hw_scan = ath10k_hw_scan,
7521 .cancel_hw_scan = ath10k_cancel_hw_scan,
7522 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02007523 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007524 .sta_state = ath10k_sta_state,
7525 .conf_tx = ath10k_conf_tx,
7526 .remain_on_channel = ath10k_remain_on_channel,
7527 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
7528 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02007529 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007530 .flush = ath10k_flush,
7531 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03007532 .set_antenna = ath10k_set_antenna,
7533 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007534 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02007535 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00007536 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01007537 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02007538 .get_tsf = ath10k_get_tsf,
Peter Oh9f0b7e72016-04-04 16:19:14 -07007539 .set_tsf = ath10k_set_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007540 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03007541 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7542 .get_et_stats = ath10k_debug_get_et_stats,
7543 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00007544 .add_chanctx = ath10k_mac_op_add_chanctx,
7545 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7546 .change_chanctx = ath10k_mac_op_change_chanctx,
7547 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7548 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7549 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Michal Kazior874b5ac2017-01-12 16:14:30 +01007550 .sta_pre_rcu_remove = ath10k_mac_op_sta_pre_rcu_remove,
Kalle Valo43d2a302014-09-10 18:23:30 +03007551
7552 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7553
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007554#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007555 .suspend = ath10k_wow_op_suspend,
7556 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007557#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007558#ifdef CONFIG_MAC80211_DEBUGFS
7559 .sta_add_debugfs = ath10k_sta_add_debugfs,
Mohammed Shafi Shajakhan120a1f02016-06-30 15:23:50 +03007560 .sta_statistics = ath10k_sta_statistics,
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007561#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03007562};
7563
Kalle Valo5e3dd152013-06-12 20:52:10 +03007564#define CHAN2G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007565 .band = NL80211_BAND_2GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007566 .hw_value = (_channel), \
7567 .center_freq = (_freq), \
7568 .flags = (_flags), \
7569 .max_antenna_gain = 0, \
7570 .max_power = 30, \
7571}
7572
7573#define CHAN5G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007574 .band = NL80211_BAND_5GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007575 .hw_value = (_channel), \
7576 .center_freq = (_freq), \
7577 .flags = (_flags), \
7578 .max_antenna_gain = 0, \
7579 .max_power = 30, \
7580}
7581
7582static const struct ieee80211_channel ath10k_2ghz_channels[] = {
7583 CHAN2G(1, 2412, 0),
7584 CHAN2G(2, 2417, 0),
7585 CHAN2G(3, 2422, 0),
7586 CHAN2G(4, 2427, 0),
7587 CHAN2G(5, 2432, 0),
7588 CHAN2G(6, 2437, 0),
7589 CHAN2G(7, 2442, 0),
7590 CHAN2G(8, 2447, 0),
7591 CHAN2G(9, 2452, 0),
7592 CHAN2G(10, 2457, 0),
7593 CHAN2G(11, 2462, 0),
7594 CHAN2G(12, 2467, 0),
7595 CHAN2G(13, 2472, 0),
7596 CHAN2G(14, 2484, 0),
7597};
7598
7599static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02007600 CHAN5G(36, 5180, 0),
7601 CHAN5G(40, 5200, 0),
7602 CHAN5G(44, 5220, 0),
7603 CHAN5G(48, 5240, 0),
7604 CHAN5G(52, 5260, 0),
7605 CHAN5G(56, 5280, 0),
7606 CHAN5G(60, 5300, 0),
7607 CHAN5G(64, 5320, 0),
7608 CHAN5G(100, 5500, 0),
7609 CHAN5G(104, 5520, 0),
7610 CHAN5G(108, 5540, 0),
7611 CHAN5G(112, 5560, 0),
7612 CHAN5G(116, 5580, 0),
7613 CHAN5G(120, 5600, 0),
7614 CHAN5G(124, 5620, 0),
7615 CHAN5G(128, 5640, 0),
7616 CHAN5G(132, 5660, 0),
7617 CHAN5G(136, 5680, 0),
7618 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07007619 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02007620 CHAN5G(149, 5745, 0),
7621 CHAN5G(153, 5765, 0),
7622 CHAN5G(157, 5785, 0),
7623 CHAN5G(161, 5805, 0),
7624 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03007625};
7626
Michal Kaziore7b54192014-08-07 11:03:27 +02007627struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007628{
7629 struct ieee80211_hw *hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007630 struct ieee80211_ops *ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007631 struct ath10k *ar;
7632
Michal Kazior4ca18072016-07-18 23:22:18 +03007633 ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);
7634 if (!ops)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007635 return NULL;
7636
Michal Kazior4ca18072016-07-18 23:22:18 +03007637 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);
7638 if (!hw) {
7639 kfree(ops);
7640 return NULL;
7641 }
7642
Kalle Valo5e3dd152013-06-12 20:52:10 +03007643 ar = hw->priv;
7644 ar->hw = hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007645 ar->ops = ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007646
7647 return ar;
7648}
7649
7650void ath10k_mac_destroy(struct ath10k *ar)
7651{
Michal Kazior4ca18072016-07-18 23:22:18 +03007652 struct ieee80211_ops *ops = ar->ops;
7653
Kalle Valo5e3dd152013-06-12 20:52:10 +03007654 ieee80211_free_hw(ar->hw);
Michal Kazior4ca18072016-07-18 23:22:18 +03007655 kfree(ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007656}
7657
7658static const struct ieee80211_iface_limit ath10k_if_limits[] = {
7659 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307660 .max = 8,
7661 .types = BIT(NL80211_IFTYPE_STATION)
7662 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02007663 },
7664 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307665 .max = 3,
7666 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02007667 },
7668 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307669 .max = 1,
7670 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01007671 },
7672 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307673 .max = 7,
7674 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007675#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307676 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007677#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02007678 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007679};
7680
Bartosz Markowskif2595092013-12-10 16:20:39 +01007681static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007682 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307683 .max = 8,
7684 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007685#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307686 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007687#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007688 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307689 {
7690 .max = 1,
7691 .types = BIT(NL80211_IFTYPE_STATION)
7692 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007693};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007694
7695static const struct ieee80211_iface_combination ath10k_if_comb[] = {
7696 {
7697 .limits = ath10k_if_limits,
7698 .n_limits = ARRAY_SIZE(ath10k_if_limits),
7699 .max_interfaces = 8,
7700 .num_different_channels = 1,
7701 .beacon_int_infra_match = true,
7702 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01007703};
7704
7705static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007706 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01007707 .limits = ath10k_10x_if_limits,
7708 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007709 .max_interfaces = 8,
7710 .num_different_channels = 1,
7711 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01007712#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007713 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7714 BIT(NL80211_CHAN_WIDTH_20) |
7715 BIT(NL80211_CHAN_WIDTH_40) |
7716 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007717#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01007718 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007719};
7720
Michal Kaziorcf327842015-03-31 10:26:25 +00007721static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
7722 {
7723 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02007724 .types = BIT(NL80211_IFTYPE_STATION),
7725 },
7726 {
7727 .max = 2,
7728 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007729#ifdef CONFIG_MAC80211_MESH
7730 BIT(NL80211_IFTYPE_MESH_POINT) |
7731#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00007732 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7733 BIT(NL80211_IFTYPE_P2P_GO),
7734 },
7735 {
7736 .max = 1,
7737 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7738 },
7739};
7740
Michal Kaziored25b112015-07-09 13:08:39 +02007741static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
7742 {
7743 .max = 2,
7744 .types = BIT(NL80211_IFTYPE_STATION),
7745 },
7746 {
7747 .max = 2,
7748 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
7749 },
7750 {
7751 .max = 1,
7752 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007753#ifdef CONFIG_MAC80211_MESH
7754 BIT(NL80211_IFTYPE_MESH_POINT) |
7755#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007756 BIT(NL80211_IFTYPE_P2P_GO),
7757 },
7758 {
7759 .max = 1,
7760 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7761 },
7762};
7763
Michal Kaziorcf327842015-03-31 10:26:25 +00007764static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7765 {
7766 .max = 1,
7767 .types = BIT(NL80211_IFTYPE_STATION),
7768 },
7769 {
7770 .max = 1,
7771 .types = BIT(NL80211_IFTYPE_ADHOC),
7772 },
7773};
7774
7775/* FIXME: This is not thouroughly tested. These combinations may over- or
7776 * underestimate hw/fw capabilities.
7777 */
7778static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7779 {
7780 .limits = ath10k_tlv_if_limit,
7781 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007782 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007783 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7784 },
7785 {
7786 .limits = ath10k_tlv_if_limit_ibss,
7787 .num_different_channels = 1,
7788 .max_interfaces = 2,
7789 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7790 },
7791};
7792
7793static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7794 {
7795 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007796 .num_different_channels = 1,
7797 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007798 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7799 },
7800 {
Michal Kaziored25b112015-07-09 13:08:39 +02007801 .limits = ath10k_tlv_qcs_if_limit,
7802 .num_different_channels = 2,
7803 .max_interfaces = 4,
7804 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7805 },
7806 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007807 .limits = ath10k_tlv_if_limit_ibss,
7808 .num_different_channels = 1,
7809 .max_interfaces = 2,
7810 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7811 },
7812};
7813
Raja Manicf36fef2015-06-22 20:22:25 +05307814static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
7815 {
7816 .max = 1,
7817 .types = BIT(NL80211_IFTYPE_STATION),
7818 },
7819 {
7820 .max = 16,
7821 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007822#ifdef CONFIG_MAC80211_MESH
7823 | BIT(NL80211_IFTYPE_MESH_POINT)
7824#endif
Raja Manicf36fef2015-06-22 20:22:25 +05307825 },
7826};
7827
7828static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
7829 {
7830 .limits = ath10k_10_4_if_limits,
7831 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
7832 .max_interfaces = 16,
7833 .num_different_channels = 1,
7834 .beacon_int_infra_match = true,
7835#ifdef CONFIG_ATH10K_DFS_CERTIFIED
7836 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7837 BIT(NL80211_CHAN_WIDTH_20) |
7838 BIT(NL80211_CHAN_WIDTH_40) |
7839 BIT(NL80211_CHAN_WIDTH_80),
7840#endif
7841 },
7842};
7843
Kalle Valo5e3dd152013-06-12 20:52:10 +03007844static void ath10k_get_arvif_iter(void *data, u8 *mac,
7845 struct ieee80211_vif *vif)
7846{
7847 struct ath10k_vif_iter *arvif_iter = data;
7848 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7849
7850 if (arvif->vdev_id == arvif_iter->vdev_id)
7851 arvif_iter->arvif = arvif;
7852}
7853
7854struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
7855{
7856 struct ath10k_vif_iter arvif_iter;
7857 u32 flags;
7858
7859 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
7860 arvif_iter.vdev_id = vdev_id;
7861
7862 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
7863 ieee80211_iterate_active_interfaces_atomic(ar->hw,
7864 flags,
7865 ath10k_get_arvif_iter,
7866 &arvif_iter);
7867 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007868 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007869 return NULL;
7870 }
7871
7872 return arvif_iter.arvif;
7873}
7874
7875int ath10k_mac_register(struct ath10k *ar)
7876{
Johannes Berg3cb10942015-01-22 21:38:45 +01007877 static const u32 cipher_suites[] = {
7878 WLAN_CIPHER_SUITE_WEP40,
7879 WLAN_CIPHER_SUITE_WEP104,
7880 WLAN_CIPHER_SUITE_TKIP,
7881 WLAN_CIPHER_SUITE_CCMP,
7882 WLAN_CIPHER_SUITE_AES_CMAC,
7883 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03007884 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007885 void *channels;
7886 int ret;
7887
7888 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
7889
7890 SET_IEEE80211_DEV(ar->hw, ar->dev);
7891
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00007892 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
7893 ARRAY_SIZE(ath10k_5ghz_channels)) !=
7894 ATH10K_NUM_CHANS);
7895
Kalle Valo5e3dd152013-06-12 20:52:10 +03007896 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
7897 channels = kmemdup(ath10k_2ghz_channels,
7898 sizeof(ath10k_2ghz_channels),
7899 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02007900 if (!channels) {
7901 ret = -ENOMEM;
7902 goto err_free;
7903 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007904
Johannes Berg57fbcce2016-04-12 15:56:15 +02007905 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007906 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
7907 band->channels = channels;
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +03007908
7909 if (ar->hw_params.cck_rate_map_rev2) {
7910 band->n_bitrates = ath10k_g_rates_rev2_size;
7911 band->bitrates = ath10k_g_rates_rev2;
7912 } else {
7913 band->n_bitrates = ath10k_g_rates_size;
7914 band->bitrates = ath10k_g_rates;
7915 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007916
Johannes Berg57fbcce2016-04-12 15:56:15 +02007917 ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007918 }
7919
7920 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
7921 channels = kmemdup(ath10k_5ghz_channels,
7922 sizeof(ath10k_5ghz_channels),
7923 GFP_KERNEL);
7924 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02007925 ret = -ENOMEM;
7926 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007927 }
7928
Johannes Berg57fbcce2016-04-12 15:56:15 +02007929 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007930 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
7931 band->channels = channels;
7932 band->n_bitrates = ath10k_a_rates_size;
7933 band->bitrates = ath10k_a_rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02007934 ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007935 }
7936
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05307937 ath10k_mac_setup_ht_vht_cap(ar);
7938
Kalle Valo5e3dd152013-06-12 20:52:10 +03007939 ar->hw->wiphy->interface_modes =
7940 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007941 BIT(NL80211_IFTYPE_AP) |
7942 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01007943
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05307944 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
7945 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03007946
Kalle Valoc4cdf752016-04-20 19:45:18 +03007947 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))
Bartosz Markowskid3541812013-12-10 16:20:40 +01007948 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01007949 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01007950 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7951 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007952
Johannes Berg30686bf2015-06-02 21:39:54 +02007953 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
7954 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
7955 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
7956 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
7957 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
7958 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
7959 ieee80211_hw_set(ar->hw, AP_LINK_PS);
7960 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02007961 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
7962 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
7963 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
7964 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
7965 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
7966 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007967
David Liuccec9032015-07-24 20:25:32 +03007968 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7969 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
7970
Eliad Peller0d8614b2014-09-10 14:07:36 +03007971 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00007972 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03007973
Kalle Valo5e3dd152013-06-12 20:52:10 +03007974 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03007975 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007976
7977 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02007978 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
7979 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007980 }
7981
7982 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
7983 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
7984
7985 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01007986 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02007987 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007988
Kalle Valo5e3dd152013-06-12 20:52:10 +03007989 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
7990
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02007991 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
7992 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
7993
7994 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
7995 * that userspace (e.g. wpa_supplicant/hostapd) can generate
7996 * correct Probe Responses. This is more of a hack advert..
7997 */
7998 ar->hw->wiphy->probe_resp_offload |=
7999 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
8000 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
8001 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
8002 }
8003
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03008004 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
8005 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
8006
Kalle Valo5e3dd152013-06-12 20:52:10 +03008007 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01008008 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008009 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
8010
8011 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05308012 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
8013 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02008014
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01008015 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
8016
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02008017 ret = ath10k_wow_init(ar);
8018 if (ret) {
8019 ath10k_warn(ar, "failed to init wow: %d\n", ret);
8020 goto err_free;
8021 }
8022
Janusz Dziedzicc7025342015-06-15 14:46:41 +03008023 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
8024
Kalle Valo5e3dd152013-06-12 20:52:10 +03008025 /*
8026 * on LL hardware queues are managed entirely by the FW
8027 * so we only advertise to mac we can do the queues thing
8028 */
Michal Kazior96d828d2015-03-31 10:26:23 +00008029 ar->hw->queues = IEEE80211_MAX_QUEUES;
8030
8031 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
8032 * something that vdev_ids can't reach so that we don't stop the queue
8033 * accidentally.
8034 */
8035 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008036
Kalle Valobf3c13a2016-04-20 19:45:33 +03008037 switch (ar->running_fw->fw_file.wmi_op_version) {
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008038 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01008039 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
8040 ar->hw->wiphy->n_iface_combinations =
8041 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03008042 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008043 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00008044 case ATH10K_FW_WMI_OP_VERSION_TLV:
8045 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
8046 ar->hw->wiphy->iface_combinations =
8047 ath10k_tlv_qcs_if_comb;
8048 ar->hw->wiphy->n_iface_combinations =
8049 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
8050 } else {
8051 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
8052 ar->hw->wiphy->n_iface_combinations =
8053 ARRAY_SIZE(ath10k_tlv_if_comb);
8054 }
8055 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
8056 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008057 case ATH10K_FW_WMI_OP_VERSION_10_1:
8058 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02008059 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008060 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
8061 ar->hw->wiphy->n_iface_combinations =
8062 ARRAY_SIZE(ath10k_10x_if_comb);
8063 break;
Raja Mani9bd21322015-06-22 20:10:09 +05308064 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05308065 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
8066 ar->hw->wiphy->n_iface_combinations =
8067 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05308068 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008069 case ATH10K_FW_WMI_OP_VERSION_UNSET:
8070 case ATH10K_FW_WMI_OP_VERSION_MAX:
8071 WARN_ON(1);
8072 ret = -EINVAL;
8073 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01008074 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008075
David Liuccec9032015-07-24 20:25:32 +03008076 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8077 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02008078
Masahiro Yamada97f26452016-08-03 13:45:50 -07008079 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008080 /* Init ath dfs pattern detector */
8081 ar->ath_common.debug_mask = ATH_DBG_DFS;
8082 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
8083 NL80211_DFS_UNSET);
8084
8085 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02008086 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008087 }
8088
Michal Kazior4ca18072016-07-18 23:22:18 +03008089 /* Current wake_tx_queue implementation imposes a significant
8090 * performance penalty in some setups. The tx scheduling code needs
8091 * more work anyway so disable the wake_tx_queue unless firmware
8092 * supports the pull-push mechanism.
8093 */
8094 if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,
8095 ar->running_fw->fw_file.fw_features))
8096 ar->ops->wake_tx_queue = NULL;
8097
Kalle Valo5e3dd152013-06-12 20:52:10 +03008098 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
8099 ath10k_reg_notifier);
8100 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008101 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008102 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008103 }
8104
Johannes Berg3cb10942015-01-22 21:38:45 +01008105 ar->hw->wiphy->cipher_suites = cipher_suites;
8106 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
8107
Kalle Valo5e3dd152013-06-12 20:52:10 +03008108 ret = ieee80211_register_hw(ar->hw);
8109 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008110 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008111 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008112 }
8113
8114 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
8115 ret = regulatory_hint(ar->hw->wiphy,
8116 ar->ath_common.regulatory.alpha2);
8117 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02008118 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008119 }
8120
8121 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02008122
8123err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03008124 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07008125
8126err_dfs_detector_exit:
Masahiro Yamada97f26452016-08-03 13:45:50 -07008127 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Jeff Johnson0e339442015-10-08 09:15:53 -07008128 ar->dfs_detector->exit(ar->dfs_detector);
8129
Michal Kaziord6015b22013-07-22 14:13:30 +02008130err_free:
Johannes Berg57fbcce2016-04-12 15:56:15 +02008131 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8132 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Michal Kaziord6015b22013-07-22 14:13:30 +02008133
Jeff Johnson0e339442015-10-08 09:15:53 -07008134 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008135 return ret;
8136}
8137
8138void ath10k_mac_unregister(struct ath10k *ar)
8139{
8140 ieee80211_unregister_hw(ar->hw);
8141
Masahiro Yamada97f26452016-08-03 13:45:50 -07008142 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008143 ar->dfs_detector->exit(ar->dfs_detector);
8144
Johannes Berg57fbcce2016-04-12 15:56:15 +02008145 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8146 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008147
8148 SET_IEEE80211_DEV(ar->hw, NULL);
8149}