blob: f2e85eb22afe6b767eb6a2923b92983ad9489c8b [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
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001227static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1228{
1229 struct ath10k *ar = arvif->ar;
1230 u32 vdev_param, rts_cts = 0;
1231
1232 lockdep_assert_held(&ar->conf_mutex);
1233
1234 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1235
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001236 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001237
1238 if (arvif->num_legacy_stations > 0)
1239 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1240 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001241 else
1242 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1243 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001244
1245 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1246 rts_cts);
1247}
1248
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001249static int ath10k_start_cac(struct ath10k *ar)
1250{
1251 int ret;
1252
1253 lockdep_assert_held(&ar->conf_mutex);
1254
1255 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1256
Michal Kazior19337472014-08-28 12:58:16 +02001257 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001258 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001259 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001260 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1261 return ret;
1262 }
1263
Michal Kazior7aa7a722014-08-25 12:09:38 +02001264 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001265 ar->monitor_vdev_id);
1266
1267 return 0;
1268}
1269
1270static int ath10k_stop_cac(struct ath10k *ar)
1271{
1272 lockdep_assert_held(&ar->conf_mutex);
1273
1274 /* CAC is not running - do nothing */
1275 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1276 return 0;
1277
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001278 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001279 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001280
Michal Kazior7aa7a722014-08-25 12:09:38 +02001281 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001282
1283 return 0;
1284}
1285
Michal Kazior500ff9f2015-03-31 10:26:21 +00001286static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1287 struct ieee80211_chanctx_conf *conf,
1288 void *data)
1289{
1290 bool *ret = data;
1291
1292 if (!*ret && conf->radar_enabled)
1293 *ret = true;
1294}
1295
1296static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1297{
1298 bool has_radar = false;
1299
1300 ieee80211_iter_chan_contexts_atomic(ar->hw,
1301 ath10k_mac_has_radar_iter,
1302 &has_radar);
1303
1304 return has_radar;
1305}
1306
Michal Kaziord6500972014-04-08 09:56:09 +03001307static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001308{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001309 int ret;
1310
1311 lockdep_assert_held(&ar->conf_mutex);
1312
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001313 ath10k_stop_cac(ar);
1314
Michal Kazior500ff9f2015-03-31 10:26:21 +00001315 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001316 return;
1317
Michal Kaziord6500972014-04-08 09:56:09 +03001318 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001319 return;
1320
1321 ret = ath10k_start_cac(ar);
1322 if (ret) {
1323 /*
1324 * Not possible to start CAC on current channel so starting
1325 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1326 * by indicating that radar was detected.
1327 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001328 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001329 ieee80211_radar_detected(ar->hw);
1330 }
1331}
1332
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301333static int ath10k_vdev_stop(struct ath10k_vif *arvif)
Michal Kazior72654fa2014-04-08 09:56:09 +03001334{
1335 struct ath10k *ar = arvif->ar;
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301336 int ret;
1337
1338 lockdep_assert_held(&ar->conf_mutex);
1339
1340 reinit_completion(&ar->vdev_setup_done);
1341
1342 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1343 if (ret) {
1344 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1345 arvif->vdev_id, ret);
1346 return ret;
1347 }
1348
1349 ret = ath10k_vdev_setup_sync(ar);
1350 if (ret) {
1351 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
1352 arvif->vdev_id, ret);
1353 return ret;
1354 }
1355
1356 WARN_ON(ar->num_started_vdevs == 0);
1357
1358 if (ar->num_started_vdevs != 0) {
1359 ar->num_started_vdevs--;
1360 ath10k_recalc_radar_detection(ar);
1361 }
1362
1363 return ret;
1364}
1365
Michal Kazior500ff9f2015-03-31 10:26:21 +00001366static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1367 const struct cfg80211_chan_def *chandef,
1368 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001369{
1370 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001371 struct wmi_vdev_start_request_arg arg = {};
1372 int ret = 0;
1373
1374 lockdep_assert_held(&ar->conf_mutex);
1375
1376 reinit_completion(&ar->vdev_setup_done);
1377
1378 arg.vdev_id = arvif->vdev_id;
1379 arg.dtim_period = arvif->dtim_period;
1380 arg.bcn_intval = arvif->beacon_interval;
1381
1382 arg.channel.freq = chandef->chan->center_freq;
1383 arg.channel.band_center_freq1 = chandef->center_freq1;
1384 arg.channel.mode = chan_to_phymode(chandef);
1385
1386 arg.channel.min_power = 0;
1387 arg.channel.max_power = chandef->chan->max_power * 2;
1388 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1389 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1390
1391 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1392 arg.ssid = arvif->u.ap.ssid;
1393 arg.ssid_len = arvif->u.ap.ssid_len;
1394 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1395
1396 /* For now allow DFS for AP mode */
1397 arg.channel.chan_radar =
1398 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1399 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1400 arg.ssid = arvif->vif->bss_conf.ssid;
1401 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1402 }
1403
Michal Kazior7aa7a722014-08-25 12:09:38 +02001404 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001405 "mac vdev %d start center_freq %d phymode %s\n",
1406 arg.vdev_id, arg.channel.freq,
1407 ath10k_wmi_phymode_str(arg.channel.mode));
1408
Michal Kaziordc55e302014-07-29 12:53:36 +03001409 if (restart)
1410 ret = ath10k_wmi_vdev_restart(ar, &arg);
1411 else
1412 ret = ath10k_wmi_vdev_start(ar, &arg);
1413
Michal Kazior72654fa2014-04-08 09:56:09 +03001414 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001415 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001416 arg.vdev_id, ret);
1417 return ret;
1418 }
1419
1420 ret = ath10k_vdev_setup_sync(ar);
1421 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001422 ath10k_warn(ar,
1423 "failed to synchronize setup for vdev %i restart %d: %d\n",
1424 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001425 return ret;
1426 }
1427
Michal Kaziord6500972014-04-08 09:56:09 +03001428 ar->num_started_vdevs++;
1429 ath10k_recalc_radar_detection(ar);
1430
Michal Kazior72654fa2014-04-08 09:56:09 +03001431 return ret;
1432}
1433
Michal Kazior500ff9f2015-03-31 10:26:21 +00001434static int ath10k_vdev_start(struct ath10k_vif *arvif,
1435 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001436{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001437 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001438}
1439
Michal Kazior500ff9f2015-03-31 10:26:21 +00001440static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1441 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001442{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001443 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kazior72654fa2014-04-08 09:56:09 +03001444}
1445
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001446static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1447 struct sk_buff *bcn)
1448{
1449 struct ath10k *ar = arvif->ar;
1450 struct ieee80211_mgmt *mgmt;
1451 const u8 *p2p_ie;
1452 int ret;
1453
Peter Oh08c27be2016-01-28 13:54:09 -08001454 if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001455 return 0;
1456
1457 mgmt = (void *)bcn->data;
1458 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1459 mgmt->u.beacon.variable,
1460 bcn->len - (mgmt->u.beacon.variable -
1461 bcn->data));
1462 if (!p2p_ie)
1463 return -ENOENT;
1464
1465 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1466 if (ret) {
1467 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1468 arvif->vdev_id, ret);
1469 return ret;
1470 }
1471
1472 return 0;
1473}
1474
1475static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1476 u8 oui_type, size_t ie_offset)
1477{
1478 size_t len;
1479 const u8 *next;
1480 const u8 *end;
1481 u8 *ie;
1482
1483 if (WARN_ON(skb->len < ie_offset))
1484 return -EINVAL;
1485
1486 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1487 skb->data + ie_offset,
1488 skb->len - ie_offset);
1489 if (!ie)
1490 return -ENOENT;
1491
1492 len = ie[1] + 2;
1493 end = skb->data + skb->len;
1494 next = ie + len;
1495
1496 if (WARN_ON(next > end))
1497 return -EINVAL;
1498
1499 memmove(ie, next, end - next);
1500 skb_trim(skb, skb->len - len);
1501
1502 return 0;
1503}
1504
1505static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1506{
1507 struct ath10k *ar = arvif->ar;
1508 struct ieee80211_hw *hw = ar->hw;
1509 struct ieee80211_vif *vif = arvif->vif;
1510 struct ieee80211_mutable_offsets offs = {};
1511 struct sk_buff *bcn;
1512 int ret;
1513
1514 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1515 return 0;
1516
Michal Kazior81a9a172015-03-05 16:02:17 +02001517 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1518 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1519 return 0;
1520
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001521 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1522 if (!bcn) {
1523 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1524 return -EPERM;
1525 }
1526
1527 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1528 if (ret) {
1529 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1530 kfree_skb(bcn);
1531 return ret;
1532 }
1533
1534 /* P2P IE is inserted by firmware automatically (as configured above)
1535 * so remove it from the base beacon template to avoid duplicate P2P
1536 * IEs in beacon frames.
1537 */
1538 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1539 offsetof(struct ieee80211_mgmt,
1540 u.beacon.variable));
1541
1542 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1543 0, NULL, 0);
1544 kfree_skb(bcn);
1545
1546 if (ret) {
1547 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1548 ret);
1549 return ret;
1550 }
1551
1552 return 0;
1553}
1554
1555static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1556{
1557 struct ath10k *ar = arvif->ar;
1558 struct ieee80211_hw *hw = ar->hw;
1559 struct ieee80211_vif *vif = arvif->vif;
1560 struct sk_buff *prb;
1561 int ret;
1562
1563 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1564 return 0;
1565
Michal Kazior81a9a172015-03-05 16:02:17 +02001566 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1567 return 0;
1568
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001569 prb = ieee80211_proberesp_get(hw, vif);
1570 if (!prb) {
1571 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1572 return -EPERM;
1573 }
1574
1575 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1576 kfree_skb(prb);
1577
1578 if (ret) {
1579 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1580 ret);
1581 return ret;
1582 }
1583
1584 return 0;
1585}
1586
Michal Kazior500ff9f2015-03-31 10:26:21 +00001587static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1588{
1589 struct ath10k *ar = arvif->ar;
1590 struct cfg80211_chan_def def;
1591 int ret;
1592
1593 /* When originally vdev is started during assign_vif_chanctx() some
1594 * information is missing, notably SSID. Firmware revisions with beacon
1595 * offloading require the SSID to be provided during vdev (re)start to
1596 * handle hidden SSID properly.
1597 *
1598 * Vdev restart must be done after vdev has been both started and
1599 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1600 * deliver vdev restart response event causing timeouts during vdev
1601 * syncing in ath10k.
1602 *
1603 * Note: The vdev down/up and template reinstallation could be skipped
1604 * since only wmi-tlv firmware are known to have beacon offload and
1605 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1606 * response delivery. It's probably more robust to keep it as is.
1607 */
1608 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1609 return 0;
1610
1611 if (WARN_ON(!arvif->is_started))
1612 return -EINVAL;
1613
1614 if (WARN_ON(!arvif->is_up))
1615 return -EINVAL;
1616
1617 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1618 return -EINVAL;
1619
1620 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1621 if (ret) {
1622 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1623 arvif->vdev_id, ret);
1624 return ret;
1625 }
1626
1627 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1628 * firmware will crash upon vdev up.
1629 */
1630
1631 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1632 if (ret) {
1633 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1634 return ret;
1635 }
1636
1637 ret = ath10k_mac_setup_prb_tmpl(arvif);
1638 if (ret) {
1639 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1640 return ret;
1641 }
1642
1643 ret = ath10k_vdev_restart(arvif, &def);
1644 if (ret) {
1645 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1646 arvif->vdev_id, ret);
1647 return ret;
1648 }
1649
1650 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1651 arvif->bssid);
1652 if (ret) {
1653 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1654 arvif->vdev_id, ret);
1655 return ret;
1656 }
1657
1658 return 0;
1659}
1660
Kalle Valo5e3dd152013-06-12 20:52:10 +03001661static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001662 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001663{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001664 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001665 int ret = 0;
1666
Michal Kazior548db542013-07-05 16:15:15 +03001667 lockdep_assert_held(&arvif->ar->conf_mutex);
1668
Kalle Valo5e3dd152013-06-12 20:52:10 +03001669 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001670 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1671 if (ret)
1672 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1673 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001674
Michal Kaziorc930f742014-01-23 11:38:25 +01001675 arvif->is_up = false;
1676
Michal Kazior748afc42014-01-23 12:48:21 +01001677 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001678 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001679 spin_unlock_bh(&arvif->ar->data_lock);
1680
Kalle Valo5e3dd152013-06-12 20:52:10 +03001681 return;
1682 }
1683
1684 arvif->tx_seq_no = 0x1000;
1685
Michal Kaziorc930f742014-01-23 11:38:25 +01001686 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001687 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001688
1689 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1690 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001691 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001692 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001693 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001694 return;
1695 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001696
Michal Kaziorc930f742014-01-23 11:38:25 +01001697 arvif->is_up = true;
1698
Michal Kazior500ff9f2015-03-31 10:26:21 +00001699 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1700 if (ret) {
1701 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1702 arvif->vdev_id, ret);
1703 return;
1704 }
1705
Michal Kazior7aa7a722014-08-25 12:09:38 +02001706 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001707}
1708
1709static void ath10k_control_ibss(struct ath10k_vif *arvif,
1710 struct ieee80211_bss_conf *info,
1711 const u8 self_peer[ETH_ALEN])
1712{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001713 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001714 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001715 int ret = 0;
1716
Michal Kazior548db542013-07-05 16:15:15 +03001717 lockdep_assert_held(&arvif->ar->conf_mutex);
1718
Kalle Valo5e3dd152013-06-12 20:52:10 +03001719 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001720 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001721 return;
1722
Joe Perches93803b32015-03-02 19:54:49 -08001723 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001724
1725 return;
1726 }
1727
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001728 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1729 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001730 ATH10K_DEFAULT_ATIM);
1731 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001732 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001733 arvif->vdev_id, ret);
1734}
1735
Michal Kazior9f9b5742014-12-12 12:41:36 +01001736static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1737{
1738 struct ath10k *ar = arvif->ar;
1739 u32 param;
1740 u32 value;
1741 int ret;
1742
1743 lockdep_assert_held(&arvif->ar->conf_mutex);
1744
1745 if (arvif->u.sta.uapsd)
1746 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1747 else
1748 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1749
1750 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1751 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1752 if (ret) {
1753 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1754 value, arvif->vdev_id, ret);
1755 return ret;
1756 }
1757
1758 return 0;
1759}
1760
1761static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1762{
1763 struct ath10k *ar = arvif->ar;
1764 u32 param;
1765 u32 value;
1766 int ret;
1767
1768 lockdep_assert_held(&arvif->ar->conf_mutex);
1769
1770 if (arvif->u.sta.uapsd)
1771 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1772 else
1773 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1774
1775 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1776 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1777 param, value);
1778 if (ret) {
1779 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1780 value, arvif->vdev_id, ret);
1781 return ret;
1782 }
1783
1784 return 0;
1785}
1786
Michal Kazior424f2632015-07-09 13:08:35 +02001787static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001788{
1789 struct ath10k_vif *arvif;
1790 int num = 0;
1791
1792 lockdep_assert_held(&ar->conf_mutex);
1793
1794 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001795 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001796 num++;
1797
1798 return num;
1799}
1800
Michal Kaziorad088bf2013-10-16 15:44:46 +03001801static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001802{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001803 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001804 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001805 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001806 enum wmi_sta_powersave_param param;
1807 enum wmi_sta_ps_mode psmode;
1808 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001809 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001810 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001811
Michal Kazior548db542013-07-05 16:15:15 +03001812 lockdep_assert_held(&arvif->ar->conf_mutex);
1813
Michal Kaziorad088bf2013-10-16 15:44:46 +03001814 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1815 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001816
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001817 enable_ps = arvif->ps;
1818
Michal Kazior424f2632015-07-09 13:08:35 +02001819 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001820 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
Kalle Valoc4cdf752016-04-20 19:45:18 +03001821 ar->running_fw->fw_file.fw_features)) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001822 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1823 arvif->vdev_id);
1824 enable_ps = false;
1825 }
1826
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001827 if (!arvif->is_started) {
1828 /* mac80211 can update vif powersave state while disconnected.
1829 * Firmware doesn't behave nicely and consumes more power than
1830 * necessary if PS is disabled on a non-started vdev. Hence
1831 * force-enable PS for non-running vdevs.
1832 */
1833 psmode = WMI_STA_PS_MODE_ENABLED;
1834 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001835 psmode = WMI_STA_PS_MODE_ENABLED;
1836 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1837
Michal Kazior526549a2014-12-12 12:41:37 +01001838 ps_timeout = conf->dynamic_ps_timeout;
1839 if (ps_timeout == 0) {
1840 /* Firmware doesn't like 0 */
1841 ps_timeout = ieee80211_tu_to_usec(
1842 vif->bss_conf.beacon_int) / 1000;
1843 }
1844
Michal Kaziorad088bf2013-10-16 15:44:46 +03001845 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001846 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001847 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001848 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001849 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001850 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001851 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001852 } else {
1853 psmode = WMI_STA_PS_MODE_DISABLED;
1854 }
1855
Michal Kazior7aa7a722014-08-25 12:09:38 +02001856 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001857 arvif->vdev_id, psmode ? "enable" : "disable");
1858
Michal Kaziorad088bf2013-10-16 15:44:46 +03001859 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1860 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001861 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001862 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001863 return ret;
1864 }
1865
1866 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001867}
1868
Michal Kazior46725b12015-01-28 09:57:49 +02001869static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1870{
1871 struct ath10k *ar = arvif->ar;
1872 struct wmi_sta_keepalive_arg arg = {};
1873 int ret;
1874
1875 lockdep_assert_held(&arvif->ar->conf_mutex);
1876
1877 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1878 return 0;
1879
1880 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1881 return 0;
1882
1883 /* Some firmware revisions have a bug and ignore the `enabled` field.
1884 * Instead use the interval to disable the keepalive.
1885 */
1886 arg.vdev_id = arvif->vdev_id;
1887 arg.enabled = 1;
1888 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1889 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1890
1891 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1892 if (ret) {
1893 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1894 arvif->vdev_id, ret);
1895 return ret;
1896 }
1897
1898 return 0;
1899}
1900
Michal Kazior81a9a172015-03-05 16:02:17 +02001901static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1902{
1903 struct ath10k *ar = arvif->ar;
1904 struct ieee80211_vif *vif = arvif->vif;
1905 int ret;
1906
Michal Kazior8513d952015-03-09 14:19:24 +01001907 lockdep_assert_held(&arvif->ar->conf_mutex);
1908
1909 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1910 return;
1911
Michal Kazior81a9a172015-03-05 16:02:17 +02001912 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1913 return;
1914
1915 if (!vif->csa_active)
1916 return;
1917
1918 if (!arvif->is_up)
1919 return;
1920
1921 if (!ieee80211_csa_is_complete(vif)) {
1922 ieee80211_csa_update_counter(vif);
1923
1924 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1925 if (ret)
1926 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1927 ret);
1928
1929 ret = ath10k_mac_setup_prb_tmpl(arvif);
1930 if (ret)
1931 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1932 ret);
1933 } else {
1934 ieee80211_csa_finish(vif);
1935 }
1936}
1937
1938static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1939{
1940 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1941 ap_csa_work);
1942 struct ath10k *ar = arvif->ar;
1943
1944 mutex_lock(&ar->conf_mutex);
1945 ath10k_mac_vif_ap_csa_count_down(arvif);
1946 mutex_unlock(&ar->conf_mutex);
1947}
1948
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001949static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1950 struct ieee80211_vif *vif)
1951{
1952 struct sk_buff *skb = data;
1953 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1954 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1955
1956 if (vif->type != NL80211_IFTYPE_STATION)
1957 return;
1958
1959 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1960 return;
1961
1962 cancel_delayed_work(&arvif->connection_loss_work);
1963}
1964
1965void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
1966{
1967 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1968 IEEE80211_IFACE_ITER_NORMAL,
1969 ath10k_mac_handle_beacon_iter,
1970 skb);
1971}
1972
1973static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
1974 struct ieee80211_vif *vif)
1975{
1976 u32 *vdev_id = data;
1977 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1978 struct ath10k *ar = arvif->ar;
1979 struct ieee80211_hw *hw = ar->hw;
1980
1981 if (arvif->vdev_id != *vdev_id)
1982 return;
1983
1984 if (!arvif->is_up)
1985 return;
1986
1987 ieee80211_beacon_loss(vif);
1988
1989 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
1990 * (done by mac80211) succeeds but beacons do not resume then it
1991 * doesn't make sense to continue operation. Queue connection loss work
1992 * which can be cancelled when beacon is received.
1993 */
1994 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
1995 ATH10K_CONNECTION_LOSS_HZ);
1996}
1997
1998void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
1999{
2000 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2001 IEEE80211_IFACE_ITER_NORMAL,
2002 ath10k_mac_handle_beacon_miss_iter,
2003 &vdev_id);
2004}
2005
2006static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
2007{
2008 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
2009 connection_loss_work.work);
2010 struct ieee80211_vif *vif = arvif->vif;
2011
2012 if (!arvif->is_up)
2013 return;
2014
2015 ieee80211_connection_loss(vif);
2016}
2017
Kalle Valo5e3dd152013-06-12 20:52:10 +03002018/**********************/
2019/* Station management */
2020/**********************/
2021
Michal Kazior590922a2014-10-21 10:10:29 +03002022static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
2023 struct ieee80211_vif *vif)
2024{
2025 /* Some firmware revisions have unstable STA powersave when listen
2026 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
2027 * generate NullFunc frames properly even if buffered frames have been
2028 * indicated in Beacon TIM. Firmware would seldom wake up to pull
2029 * buffered frames. Often pinging the device from AP would simply fail.
2030 *
2031 * As a workaround set it to 1.
2032 */
2033 if (vif->type == NL80211_IFTYPE_STATION)
2034 return 1;
2035
2036 return ar->hw->conf.listen_interval;
2037}
2038
Kalle Valo5e3dd152013-06-12 20:52:10 +03002039static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002040 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002041 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002042 struct wmi_peer_assoc_complete_arg *arg)
2043{
Michal Kazior590922a2014-10-21 10:10:29 +03002044 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorc51880e2015-03-30 09:51:57 +03002045 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03002046
Michal Kazior548db542013-07-05 16:15:15 +03002047 lockdep_assert_held(&ar->conf_mutex);
2048
Michal Kaziorc51880e2015-03-30 09:51:57 +03002049 if (vif->type == NL80211_IFTYPE_STATION)
2050 aid = vif->bss_conf.aid;
2051 else
2052 aid = sta->aid;
2053
Kalle Valob25f32c2014-09-14 12:50:49 +03002054 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002055 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002056 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002057 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03002058 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002059 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03002060 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002061}
2062
2063static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002064 struct ieee80211_vif *vif,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002065 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002066 struct wmi_peer_assoc_complete_arg *arg)
2067{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002068 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002069 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002070 struct cfg80211_bss *bss;
2071 const u8 *rsnie = NULL;
2072 const u8 *wpaie = NULL;
2073
Michal Kazior548db542013-07-05 16:15:15 +03002074 lockdep_assert_held(&ar->conf_mutex);
2075
Michal Kazior500ff9f2015-03-31 10:26:21 +00002076 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2077 return;
2078
2079 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
2080 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002081 if (bss) {
2082 const struct cfg80211_bss_ies *ies;
2083
2084 rcu_read_lock();
2085 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
2086
2087 ies = rcu_dereference(bss->ies);
2088
2089 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03002090 WLAN_OUI_TYPE_MICROSOFT_WPA,
2091 ies->data,
2092 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002093 rcu_read_unlock();
2094 cfg80211_put_bss(ar->hw->wiphy, bss);
2095 }
2096
2097 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2098 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002099 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002100 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002101 }
2102
2103 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002104 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002105 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002106 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002107
2108 if (sta->mfp &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03002109 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT,
2110 ar->running_fw->fw_file.fw_features)) {
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002111 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002112 }
2113}
2114
2115static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002116 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002117 struct ieee80211_sta *sta,
2118 struct wmi_peer_assoc_complete_arg *arg)
2119{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002120 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002121 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002122 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002123 const struct ieee80211_supported_band *sband;
2124 const struct ieee80211_rate *rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002125 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002126 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002127 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002128 int i;
2129
Michal Kazior548db542013-07-05 16:15:15 +03002130 lockdep_assert_held(&ar->conf_mutex);
2131
Michal Kazior500ff9f2015-03-31 10:26:21 +00002132 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2133 return;
2134
Michal Kazior45c9abc2015-04-21 20:42:58 +03002135 band = def.chan->band;
2136 sband = ar->hw->wiphy->bands[band];
2137 ratemask = sta->supp_rates[band];
2138 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002139 rates = sband->bitrates;
2140
2141 rateset->num_rates = 0;
2142
2143 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2144 if (!(ratemask & 1))
2145 continue;
2146
Michal Kazior486017c2015-03-30 09:51:54 +03002147 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2148 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002149 rateset->num_rates++;
2150 }
2151}
2152
Michal Kazior45c9abc2015-04-21 20:42:58 +03002153static bool
2154ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2155{
2156 int nss;
2157
2158 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2159 if (ht_mcs_mask[nss])
2160 return false;
2161
2162 return true;
2163}
2164
2165static bool
2166ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2167{
2168 int nss;
2169
2170 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2171 if (vht_mcs_mask[nss])
2172 return false;
2173
2174 return true;
2175}
2176
Kalle Valo5e3dd152013-06-12 20:52:10 +03002177static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002178 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002179 struct ieee80211_sta *sta,
2180 struct wmi_peer_assoc_complete_arg *arg)
2181{
2182 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002183 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2184 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002185 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002186 const u8 *ht_mcs_mask;
2187 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002188 int i, n;
2189 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002190 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002191
Michal Kazior548db542013-07-05 16:15:15 +03002192 lockdep_assert_held(&ar->conf_mutex);
2193
Michal Kazior45c9abc2015-04-21 20:42:58 +03002194 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2195 return;
2196
Kalle Valo5e3dd152013-06-12 20:52:10 +03002197 if (!ht_cap->ht_supported)
2198 return;
2199
Michal Kazior45c9abc2015-04-21 20:42:58 +03002200 band = def.chan->band;
2201 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2202 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2203
2204 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2205 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2206 return;
2207
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002208 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002209 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2210 ht_cap->ampdu_factor)) - 1;
2211
2212 arg->peer_mpdu_density =
2213 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2214
2215 arg->peer_ht_caps = ht_cap->cap;
2216 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2217
2218 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002219 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002220
2221 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002222 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002223 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2224 }
2225
Michal Kazior45c9abc2015-04-21 20:42:58 +03002226 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2227 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2228 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002229
Michal Kazior45c9abc2015-04-21 20:42:58 +03002230 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2231 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2232 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002233
2234 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2235 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002236 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002237 }
2238
2239 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002240 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2241 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2242 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2243 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002244 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002245 }
2246
Kalle Valo5e3dd152013-06-12 20:52:10 +03002247 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2248 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2249 else if (ht_cap->mcs.rx_mask[1])
2250 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2251
Michal Kazior45c9abc2015-04-21 20:42:58 +03002252 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2253 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2254 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2255 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002256 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002257 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002258
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002259 /*
2260 * This is a workaround for HT-enabled STAs which break the spec
2261 * and have no HT capabilities RX mask (no HT RX MCS map).
2262 *
2263 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2264 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2265 *
2266 * Firmware asserts if such situation occurs.
2267 */
2268 if (n == 0) {
2269 arg->peer_ht_rates.num_rates = 8;
2270 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2271 arg->peer_ht_rates.rates[i] = i;
2272 } else {
2273 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002274 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002275 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002276
Michal Kazior7aa7a722014-08-25 12:09:38 +02002277 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002278 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002279 arg->peer_ht_rates.num_rates,
2280 arg->peer_num_spatial_streams);
2281}
2282
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002283static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2284 struct ath10k_vif *arvif,
2285 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002286{
2287 u32 uapsd = 0;
2288 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002289 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002290
Michal Kazior548db542013-07-05 16:15:15 +03002291 lockdep_assert_held(&ar->conf_mutex);
2292
Kalle Valo5e3dd152013-06-12 20:52:10 +03002293 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002294 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002295 sta->uapsd_queues, sta->max_sp);
2296
Kalle Valo5e3dd152013-06-12 20:52:10 +03002297 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2298 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2299 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2300 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2301 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2302 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2303 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2304 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2305 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2306 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2307 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2308 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2309
Kalle Valo5e3dd152013-06-12 20:52:10 +03002310 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2311 max_sp = sta->max_sp;
2312
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002313 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2314 sta->addr,
2315 WMI_AP_PS_PEER_PARAM_UAPSD,
2316 uapsd);
2317 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002318 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002319 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002320 return ret;
2321 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002322
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002323 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2324 sta->addr,
2325 WMI_AP_PS_PEER_PARAM_MAX_SP,
2326 max_sp);
2327 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002328 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002329 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002330 return ret;
2331 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002332
2333 /* TODO setup this based on STA listen interval and
2334 beacon interval. Currently we don't know
2335 sta->listen_interval - mac80211 patch required.
2336 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002337 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002338 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2339 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002340 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002341 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002342 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002343 return ret;
2344 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002345 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002346
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002347 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002348}
2349
Michal Kazior45c9abc2015-04-21 20:42:58 +03002350static u16
2351ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2352 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2353{
2354 int idx_limit;
2355 int nss;
2356 u16 mcs_map;
2357 u16 mcs;
2358
2359 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2360 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2361 vht_mcs_limit[nss];
2362
2363 if (mcs_map)
2364 idx_limit = fls(mcs_map) - 1;
2365 else
2366 idx_limit = -1;
2367
2368 switch (idx_limit) {
2369 case 0: /* fall through */
2370 case 1: /* fall through */
2371 case 2: /* fall through */
2372 case 3: /* fall through */
2373 case 4: /* fall through */
2374 case 5: /* fall through */
2375 case 6: /* fall through */
2376 default:
2377 /* see ath10k_mac_can_set_bitrate_mask() */
2378 WARN_ON(1);
2379 /* fall through */
2380 case -1:
2381 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2382 break;
2383 case 7:
2384 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2385 break;
2386 case 8:
2387 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2388 break;
2389 case 9:
2390 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2391 break;
2392 }
2393
2394 tx_mcs_set &= ~(0x3 << (nss * 2));
2395 tx_mcs_set |= mcs << (nss * 2);
2396 }
2397
2398 return tx_mcs_set;
2399}
2400
Kalle Valo5e3dd152013-06-12 20:52:10 +03002401static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002402 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002403 struct ieee80211_sta *sta,
2404 struct wmi_peer_assoc_complete_arg *arg)
2405{
2406 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002407 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002408 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002409 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002410 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002411 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002412
Michal Kazior500ff9f2015-03-31 10:26:21 +00002413 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2414 return;
2415
Kalle Valo5e3dd152013-06-12 20:52:10 +03002416 if (!vht_cap->vht_supported)
2417 return;
2418
Michal Kazior45c9abc2015-04-21 20:42:58 +03002419 band = def.chan->band;
2420 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2421
2422 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2423 return;
2424
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002425 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002426
Johannes Berg57fbcce2016-04-12 15:56:15 +02002427 if (def.chan->band == NL80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002428 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002429
Kalle Valo5e3dd152013-06-12 20:52:10 +03002430 arg->peer_vht_caps = vht_cap->cap;
2431
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002432 ampdu_factor = (vht_cap->cap &
2433 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2434 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2435
2436 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2437 * zero in VHT IE. Using it would result in degraded throughput.
2438 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2439 * it if VHT max_mpdu is smaller. */
2440 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2441 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2442 ampdu_factor)) - 1);
2443
Kalle Valo5e3dd152013-06-12 20:52:10 +03002444 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002445 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002446
2447 arg->peer_vht_rates.rx_max_rate =
2448 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2449 arg->peer_vht_rates.rx_mcs_set =
2450 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2451 arg->peer_vht_rates.tx_max_rate =
2452 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002453 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2454 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002455
Michal Kazior7aa7a722014-08-25 12:09:38 +02002456 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002457 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002458}
2459
2460static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002461 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002462 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002463 struct wmi_peer_assoc_complete_arg *arg)
2464{
Michal Kazior590922a2014-10-21 10:10:29 +03002465 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2466
Kalle Valo5e3dd152013-06-12 20:52:10 +03002467 switch (arvif->vdev_type) {
2468 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002469 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002470 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002471
2472 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002473 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002474 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2475 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002476 break;
2477 case WMI_VDEV_TYPE_STA:
Michal Kazior590922a2014-10-21 10:10:29 +03002478 if (vif->bss_conf.qos)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002479 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002480 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002481 case WMI_VDEV_TYPE_IBSS:
2482 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002483 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002484 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002485 default:
2486 break;
2487 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002488
2489 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002490 sta->addr, !!(arg->peer_flags &
2491 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002492}
2493
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002494static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002495{
Johannes Berg57fbcce2016-04-12 15:56:15 +02002496 return sta->supp_rates[NL80211_BAND_2GHZ] >>
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002497 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002498}
2499
Kalle Valo5e3dd152013-06-12 20:52:10 +03002500static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002501 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002502 struct ieee80211_sta *sta,
2503 struct wmi_peer_assoc_complete_arg *arg)
2504{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002505 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002506 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002507 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002508 const u8 *ht_mcs_mask;
2509 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002510 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2511
Michal Kazior500ff9f2015-03-31 10:26:21 +00002512 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2513 return;
2514
Michal Kazior45c9abc2015-04-21 20:42:58 +03002515 band = def.chan->band;
2516 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2517 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2518
2519 switch (band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02002520 case NL80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002521 if (sta->vht_cap.vht_supported &&
2522 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002523 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2524 phymode = MODE_11AC_VHT40;
2525 else
2526 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002527 } else if (sta->ht_cap.ht_supported &&
2528 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002529 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2530 phymode = MODE_11NG_HT40;
2531 else
2532 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002533 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002534 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002535 } else {
2536 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002537 }
2538
2539 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002540 case NL80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002541 /*
2542 * Check VHT first.
2543 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002544 if (sta->vht_cap.vht_supported &&
2545 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002546 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2547 phymode = MODE_11AC_VHT80;
2548 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2549 phymode = MODE_11AC_VHT40;
2550 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2551 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002552 } else if (sta->ht_cap.ht_supported &&
2553 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2554 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002555 phymode = MODE_11NA_HT40;
2556 else
2557 phymode = MODE_11NA_HT20;
2558 } else {
2559 phymode = MODE_11A;
2560 }
2561
2562 break;
2563 default:
2564 break;
2565 }
2566
Michal Kazior7aa7a722014-08-25 12:09:38 +02002567 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002568 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002569
Kalle Valo5e3dd152013-06-12 20:52:10 +03002570 arg->peer_phymode = phymode;
2571 WARN_ON(phymode == MODE_UNKNOWN);
2572}
2573
Kalle Valob9ada652013-10-16 15:44:46 +03002574static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002575 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002576 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002577 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002578{
Michal Kazior548db542013-07-05 16:15:15 +03002579 lockdep_assert_held(&ar->conf_mutex);
2580
Kalle Valob9ada652013-10-16 15:44:46 +03002581 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002582
Michal Kazior590922a2014-10-21 10:10:29 +03002583 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002584 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002585 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002586 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002587 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002588 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2589 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002590
Kalle Valob9ada652013-10-16 15:44:46 +03002591 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002592}
2593
Michal Kazior90046f52014-02-14 14:45:51 +01002594static const u32 ath10k_smps_map[] = {
2595 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2596 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2597 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2598 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2599};
2600
2601static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2602 const u8 *addr,
2603 const struct ieee80211_sta_ht_cap *ht_cap)
2604{
2605 int smps;
2606
2607 if (!ht_cap->ht_supported)
2608 return 0;
2609
2610 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2611 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2612
2613 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2614 return -EINVAL;
2615
2616 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2617 WMI_PEER_SMPS_STATE,
2618 ath10k_smps_map[smps]);
2619}
2620
Michal Kazior139e1702015-02-15 16:50:42 +02002621static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2622 struct ieee80211_vif *vif,
2623 struct ieee80211_sta_vht_cap vht_cap)
2624{
2625 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2626 int ret;
2627 u32 param;
2628 u32 value;
2629
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302630 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2631 return 0;
2632
Michal Kazior139e1702015-02-15 16:50:42 +02002633 if (!(ar->vht_cap_info &
2634 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2635 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2636 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2637 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2638 return 0;
2639
2640 param = ar->wmi.vdev_param->txbf;
2641 value = 0;
2642
2643 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2644 return 0;
2645
2646 /* The following logic is correct. If a remote STA advertises support
2647 * for being a beamformer then we should enable us being a beamformee.
2648 */
2649
2650 if (ar->vht_cap_info &
2651 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2652 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2653 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2654 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2655
2656 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2657 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2658 }
2659
2660 if (ar->vht_cap_info &
2661 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2662 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2663 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2664 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2665
2666 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2667 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2668 }
2669
2670 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2671 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2672
2673 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2674 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2675
2676 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2677 if (ret) {
2678 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2679 value, ret);
2680 return ret;
2681 }
2682
2683 return 0;
2684}
2685
Kalle Valo5e3dd152013-06-12 20:52:10 +03002686/* can be called only in mac80211 callbacks due to `key_count` usage */
2687static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2688 struct ieee80211_vif *vif,
2689 struct ieee80211_bss_conf *bss_conf)
2690{
2691 struct ath10k *ar = hw->priv;
2692 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002693 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002694 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002695 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002696 struct ieee80211_sta *ap_sta;
2697 int ret;
2698
Michal Kazior548db542013-07-05 16:15:15 +03002699 lockdep_assert_held(&ar->conf_mutex);
2700
Michal Kazior077efc82014-10-21 10:10:29 +03002701 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2702 arvif->vdev_id, arvif->bssid, arvif->aid);
2703
Kalle Valo5e3dd152013-06-12 20:52:10 +03002704 rcu_read_lock();
2705
2706 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2707 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002708 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002709 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002710 rcu_read_unlock();
2711 return;
2712 }
2713
Michal Kazior90046f52014-02-14 14:45:51 +01002714 /* ap_sta must be accessed only within rcu section which must be left
2715 * before calling ath10k_setup_peer_smps() which might sleep. */
2716 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002717 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002718
Michal Kazior590922a2014-10-21 10:10:29 +03002719 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002720 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002721 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002722 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002723 rcu_read_unlock();
2724 return;
2725 }
2726
2727 rcu_read_unlock();
2728
Kalle Valob9ada652013-10-16 15:44:46 +03002729 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2730 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002731 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002732 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002733 return;
2734 }
2735
Michal Kazior90046f52014-02-14 14:45:51 +01002736 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2737 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002738 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002739 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002740 return;
2741 }
2742
Michal Kazior139e1702015-02-15 16:50:42 +02002743 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2744 if (ret) {
2745 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2746 arvif->vdev_id, bss_conf->bssid, ret);
2747 return;
2748 }
2749
Michal Kazior7aa7a722014-08-25 12:09:38 +02002750 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002751 "mac vdev %d up (associated) bssid %pM aid %d\n",
2752 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2753
Michal Kazior077efc82014-10-21 10:10:29 +03002754 WARN_ON(arvif->is_up);
2755
Michal Kaziorc930f742014-01-23 11:38:25 +01002756 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002757 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002758
2759 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2760 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002761 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002762 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002763 return;
2764 }
2765
2766 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002767
2768 /* Workaround: Some firmware revisions (tested with qca6174
2769 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2770 * poked with peer param command.
2771 */
2772 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2773 WMI_PEER_DUMMY_VAR, 1);
2774 if (ret) {
2775 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2776 arvif->bssid, arvif->vdev_id, ret);
2777 return;
2778 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002779}
2780
Kalle Valo5e3dd152013-06-12 20:52:10 +03002781static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2782 struct ieee80211_vif *vif)
2783{
2784 struct ath10k *ar = hw->priv;
2785 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002786 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002787 int ret;
2788
Michal Kazior548db542013-07-05 16:15:15 +03002789 lockdep_assert_held(&ar->conf_mutex);
2790
Michal Kazior077efc82014-10-21 10:10:29 +03002791 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2792 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002793
Kalle Valo5e3dd152013-06-12 20:52:10 +03002794 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002795 if (ret)
Ben Greearaa66ba02016-09-26 21:56:25 +03002796 ath10k_warn(ar, "failed to down vdev %i: %d\n",
Michal Kazior077efc82014-10-21 10:10:29 +03002797 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002798
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002799 arvif->def_wep_key_idx = -1;
2800
Michal Kazior139e1702015-02-15 16:50:42 +02002801 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2802 if (ret) {
2803 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2804 arvif->vdev_id, ret);
2805 return;
2806 }
2807
Michal Kaziorc930f742014-01-23 11:38:25 +01002808 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002809
2810 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002811}
2812
Michal Kazior590922a2014-10-21 10:10:29 +03002813static int ath10k_station_assoc(struct ath10k *ar,
2814 struct ieee80211_vif *vif,
2815 struct ieee80211_sta *sta,
2816 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002817{
Michal Kazior590922a2014-10-21 10:10:29 +03002818 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002819 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002820 int ret = 0;
2821
Michal Kazior548db542013-07-05 16:15:15 +03002822 lockdep_assert_held(&ar->conf_mutex);
2823
Michal Kazior590922a2014-10-21 10:10:29 +03002824 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002825 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002826 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002827 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002828 return ret;
2829 }
2830
2831 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2832 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002833 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002834 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002835 return ret;
2836 }
2837
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002838 /* Re-assoc is run only to update supported rates for given station. It
2839 * doesn't make much sense to reconfigure the peer completely.
2840 */
2841 if (!reassoc) {
2842 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2843 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002844 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002845 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002846 arvif->vdev_id, ret);
2847 return ret;
2848 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002849
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002850 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2851 if (ret) {
2852 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2853 sta->addr, arvif->vdev_id, ret);
2854 return ret;
2855 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002856
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002857 if (!sta->wme) {
2858 arvif->num_legacy_stations++;
2859 ret = ath10k_recalc_rtscts_prot(arvif);
2860 if (ret) {
2861 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2862 arvif->vdev_id, ret);
2863 return ret;
2864 }
2865 }
2866
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002867 /* Plumb cached keys only for static WEP */
2868 if (arvif->def_wep_key_idx != -1) {
2869 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2870 if (ret) {
2871 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2872 arvif->vdev_id, ret);
2873 return ret;
2874 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002875 }
2876 }
2877
Kalle Valo5e3dd152013-06-12 20:52:10 +03002878 return ret;
2879}
2880
Michal Kazior590922a2014-10-21 10:10:29 +03002881static int ath10k_station_disassoc(struct ath10k *ar,
2882 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002883 struct ieee80211_sta *sta)
2884{
Michal Kazior590922a2014-10-21 10:10:29 +03002885 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002886 int ret = 0;
2887
2888 lockdep_assert_held(&ar->conf_mutex);
2889
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002890 if (!sta->wme) {
2891 arvif->num_legacy_stations--;
2892 ret = ath10k_recalc_rtscts_prot(arvif);
2893 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002894 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002895 arvif->vdev_id, ret);
2896 return ret;
2897 }
2898 }
2899
Kalle Valo5e3dd152013-06-12 20:52:10 +03002900 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2901 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002902 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002903 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002904 return ret;
2905 }
2906
2907 return ret;
2908}
2909
2910/**************/
2911/* Regulatory */
2912/**************/
2913
2914static int ath10k_update_channel_list(struct ath10k *ar)
2915{
2916 struct ieee80211_hw *hw = ar->hw;
2917 struct ieee80211_supported_band **bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002918 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002919 struct ieee80211_channel *channel;
2920 struct wmi_scan_chan_list_arg arg = {0};
2921 struct wmi_channel_arg *ch;
2922 bool passive;
2923 int len;
2924 int ret;
2925 int i;
2926
Michal Kazior548db542013-07-05 16:15:15 +03002927 lockdep_assert_held(&ar->conf_mutex);
2928
Kalle Valo5e3dd152013-06-12 20:52:10 +03002929 bands = hw->wiphy->bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002930 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002931 if (!bands[band])
2932 continue;
2933
2934 for (i = 0; i < bands[band]->n_channels; i++) {
2935 if (bands[band]->channels[i].flags &
2936 IEEE80211_CHAN_DISABLED)
2937 continue;
2938
2939 arg.n_channels++;
2940 }
2941 }
2942
2943 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2944 arg.channels = kzalloc(len, GFP_KERNEL);
2945 if (!arg.channels)
2946 return -ENOMEM;
2947
2948 ch = arg.channels;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002949 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002950 if (!bands[band])
2951 continue;
2952
2953 for (i = 0; i < bands[band]->n_channels; i++) {
2954 channel = &bands[band]->channels[i];
2955
2956 if (channel->flags & IEEE80211_CHAN_DISABLED)
2957 continue;
2958
Eduardo Abinader98029772016-06-30 15:23:55 +03002959 ch->allow_ht = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002960
2961 /* FIXME: when should we really allow VHT? */
2962 ch->allow_vht = true;
2963
2964 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002965 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002966
2967 ch->ht40plus =
2968 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2969
Marek Puzyniake8a50f82013-11-20 09:59:47 +02002970 ch->chan_radar =
2971 !!(channel->flags & IEEE80211_CHAN_RADAR);
2972
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002973 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002974 ch->passive = passive;
2975
2976 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02002977 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07002978 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07002979 ch->max_power = channel->max_power * 2;
2980 ch->max_reg_power = channel->max_reg_power * 2;
2981 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002982 ch->reg_class_id = 0; /* FIXME */
2983
2984 /* FIXME: why use only legacy modes, why not any
2985 * HT/VHT modes? Would that even make any
2986 * difference? */
Johannes Berg57fbcce2016-04-12 15:56:15 +02002987 if (channel->band == NL80211_BAND_2GHZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002988 ch->mode = MODE_11G;
2989 else
2990 ch->mode = MODE_11A;
2991
2992 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
2993 continue;
2994
Michal Kazior7aa7a722014-08-25 12:09:38 +02002995 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002996 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
2997 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002998 ch->freq, ch->max_power, ch->max_reg_power,
2999 ch->max_antenna_gain, ch->mode);
3000
3001 ch++;
3002 }
3003 }
3004
3005 ret = ath10k_wmi_scan_chan_list(ar, &arg);
3006 kfree(arg.channels);
3007
3008 return ret;
3009}
3010
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003011static enum wmi_dfs_region
3012ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
3013{
3014 switch (dfs_region) {
3015 case NL80211_DFS_UNSET:
3016 return WMI_UNINIT_DFS_DOMAIN;
3017 case NL80211_DFS_FCC:
3018 return WMI_FCC_DFS_DOMAIN;
3019 case NL80211_DFS_ETSI:
3020 return WMI_ETSI_DFS_DOMAIN;
3021 case NL80211_DFS_JP:
3022 return WMI_MKK4_DFS_DOMAIN;
3023 }
3024 return WMI_UNINIT_DFS_DOMAIN;
3025}
3026
Michal Kaziorf7843d72013-07-16 09:38:52 +02003027static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003028{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003029 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003030 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003031 enum wmi_dfs_region wmi_dfs_reg;
3032 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003033
Michal Kaziorf7843d72013-07-16 09:38:52 +02003034 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003035
3036 ret = ath10k_update_channel_list(ar);
3037 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003038 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003039
3040 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003041
Masahiro Yamada97f26452016-08-03 13:45:50 -07003042 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003043 nl_dfs_reg = ar->dfs_detector->region;
3044 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
3045 } else {
3046 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
3047 }
3048
Kalle Valo5e3dd152013-06-12 20:52:10 +03003049 /* Target allows setting up per-band regdomain but ath_common provides
3050 * a combined one only */
3051 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02003052 regpair->reg_domain,
3053 regpair->reg_domain, /* 2ghz */
3054 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003055 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003056 regpair->reg_5ghz_ctl,
3057 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003058 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003059 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02003060}
Michal Kazior548db542013-07-05 16:15:15 +03003061
Michal Kaziorf7843d72013-07-16 09:38:52 +02003062static void ath10k_reg_notifier(struct wiphy *wiphy,
3063 struct regulatory_request *request)
3064{
3065 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
3066 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003067 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003068
3069 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3070
Masahiro Yamada97f26452016-08-03 13:45:50 -07003071 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003072 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003073 request->dfs_region);
3074 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3075 request->dfs_region);
3076 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003077 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003078 request->dfs_region);
3079 }
3080
Michal Kaziorf7843d72013-07-16 09:38:52 +02003081 mutex_lock(&ar->conf_mutex);
3082 if (ar->state == ATH10K_STATE_ON)
3083 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003084 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003085}
3086
3087/***************/
3088/* TX handlers */
3089/***************/
3090
Michal Kaziora30c7d02016-03-06 16:14:23 +02003091enum ath10k_mac_tx_path {
3092 ATH10K_MAC_TX_HTT,
3093 ATH10K_MAC_TX_HTT_MGMT,
3094 ATH10K_MAC_TX_WMI_MGMT,
3095 ATH10K_MAC_TX_UNKNOWN,
3096};
3097
Michal Kazior96d828d2015-03-31 10:26:23 +00003098void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3099{
3100 lockdep_assert_held(&ar->htt.tx_lock);
3101
3102 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3103 ar->tx_paused |= BIT(reason);
3104 ieee80211_stop_queues(ar->hw);
3105}
3106
3107static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3108 struct ieee80211_vif *vif)
3109{
3110 struct ath10k *ar = data;
3111 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3112
3113 if (arvif->tx_paused)
3114 return;
3115
3116 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3117}
3118
3119void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3120{
3121 lockdep_assert_held(&ar->htt.tx_lock);
3122
3123 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3124 ar->tx_paused &= ~BIT(reason);
3125
3126 if (ar->tx_paused)
3127 return;
3128
3129 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3130 IEEE80211_IFACE_ITER_RESUME_ALL,
3131 ath10k_mac_tx_unlock_iter,
3132 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003133
3134 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003135}
3136
3137void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3138{
3139 struct ath10k *ar = arvif->ar;
3140
3141 lockdep_assert_held(&ar->htt.tx_lock);
3142
3143 WARN_ON(reason >= BITS_PER_LONG);
3144 arvif->tx_paused |= BIT(reason);
3145 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3146}
3147
3148void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3149{
3150 struct ath10k *ar = arvif->ar;
3151
3152 lockdep_assert_held(&ar->htt.tx_lock);
3153
3154 WARN_ON(reason >= BITS_PER_LONG);
3155 arvif->tx_paused &= ~BIT(reason);
3156
3157 if (ar->tx_paused)
3158 return;
3159
3160 if (arvif->tx_paused)
3161 return;
3162
3163 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3164}
3165
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003166static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3167 enum wmi_tlv_tx_pause_id pause_id,
3168 enum wmi_tlv_tx_pause_action action)
3169{
3170 struct ath10k *ar = arvif->ar;
3171
3172 lockdep_assert_held(&ar->htt.tx_lock);
3173
Michal Kazioracd0b272015-07-09 13:08:38 +02003174 switch (action) {
3175 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3176 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003177 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003178 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3179 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3180 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003181 default:
Michal Kazioracd0b272015-07-09 13:08:38 +02003182 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
3183 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003184 break;
3185 }
3186}
3187
3188struct ath10k_mac_tx_pause {
3189 u32 vdev_id;
3190 enum wmi_tlv_tx_pause_id pause_id;
3191 enum wmi_tlv_tx_pause_action action;
3192};
3193
3194static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3195 struct ieee80211_vif *vif)
3196{
3197 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3198 struct ath10k_mac_tx_pause *arg = data;
3199
Michal Kazioracd0b272015-07-09 13:08:38 +02003200 if (arvif->vdev_id != arg->vdev_id)
3201 return;
3202
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003203 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3204}
3205
Michal Kazioracd0b272015-07-09 13:08:38 +02003206void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3207 enum wmi_tlv_tx_pause_id pause_id,
3208 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003209{
3210 struct ath10k_mac_tx_pause arg = {
3211 .vdev_id = vdev_id,
3212 .pause_id = pause_id,
3213 .action = action,
3214 };
3215
3216 spin_lock_bh(&ar->htt.tx_lock);
3217 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3218 IEEE80211_IFACE_ITER_RESUME_ALL,
3219 ath10k_mac_handle_tx_pause_iter,
3220 &arg);
3221 spin_unlock_bh(&ar->htt.tx_lock);
3222}
3223
Michal Kaziord740d8f2015-03-30 09:51:51 +03003224static enum ath10k_hw_txrx_mode
Michal Kazior6a2636d2015-11-18 06:59:16 +01003225ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3226 struct ieee80211_vif *vif,
3227 struct ieee80211_sta *sta,
3228 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003229{
3230 const struct ieee80211_hdr *hdr = (void *)skb->data;
3231 __le16 fc = hdr->frame_control;
3232
3233 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3234 return ATH10K_HW_TXRX_RAW;
3235
3236 if (ieee80211_is_mgmt(fc))
3237 return ATH10K_HW_TXRX_MGMT;
3238
3239 /* Workaround:
3240 *
3241 * NullFunc frames are mostly used to ping if a client or AP are still
3242 * reachable and responsive. This implies tx status reports must be
3243 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3244 * come to a conclusion that the other end disappeared and tear down
3245 * BSS connection or it can never disconnect from BSS/client (which is
3246 * the case).
3247 *
3248 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3249 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3250 * which seems to deliver correct tx reports for NullFunc frames. The
3251 * downside of using it is it ignores client powersave state so it can
3252 * end up disconnecting sleeping clients in AP mode. It should fix STA
3253 * mode though because AP don't sleep.
3254 */
3255 if (ar->htt.target_version_major < 3 &&
3256 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03003257 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3258 ar->running_fw->fw_file.fw_features))
Michal Kaziord740d8f2015-03-30 09:51:51 +03003259 return ATH10K_HW_TXRX_MGMT;
3260
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003261 /* Workaround:
3262 *
3263 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3264 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3265 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003266 *
3267 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003268 */
3269 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3270 return ATH10K_HW_TXRX_ETHERNET;
3271
David Liuccec9032015-07-24 20:25:32 +03003272 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3273 return ATH10K_HW_TXRX_RAW;
3274
Michal Kaziord740d8f2015-03-30 09:51:51 +03003275 return ATH10K_HW_TXRX_NATIVE_WIFI;
3276}
3277
David Liuccec9032015-07-24 20:25:32 +03003278static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003279 struct sk_buff *skb)
3280{
3281 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3282 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003283 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3284 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003285
3286 if (!ieee80211_has_protected(hdr->frame_control))
3287 return false;
3288
David Liuccec9032015-07-24 20:25:32 +03003289 if ((info->flags & mask) == mask)
3290 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003291
David Liuccec9032015-07-24 20:25:32 +03003292 if (vif)
3293 return !ath10k_vif_to_arvif(vif)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003294
David Liuccec9032015-07-24 20:25:32 +03003295 return true;
3296}
3297
Michal Kazior4b604552014-07-21 21:03:09 +03003298/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3299 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003300 */
Michal Kazior4b604552014-07-21 21:03:09 +03003301static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003302{
3303 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003304 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003305 u8 *qos_ctl;
3306
3307 if (!ieee80211_is_data_qos(hdr->frame_control))
3308 return;
3309
3310 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003311 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3312 skb->data, (void *)qos_ctl - (void *)skb->data);
3313 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003314
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003315 /* Some firmware revisions don't handle sending QoS NullFunc well.
3316 * These frames are mainly used for CQM purposes so it doesn't really
3317 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003318 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003319 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003320 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003321 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003322
3323 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003324}
3325
Michal Kaziord740d8f2015-03-30 09:51:51 +03003326static void ath10k_tx_h_8023(struct sk_buff *skb)
3327{
3328 struct ieee80211_hdr *hdr;
3329 struct rfc1042_hdr *rfc1042;
3330 struct ethhdr *eth;
3331 size_t hdrlen;
3332 u8 da[ETH_ALEN];
3333 u8 sa[ETH_ALEN];
3334 __be16 type;
3335
3336 hdr = (void *)skb->data;
3337 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3338 rfc1042 = (void *)skb->data + hdrlen;
3339
3340 ether_addr_copy(da, ieee80211_get_DA(hdr));
3341 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3342 type = rfc1042->snap_type;
3343
3344 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3345 skb_push(skb, sizeof(*eth));
3346
3347 eth = (void *)skb->data;
3348 ether_addr_copy(eth->h_dest, da);
3349 ether_addr_copy(eth->h_source, sa);
3350 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003351}
3352
Michal Kazior4b604552014-07-21 21:03:09 +03003353static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3354 struct ieee80211_vif *vif,
3355 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003356{
3357 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003358 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3359
3360 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003361 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003362 return;
3363
3364 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3365 spin_lock_bh(&ar->data_lock);
3366 if (arvif->u.ap.noa_data)
3367 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3368 GFP_ATOMIC))
3369 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3370 arvif->u.ap.noa_data,
3371 arvif->u.ap.noa_len);
3372 spin_unlock_bh(&ar->data_lock);
3373 }
3374}
3375
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003376static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3377 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003378 struct ieee80211_txq *txq,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003379 struct sk_buff *skb)
3380{
3381 struct ieee80211_hdr *hdr = (void *)skb->data;
3382 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3383
3384 cb->flags = 0;
3385 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3386 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3387
3388 if (ieee80211_is_mgmt(hdr->frame_control))
3389 cb->flags |= ATH10K_SKB_F_MGMT;
3390
3391 if (ieee80211_is_data_qos(hdr->frame_control))
3392 cb->flags |= ATH10K_SKB_F_QOS;
3393
3394 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003395 cb->txq = txq;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003396}
3397
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303398bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003399{
3400 /* FIXME: Not really sure since when the behaviour changed. At some
3401 * point new firmware stopped requiring creation of peer entries for
3402 * offchannel tx (and actually creating them causes issues with wmi-htc
3403 * tx credit replenishment and reliability). Assuming it's at least 3.4
3404 * because that's when the `freq` was introduced to TX_FRM HTT command.
3405 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303406 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303407 ar->htt.target_version_minor >= 4 &&
Kalle Valo77561f92016-04-20 19:45:47 +03003408 ar->running_fw->fw_file.htt_op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003409}
3410
Michal Kaziord740d8f2015-03-30 09:51:51 +03003411static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003412{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003413 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003414 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003415
Michal Kaziord740d8f2015-03-30 09:51:51 +03003416 spin_lock_bh(&ar->data_lock);
3417
3418 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3419 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3420 ret = -ENOSPC;
3421 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003422 }
3423
Michal Kaziord740d8f2015-03-30 09:51:51 +03003424 __skb_queue_tail(q, skb);
3425 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3426
3427unlock:
3428 spin_unlock_bh(&ar->data_lock);
3429
3430 return ret;
3431}
3432
Michal Kaziora30c7d02016-03-06 16:14:23 +02003433static enum ath10k_mac_tx_path
3434ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3435 struct sk_buff *skb,
3436 enum ath10k_hw_txrx_mode txmode)
3437{
3438 switch (txmode) {
3439 case ATH10K_HW_TXRX_RAW:
3440 case ATH10K_HW_TXRX_NATIVE_WIFI:
3441 case ATH10K_HW_TXRX_ETHERNET:
3442 return ATH10K_MAC_TX_HTT;
3443 case ATH10K_HW_TXRX_MGMT:
3444 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Kalle Valoc4cdf752016-04-20 19:45:18 +03003445 ar->running_fw->fw_file.fw_features))
Michal Kaziora30c7d02016-03-06 16:14:23 +02003446 return ATH10K_MAC_TX_WMI_MGMT;
3447 else if (ar->htt.target_version_major >= 3)
3448 return ATH10K_MAC_TX_HTT;
3449 else
3450 return ATH10K_MAC_TX_HTT_MGMT;
3451 }
3452
3453 return ATH10K_MAC_TX_UNKNOWN;
3454}
3455
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003456static int ath10k_mac_tx_submit(struct ath10k *ar,
3457 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003458 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003459 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003460{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003461 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003462 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003463
3464 switch (txpath) {
3465 case ATH10K_MAC_TX_HTT:
Michal Kazior8a933962015-11-18 06:59:17 +01003466 ret = ath10k_htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003467 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003468 case ATH10K_MAC_TX_HTT_MGMT:
3469 ret = ath10k_htt_mgmt_tx(htt, skb);
3470 break;
3471 case ATH10K_MAC_TX_WMI_MGMT:
3472 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3473 break;
3474 case ATH10K_MAC_TX_UNKNOWN:
3475 WARN_ON_ONCE(1);
3476 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003477 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003478 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003479
3480 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003481 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3482 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003483 ieee80211_free_txskb(ar->hw, skb);
3484 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003485
3486 return ret;
3487}
3488
3489/* This function consumes the sk_buff regardless of return value as far as
3490 * caller is concerned so no freeing is necessary afterwards.
3491 */
3492static int ath10k_mac_tx(struct ath10k *ar,
3493 struct ieee80211_vif *vif,
3494 struct ieee80211_sta *sta,
3495 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003496 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003497 struct sk_buff *skb)
3498{
3499 struct ieee80211_hw *hw = ar->hw;
3500 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3501 int ret;
3502
3503 /* We should disable CCK RATE due to P2P */
3504 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3505 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3506
3507 switch (txmode) {
3508 case ATH10K_HW_TXRX_MGMT:
3509 case ATH10K_HW_TXRX_NATIVE_WIFI:
3510 ath10k_tx_h_nwifi(hw, skb);
3511 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3512 ath10k_tx_h_seq_no(vif, skb);
3513 break;
3514 case ATH10K_HW_TXRX_ETHERNET:
3515 ath10k_tx_h_8023(skb);
3516 break;
3517 case ATH10K_HW_TXRX_RAW:
3518 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3519 WARN_ON_ONCE(1);
3520 ieee80211_free_txskb(hw, skb);
3521 return -ENOTSUPP;
3522 }
3523 }
3524
3525 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3526 if (!ath10k_mac_tx_frm_has_freq(ar)) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303527 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %pK\n",
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003528 skb);
3529
3530 skb_queue_tail(&ar->offchan_tx_queue, skb);
3531 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3532 return 0;
3533 }
3534 }
3535
Michal Kazior6421969f2016-03-06 16:14:25 +02003536 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003537 if (ret) {
3538 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3539 return ret;
3540 }
3541
3542 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003543}
3544
3545void ath10k_offchan_tx_purge(struct ath10k *ar)
3546{
3547 struct sk_buff *skb;
3548
3549 for (;;) {
3550 skb = skb_dequeue(&ar->offchan_tx_queue);
3551 if (!skb)
3552 break;
3553
3554 ieee80211_free_txskb(ar->hw, skb);
3555 }
3556}
3557
3558void ath10k_offchan_tx_work(struct work_struct *work)
3559{
3560 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3561 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003562 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003563 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003564 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003565 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003566 struct ieee80211_vif *vif;
3567 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003568 struct sk_buff *skb;
3569 const u8 *peer_addr;
3570 int vdev_id;
3571 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003572 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003573 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003574
3575 /* FW requirement: We must create a peer before FW will send out
3576 * an offchannel frame. Otherwise the frame will be stuck and
3577 * never transmitted. We delete the peer upon tx completion.
3578 * It is unlikely that a peer for offchannel tx will already be
3579 * present. However it may be in some rare cases so account for that.
3580 * Otherwise we might remove a legitimate peer and break stuff. */
3581
3582 for (;;) {
3583 skb = skb_dequeue(&ar->offchan_tx_queue);
3584 if (!skb)
3585 break;
3586
3587 mutex_lock(&ar->conf_mutex);
3588
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303589 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003590 skb);
3591
3592 hdr = (struct ieee80211_hdr *)skb->data;
3593 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003594
3595 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003596 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003597 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3598 spin_unlock_bh(&ar->data_lock);
3599
3600 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003601 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003602 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003603 peer_addr, vdev_id);
3604
3605 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003606 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3607 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003608 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003609 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003610 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003611 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003612 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003613 }
3614
3615 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003616 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003617 ar->offchan_tx_skb = skb;
3618 spin_unlock_bh(&ar->data_lock);
3619
Michal Kazior8a933962015-11-18 06:59:17 +01003620 /* It's safe to access vif and sta - conf_mutex guarantees that
3621 * sta_state() and remove_interface() are locked exclusively
3622 * out wrt to this offchannel worker.
3623 */
3624 arvif = ath10k_get_arvif(ar, vdev_id);
3625 if (arvif) {
3626 vif = arvif->vif;
3627 sta = ieee80211_find_sta(vif, peer_addr);
3628 } else {
3629 vif = NULL;
3630 sta = NULL;
3631 }
3632
3633 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003634 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003635
Michal Kazior6421969f2016-03-06 16:14:25 +02003636 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003637 if (ret) {
3638 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3639 ret);
3640 /* not serious */
3641 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003642
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003643 time_left =
3644 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3645 if (time_left == 0)
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303646 ath10k_warn(ar, "timed out waiting for offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003647 skb);
3648
Michal Kazioradaeed72015-08-05 12:15:23 +02003649 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003650 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3651 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003652 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003653 peer_addr, vdev_id, ret);
3654 }
3655
3656 mutex_unlock(&ar->conf_mutex);
3657 }
3658}
3659
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003660void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3661{
3662 struct sk_buff *skb;
3663
3664 for (;;) {
3665 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3666 if (!skb)
3667 break;
3668
3669 ieee80211_free_txskb(ar->hw, skb);
3670 }
3671}
3672
3673void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3674{
3675 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3676 struct sk_buff *skb;
3677 int ret;
3678
3679 for (;;) {
3680 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3681 if (!skb)
3682 break;
3683
3684 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003685 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003686 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003687 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003688 ieee80211_free_txskb(ar->hw, skb);
3689 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003690 }
3691}
3692
Michal Kazior29946872016-03-06 16:14:34 +02003693static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3694{
Bob Copelanda66cd732016-06-29 19:29:25 +03003695 struct ath10k_txq *artxq;
Michal Kazior29946872016-03-06 16:14:34 +02003696
3697 if (!txq)
3698 return;
3699
Bob Copelanda66cd732016-06-29 19:29:25 +03003700 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003701 INIT_LIST_HEAD(&artxq->list);
3702}
3703
3704static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3705{
Bob Copelanda66cd732016-06-29 19:29:25 +03003706 struct ath10k_txq *artxq;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003707 struct ath10k_skb_cb *cb;
3708 struct sk_buff *msdu;
3709 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003710
3711 if (!txq)
3712 return;
3713
Bob Copelanda66cd732016-06-29 19:29:25 +03003714 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003715 spin_lock_bh(&ar->txqs_lock);
3716 if (!list_empty(&artxq->list))
3717 list_del_init(&artxq->list);
3718 spin_unlock_bh(&ar->txqs_lock);
Michal Kaziordd4717b2016-03-06 16:14:39 +02003719
3720 spin_lock_bh(&ar->htt.tx_lock);
3721 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3722 cb = ATH10K_SKB_CB(msdu);
3723 if (cb->txq == txq)
3724 cb->txq = NULL;
3725 }
3726 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003727}
3728
Michal Kazior426e10e2016-03-06 16:14:43 +02003729struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
3730 u16 peer_id,
3731 u8 tid)
3732{
3733 struct ath10k_peer *peer;
3734
3735 lockdep_assert_held(&ar->data_lock);
3736
3737 peer = ar->peer_map[peer_id];
3738 if (!peer)
3739 return NULL;
3740
3741 if (peer->sta)
3742 return peer->sta->txq[tid];
3743 else if (peer->vif)
3744 return peer->vif->txq;
3745 else
3746 return NULL;
3747}
3748
Michal Kazior29946872016-03-06 16:14:34 +02003749static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3750 struct ieee80211_txq *txq)
3751{
Michal Kazior426e10e2016-03-06 16:14:43 +02003752 struct ath10k *ar = hw->priv;
3753 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3754
3755 /* No need to get locks */
3756
3757 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3758 return true;
3759
3760 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3761 return true;
3762
3763 if (artxq->num_fw_queued < artxq->num_push_allowed)
3764 return true;
3765
3766 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003767}
3768
Michal Kazior426e10e2016-03-06 16:14:43 +02003769int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3770 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02003771{
Michal Kazior29946872016-03-06 16:14:34 +02003772 struct ath10k *ar = hw->priv;
3773 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003774 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003775 struct ieee80211_vif *vif = txq->vif;
3776 struct ieee80211_sta *sta = txq->sta;
3777 enum ath10k_hw_txrx_mode txmode;
3778 enum ath10k_mac_tx_path txpath;
3779 struct sk_buff *skb;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303780 struct ieee80211_hdr *hdr;
Michal Kazior426e10e2016-03-06 16:14:43 +02003781 size_t skb_len;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303782 bool is_mgmt, is_presp;
Michal Kazior29946872016-03-06 16:14:34 +02003783 int ret;
3784
3785 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303786 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003787 spin_unlock_bh(&ar->htt.tx_lock);
3788
3789 if (ret)
3790 return ret;
3791
3792 skb = ieee80211_tx_dequeue(hw, txq);
3793 if (!skb) {
3794 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303795 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003796 spin_unlock_bh(&ar->htt.tx_lock);
3797
3798 return -ENOENT;
3799 }
3800
Michal Kaziordd4717b2016-03-06 16:14:39 +02003801 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Michal Kazior29946872016-03-06 16:14:34 +02003802
Michal Kazior426e10e2016-03-06 16:14:43 +02003803 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02003804 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
3805 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303806 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
3807
3808 if (is_mgmt) {
3809 hdr = (struct ieee80211_hdr *)skb->data;
3810 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
3811
3812 spin_lock_bh(&ar->htt.tx_lock);
3813 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
3814
3815 if (ret) {
3816 ath10k_htt_tx_dec_pending(htt);
3817 spin_unlock_bh(&ar->htt.tx_lock);
3818 return ret;
3819 }
3820 spin_unlock_bh(&ar->htt.tx_lock);
3821 }
Michal Kazior29946872016-03-06 16:14:34 +02003822
3823 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
3824 if (unlikely(ret)) {
3825 ath10k_warn(ar, "failed to push frame: %d\n", ret);
3826
3827 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303828 ath10k_htt_tx_dec_pending(htt);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303829 if (is_mgmt)
3830 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003831 spin_unlock_bh(&ar->htt.tx_lock);
3832
3833 return ret;
3834 }
3835
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003836 spin_lock_bh(&ar->htt.tx_lock);
3837 artxq->num_fw_queued++;
3838 spin_unlock_bh(&ar->htt.tx_lock);
3839
Michal Kazior426e10e2016-03-06 16:14:43 +02003840 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003841}
3842
3843void ath10k_mac_tx_push_pending(struct ath10k *ar)
3844{
3845 struct ieee80211_hw *hw = ar->hw;
3846 struct ieee80211_txq *txq;
3847 struct ath10k_txq *artxq;
3848 struct ath10k_txq *last;
3849 int ret;
3850 int max;
3851
Michal Kazior7a0adc82016-05-23 23:12:45 +03003852 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
3853 return;
3854
Michal Kazior29946872016-03-06 16:14:34 +02003855 spin_lock_bh(&ar->txqs_lock);
3856 rcu_read_lock();
3857
3858 last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
3859 while (!list_empty(&ar->txqs)) {
3860 artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
3861 txq = container_of((void *)artxq, struct ieee80211_txq,
3862 drv_priv);
3863
3864 /* Prevent aggressive sta/tid taking over tx queue */
3865 max = 16;
Michal Kazior750eeed2016-03-17 10:51:05 +01003866 ret = 0;
3867 while (ath10k_mac_tx_can_push(hw, txq) && max--) {
Michal Kazior29946872016-03-06 16:14:34 +02003868 ret = ath10k_mac_tx_push_txq(hw, txq);
3869 if (ret < 0)
3870 break;
3871 }
3872
3873 list_del_init(&artxq->list);
Michal Kazior9d71d472016-03-17 10:51:04 +01003874 if (ret != -ENOENT)
3875 list_add_tail(&artxq->list, &ar->txqs);
3876
Michal Kaziorc1a43d92016-03-06 16:14:36 +02003877 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02003878
Michal Kazior9d71d472016-03-17 10:51:04 +01003879 if (artxq == last || (ret < 0 && ret != -ENOENT))
Michal Kazior29946872016-03-06 16:14:34 +02003880 break;
Michal Kazior29946872016-03-06 16:14:34 +02003881 }
3882
3883 rcu_read_unlock();
3884 spin_unlock_bh(&ar->txqs_lock);
3885}
3886
Kalle Valo5e3dd152013-06-12 20:52:10 +03003887/************/
3888/* Scanning */
3889/************/
3890
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003891void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003892{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003893 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003894
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003895 switch (ar->scan.state) {
3896 case ATH10K_SCAN_IDLE:
3897 break;
3898 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01003899 case ATH10K_SCAN_ABORTING:
Avraham Stern7947d3e2016-07-05 15:23:12 +03003900 if (!ar->scan.is_roc) {
3901 struct cfg80211_scan_info info = {
3902 .aborted = (ar->scan.state ==
3903 ATH10K_SCAN_ABORTING),
3904 };
3905
3906 ieee80211_scan_completed(ar->hw, &info);
3907 } else if (ar->scan.roc_notify) {
Michal Kaziord710e752015-07-09 13:08:36 +02003908 ieee80211_remain_on_channel_expired(ar->hw);
Avraham Stern7947d3e2016-07-05 15:23:12 +03003909 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003910 /* fall through */
3911 case ATH10K_SCAN_STARTING:
3912 ar->scan.state = ATH10K_SCAN_IDLE;
3913 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01003914 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003915 ath10k_offchan_tx_purge(ar);
3916 cancel_delayed_work(&ar->scan.timeout);
Daniel Wagner881ed542016-08-18 15:12:06 +02003917 complete(&ar->scan.completed);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003918 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003919 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003920}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003921
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003922void ath10k_scan_finish(struct ath10k *ar)
3923{
3924 spin_lock_bh(&ar->data_lock);
3925 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003926 spin_unlock_bh(&ar->data_lock);
3927}
3928
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003929static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003930{
3931 struct wmi_stop_scan_arg arg = {
3932 .req_id = 1, /* FIXME */
3933 .req_type = WMI_SCAN_STOP_ONE,
3934 .u.scan_id = ATH10K_SCAN_ID,
3935 };
3936 int ret;
3937
3938 lockdep_assert_held(&ar->conf_mutex);
3939
Kalle Valo5e3dd152013-06-12 20:52:10 +03003940 ret = ath10k_wmi_stop_scan(ar, &arg);
3941 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003942 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003943 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003944 }
3945
Kalle Valo14e105c2016-04-13 14:13:21 +03003946 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003947 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003948 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003949 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003950 } else if (ret > 0) {
3951 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003952 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003953
3954out:
3955 /* Scan state should be updated upon scan completion but in case
3956 * firmware fails to deliver the event (for whatever reason) it is
3957 * desired to clean up scan state anyway. Firmware may have just
3958 * dropped the scan completion event delivery due to transport pipe
3959 * being overflown with data and/or it can recover on its own before
3960 * next scan request is submitted.
3961 */
3962 spin_lock_bh(&ar->data_lock);
3963 if (ar->scan.state != ATH10K_SCAN_IDLE)
3964 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003965 spin_unlock_bh(&ar->data_lock);
3966
3967 return ret;
3968}
3969
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003970static void ath10k_scan_abort(struct ath10k *ar)
3971{
3972 int ret;
3973
3974 lockdep_assert_held(&ar->conf_mutex);
3975
3976 spin_lock_bh(&ar->data_lock);
3977
3978 switch (ar->scan.state) {
3979 case ATH10K_SCAN_IDLE:
3980 /* This can happen if timeout worker kicked in and called
3981 * abortion while scan completion was being processed.
3982 */
3983 break;
3984 case ATH10K_SCAN_STARTING:
3985 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02003986 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003987 ath10k_scan_state_str(ar->scan.state),
3988 ar->scan.state);
3989 break;
3990 case ATH10K_SCAN_RUNNING:
3991 ar->scan.state = ATH10K_SCAN_ABORTING;
3992 spin_unlock_bh(&ar->data_lock);
3993
3994 ret = ath10k_scan_stop(ar);
3995 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003996 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003997
3998 spin_lock_bh(&ar->data_lock);
3999 break;
4000 }
4001
4002 spin_unlock_bh(&ar->data_lock);
4003}
4004
4005void ath10k_scan_timeout_work(struct work_struct *work)
4006{
4007 struct ath10k *ar = container_of(work, struct ath10k,
4008 scan.timeout.work);
4009
4010 mutex_lock(&ar->conf_mutex);
4011 ath10k_scan_abort(ar);
4012 mutex_unlock(&ar->conf_mutex);
4013}
4014
Kalle Valo5e3dd152013-06-12 20:52:10 +03004015static int ath10k_start_scan(struct ath10k *ar,
4016 const struct wmi_start_scan_arg *arg)
4017{
4018 int ret;
4019
4020 lockdep_assert_held(&ar->conf_mutex);
4021
4022 ret = ath10k_wmi_start_scan(ar, arg);
4023 if (ret)
4024 return ret;
4025
Kalle Valo14e105c2016-04-13 14:13:21 +03004026 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004027 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004028 ret = ath10k_scan_stop(ar);
4029 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004030 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004031
4032 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004033 }
4034
Ben Greear2f9eec02015-02-15 16:50:38 +02004035 /* If we failed to start the scan, return error code at
4036 * this point. This is probably due to some issue in the
4037 * firmware, but no need to wedge the driver due to that...
4038 */
4039 spin_lock_bh(&ar->data_lock);
4040 if (ar->scan.state == ATH10K_SCAN_IDLE) {
4041 spin_unlock_bh(&ar->data_lock);
4042 return -EINVAL;
4043 }
4044 spin_unlock_bh(&ar->data_lock);
4045
Kalle Valo5e3dd152013-06-12 20:52:10 +03004046 return 0;
4047}
4048
4049/**********************/
4050/* mac80211 callbacks */
4051/**********************/
4052
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004053static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4054 struct ieee80211_tx_control *control,
4055 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004056{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004057 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02004058 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03004059 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4060 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004061 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02004062 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02004063 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01004064 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02004065 enum ath10k_mac_tx_path txpath;
4066 bool is_htt;
4067 bool is_mgmt;
4068 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004069 int ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004070
Michal Kaziordd4717b2016-03-06 16:14:39 +02004071 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004072
Michal Kazior8a933962015-11-18 06:59:17 +01004073 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004074 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
4075 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
4076 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304077 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004078
Michal Kazior6421969f2016-03-06 16:14:25 +02004079 if (is_htt) {
4080 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004081 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4082
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304083 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004084 if (ret) {
4085 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4086 ret);
4087 spin_unlock_bh(&ar->htt.tx_lock);
4088 ieee80211_free_txskb(ar->hw, skb);
4089 return;
4090 }
4091
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304092 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4093 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304094 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4095 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304096 ath10k_htt_tx_dec_pending(htt);
4097 spin_unlock_bh(&ar->htt.tx_lock);
4098 ieee80211_free_txskb(ar->hw, skb);
4099 return;
4100 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004101 spin_unlock_bh(&ar->htt.tx_lock);
4102 }
4103
4104 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
4105 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004106 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004107 if (is_htt) {
4108 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304109 ath10k_htt_tx_dec_pending(htt);
4110 if (is_mgmt)
4111 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004112 spin_unlock_bh(&ar->htt.tx_lock);
4113 }
4114 return;
4115 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004116}
4117
Michal Kazior29946872016-03-06 16:14:34 +02004118static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4119 struct ieee80211_txq *txq)
4120{
4121 struct ath10k *ar = hw->priv;
4122 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304123 struct ieee80211_txq *f_txq;
4124 struct ath10k_txq *f_artxq;
4125 int ret = 0;
4126 int max = 16;
Michal Kazior29946872016-03-06 16:14:34 +02004127
Michal Kazior750eeed2016-03-17 10:51:05 +01004128 spin_lock_bh(&ar->txqs_lock);
4129 if (list_empty(&artxq->list))
4130 list_add_tail(&artxq->list, &ar->txqs);
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304131
4132 f_artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
4133 f_txq = container_of((void *)f_artxq, struct ieee80211_txq, drv_priv);
4134 list_del_init(&f_artxq->list);
4135
4136 while (ath10k_mac_tx_can_push(hw, f_txq) && max--) {
4137 ret = ath10k_mac_tx_push_txq(hw, f_txq);
4138 if (ret)
4139 break;
4140 }
4141 if (ret != -ENOENT)
4142 list_add_tail(&f_artxq->list, &ar->txqs);
Michal Kazior750eeed2016-03-17 10:51:05 +01004143 spin_unlock_bh(&ar->txqs_lock);
Michal Kazior29946872016-03-06 16:14:34 +02004144
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304145 ath10k_htt_tx_txq_update(hw, f_txq);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004146 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02004147}
4148
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004149/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004150void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004151{
4152 /* make sure rcu-protected mac80211 tx path itself is drained */
4153 synchronize_net();
4154
4155 ath10k_offchan_tx_purge(ar);
4156 ath10k_mgmt_over_wmi_tx_purge(ar);
4157
4158 cancel_work_sync(&ar->offchan_tx_work);
4159 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4160}
4161
Michal Kazioraffd3212013-07-16 09:54:35 +02004162void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004163{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004164 struct ath10k_vif *arvif;
4165
Michal Kazior818bdd12013-07-16 09:38:57 +02004166 lockdep_assert_held(&ar->conf_mutex);
4167
Michal Kazior19337472014-08-28 12:58:16 +02004168 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4169 ar->filter_flags = 0;
4170 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004171 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004172
4173 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004174 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004175
4176 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004177 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004178
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004179 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004180 ath10k_peer_cleanup_all(ar);
4181 ath10k_core_stop(ar);
4182 ath10k_hif_power_down(ar);
4183
4184 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004185 list_for_each_entry(arvif, &ar->arvifs, list)
4186 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004187 spin_unlock_bh(&ar->data_lock);
4188}
4189
Ben Greear46acf7b2014-05-16 17:15:38 +03004190static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4191{
4192 struct ath10k *ar = hw->priv;
4193
4194 mutex_lock(&ar->conf_mutex);
4195
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304196 *tx_ant = ar->cfg_tx_chainmask;
4197 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03004198
4199 mutex_unlock(&ar->conf_mutex);
4200
4201 return 0;
4202}
4203
Ben Greear5572a952014-11-24 16:22:10 +02004204static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4205{
4206 /* It is not clear that allowing gaps in chainmask
4207 * is helpful. Probably it will not do what user
4208 * is hoping for, so warn in that case.
4209 */
4210 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4211 return;
4212
4213 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4214 dbg, cm);
4215}
4216
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304217static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4218{
4219 int nsts = ar->vht_cap_info;
4220
4221 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4222 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4223
4224 /* If firmware does not deliver to host number of space-time
4225 * streams supported, assume it support up to 4 BF STS and return
4226 * the value for VHT CAP: nsts-1)
4227 */
4228 if (nsts == 0)
4229 return 3;
4230
4231 return nsts;
4232}
4233
4234static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4235{
4236 int sound_dim = ar->vht_cap_info;
4237
4238 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4239 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4240
4241 /* If the sounding dimension is not advertised by the firmware,
4242 * let's use a default value of 1
4243 */
4244 if (sound_dim == 0)
4245 return 1;
4246
4247 return sound_dim;
4248}
4249
4250static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4251{
4252 struct ieee80211_sta_vht_cap vht_cap = {0};
4253 u16 mcs_map;
4254 u32 val;
4255 int i;
4256
4257 vht_cap.vht_supported = 1;
4258 vht_cap.cap = ar->vht_cap_info;
4259
4260 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4261 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4262 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4263 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4264 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4265
4266 vht_cap.cap |= val;
4267 }
4268
4269 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4270 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4271 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4272 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4273 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4274
4275 vht_cap.cap |= val;
4276 }
4277
4278 mcs_map = 0;
4279 for (i = 0; i < 8; i++) {
4280 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4281 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4282 else
4283 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4284 }
4285
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004286 if (ar->cfg_tx_chainmask <= 1)
4287 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4288
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304289 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4290 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4291
4292 return vht_cap;
4293}
4294
4295static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4296{
4297 int i;
4298 struct ieee80211_sta_ht_cap ht_cap = {0};
4299
4300 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4301 return ht_cap;
4302
4303 ht_cap.ht_supported = 1;
4304 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4305 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4306 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4307 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004308 ht_cap.cap |=
4309 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304310
4311 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4312 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4313
4314 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4315 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4316
4317 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4318 u32 smps;
4319
4320 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4321 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4322
4323 ht_cap.cap |= smps;
4324 }
4325
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004326 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304327 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4328
4329 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4330 u32 stbc;
4331
4332 stbc = ar->ht_cap_info;
4333 stbc &= WMI_HT_CAP_RX_STBC;
4334 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4335 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4336 stbc &= IEEE80211_HT_CAP_RX_STBC;
4337
4338 ht_cap.cap |= stbc;
4339 }
4340
4341 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
4342 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4343
4344 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4345 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4346
4347 /* max AMSDU is implicitly taken from vht_cap_info */
4348 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4349 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4350
4351 for (i = 0; i < ar->num_rf_chains; i++) {
4352 if (ar->cfg_rx_chainmask & BIT(i))
4353 ht_cap.mcs.rx_mask[i] = 0xFF;
4354 }
4355
4356 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4357
4358 return ht_cap;
4359}
4360
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304361static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4362{
4363 struct ieee80211_supported_band *band;
4364 struct ieee80211_sta_vht_cap vht_cap;
4365 struct ieee80211_sta_ht_cap ht_cap;
4366
4367 ht_cap = ath10k_get_ht_cap(ar);
4368 vht_cap = ath10k_create_vht_cap(ar);
4369
4370 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004371 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304372 band->ht_cap = ht_cap;
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304373 }
4374 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004375 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304376 band->ht_cap = ht_cap;
4377 band->vht_cap = vht_cap;
4378 }
4379}
4380
Ben Greear46acf7b2014-05-16 17:15:38 +03004381static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4382{
4383 int ret;
4384
4385 lockdep_assert_held(&ar->conf_mutex);
4386
Ben Greear5572a952014-11-24 16:22:10 +02004387 ath10k_check_chain_mask(ar, tx_ant, "tx");
4388 ath10k_check_chain_mask(ar, rx_ant, "rx");
4389
Ben Greear46acf7b2014-05-16 17:15:38 +03004390 ar->cfg_tx_chainmask = tx_ant;
4391 ar->cfg_rx_chainmask = rx_ant;
4392
4393 if ((ar->state != ATH10K_STATE_ON) &&
4394 (ar->state != ATH10K_STATE_RESTARTED))
4395 return 0;
4396
4397 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4398 tx_ant);
4399 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004400 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004401 ret, tx_ant);
4402 return ret;
4403 }
4404
4405 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4406 rx_ant);
4407 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004408 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004409 ret, rx_ant);
4410 return ret;
4411 }
4412
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304413 /* Reload HT/VHT capability */
4414 ath10k_mac_setup_ht_vht_cap(ar);
4415
Ben Greear46acf7b2014-05-16 17:15:38 +03004416 return 0;
4417}
4418
4419static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4420{
4421 struct ath10k *ar = hw->priv;
4422 int ret;
4423
4424 mutex_lock(&ar->conf_mutex);
4425 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4426 mutex_unlock(&ar->conf_mutex);
4427 return ret;
4428}
4429
Kalle Valo5e3dd152013-06-12 20:52:10 +03004430static int ath10k_start(struct ieee80211_hw *hw)
4431{
4432 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304433 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004434 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004435
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004436 /*
4437 * This makes sense only when restarting hw. It is harmless to call
Mohammed Shafi Shajakhan6dfdbfc2016-04-26 14:41:36 +03004438 * unconditionally. This is necessary to make sure no HTT/WMI tx
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004439 * commands will be submitted while restarting.
4440 */
4441 ath10k_drain_tx(ar);
4442
Michal Kazior548db542013-07-05 16:15:15 +03004443 mutex_lock(&ar->conf_mutex);
4444
Michal Kaziorc5058f52014-05-26 12:46:03 +03004445 switch (ar->state) {
4446 case ATH10K_STATE_OFF:
4447 ar->state = ATH10K_STATE_ON;
4448 break;
4449 case ATH10K_STATE_RESTARTING:
Michal Kaziorc5058f52014-05-26 12:46:03 +03004450 ar->state = ATH10K_STATE_RESTARTED;
4451 break;
4452 case ATH10K_STATE_ON:
4453 case ATH10K_STATE_RESTARTED:
4454 case ATH10K_STATE_WEDGED:
4455 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004456 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004457 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004458 case ATH10K_STATE_UTF:
4459 ret = -EBUSY;
4460 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004461 }
4462
4463 ret = ath10k_hif_power_up(ar);
4464 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004465 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004466 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004467 }
4468
Kalle Valo7ebf7212016-04-20 19:44:51 +03004469 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
4470 &ar->normal_mode_fw);
Michal Kazior818bdd12013-07-16 09:38:57 +02004471 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004472 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004473 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004474 }
4475
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304476 param = ar->wmi.pdev_param->pmf_qos;
4477 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004478 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004479 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004480 goto err_core_stop;
4481 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004482
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304483 param = ar->wmi.pdev_param->dynamic_bw;
4484 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004485 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004486 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004487 goto err_core_stop;
4488 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004489
Michal Kaziorcf327842015-03-31 10:26:25 +00004490 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4491 ret = ath10k_wmi_adaptive_qcs(ar, true);
4492 if (ret) {
4493 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4494 ret);
4495 goto err_core_stop;
4496 }
4497 }
4498
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004499 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304500 param = ar->wmi.pdev_param->burst_enable;
4501 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004502 if (ret) {
4503 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4504 goto err_core_stop;
4505 }
4506 }
4507
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304508 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7b2014-05-16 17:15:38 +03004509
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004510 /*
4511 * By default FW set ARP frames ac to voice (6). In that case ARP
4512 * exchange is not working properly for UAPSD enabled AP. ARP requests
4513 * which arrives with access category 0 are processed by network stack
4514 * and send back with access category 0, but FW changes access category
4515 * to 6. Set ARP frames access category to best effort (0) solves
4516 * this problem.
4517 */
4518
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304519 param = ar->wmi.pdev_param->arp_ac_override;
4520 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004521 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004522 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004523 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004524 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004525 }
4526
Maharaja62f77f02015-10-21 11:49:18 +03004527 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
Kalle Valoc4cdf752016-04-20 19:45:18 +03004528 ar->running_fw->fw_file.fw_features)) {
Maharaja62f77f02015-10-21 11:49:18 +03004529 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4530 WMI_CCA_DETECT_LEVEL_AUTO,
4531 WMI_CCA_DETECT_MARGIN_AUTO);
4532 if (ret) {
4533 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4534 ret);
4535 goto err_core_stop;
4536 }
4537 }
4538
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304539 param = ar->wmi.pdev_param->ani_enable;
4540 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304541 if (ret) {
4542 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4543 ret);
4544 goto err_core_stop;
4545 }
4546
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304547 ar->ani_enabled = true;
4548
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304549 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304550 param = ar->wmi.pdev_param->peer_stats_update_period;
4551 ret = ath10k_wmi_pdev_set_param(ar, param,
4552 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4553 if (ret) {
4554 ath10k_warn(ar,
4555 "failed to set peer stats period : %d\n",
4556 ret);
4557 goto err_core_stop;
4558 }
4559 }
4560
Rajkumar Manoharan39136242016-05-27 20:15:59 +05304561 param = ar->wmi.pdev_param->enable_btcoex;
4562 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
4563 test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
4564 ar->running_fw->fw_file.fw_features)) {
4565 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4566 if (ret) {
4567 ath10k_warn(ar,
4568 "failed to set btcoex param: %d\n", ret);
4569 goto err_core_stop;
4570 }
4571 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
4572 }
4573
Michal Kaziord6500972014-04-08 09:56:09 +03004574 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004575 ath10k_regd_update(ar);
4576
Simon Wunderlich855aed12014-08-02 09:12:54 +03004577 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304578 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004579
Michal Kaziorae254432014-05-26 12:46:02 +03004580 mutex_unlock(&ar->conf_mutex);
4581 return 0;
4582
4583err_core_stop:
4584 ath10k_core_stop(ar);
4585
4586err_power_down:
4587 ath10k_hif_power_down(ar);
4588
4589err_off:
4590 ar->state = ATH10K_STATE_OFF;
4591
4592err:
Michal Kazior548db542013-07-05 16:15:15 +03004593 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004594 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004595}
4596
4597static void ath10k_stop(struct ieee80211_hw *hw)
4598{
4599 struct ath10k *ar = hw->priv;
4600
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004601 ath10k_drain_tx(ar);
4602
Michal Kazior548db542013-07-05 16:15:15 +03004603 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004604 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004605 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004606 ar->state = ATH10K_STATE_OFF;
4607 }
Michal Kazior548db542013-07-05 16:15:15 +03004608 mutex_unlock(&ar->conf_mutex);
4609
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004610 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004611 cancel_work_sync(&ar->restart_work);
4612}
4613
Michal Kaziorad088bf2013-10-16 15:44:46 +03004614static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004615{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004616 struct ath10k_vif *arvif;
4617 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004618
4619 lockdep_assert_held(&ar->conf_mutex);
4620
Michal Kaziorad088bf2013-10-16 15:44:46 +03004621 list_for_each_entry(arvif, &ar->arvifs, list) {
4622 ret = ath10k_mac_vif_setup_ps(arvif);
4623 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004624 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004625 break;
4626 }
4627 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004628
Michal Kaziorad088bf2013-10-16 15:44:46 +03004629 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004630}
4631
Michal Kazior7d9d5582014-10-21 10:40:15 +03004632static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4633{
4634 int ret;
4635 u32 param;
4636
4637 lockdep_assert_held(&ar->conf_mutex);
4638
4639 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4640
4641 param = ar->wmi.pdev_param->txpower_limit2g;
4642 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4643 if (ret) {
4644 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4645 txpower, ret);
4646 return ret;
4647 }
4648
4649 param = ar->wmi.pdev_param->txpower_limit5g;
4650 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4651 if (ret) {
4652 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4653 txpower, ret);
4654 return ret;
4655 }
4656
4657 return 0;
4658}
4659
4660static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4661{
4662 struct ath10k_vif *arvif;
4663 int ret, txpower = -1;
4664
4665 lockdep_assert_held(&ar->conf_mutex);
4666
4667 list_for_each_entry(arvif, &ar->arvifs, list) {
4668 WARN_ON(arvif->txpower < 0);
4669
4670 if (txpower == -1)
4671 txpower = arvif->txpower;
4672 else
4673 txpower = min(txpower, arvif->txpower);
4674 }
4675
4676 if (WARN_ON(txpower == -1))
4677 return -EINVAL;
4678
4679 ret = ath10k_mac_txpower_setup(ar, txpower);
4680 if (ret) {
4681 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4682 txpower, ret);
4683 return ret;
4684 }
4685
4686 return 0;
4687}
4688
Kalle Valo5e3dd152013-06-12 20:52:10 +03004689static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4690{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004691 struct ath10k *ar = hw->priv;
4692 struct ieee80211_conf *conf = &hw->conf;
4693 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004694
4695 mutex_lock(&ar->conf_mutex);
4696
Michal Kazioraffd3212013-07-16 09:54:35 +02004697 if (changed & IEEE80211_CONF_CHANGE_PS)
4698 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004699
4700 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004701 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4702 ret = ath10k_monitor_recalc(ar);
4703 if (ret)
4704 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004705 }
4706
4707 mutex_unlock(&ar->conf_mutex);
4708 return ret;
4709}
4710
Ben Greear5572a952014-11-24 16:22:10 +02004711static u32 get_nss_from_chainmask(u16 chain_mask)
4712{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05304713 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02004714 return 4;
4715 else if ((chain_mask & 0x7) == 0x7)
4716 return 3;
4717 else if ((chain_mask & 0x3) == 0x3)
4718 return 2;
4719 return 1;
4720}
4721
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304722static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4723{
4724 u32 value = 0;
4725 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004726 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004727 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304728
4729 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4730 return 0;
4731
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004732 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304733 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4734 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004735 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304736
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004737 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304738 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4739 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004740 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304741
4742 if (!value)
4743 return 0;
4744
4745 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4746 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4747
4748 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4749 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4750 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4751
4752 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4753 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4754
4755 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4756 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4757 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4758
4759 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4760 ar->wmi.vdev_param->txbf, value);
4761}
4762
Kalle Valo5e3dd152013-06-12 20:52:10 +03004763/*
4764 * TODO:
4765 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4766 * because we will send mgmt frames without CCK. This requirement
4767 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4768 * in the TX packet.
4769 */
4770static int ath10k_add_interface(struct ieee80211_hw *hw,
4771 struct ieee80211_vif *vif)
4772{
4773 struct ath10k *ar = hw->priv;
4774 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004775 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004776 enum wmi_sta_powersave_param param;
4777 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004778 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004779 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004780 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004781 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004782
Johannes Berg848955c2014-11-11 12:48:42 +01004783 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4784
Kalle Valo5e3dd152013-06-12 20:52:10 +03004785 mutex_lock(&ar->conf_mutex);
4786
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004787 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02004788 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004789
Kalle Valo5e3dd152013-06-12 20:52:10 +03004790 arvif->ar = ar;
4791 arvif->vif = vif;
4792
Ben Greeare63b33f2013-10-22 14:54:14 -07004793 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004794 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004795 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4796 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004797
Michal Kazior45c9abc2015-04-21 20:42:58 +03004798 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4799 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4800 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4801 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4802 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4803 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4804 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004805
Michal Kaziore04cafb2015-08-05 12:15:24 +02004806 if (ar->num_peers >= ar->max_num_peers) {
4807 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004808 ret = -ENOBUFS;
4809 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004810 }
4811
Ben Greeara9aefb32014-08-12 11:02:19 +03004812 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004813 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004814 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03004815 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004816 }
Ben Greear16c11172014-09-23 14:17:16 -07004817 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004818
Ben Greear16c11172014-09-23 14:17:16 -07004819 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4820 bit, ar->free_vdev_map);
4821
4822 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004823 arvif->vdev_subtype =
4824 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004825
Kalle Valo5e3dd152013-06-12 20:52:10 +03004826 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004827 case NL80211_IFTYPE_P2P_DEVICE:
4828 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004829 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4830 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01004831 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004832 case NL80211_IFTYPE_UNSPECIFIED:
4833 case NL80211_IFTYPE_STATION:
4834 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4835 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004836 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4837 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004838 break;
4839 case NL80211_IFTYPE_ADHOC:
4840 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4841 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004842 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08004843 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08004844 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4845 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08004846 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004847 ret = -EINVAL;
4848 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
4849 goto err;
4850 }
4851 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4852 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004853 case NL80211_IFTYPE_AP:
4854 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4855
4856 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004857 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4858 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004859 break;
4860 case NL80211_IFTYPE_MONITOR:
4861 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4862 break;
4863 default:
4864 WARN_ON(1);
4865 break;
4866 }
4867
Michal Kazior96d828d2015-03-31 10:26:23 +00004868 /* Using vdev_id as queue number will make it very easy to do per-vif
4869 * tx queue locking. This shouldn't wrap due to interface combinations
4870 * but do a modulo for correctness sake and prevent using offchannel tx
4871 * queues for regular vif tx.
4872 */
4873 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4874 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4875 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4876
Michal Kazior64badcb2014-09-18 11:18:02 +03004877 /* Some firmware revisions don't wait for beacon tx completion before
4878 * sending another SWBA event. This could lead to hardware using old
4879 * (freed) beacon data in some cases, e.g. tx credit starvation
4880 * combined with missed TBTT. This is very very rare.
4881 *
4882 * On non-IOMMU-enabled hosts this could be a possible security issue
4883 * because hw could beacon some random data on the air. On
4884 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4885 * device would crash.
4886 *
4887 * Since there are no beacon tx completions (implicit nor explicit)
4888 * propagated to host the only workaround for this is to allocate a
4889 * DMA-coherent buffer for a lifetime of a vif and use it for all
4890 * beacon tx commands. Worst case for this approach is some beacons may
4891 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4892 */
4893 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004894 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03004895 vif->type == NL80211_IFTYPE_AP) {
4896 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4897 IEEE80211_MAX_FRAME_LEN,
4898 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304899 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004900 if (!arvif->beacon_buf) {
4901 ret = -ENOMEM;
4902 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4903 ret);
4904 goto err;
4905 }
4906 }
David Liuccec9032015-07-24 20:25:32 +03004907 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
4908 arvif->nohwcrypt = true;
4909
4910 if (arvif->nohwcrypt &&
4911 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4912 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
4913 goto err;
4914 }
Michal Kazior64badcb2014-09-18 11:18:02 +03004915
4916 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4917 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4918 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004919
4920 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4921 arvif->vdev_subtype, vif->addr);
4922 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004923 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004924 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004925 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004926 }
4927
Ben Greear16c11172014-09-23 14:17:16 -07004928 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Michal Kazior05791192013-10-16 15:44:45 +03004929 list_add(&arvif->list, &ar->arvifs);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004930
Michal Kazior46725b12015-01-28 09:57:49 +02004931 /* It makes no sense to have firmware do keepalives. mac80211 already
4932 * takes care of this with idle connection polling.
4933 */
4934 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004935 if (ret) {
Michal Kazior46725b12015-01-28 09:57:49 +02004936 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004937 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004938 goto err_vdev_delete;
4939 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004940
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004941 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004942
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004943 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4944 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004945 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004946 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03004947 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004948 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004949 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004950 goto err_vdev_delete;
4951 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004952
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05304953 /* Configuring number of spatial stream for monitor interface is causing
4954 * target assert in qca9888 and qca6174.
4955 */
4956 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02004957 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
4958
4959 vdev_param = ar->wmi.vdev_param->nss;
4960 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4961 nss);
4962 if (ret) {
4963 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
4964 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
4965 ret);
4966 goto err_vdev_delete;
4967 }
4968 }
4969
Michal Kaziore57e0572015-03-24 13:14:03 +00004970 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4971 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02004972 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
4973 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004974 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00004975 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004976 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004977 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004978 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004979
4980 spin_lock_bh(&ar->data_lock);
4981
4982 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
4983 if (!peer) {
4984 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
4985 vif->addr, arvif->vdev_id);
4986 spin_unlock_bh(&ar->data_lock);
4987 ret = -ENOENT;
4988 goto err_peer_delete;
4989 }
4990
4991 arvif->peer_id = find_first_bit(peer->peer_ids,
4992 ATH10K_MAX_NUM_PEER_IDS);
4993
4994 spin_unlock_bh(&ar->data_lock);
4995 } else {
4996 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00004997 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01004998
Michal Kaziore57e0572015-03-24 13:14:03 +00004999 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02005000 ret = ath10k_mac_set_kickout(arvif);
5001 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005002 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005003 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02005004 goto err_peer_delete;
5005 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005006 }
5007
5008 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
5009 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
5010 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5011 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5012 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005013 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005014 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005015 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005016 goto err_peer_delete;
5017 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005018
Michal Kazior9f9b5742014-12-12 12:41:36 +01005019 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005020 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005021 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005022 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005023 goto err_peer_delete;
5024 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005025
Michal Kazior9f9b5742014-12-12 12:41:36 +01005026 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005027 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005028 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005029 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005030 goto err_peer_delete;
5031 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005032 }
5033
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305034 ret = ath10k_mac_set_txbf_conf(arvif);
5035 if (ret) {
5036 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
5037 arvif->vdev_id, ret);
5038 goto err_peer_delete;
5039 }
5040
Michal Kazior424121c2013-07-22 14:13:31 +02005041 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005042 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005043 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03005044 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005045 goto err_peer_delete;
5046 }
Michal Kazior679c54a2013-07-05 16:15:04 +03005047
Michal Kazior7d9d5582014-10-21 10:40:15 +03005048 arvif->txpower = vif->bss_conf.txpower;
5049 ret = ath10k_mac_txpower_recalc(ar);
5050 if (ret) {
5051 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5052 goto err_peer_delete;
5053 }
5054
Michal Kazior500ff9f2015-03-31 10:26:21 +00005055 if (vif->type == NL80211_IFTYPE_MONITOR) {
5056 ar->monitor_arvif = arvif;
5057 ret = ath10k_monitor_recalc(ar);
5058 if (ret) {
5059 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5060 goto err_peer_delete;
5061 }
5062 }
5063
Michal Kazior6d2d51e2015-08-07 09:08:21 +02005064 spin_lock_bh(&ar->htt.tx_lock);
5065 if (!ar->tx_paused)
5066 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
5067 spin_unlock_bh(&ar->htt.tx_lock);
5068
Kalle Valo5e3dd152013-06-12 20:52:10 +03005069 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005070 return 0;
5071
5072err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00005073 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5074 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14a2013-10-16 15:44:45 +03005075 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
5076
5077err_vdev_delete:
5078 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07005079 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03005080 list_del(&arvif->list);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005081
5082err:
Michal Kazior64badcb2014-09-18 11:18:02 +03005083 if (arvif->beacon_buf) {
5084 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
5085 arvif->beacon_buf, arvif->beacon_paddr);
5086 arvif->beacon_buf = NULL;
5087 }
5088
Michal Kazior9dad14a2013-10-16 15:44:45 +03005089 mutex_unlock(&ar->conf_mutex);
5090
Kalle Valo5e3dd152013-06-12 20:52:10 +03005091 return ret;
5092}
5093
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005094static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
5095{
5096 int i;
5097
5098 for (i = 0; i < BITS_PER_LONG; i++)
5099 ath10k_mac_vif_tx_unlock(arvif, i);
5100}
5101
Kalle Valo5e3dd152013-06-12 20:52:10 +03005102static void ath10k_remove_interface(struct ieee80211_hw *hw,
5103 struct ieee80211_vif *vif)
5104{
5105 struct ath10k *ar = hw->priv;
5106 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior69427262016-03-06 16:14:30 +02005107 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005108 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005109 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005110
Michal Kazior81a9a172015-03-05 16:02:17 +02005111 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005112 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005113
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305114 mutex_lock(&ar->conf_mutex);
5115
Michal Kaziored543882013-09-13 14:16:56 +02005116 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03005117 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02005118 spin_unlock_bh(&ar->data_lock);
5119
Simon Wunderlich855aed12014-08-02 09:12:54 +03005120 ret = ath10k_spectral_vif_stop(arvif);
5121 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005122 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005123 arvif->vdev_id, ret);
5124
Ben Greear16c11172014-09-23 14:17:16 -07005125 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03005126 list_del(&arvif->list);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005127
Michal Kaziore57e0572015-03-24 13:14:03 +00005128 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5129 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005130 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5131 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005132 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005133 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005134 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005135
5136 kfree(arvif->u.ap.noa_data);
5137 }
5138
Michal Kazior7aa7a722014-08-25 12:09:38 +02005139 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005140 arvif->vdev_id);
5141
Kalle Valo5e3dd152013-06-12 20:52:10 +03005142 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5143 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005144 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005145 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005146
Michal Kazior2c512052015-02-15 16:50:40 +02005147 /* Some firmware revisions don't notify host about self-peer removal
5148 * until after associated vdev is deleted.
5149 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005150 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5151 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005152 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5153 vif->addr);
5154 if (ret)
5155 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5156 arvif->vdev_id, ret);
5157
5158 spin_lock_bh(&ar->data_lock);
5159 ar->num_peers--;
5160 spin_unlock_bh(&ar->data_lock);
5161 }
5162
Michal Kazior69427262016-03-06 16:14:30 +02005163 spin_lock_bh(&ar->data_lock);
5164 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5165 peer = ar->peer_map[i];
5166 if (!peer)
5167 continue;
5168
5169 if (peer->vif == vif) {
5170 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5171 vif->addr, arvif->vdev_id);
5172 peer->vif = NULL;
5173 }
5174 }
5175 spin_unlock_bh(&ar->data_lock);
5176
Kalle Valo5e3dd152013-06-12 20:52:10 +03005177 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005178 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005179
Michal Kazior500ff9f2015-03-31 10:26:21 +00005180 if (vif->type == NL80211_IFTYPE_MONITOR) {
5181 ar->monitor_arvif = NULL;
5182 ret = ath10k_monitor_recalc(ar);
5183 if (ret)
5184 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5185 }
5186
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005187 spin_lock_bh(&ar->htt.tx_lock);
5188 ath10k_mac_vif_tx_unlock_all(arvif);
5189 spin_unlock_bh(&ar->htt.tx_lock);
5190
Michal Kazior29946872016-03-06 16:14:34 +02005191 ath10k_mac_txq_unref(ar, vif->txq);
5192
Kalle Valo5e3dd152013-06-12 20:52:10 +03005193 mutex_unlock(&ar->conf_mutex);
5194}
5195
5196/*
5197 * FIXME: Has to be verified.
5198 */
5199#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005200 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005201 FIF_CONTROL | \
5202 FIF_PSPOLL | \
5203 FIF_OTHER_BSS | \
5204 FIF_BCN_PRBRESP_PROMISC | \
5205 FIF_PROBE_REQ | \
5206 FIF_FCSFAIL)
5207
5208static void ath10k_configure_filter(struct ieee80211_hw *hw,
5209 unsigned int changed_flags,
5210 unsigned int *total_flags,
5211 u64 multicast)
5212{
5213 struct ath10k *ar = hw->priv;
5214 int ret;
5215
5216 mutex_lock(&ar->conf_mutex);
5217
5218 changed_flags &= SUPPORTED_FILTERS;
5219 *total_flags &= SUPPORTED_FILTERS;
5220 ar->filter_flags = *total_flags;
5221
Michal Kazior19337472014-08-28 12:58:16 +02005222 ret = ath10k_monitor_recalc(ar);
5223 if (ret)
Colin Ian King7f03d302016-08-26 19:08:52 +01005224 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005225
5226 mutex_unlock(&ar->conf_mutex);
5227}
5228
5229static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5230 struct ieee80211_vif *vif,
5231 struct ieee80211_bss_conf *info,
5232 u32 changed)
5233{
5234 struct ath10k *ar = hw->priv;
5235 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5236 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03005237 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005238
5239 mutex_lock(&ar->conf_mutex);
5240
5241 if (changed & BSS_CHANGED_IBSS)
5242 ath10k_control_ibss(arvif, info, vif->addr);
5243
5244 if (changed & BSS_CHANGED_BEACON_INT) {
5245 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005246 vdev_param = ar->wmi.vdev_param->beacon_interval;
5247 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005248 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005249 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005250 "mac vdev %d beacon_interval %d\n",
5251 arvif->vdev_id, arvif->beacon_interval);
5252
Kalle Valo5e3dd152013-06-12 20:52:10 +03005253 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005254 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005255 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005256 }
5257
5258 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005259 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005260 "vdev %d set beacon tx mode to staggered\n",
5261 arvif->vdev_id);
5262
Bartosz Markowski226a3392013-09-26 17:47:16 +02005263 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5264 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005265 WMI_BEACON_STAGGERED_MODE);
5266 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005267 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005268 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005269
5270 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5271 if (ret)
5272 ath10k_warn(ar, "failed to update beacon template: %d\n",
5273 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005274
5275 if (ieee80211_vif_is_mesh(vif)) {
5276 /* mesh doesn't use SSID but firmware needs it */
5277 strncpy(arvif->u.ap.ssid, "mesh",
5278 sizeof(arvif->u.ap.ssid));
5279 arvif->u.ap.ssid_len = 4;
5280 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005281 }
5282
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005283 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5284 ret = ath10k_mac_setup_prb_tmpl(arvif);
5285 if (ret)
5286 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5287 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005288 }
5289
Michal Kaziorba2479f2015-01-24 12:14:51 +02005290 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005291 arvif->dtim_period = info->dtim_period;
5292
Michal Kazior7aa7a722014-08-25 12:09:38 +02005293 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005294 "mac vdev %d dtim_period %d\n",
5295 arvif->vdev_id, arvif->dtim_period);
5296
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005297 vdev_param = ar->wmi.vdev_param->dtim_period;
5298 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005299 arvif->dtim_period);
5300 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005301 ath10k_warn(ar, "failed to set dtim period 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_SSID &&
5306 vif->type == NL80211_IFTYPE_AP) {
5307 arvif->u.ap.ssid_len = info->ssid_len;
5308 if (info->ssid_len)
5309 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5310 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5311 }
5312
Michal Kazior077efc82014-10-21 10:10:29 +03005313 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5314 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005315
5316 if (changed & BSS_CHANGED_BEACON_ENABLED)
5317 ath10k_control_beaconing(arvif, info);
5318
5319 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005320 arvif->use_cts_prot = info->use_cts_prot;
Michal Kazior7aa7a722014-08-25 12:09:38 +02005321 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005322 arvif->vdev_id, info->use_cts_prot);
Kalle Valo60c3daa2013-09-08 17:56:07 +03005323
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005324 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005325 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005326 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005327 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005328
5329 vdev_param = ar->wmi.vdev_param->protection_mode;
5330 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5331 info->use_cts_prot ? 1 : 0);
5332 if (ret)
5333 ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
Kalle Valo617b0f42015-10-05 17:56:35 +03005334 info->use_cts_prot, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005335 }
5336
5337 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005338 if (info->use_short_slot)
5339 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5340
5341 else
5342 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5343
Michal Kazior7aa7a722014-08-25 12:09:38 +02005344 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005345 arvif->vdev_id, slottime);
5346
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005347 vdev_param = ar->wmi.vdev_param->slot_time;
5348 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005349 slottime);
5350 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005351 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005352 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005353 }
5354
5355 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005356 if (info->use_short_preamble)
5357 preamble = WMI_VDEV_PREAMBLE_SHORT;
5358 else
5359 preamble = WMI_VDEV_PREAMBLE_LONG;
5360
Michal Kazior7aa7a722014-08-25 12:09:38 +02005361 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005362 "mac vdev %d preamble %dn",
5363 arvif->vdev_id, preamble);
5364
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005365 vdev_param = ar->wmi.vdev_param->preamble;
5366 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005367 preamble);
5368 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005369 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005370 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005371 }
5372
5373 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005374 if (info->assoc) {
5375 /* Workaround: Make sure monitor vdev is not running
5376 * when associating to prevent some firmware revisions
5377 * (e.g. 10.1 and 10.2) from crashing.
5378 */
5379 if (ar->monitor_started)
5380 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005381 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005382 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005383 } else {
5384 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005385 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005386 }
5387
Michal Kazior7d9d5582014-10-21 10:40:15 +03005388 if (changed & BSS_CHANGED_TXPOWER) {
5389 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5390 arvif->vdev_id, info->txpower);
5391
5392 arvif->txpower = info->txpower;
5393 ret = ath10k_mac_txpower_recalc(ar);
5394 if (ret)
5395 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5396 }
5397
Michal Kaziorbf14e652014-12-12 12:41:38 +01005398 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005399 arvif->ps = vif->bss_conf.ps;
5400
5401 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005402 if (ret)
5403 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5404 arvif->vdev_id, ret);
5405 }
5406
Kalle Valo5e3dd152013-06-12 20:52:10 +03005407 mutex_unlock(&ar->conf_mutex);
5408}
5409
5410static int ath10k_hw_scan(struct ieee80211_hw *hw,
5411 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005412 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005413{
5414 struct ath10k *ar = hw->priv;
5415 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02005416 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005417 struct wmi_start_scan_arg arg;
5418 int ret = 0;
5419 int i;
5420
5421 mutex_lock(&ar->conf_mutex);
5422
5423 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005424 switch (ar->scan.state) {
5425 case ATH10K_SCAN_IDLE:
5426 reinit_completion(&ar->scan.started);
5427 reinit_completion(&ar->scan.completed);
5428 ar->scan.state = ATH10K_SCAN_STARTING;
5429 ar->scan.is_roc = false;
5430 ar->scan.vdev_id = arvif->vdev_id;
5431 ret = 0;
5432 break;
5433 case ATH10K_SCAN_STARTING:
5434 case ATH10K_SCAN_RUNNING:
5435 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005436 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005437 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005438 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005439 spin_unlock_bh(&ar->data_lock);
5440
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005441 if (ret)
5442 goto exit;
5443
Kalle Valo5e3dd152013-06-12 20:52:10 +03005444 memset(&arg, 0, sizeof(arg));
5445 ath10k_wmi_start_scan_init(ar, &arg);
5446 arg.vdev_id = arvif->vdev_id;
5447 arg.scan_id = ATH10K_SCAN_ID;
5448
Kalle Valo5e3dd152013-06-12 20:52:10 +03005449 if (req->ie_len) {
5450 arg.ie_len = req->ie_len;
5451 memcpy(arg.ie, req->ie, arg.ie_len);
5452 }
5453
5454 if (req->n_ssids) {
5455 arg.n_ssids = req->n_ssids;
5456 for (i = 0; i < arg.n_ssids; i++) {
5457 arg.ssids[i].len = req->ssids[i].ssid_len;
5458 arg.ssids[i].ssid = req->ssids[i].ssid;
5459 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005460 } else {
5461 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005462 }
5463
5464 if (req->n_channels) {
5465 arg.n_channels = req->n_channels;
5466 for (i = 0; i < arg.n_channels; i++)
5467 arg.channels[i] = req->channels[i]->center_freq;
5468 }
5469
5470 ret = ath10k_start_scan(ar, &arg);
5471 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005472 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005473 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005474 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005475 spin_unlock_bh(&ar->data_lock);
5476 }
5477
Michal Kazior634349b2015-09-03 10:43:45 +02005478 /* Add a 200ms margin to account for event/command processing */
5479 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5480 msecs_to_jiffies(arg.max_scan_time +
5481 200));
5482
Kalle Valo5e3dd152013-06-12 20:52:10 +03005483exit:
5484 mutex_unlock(&ar->conf_mutex);
5485 return ret;
5486}
5487
5488static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5489 struct ieee80211_vif *vif)
5490{
5491 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005492
5493 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005494 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005495 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01005496
5497 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005498}
5499
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005500static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
5501 struct ath10k_vif *arvif,
5502 enum set_key_cmd cmd,
5503 struct ieee80211_key_conf *key)
5504{
5505 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
5506 int ret;
5507
5508 /* 10.1 firmware branch requires default key index to be set to group
5509 * key index after installing it. Otherwise FW/HW Txes corrupted
5510 * frames with multi-vif APs. This is not required for main firmware
5511 * branch (e.g. 636).
5512 *
Michal Kazior8461baf2015-04-10 13:23:22 +00005513 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
5514 *
5515 * FIXME: It remains unknown if this is required for multi-vif STA
5516 * interfaces on 10.1.
5517 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005518
Michal Kazior8461baf2015-04-10 13:23:22 +00005519 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
5520 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005521 return;
5522
5523 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
5524 return;
5525
5526 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
5527 return;
5528
5529 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5530 return;
5531
5532 if (cmd != SET_KEY)
5533 return;
5534
5535 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5536 key->keyidx);
5537 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005538 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005539 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005540}
5541
Kalle Valo5e3dd152013-06-12 20:52:10 +03005542static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5543 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5544 struct ieee80211_key_conf *key)
5545{
5546 struct ath10k *ar = hw->priv;
5547 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5548 struct ath10k_peer *peer;
5549 const u8 *peer_addr;
5550 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5551 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5552 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005553 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005554 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005555 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005556
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005557 /* this one needs to be done in software */
5558 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
5559 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005560
David Liuccec9032015-07-24 20:25:32 +03005561 if (arvif->nohwcrypt)
5562 return 1;
5563
Kalle Valo5e3dd152013-06-12 20:52:10 +03005564 if (key->keyidx > WMI_MAX_KEY_INDEX)
5565 return -ENOSPC;
5566
5567 mutex_lock(&ar->conf_mutex);
5568
5569 if (sta)
5570 peer_addr = sta->addr;
5571 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5572 peer_addr = vif->bss_conf.bssid;
5573 else
5574 peer_addr = vif->addr;
5575
5576 key->hw_key_idx = key->keyidx;
5577
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005578 if (is_wep) {
5579 if (cmd == SET_KEY)
5580 arvif->wep_keys[key->keyidx] = key;
5581 else
5582 arvif->wep_keys[key->keyidx] = NULL;
5583 }
5584
Kalle Valo5e3dd152013-06-12 20:52:10 +03005585 /* the peer should not disappear in mid-way (unless FW goes awry) since
5586 * we already hold conf_mutex. we just make sure its there now. */
5587 spin_lock_bh(&ar->data_lock);
5588 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5589 spin_unlock_bh(&ar->data_lock);
5590
5591 if (!peer) {
5592 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005593 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005594 peer_addr);
5595 ret = -EOPNOTSUPP;
5596 goto exit;
5597 } else {
5598 /* if the peer doesn't exist there is no key to disable
5599 * anymore */
5600 goto exit;
5601 }
5602 }
5603
Michal Kazior7cc45732015-03-09 14:24:17 +01005604 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5605 flags |= WMI_KEY_PAIRWISE;
5606 else
5607 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005608
Kalle Valo5e3dd152013-06-12 20:52:10 +03005609 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005610 if (cmd == DISABLE_KEY)
5611 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005612
Michal Kaziorad325cb2015-02-18 14:02:27 +01005613 /* When WEP keys are uploaded it's possible that there are
5614 * stations associated already (e.g. when merging) without any
5615 * keys. Static WEP needs an explicit per-peer key upload.
5616 */
5617 if (vif->type == NL80211_IFTYPE_ADHOC &&
5618 cmd == SET_KEY)
5619 ath10k_mac_vif_update_wep_key(arvif, key);
5620
Michal Kazior370e5672015-02-18 14:02:26 +01005621 /* 802.1x never sets the def_wep_key_idx so each set_key()
5622 * call changes default tx key.
5623 *
5624 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5625 * after first set_key().
5626 */
5627 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5628 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005629 }
5630
Michal Kazior370e5672015-02-18 14:02:26 +01005631 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005632 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005633 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005634 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005635 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005636 goto exit;
5637 }
5638
Michal Kazior29a10002015-04-10 13:05:58 +00005639 /* mac80211 sets static WEP keys as groupwise while firmware requires
5640 * them to be installed twice as both pairwise and groupwise.
5641 */
5642 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5643 flags2 = flags;
5644 flags2 &= ~WMI_KEY_GROUP;
5645 flags2 |= WMI_KEY_PAIRWISE;
5646
5647 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5648 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005649 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005650 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5651 arvif->vdev_id, peer_addr, ret);
5652 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5653 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005654 if (ret2) {
5655 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005656 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5657 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005658 }
Michal Kazior29a10002015-04-10 13:05:58 +00005659 goto exit;
5660 }
5661 }
5662
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005663 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5664
Kalle Valo5e3dd152013-06-12 20:52:10 +03005665 spin_lock_bh(&ar->data_lock);
5666 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5667 if (peer && cmd == SET_KEY)
5668 peer->keys[key->keyidx] = key;
5669 else if (peer && cmd == DISABLE_KEY)
5670 peer->keys[key->keyidx] = NULL;
5671 else if (peer == NULL)
5672 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005673 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005674 spin_unlock_bh(&ar->data_lock);
5675
5676exit:
5677 mutex_unlock(&ar->conf_mutex);
5678 return ret;
5679}
5680
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005681static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5682 struct ieee80211_vif *vif,
5683 int keyidx)
5684{
5685 struct ath10k *ar = hw->priv;
5686 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5687 int ret;
5688
5689 mutex_lock(&arvif->ar->conf_mutex);
5690
5691 if (arvif->ar->state != ATH10K_STATE_ON)
5692 goto unlock;
5693
5694 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5695 arvif->vdev_id, keyidx);
5696
5697 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5698 arvif->vdev_id,
5699 arvif->ar->wmi.vdev_param->def_keyid,
5700 keyidx);
5701
5702 if (ret) {
5703 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5704 arvif->vdev_id,
5705 ret);
5706 goto unlock;
5707 }
5708
5709 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005710
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005711unlock:
5712 mutex_unlock(&arvif->ar->conf_mutex);
5713}
5714
Michal Kazior9797feb2014-02-14 14:49:48 +01005715static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5716{
5717 struct ath10k *ar;
5718 struct ath10k_vif *arvif;
5719 struct ath10k_sta *arsta;
5720 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005721 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02005722 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005723 const u8 *ht_mcs_mask;
5724 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005725 u32 changed, bw, nss, smps;
5726 int err;
5727
5728 arsta = container_of(wk, struct ath10k_sta, update_wk);
5729 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5730 arvif = arsta->arvif;
5731 ar = arvif->ar;
5732
Michal Kazior45c9abc2015-04-21 20:42:58 +03005733 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5734 return;
5735
5736 band = def.chan->band;
5737 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5738 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5739
Michal Kazior9797feb2014-02-14 14:49:48 +01005740 spin_lock_bh(&ar->data_lock);
5741
5742 changed = arsta->changed;
5743 arsta->changed = 0;
5744
5745 bw = arsta->bw;
5746 nss = arsta->nss;
5747 smps = arsta->smps;
5748
5749 spin_unlock_bh(&ar->data_lock);
5750
5751 mutex_lock(&ar->conf_mutex);
5752
Michal Kazior45c9abc2015-04-21 20:42:58 +03005753 nss = max_t(u32, 1, nss);
5754 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
5755 ath10k_mac_max_vht_nss(vht_mcs_mask)));
5756
Michal Kazior9797feb2014-02-14 14:49:48 +01005757 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005758 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005759 sta->addr, bw);
5760
5761 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5762 WMI_PEER_CHAN_WIDTH, bw);
5763 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005764 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005765 sta->addr, bw, err);
5766 }
5767
5768 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005769 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005770 sta->addr, nss);
5771
5772 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5773 WMI_PEER_NSS, nss);
5774 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005775 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005776 sta->addr, nss, err);
5777 }
5778
5779 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005780 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005781 sta->addr, smps);
5782
5783 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5784 WMI_PEER_SMPS_STATE, smps);
5785 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005786 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005787 sta->addr, smps, err);
5788 }
5789
Janusz Dziedzic55884c02014-12-17 12:30:02 +02005790 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
5791 changed & IEEE80211_RC_NSS_CHANGED) {
5792 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005793 sta->addr);
5794
Michal Kazior590922a2014-10-21 10:10:29 +03005795 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005796 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005797 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005798 sta->addr);
5799 }
5800
Michal Kazior9797feb2014-02-14 14:49:48 +01005801 mutex_unlock(&ar->conf_mutex);
5802}
5803
Marek Puzyniak7c354242015-03-30 09:51:52 +03005804static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
5805 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005806{
5807 struct ath10k *ar = arvif->ar;
5808
5809 lockdep_assert_held(&ar->conf_mutex);
5810
Marek Puzyniak7c354242015-03-30 09:51:52 +03005811 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005812 return 0;
5813
5814 if (ar->num_stations >= ar->max_num_stations)
5815 return -ENOBUFS;
5816
5817 ar->num_stations++;
5818
5819 return 0;
5820}
5821
Marek Puzyniak7c354242015-03-30 09:51:52 +03005822static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
5823 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005824{
5825 struct ath10k *ar = arvif->ar;
5826
5827 lockdep_assert_held(&ar->conf_mutex);
5828
Marek Puzyniak7c354242015-03-30 09:51:52 +03005829 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005830 return;
5831
5832 ar->num_stations--;
5833}
5834
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005835struct ath10k_mac_tdls_iter_data {
5836 u32 num_tdls_stations;
5837 struct ieee80211_vif *curr_vif;
5838};
5839
5840static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5841 struct ieee80211_sta *sta)
5842{
5843 struct ath10k_mac_tdls_iter_data *iter_data = data;
5844 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5845 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5846
5847 if (sta->tdls && sta_vif == iter_data->curr_vif)
5848 iter_data->num_tdls_stations++;
5849}
5850
5851static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5852 struct ieee80211_vif *vif)
5853{
5854 struct ath10k_mac_tdls_iter_data data = {};
5855
5856 data.curr_vif = vif;
5857
5858 ieee80211_iterate_stations_atomic(hw,
5859 ath10k_mac_tdls_vif_stations_count_iter,
5860 &data);
5861 return data.num_tdls_stations;
5862}
5863
5864static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5865 struct ieee80211_vif *vif)
5866{
5867 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5868 int *num_tdls_vifs = data;
5869
5870 if (vif->type != NL80211_IFTYPE_STATION)
5871 return;
5872
5873 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5874 (*num_tdls_vifs)++;
5875}
5876
5877static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5878{
5879 int num_tdls_vifs = 0;
5880
5881 ieee80211_iterate_active_interfaces_atomic(hw,
5882 IEEE80211_IFACE_ITER_NORMAL,
5883 ath10k_mac_tdls_vifs_count_iter,
5884 &num_tdls_vifs);
5885 return num_tdls_vifs;
5886}
5887
Kalle Valo5e3dd152013-06-12 20:52:10 +03005888static int ath10k_sta_state(struct ieee80211_hw *hw,
5889 struct ieee80211_vif *vif,
5890 struct ieee80211_sta *sta,
5891 enum ieee80211_sta_state old_state,
5892 enum ieee80211_sta_state new_state)
5893{
5894 struct ath10k *ar = hw->priv;
5895 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005896 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005897 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005898 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02005899 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005900
Michal Kazior76f90022014-02-25 09:29:57 +02005901 if (old_state == IEEE80211_STA_NOTEXIST &&
5902 new_state == IEEE80211_STA_NONE) {
5903 memset(arsta, 0, sizeof(*arsta));
5904 arsta->arvif = arvif;
5905 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02005906
5907 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5908 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02005909 }
5910
Michal Kazior9797feb2014-02-14 14:49:48 +01005911 /* cancel must be done outside the mutex to avoid deadlock */
5912 if ((old_state == IEEE80211_STA_NONE &&
5913 new_state == IEEE80211_STA_NOTEXIST))
5914 cancel_work_sync(&arsta->update_wk);
5915
Kalle Valo5e3dd152013-06-12 20:52:10 +03005916 mutex_lock(&ar->conf_mutex);
5917
5918 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005919 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005920 /*
5921 * New station addition.
5922 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005923 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5924 u32 num_tdls_stations;
5925 u32 num_tdls_vifs;
5926
Michal Kaziorcfd10612014-11-25 15:16:05 +01005927 ath10k_dbg(ar, ATH10K_DBG_MAC,
5928 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5929 arvif->vdev_id, sta->addr,
5930 ar->num_stations + 1, ar->max_num_stations,
5931 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005932
Marek Puzyniak7c354242015-03-30 09:51:52 +03005933 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005934 if (ret) {
5935 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5936 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005937 goto exit;
5938 }
5939
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005940 if (sta->tdls)
5941 peer_type = WMI_PEER_TYPE_TDLS;
5942
Michal Kazior69427262016-03-06 16:14:30 +02005943 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
5944 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005945 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005946 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 -08005947 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005948 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005949 goto exit;
5950 }
Michal Kazior077efc82014-10-21 10:10:29 +03005951
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005952 spin_lock_bh(&ar->data_lock);
5953
5954 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
5955 if (!peer) {
5956 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5957 vif->addr, arvif->vdev_id);
5958 spin_unlock_bh(&ar->data_lock);
5959 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5960 ath10k_mac_dec_num_stations(arvif, sta);
5961 ret = -ENOENT;
5962 goto exit;
5963 }
5964
5965 arsta->peer_id = find_first_bit(peer->peer_ids,
5966 ATH10K_MAX_NUM_PEER_IDS);
5967
5968 spin_unlock_bh(&ar->data_lock);
5969
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005970 if (!sta->tdls)
5971 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03005972
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005973 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
5974 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
5975
5976 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
5977 num_tdls_stations == 0) {
5978 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
5979 arvif->vdev_id, ar->max_num_tdls_vdevs);
5980 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5981 ath10k_mac_dec_num_stations(arvif, sta);
5982 ret = -ENOBUFS;
5983 goto exit;
5984 }
5985
5986 if (num_tdls_stations == 0) {
5987 /* This is the first tdls peer in current vif */
5988 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
5989
5990 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5991 state);
Michal Kazior077efc82014-10-21 10:10:29 +03005992 if (ret) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005993 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
Michal Kazior077efc82014-10-21 10:10:29 +03005994 arvif->vdev_id, ret);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005995 ath10k_peer_delete(ar, arvif->vdev_id,
5996 sta->addr);
5997 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03005998 goto exit;
5999 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006000 }
Michal Kazior077efc82014-10-21 10:10:29 +03006001
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006002 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6003 WMI_TDLS_PEER_STATE_PEERING);
6004 if (ret) {
6005 ath10k_warn(ar,
6006 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
6007 sta->addr, arvif->vdev_id, ret);
6008 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6009 ath10k_mac_dec_num_stations(arvif, sta);
6010
6011 if (num_tdls_stations != 0)
6012 goto exit;
6013 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6014 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03006015 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006016 } else if ((old_state == IEEE80211_STA_NONE &&
6017 new_state == IEEE80211_STA_NOTEXIST)) {
6018 /*
6019 * Existing station deletion.
6020 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006021 ath10k_dbg(ar, ATH10K_DBG_MAC,
Ben Greear30404202016-08-18 18:26:35 -07006022 "mac vdev %d peer delete %pM sta %pK (sta gone)\n",
6023 arvif->vdev_id, sta->addr, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006024
Kalle Valo5e3dd152013-06-12 20:52:10 +03006025 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6026 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006027 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006028 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006029
Marek Puzyniak7c354242015-03-30 09:51:52 +03006030 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006031
Michal Kazior69427262016-03-06 16:14:30 +02006032 spin_lock_bh(&ar->data_lock);
6033 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
6034 peer = ar->peer_map[i];
6035 if (!peer)
6036 continue;
6037
6038 if (peer->sta == sta) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05306039 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 +03006040 sta->addr, peer, i, arvif->vdev_id);
Michal Kazior69427262016-03-06 16:14:30 +02006041 peer->sta = NULL;
Ben Greeard0eeafa2016-06-30 15:23:59 +03006042
6043 /* Clean up the peer object as well since we
6044 * must have failed to do this above.
6045 */
6046 list_del(&peer->list);
6047 ar->peer_map[i] = NULL;
6048 kfree(peer);
6049 ar->num_peers--;
Michal Kazior69427262016-03-06 16:14:30 +02006050 }
6051 }
6052 spin_unlock_bh(&ar->data_lock);
6053
Michal Kazior29946872016-03-06 16:14:34 +02006054 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6055 ath10k_mac_txq_unref(ar, sta->txq[i]);
6056
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006057 if (!sta->tdls)
6058 goto exit;
6059
6060 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
6061 goto exit;
6062
6063 /* This was the last tdls peer in current vif */
6064 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6065 WMI_TDLS_DISABLE);
6066 if (ret) {
6067 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6068 arvif->vdev_id, ret);
6069 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006070 } else if (old_state == IEEE80211_STA_AUTH &&
6071 new_state == IEEE80211_STA_ASSOC &&
6072 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006073 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03006074 vif->type == NL80211_IFTYPE_ADHOC)) {
6075 /*
6076 * New association.
6077 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006078 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006079 sta->addr);
6080
Michal Kazior590922a2014-10-21 10:10:29 +03006081 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006082 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006083 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006084 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006085 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006086 new_state == IEEE80211_STA_AUTHORIZED &&
6087 sta->tdls) {
6088 /*
6089 * Tdls station authorized.
6090 */
6091 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
6092 sta->addr);
6093
6094 ret = ath10k_station_assoc(ar, vif, sta, false);
6095 if (ret) {
6096 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
6097 sta->addr, arvif->vdev_id, ret);
6098 goto exit;
6099 }
6100
6101 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6102 WMI_TDLS_PEER_STATE_CONNECTED);
6103 if (ret)
6104 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
6105 sta->addr, arvif->vdev_id, ret);
6106 } else if (old_state == IEEE80211_STA_ASSOC &&
6107 new_state == IEEE80211_STA_AUTH &&
6108 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006109 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006110 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006111 /*
6112 * Disassociation.
6113 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006114 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006115 sta->addr);
6116
Michal Kazior590922a2014-10-21 10:10:29 +03006117 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006118 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006119 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006120 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006121 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006122exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006123 mutex_unlock(&ar->conf_mutex);
6124 return ret;
6125}
6126
6127static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006128 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006129{
6130 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02006131 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6132 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006133 u32 value = 0;
6134 int ret = 0;
6135
Michal Kazior548db542013-07-05 16:15:15 +03006136 lockdep_assert_held(&ar->conf_mutex);
6137
Kalle Valo5e3dd152013-06-12 20:52:10 +03006138 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6139 return 0;
6140
6141 switch (ac) {
6142 case IEEE80211_AC_VO:
6143 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6144 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006145 prio = 7;
6146 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006147 break;
6148 case IEEE80211_AC_VI:
6149 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6150 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006151 prio = 5;
6152 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006153 break;
6154 case IEEE80211_AC_BE:
6155 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6156 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006157 prio = 2;
6158 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006159 break;
6160 case IEEE80211_AC_BK:
6161 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6162 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006163 prio = 0;
6164 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006165 break;
6166 }
6167
6168 if (enable)
6169 arvif->u.sta.uapsd |= value;
6170 else
6171 arvif->u.sta.uapsd &= ~value;
6172
6173 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6174 WMI_STA_PS_PARAM_UAPSD,
6175 arvif->u.sta.uapsd);
6176 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006177 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006178 goto exit;
6179 }
6180
6181 if (arvif->u.sta.uapsd)
6182 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6183 else
6184 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6185
6186 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6187 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6188 value);
6189 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006190 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006191
Michal Kazior9f9b5742014-12-12 12:41:36 +01006192 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6193 if (ret) {
6194 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6195 arvif->vdev_id, ret);
6196 return ret;
6197 }
6198
6199 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6200 if (ret) {
6201 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6202 arvif->vdev_id, ret);
6203 return ret;
6204 }
6205
Michal Kaziorb0e56152015-01-24 12:14:52 +02006206 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6207 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6208 /* Only userspace can make an educated decision when to send
6209 * trigger frame. The following effectively disables u-UAPSD
6210 * autotrigger in firmware (which is enabled by default
6211 * provided the autotrigger service is available).
6212 */
6213
6214 arg.wmm_ac = acc;
6215 arg.user_priority = prio;
6216 arg.service_interval = 0;
6217 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6218 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6219
6220 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6221 arvif->bssid, &arg, 1);
6222 if (ret) {
6223 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6224 ret);
6225 return ret;
6226 }
6227 }
6228
Kalle Valo5e3dd152013-06-12 20:52:10 +03006229exit:
6230 return ret;
6231}
6232
6233static int ath10k_conf_tx(struct ieee80211_hw *hw,
6234 struct ieee80211_vif *vif, u16 ac,
6235 const struct ieee80211_tx_queue_params *params)
6236{
6237 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01006238 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006239 struct wmi_wmm_params_arg *p = NULL;
6240 int ret;
6241
6242 mutex_lock(&ar->conf_mutex);
6243
6244 switch (ac) {
6245 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006246 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006247 break;
6248 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006249 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006250 break;
6251 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006252 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006253 break;
6254 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006255 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006256 break;
6257 }
6258
6259 if (WARN_ON(!p)) {
6260 ret = -EINVAL;
6261 goto exit;
6262 }
6263
6264 p->cwmin = params->cw_min;
6265 p->cwmax = params->cw_max;
6266 p->aifs = params->aifs;
6267
6268 /*
6269 * The channel time duration programmed in the HW is in absolute
6270 * microseconds, while mac80211 gives the txop in units of
6271 * 32 microseconds.
6272 */
6273 p->txop = params->txop * 32;
6274
Michal Kazior7fc979a2015-01-28 09:57:28 +02006275 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6276 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6277 &arvif->wmm_params);
6278 if (ret) {
6279 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6280 arvif->vdev_id, ret);
6281 goto exit;
6282 }
6283 } else {
6284 /* This won't work well with multi-interface cases but it's
6285 * better than nothing.
6286 */
6287 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6288 if (ret) {
6289 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6290 goto exit;
6291 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006292 }
6293
6294 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6295 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006296 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006297
6298exit:
6299 mutex_unlock(&ar->conf_mutex);
6300 return ret;
6301}
6302
Kalle Valo14e105c2016-04-13 14:13:21 +03006303#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006304
6305static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6306 struct ieee80211_vif *vif,
6307 struct ieee80211_channel *chan,
6308 int duration,
6309 enum ieee80211_roc_type type)
6310{
6311 struct ath10k *ar = hw->priv;
6312 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6313 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006314 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006315 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006316
6317 mutex_lock(&ar->conf_mutex);
6318
6319 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006320 switch (ar->scan.state) {
6321 case ATH10K_SCAN_IDLE:
6322 reinit_completion(&ar->scan.started);
6323 reinit_completion(&ar->scan.completed);
6324 reinit_completion(&ar->scan.on_channel);
6325 ar->scan.state = ATH10K_SCAN_STARTING;
6326 ar->scan.is_roc = true;
6327 ar->scan.vdev_id = arvif->vdev_id;
6328 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006329 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006330 ret = 0;
6331 break;
6332 case ATH10K_SCAN_STARTING:
6333 case ATH10K_SCAN_RUNNING:
6334 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006335 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006336 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006337 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006338 spin_unlock_bh(&ar->data_lock);
6339
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006340 if (ret)
6341 goto exit;
6342
Michal Kaziorfcf98442015-03-31 11:03:47 +00006343 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006344
Kalle Valo5e3dd152013-06-12 20:52:10 +03006345 memset(&arg, 0, sizeof(arg));
6346 ath10k_wmi_start_scan_init(ar, &arg);
6347 arg.vdev_id = arvif->vdev_id;
6348 arg.scan_id = ATH10K_SCAN_ID;
6349 arg.n_channels = 1;
6350 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006351 arg.dwell_time_active = scan_time_msec;
6352 arg.dwell_time_passive = scan_time_msec;
6353 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006354 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6355 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006356 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006357
6358 ret = ath10k_start_scan(ar, &arg);
6359 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006360 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006361 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006362 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006363 spin_unlock_bh(&ar->data_lock);
6364 goto exit;
6365 }
6366
Kalle Valo14e105c2016-04-13 14:13:21 +03006367 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006368 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006369 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006370
6371 ret = ath10k_scan_stop(ar);
6372 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006373 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006374
Kalle Valo5e3dd152013-06-12 20:52:10 +03006375 ret = -ETIMEDOUT;
6376 goto exit;
6377 }
6378
Michal Kaziorfcf98442015-03-31 11:03:47 +00006379 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6380 msecs_to_jiffies(duration));
6381
Kalle Valo5e3dd152013-06-12 20:52:10 +03006382 ret = 0;
6383exit:
6384 mutex_unlock(&ar->conf_mutex);
6385 return ret;
6386}
6387
6388static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6389{
6390 struct ath10k *ar = hw->priv;
6391
6392 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006393
6394 spin_lock_bh(&ar->data_lock);
6395 ar->scan.roc_notify = false;
6396 spin_unlock_bh(&ar->data_lock);
6397
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006398 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006399
Kalle Valo5e3dd152013-06-12 20:52:10 +03006400 mutex_unlock(&ar->conf_mutex);
6401
Michal Kazior4eb2e162014-10-28 10:23:09 +01006402 cancel_delayed_work_sync(&ar->scan.timeout);
6403
Kalle Valo5e3dd152013-06-12 20:52:10 +03006404 return 0;
6405}
6406
6407/*
6408 * Both RTS and Fragmentation threshold are interface-specific
6409 * in ath10k, but device-specific in mac80211.
6410 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006411
6412static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6413{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006414 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006415 struct ath10k_vif *arvif;
6416 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006417
Michal Kaziorad088bf2013-10-16 15:44:46 +03006418 mutex_lock(&ar->conf_mutex);
6419 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006420 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006421 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006422
Michal Kaziorad088bf2013-10-16 15:44:46 +03006423 ret = ath10k_mac_set_rts(arvif, value);
6424 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006425 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006426 arvif->vdev_id, ret);
6427 break;
6428 }
6429 }
6430 mutex_unlock(&ar->conf_mutex);
6431
6432 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006433}
6434
Michal Kazior92092fe2015-08-03 11:16:43 +02006435static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6436{
6437 /* Even though there's a WMI enum for fragmentation threshold no known
6438 * firmware actually implements it. Moreover it is not possible to rely
6439 * frame fragmentation to mac80211 because firmware clears the "more
6440 * fragments" bit in frame control making it impossible for remote
6441 * devices to reassemble frames.
6442 *
6443 * Hence implement a dummy callback just to say fragmentation isn't
6444 * supported. This effectively prevents mac80211 from doing frame
6445 * fragmentation in software.
6446 */
6447 return -EOPNOTSUPP;
6448}
6449
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02006450static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6451 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006452{
6453 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02006454 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006455 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006456
6457 /* mac80211 doesn't care if we really xmit queued frames or not
6458 * we'll collect those frames either way if we stop/delete vdevs */
6459 if (drop)
6460 return;
6461
Michal Kazior548db542013-07-05 16:15:15 +03006462 mutex_lock(&ar->conf_mutex);
6463
Michal Kazioraffd3212013-07-16 09:54:35 +02006464 if (ar->state == ATH10K_STATE_WEDGED)
6465 goto skip;
6466
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006467 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006468 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006469
Michal Kazioredb82362013-07-05 16:15:14 +03006470 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006471 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006472 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006473
Michal Kazior7962b0d2014-10-28 10:34:38 +01006474 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6475 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6476 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006477
6478 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006479 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006480
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006481 if (time_left == 0 || skip)
6482 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6483 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03006484
Michal Kazioraffd3212013-07-16 09:54:35 +02006485skip:
Michal Kazior548db542013-07-05 16:15:15 +03006486 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006487}
6488
6489/* TODO: Implement this function properly
6490 * For now it is needed to reply to Probe Requests in IBSS mode.
6491 * Propably we need this information from FW.
6492 */
6493static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
6494{
6495 return 1;
6496}
6497
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006498static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
6499 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02006500{
6501 struct ath10k *ar = hw->priv;
6502
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006503 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
6504 return;
6505
Michal Kazioraffd3212013-07-16 09:54:35 +02006506 mutex_lock(&ar->conf_mutex);
6507
6508 /* If device failed to restart it will be in a different state, e.g.
6509 * ATH10K_STATE_WEDGED */
6510 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006511 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02006512 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01006513 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02006514 }
6515
6516 mutex_unlock(&ar->conf_mutex);
6517}
6518
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306519static void
6520ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
6521 struct ieee80211_channel *channel)
6522{
6523 int ret;
6524 enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
6525
6526 lockdep_assert_held(&ar->conf_mutex);
6527
6528 if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
6529 (ar->rx_channel != channel))
6530 return;
6531
6532 if (ar->scan.state != ATH10K_SCAN_IDLE) {
6533 ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
6534 return;
6535 }
6536
6537 reinit_completion(&ar->bss_survey_done);
6538
6539 ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
6540 if (ret) {
6541 ath10k_warn(ar, "failed to send pdev bss chan info request\n");
6542 return;
6543 }
6544
6545 ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
6546 if (!ret) {
6547 ath10k_warn(ar, "bss channel survey timed out\n");
6548 return;
6549 }
6550}
6551
Michal Kazior2e1dea42013-07-31 10:32:40 +02006552static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
6553 struct survey_info *survey)
6554{
6555 struct ath10k *ar = hw->priv;
6556 struct ieee80211_supported_band *sband;
6557 struct survey_info *ar_survey = &ar->survey[idx];
6558 int ret = 0;
6559
6560 mutex_lock(&ar->conf_mutex);
6561
Johannes Berg57fbcce2016-04-12 15:56:15 +02006562 sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006563 if (sband && idx >= sband->n_channels) {
6564 idx -= sband->n_channels;
6565 sband = NULL;
6566 }
6567
6568 if (!sband)
Johannes Berg57fbcce2016-04-12 15:56:15 +02006569 sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006570
6571 if (!sband || idx >= sband->n_channels) {
6572 ret = -ENOENT;
6573 goto exit;
6574 }
6575
Ashok Raj Nagarajan77eb3d62016-09-02 10:59:53 +05306576 ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306577
Michal Kazior2e1dea42013-07-31 10:32:40 +02006578 spin_lock_bh(&ar->data_lock);
6579 memcpy(survey, ar_survey, sizeof(*survey));
6580 spin_unlock_bh(&ar->data_lock);
6581
6582 survey->channel = &sband->channels[idx];
6583
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03006584 if (ar->rx_channel == survey->channel)
6585 survey->filled |= SURVEY_INFO_IN_USE;
6586
Michal Kazior2e1dea42013-07-31 10:32:40 +02006587exit:
6588 mutex_unlock(&ar->conf_mutex);
6589 return ret;
6590}
6591
Michal Kazior3ae54222015-03-31 10:49:20 +00006592static bool
6593ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006594 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006595 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006596{
Michal Kazior3ae54222015-03-31 10:49:20 +00006597 int num_rates = 0;
6598 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006599
Michal Kazior3ae54222015-03-31 10:49:20 +00006600 num_rates += hweight32(mask->control[band].legacy);
6601
6602 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
6603 num_rates += hweight8(mask->control[band].ht_mcs[i]);
6604
6605 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
6606 num_rates += hweight16(mask->control[band].vht_mcs[i]);
6607
6608 return num_rates == 1;
6609}
6610
6611static bool
6612ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006613 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006614 const struct cfg80211_bitrate_mask *mask,
6615 int *nss)
6616{
6617 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6618 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6619 u8 ht_nss_mask = 0;
6620 u8 vht_nss_mask = 0;
6621 int i;
6622
6623 if (mask->control[band].legacy)
6624 return false;
6625
6626 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6627 if (mask->control[band].ht_mcs[i] == 0)
6628 continue;
6629 else if (mask->control[band].ht_mcs[i] ==
6630 sband->ht_cap.mcs.rx_mask[i])
6631 ht_nss_mask |= BIT(i);
6632 else
6633 return false;
6634 }
6635
6636 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6637 if (mask->control[band].vht_mcs[i] == 0)
6638 continue;
6639 else if (mask->control[band].vht_mcs[i] ==
6640 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6641 vht_nss_mask |= BIT(i);
6642 else
6643 return false;
6644 }
6645
6646 if (ht_nss_mask != vht_nss_mask)
6647 return false;
6648
6649 if (ht_nss_mask == 0)
6650 return false;
6651
6652 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6653 return false;
6654
6655 *nss = fls(ht_nss_mask);
6656
6657 return true;
6658}
6659
6660static int
6661ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006662 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006663 const struct cfg80211_bitrate_mask *mask,
6664 u8 *rate, u8 *nss)
6665{
6666 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6667 int rate_idx;
6668 int i;
6669 u16 bitrate;
6670 u8 preamble;
6671 u8 hw_rate;
6672
6673 if (hweight32(mask->control[band].legacy) == 1) {
6674 rate_idx = ffs(mask->control[band].legacy) - 1;
6675
6676 hw_rate = sband->bitrates[rate_idx].hw_value;
6677 bitrate = sband->bitrates[rate_idx].bitrate;
6678
6679 if (ath10k_mac_bitrate_is_cck(bitrate))
6680 preamble = WMI_RATE_PREAMBLE_CCK;
6681 else
6682 preamble = WMI_RATE_PREAMBLE_OFDM;
6683
6684 *nss = 1;
6685 *rate = preamble << 6 |
6686 (*nss - 1) << 4 |
6687 hw_rate << 0;
6688
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006689 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006690 }
6691
Michal Kazior3ae54222015-03-31 10:49:20 +00006692 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6693 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6694 *nss = i + 1;
6695 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6696 (*nss - 1) << 4 |
6697 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006698
Michal Kazior3ae54222015-03-31 10:49:20 +00006699 return 0;
6700 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006701 }
6702
Michal Kazior3ae54222015-03-31 10:49:20 +00006703 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6704 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6705 *nss = i + 1;
6706 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6707 (*nss - 1) << 4 |
6708 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006709
Michal Kazior3ae54222015-03-31 10:49:20 +00006710 return 0;
6711 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006712 }
6713
Michal Kazior3ae54222015-03-31 10:49:20 +00006714 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006715}
6716
Michal Kazior3ae54222015-03-31 10:49:20 +00006717static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306718 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006719{
6720 struct ath10k *ar = arvif->ar;
6721 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006722 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006723
Michal Kazior3ae54222015-03-31 10:49:20 +00006724 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006725
Michal Kazior3ae54222015-03-31 10:49:20 +00006726 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6727 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006728
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006729 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006730 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006731 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006732 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006733 rate, ret);
6734 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006735 }
6736
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006737 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006738 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006739 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006740 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6741 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006742 }
6743
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006744 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006745 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006746 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006747 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6748 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006749 }
6750
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306751 vdev_param = ar->wmi.vdev_param->ldpc;
6752 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6753 if (ret) {
6754 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6755 return ret;
6756 }
6757
Michal Kazior3ae54222015-03-31 10:49:20 +00006758 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006759}
6760
Michal Kazior45c9abc2015-04-21 20:42:58 +03006761static bool
6762ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006763 enum nl80211_band band,
Michal Kazior45c9abc2015-04-21 20:42:58 +03006764 const struct cfg80211_bitrate_mask *mask)
6765{
6766 int i;
6767 u16 vht_mcs;
6768
6769 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6770 * to express all VHT MCS rate masks. Effectively only the following
6771 * ranges can be used: none, 0-7, 0-8 and 0-9.
6772 */
6773 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6774 vht_mcs = mask->control[band].vht_mcs[i];
6775
6776 switch (vht_mcs) {
6777 case 0:
6778 case BIT(8) - 1:
6779 case BIT(9) - 1:
6780 case BIT(10) - 1:
6781 break;
6782 default:
6783 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6784 return false;
6785 }
6786 }
6787
6788 return true;
6789}
6790
6791static void ath10k_mac_set_bitrate_mask_iter(void *data,
6792 struct ieee80211_sta *sta)
6793{
6794 struct ath10k_vif *arvif = data;
6795 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6796 struct ath10k *ar = arvif->ar;
6797
6798 if (arsta->arvif != arvif)
6799 return;
6800
6801 spin_lock_bh(&ar->data_lock);
6802 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
6803 spin_unlock_bh(&ar->data_lock);
6804
6805 ieee80211_queue_work(ar->hw, &arsta->update_wk);
6806}
6807
Michal Kazior3ae54222015-03-31 10:49:20 +00006808static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
6809 struct ieee80211_vif *vif,
6810 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006811{
6812 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006813 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006814 struct ath10k *ar = arvif->ar;
Johannes Berg57fbcce2016-04-12 15:56:15 +02006815 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006816 const u8 *ht_mcs_mask;
6817 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00006818 u8 rate;
6819 u8 nss;
6820 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306821 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00006822 int single_nss;
6823 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006824
Michal Kazior500ff9f2015-03-31 10:26:21 +00006825 if (ath10k_mac_vif_chan(vif, &def))
6826 return -EPERM;
6827
Michal Kazior500ff9f2015-03-31 10:26:21 +00006828 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006829 ht_mcs_mask = mask->control[band].ht_mcs;
6830 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306831 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006832
Michal Kazior3ae54222015-03-31 10:49:20 +00006833 sgi = mask->control[band].gi;
6834 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006835 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006836
Michal Kazior3ae54222015-03-31 10:49:20 +00006837 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
6838 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
6839 &rate, &nss);
6840 if (ret) {
6841 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
6842 arvif->vdev_id, ret);
6843 return ret;
6844 }
6845 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
6846 &single_nss)) {
6847 rate = WMI_FIXED_RATE_NONE;
6848 nss = single_nss;
6849 } else {
6850 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006851 nss = min(ar->num_rf_chains,
6852 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6853 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6854
6855 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
6856 return -EINVAL;
6857
6858 mutex_lock(&ar->conf_mutex);
6859
6860 arvif->bitrate_mask = *mask;
6861 ieee80211_iterate_stations_atomic(ar->hw,
6862 ath10k_mac_set_bitrate_mask_iter,
6863 arvif);
6864
6865 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006866 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006867
6868 mutex_lock(&ar->conf_mutex);
6869
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306870 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006871 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006872 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
6873 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006874 goto exit;
6875 }
6876
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006877exit:
6878 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00006879
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006880 return ret;
6881}
6882
Michal Kazior9797feb2014-02-14 14:49:48 +01006883static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6884 struct ieee80211_vif *vif,
6885 struct ieee80211_sta *sta,
6886 u32 changed)
6887{
6888 struct ath10k *ar = hw->priv;
6889 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6890 u32 bw, smps;
6891
6892 spin_lock_bh(&ar->data_lock);
6893
Michal Kazior7aa7a722014-08-25 12:09:38 +02006894 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01006895 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
6896 sta->addr, changed, sta->bandwidth, sta->rx_nss,
6897 sta->smps_mode);
6898
6899 if (changed & IEEE80211_RC_BW_CHANGED) {
6900 bw = WMI_PEER_CHWIDTH_20MHZ;
6901
6902 switch (sta->bandwidth) {
6903 case IEEE80211_STA_RX_BW_20:
6904 bw = WMI_PEER_CHWIDTH_20MHZ;
6905 break;
6906 case IEEE80211_STA_RX_BW_40:
6907 bw = WMI_PEER_CHWIDTH_40MHZ;
6908 break;
6909 case IEEE80211_STA_RX_BW_80:
6910 bw = WMI_PEER_CHWIDTH_80MHZ;
6911 break;
6912 case IEEE80211_STA_RX_BW_160:
Masanari Iidad939be32015-02-27 23:52:31 +09006913 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006914 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006915 bw = WMI_PEER_CHWIDTH_20MHZ;
6916 break;
6917 }
6918
6919 arsta->bw = bw;
6920 }
6921
6922 if (changed & IEEE80211_RC_NSS_CHANGED)
6923 arsta->nss = sta->rx_nss;
6924
6925 if (changed & IEEE80211_RC_SMPS_CHANGED) {
6926 smps = WMI_PEER_SMPS_PS_NONE;
6927
6928 switch (sta->smps_mode) {
6929 case IEEE80211_SMPS_AUTOMATIC:
6930 case IEEE80211_SMPS_OFF:
6931 smps = WMI_PEER_SMPS_PS_NONE;
6932 break;
6933 case IEEE80211_SMPS_STATIC:
6934 smps = WMI_PEER_SMPS_STATIC;
6935 break;
6936 case IEEE80211_SMPS_DYNAMIC:
6937 smps = WMI_PEER_SMPS_DYNAMIC;
6938 break;
6939 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02006940 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006941 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006942 smps = WMI_PEER_SMPS_PS_NONE;
6943 break;
6944 }
6945
6946 arsta->smps = smps;
6947 }
6948
Michal Kazior9797feb2014-02-14 14:49:48 +01006949 arsta->changed |= changed;
6950
6951 spin_unlock_bh(&ar->data_lock);
6952
6953 ieee80211_queue_work(hw, &arsta->update_wk);
6954}
6955
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006956static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
6957{
6958 /*
6959 * FIXME: Return 0 for time being. Need to figure out whether FW
6960 * has the API to fetch 64-bit local TSF
6961 */
6962
6963 return 0;
6964}
6965
Peter Oh9f0b7e72016-04-04 16:19:14 -07006966static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
Kalle Valo4d165442016-04-13 14:14:16 +03006967 u64 tsf)
Peter Oh9f0b7e72016-04-04 16:19:14 -07006968{
6969 struct ath10k *ar = hw->priv;
6970 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6971 u32 tsf_offset, vdev_param = ar->wmi.vdev_param->set_tsf;
6972 int ret;
6973
6974 /* Workaround:
6975 *
6976 * Given tsf argument is entire TSF value, but firmware accepts
6977 * only TSF offset to current TSF.
6978 *
6979 * get_tsf function is used to get offset value, however since
6980 * ath10k_get_tsf is not implemented properly, it will return 0 always.
6981 * Luckily all the caller functions to set_tsf, as of now, also rely on
6982 * get_tsf function to get entire tsf value such get_tsf() + tsf_delta,
6983 * final tsf offset value to firmware will be arithmetically correct.
6984 */
6985 tsf_offset = tsf - ath10k_get_tsf(hw, vif);
6986 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
6987 vdev_param, tsf_offset);
6988 if (ret && ret != -EOPNOTSUPP)
6989 ath10k_warn(ar, "failed to set tsf offset: %d\n", ret);
6990}
6991
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006992static int ath10k_ampdu_action(struct ieee80211_hw *hw,
6993 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02006994 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006995{
Michal Kazior7aa7a722014-08-25 12:09:38 +02006996 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006997 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Sara Sharon50ea05e2015-12-30 16:06:04 +02006998 struct ieee80211_sta *sta = params->sta;
6999 enum ieee80211_ampdu_mlme_action action = params->action;
7000 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007001
Michal Kazior7aa7a722014-08-25 12:09:38 +02007002 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 +02007003 arvif->vdev_id, sta->addr, tid, action);
7004
7005 switch (action) {
7006 case IEEE80211_AMPDU_RX_START:
7007 case IEEE80211_AMPDU_RX_STOP:
7008 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
7009 * creation/removal. Do we need to verify this?
7010 */
7011 return 0;
7012 case IEEE80211_AMPDU_TX_START:
7013 case IEEE80211_AMPDU_TX_STOP_CONT:
7014 case IEEE80211_AMPDU_TX_STOP_FLUSH:
7015 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
7016 case IEEE80211_AMPDU_TX_OPERATIONAL:
7017 /* Firmware offloads Tx aggregation entirely so deny mac80211
7018 * Tx aggregation requests.
7019 */
7020 return -EOPNOTSUPP;
7021 }
7022
7023 return -EINVAL;
7024}
7025
Michal Kazior500ff9f2015-03-31 10:26:21 +00007026static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007027ath10k_mac_update_rx_channel(struct ath10k *ar,
7028 struct ieee80211_chanctx_conf *ctx,
7029 struct ieee80211_vif_chanctx_switch *vifs,
7030 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00007031{
7032 struct cfg80211_chan_def *def = NULL;
7033
7034 /* Both locks are required because ar->rx_channel is modified. This
7035 * allows readers to hold either lock.
7036 */
7037 lockdep_assert_held(&ar->conf_mutex);
7038 lockdep_assert_held(&ar->data_lock);
7039
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007040 WARN_ON(ctx && vifs);
7041 WARN_ON(vifs && n_vifs != 1);
7042
Michal Kazior500ff9f2015-03-31 10:26:21 +00007043 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
7044 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
7045 * ppdu on Rx may reduce performance on low-end systems. It should be
7046 * possible to make tables/hashmaps to speed the lookup up (be vary of
7047 * cpu data cache lines though regarding sizes) but to keep the initial
7048 * implementation simple and less intrusive fallback to the slow lookup
7049 * only for multi-channel cases. Single-channel cases will remain to
7050 * use the old channel derival and thus performance should not be
7051 * affected much.
7052 */
7053 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007054 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00007055 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03007056 ath10k_mac_get_any_chandef_iter,
7057 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007058
7059 if (vifs)
7060 def = &vifs[0].new_ctx->def;
7061
Michal Kazior500ff9f2015-03-31 10:26:21 +00007062 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05307063 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
7064 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
7065 /* During driver restart due to firmware assert, since mac80211
7066 * already has valid channel context for given radio, channel
7067 * context iteration return num_chanctx > 0. So fix rx_channel
7068 * when restart is in progress.
7069 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007070 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007071 } else {
7072 ar->rx_channel = NULL;
7073 }
7074 rcu_read_unlock();
7075}
7076
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007077static void
7078ath10k_mac_update_vif_chan(struct ath10k *ar,
7079 struct ieee80211_vif_chanctx_switch *vifs,
7080 int n_vifs)
7081{
7082 struct ath10k_vif *arvif;
7083 int ret;
7084 int i;
7085
7086 lockdep_assert_held(&ar->conf_mutex);
7087
7088 /* First stop monitor interface. Some FW versions crash if there's a
7089 * lone monitor interface.
7090 */
7091 if (ar->monitor_started)
7092 ath10k_monitor_stop(ar);
7093
7094 for (i = 0; i < n_vifs; i++) {
7095 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7096
7097 ath10k_dbg(ar, ATH10K_DBG_MAC,
7098 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
7099 arvif->vdev_id,
7100 vifs[i].old_ctx->def.chan->center_freq,
7101 vifs[i].new_ctx->def.chan->center_freq,
7102 vifs[i].old_ctx->def.width,
7103 vifs[i].new_ctx->def.width);
7104
7105 if (WARN_ON(!arvif->is_started))
7106 continue;
7107
7108 if (WARN_ON(!arvif->is_up))
7109 continue;
7110
7111 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7112 if (ret) {
7113 ath10k_warn(ar, "failed to down vdev %d: %d\n",
7114 arvif->vdev_id, ret);
7115 continue;
7116 }
7117 }
7118
7119 /* All relevant vdevs are downed and associated channel resources
7120 * should be available for the channel switch now.
7121 */
7122
7123 spin_lock_bh(&ar->data_lock);
7124 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
7125 spin_unlock_bh(&ar->data_lock);
7126
7127 for (i = 0; i < n_vifs; i++) {
7128 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7129
7130 if (WARN_ON(!arvif->is_started))
7131 continue;
7132
7133 if (WARN_ON(!arvif->is_up))
7134 continue;
7135
7136 ret = ath10k_mac_setup_bcn_tmpl(arvif);
7137 if (ret)
7138 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
7139 ret);
7140
7141 ret = ath10k_mac_setup_prb_tmpl(arvif);
7142 if (ret)
7143 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
7144 ret);
7145
7146 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7147 if (ret) {
7148 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7149 arvif->vdev_id, ret);
7150 continue;
7151 }
7152
7153 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7154 arvif->bssid);
7155 if (ret) {
7156 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7157 arvif->vdev_id, ret);
7158 continue;
7159 }
7160 }
7161
7162 ath10k_monitor_recalc(ar);
7163}
7164
Michal Kazior500ff9f2015-03-31 10:26:21 +00007165static int
7166ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7167 struct ieee80211_chanctx_conf *ctx)
7168{
7169 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007170
7171 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307172 "mac chanctx add freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007173 ctx->def.chan->center_freq, ctx->def.width, ctx);
7174
7175 mutex_lock(&ar->conf_mutex);
7176
7177 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007178 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007179 spin_unlock_bh(&ar->data_lock);
7180
7181 ath10k_recalc_radar_detection(ar);
7182 ath10k_monitor_recalc(ar);
7183
7184 mutex_unlock(&ar->conf_mutex);
7185
7186 return 0;
7187}
7188
7189static void
7190ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7191 struct ieee80211_chanctx_conf *ctx)
7192{
7193 struct ath10k *ar = hw->priv;
7194
7195 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307196 "mac chanctx remove freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007197 ctx->def.chan->center_freq, ctx->def.width, ctx);
7198
7199 mutex_lock(&ar->conf_mutex);
7200
7201 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007202 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007203 spin_unlock_bh(&ar->data_lock);
7204
7205 ath10k_recalc_radar_detection(ar);
7206 ath10k_monitor_recalc(ar);
7207
7208 mutex_unlock(&ar->conf_mutex);
7209}
7210
Michal Kazior9713e3d2015-09-03 10:44:52 +02007211struct ath10k_mac_change_chanctx_arg {
7212 struct ieee80211_chanctx_conf *ctx;
7213 struct ieee80211_vif_chanctx_switch *vifs;
7214 int n_vifs;
7215 int next_vif;
7216};
7217
7218static void
7219ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
7220 struct ieee80211_vif *vif)
7221{
7222 struct ath10k_mac_change_chanctx_arg *arg = data;
7223
7224 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
7225 return;
7226
7227 arg->n_vifs++;
7228}
7229
7230static void
7231ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
7232 struct ieee80211_vif *vif)
7233{
7234 struct ath10k_mac_change_chanctx_arg *arg = data;
7235 struct ieee80211_chanctx_conf *ctx;
7236
7237 ctx = rcu_access_pointer(vif->chanctx_conf);
7238 if (ctx != arg->ctx)
7239 return;
7240
7241 if (WARN_ON(arg->next_vif == arg->n_vifs))
7242 return;
7243
7244 arg->vifs[arg->next_vif].vif = vif;
7245 arg->vifs[arg->next_vif].old_ctx = ctx;
7246 arg->vifs[arg->next_vif].new_ctx = ctx;
7247 arg->next_vif++;
7248}
7249
Michal Kazior500ff9f2015-03-31 10:26:21 +00007250static void
7251ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7252 struct ieee80211_chanctx_conf *ctx,
7253 u32 changed)
7254{
7255 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007256 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007257
7258 mutex_lock(&ar->conf_mutex);
7259
7260 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307261 "mac chanctx change freq %hu width %d ptr %pK changed %x\n",
Michal Kazior089ab7a2015-06-03 12:16:55 +02007262 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007263
7264 /* This shouldn't really happen because channel switching should use
7265 * switch_vif_chanctx().
7266 */
7267 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7268 goto unlock;
7269
Michal Kazior9713e3d2015-09-03 10:44:52 +02007270 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7271 ieee80211_iterate_active_interfaces_atomic(
7272 hw,
7273 IEEE80211_IFACE_ITER_NORMAL,
7274 ath10k_mac_change_chanctx_cnt_iter,
7275 &arg);
7276 if (arg.n_vifs == 0)
7277 goto radar;
7278
7279 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7280 GFP_KERNEL);
7281 if (!arg.vifs)
7282 goto radar;
7283
7284 ieee80211_iterate_active_interfaces_atomic(
7285 hw,
7286 IEEE80211_IFACE_ITER_NORMAL,
7287 ath10k_mac_change_chanctx_fill_iter,
7288 &arg);
7289 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7290 kfree(arg.vifs);
7291 }
7292
7293radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007294 ath10k_recalc_radar_detection(ar);
7295
7296 /* FIXME: How to configure Rx chains properly? */
7297
7298 /* No other actions are actually necessary. Firmware maintains channel
7299 * definitions per vdev internally and there's no host-side channel
7300 * context abstraction to configure, e.g. channel width.
7301 */
7302
7303unlock:
7304 mutex_unlock(&ar->conf_mutex);
7305}
7306
7307static int
7308ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7309 struct ieee80211_vif *vif,
7310 struct ieee80211_chanctx_conf *ctx)
7311{
7312 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007313 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7314 int ret;
7315
7316 mutex_lock(&ar->conf_mutex);
7317
7318 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307319 "mac chanctx assign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007320 ctx, arvif->vdev_id);
7321
7322 if (WARN_ON(arvif->is_started)) {
7323 mutex_unlock(&ar->conf_mutex);
7324 return -EBUSY;
7325 }
7326
Michal Kazior089ab7a2015-06-03 12:16:55 +02007327 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007328 if (ret) {
7329 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7330 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007331 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007332 goto err;
7333 }
7334
7335 arvif->is_started = true;
7336
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007337 ret = ath10k_mac_vif_setup_ps(arvif);
7338 if (ret) {
7339 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7340 arvif->vdev_id, ret);
7341 goto err_stop;
7342 }
7343
Michal Kazior500ff9f2015-03-31 10:26:21 +00007344 if (vif->type == NL80211_IFTYPE_MONITOR) {
7345 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7346 if (ret) {
7347 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7348 arvif->vdev_id, ret);
7349 goto err_stop;
7350 }
7351
7352 arvif->is_up = true;
7353 }
7354
7355 mutex_unlock(&ar->conf_mutex);
7356 return 0;
7357
7358err_stop:
7359 ath10k_vdev_stop(arvif);
7360 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007361 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007362
7363err:
7364 mutex_unlock(&ar->conf_mutex);
7365 return ret;
7366}
7367
7368static void
7369ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7370 struct ieee80211_vif *vif,
7371 struct ieee80211_chanctx_conf *ctx)
7372{
7373 struct ath10k *ar = hw->priv;
7374 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7375 int ret;
7376
7377 mutex_lock(&ar->conf_mutex);
7378
7379 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307380 "mac chanctx unassign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007381 ctx, arvif->vdev_id);
7382
7383 WARN_ON(!arvif->is_started);
7384
7385 if (vif->type == NL80211_IFTYPE_MONITOR) {
7386 WARN_ON(!arvif->is_up);
7387
7388 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7389 if (ret)
7390 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7391 arvif->vdev_id, ret);
7392
7393 arvif->is_up = false;
7394 }
7395
7396 ret = ath10k_vdev_stop(arvif);
7397 if (ret)
7398 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7399 arvif->vdev_id, ret);
7400
7401 arvif->is_started = false;
7402
7403 mutex_unlock(&ar->conf_mutex);
7404}
7405
7406static int
7407ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7408 struct ieee80211_vif_chanctx_switch *vifs,
7409 int n_vifs,
7410 enum ieee80211_chanctx_switch_mode mode)
7411{
7412 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007413
7414 mutex_lock(&ar->conf_mutex);
7415
7416 ath10k_dbg(ar, ATH10K_DBG_MAC,
7417 "mac chanctx switch n_vifs %d mode %d\n",
7418 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007419 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007420
7421 mutex_unlock(&ar->conf_mutex);
7422 return 0;
7423}
7424
Kalle Valo5e3dd152013-06-12 20:52:10 +03007425static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01007426 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02007427 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007428 .start = ath10k_start,
7429 .stop = ath10k_stop,
7430 .config = ath10k_config,
7431 .add_interface = ath10k_add_interface,
7432 .remove_interface = ath10k_remove_interface,
7433 .configure_filter = ath10k_configure_filter,
7434 .bss_info_changed = ath10k_bss_info_changed,
7435 .hw_scan = ath10k_hw_scan,
7436 .cancel_hw_scan = ath10k_cancel_hw_scan,
7437 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02007438 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007439 .sta_state = ath10k_sta_state,
7440 .conf_tx = ath10k_conf_tx,
7441 .remain_on_channel = ath10k_remain_on_channel,
7442 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
7443 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02007444 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007445 .flush = ath10k_flush,
7446 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03007447 .set_antenna = ath10k_set_antenna,
7448 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007449 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02007450 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00007451 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01007452 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02007453 .get_tsf = ath10k_get_tsf,
Peter Oh9f0b7e72016-04-04 16:19:14 -07007454 .set_tsf = ath10k_set_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007455 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03007456 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7457 .get_et_stats = ath10k_debug_get_et_stats,
7458 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00007459 .add_chanctx = ath10k_mac_op_add_chanctx,
7460 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7461 .change_chanctx = ath10k_mac_op_change_chanctx,
7462 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7463 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7464 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Kalle Valo43d2a302014-09-10 18:23:30 +03007465
7466 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7467
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007468#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007469 .suspend = ath10k_wow_op_suspend,
7470 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007471#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007472#ifdef CONFIG_MAC80211_DEBUGFS
7473 .sta_add_debugfs = ath10k_sta_add_debugfs,
Mohammed Shafi Shajakhan120a1f02016-06-30 15:23:50 +03007474 .sta_statistics = ath10k_sta_statistics,
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007475#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03007476};
7477
Kalle Valo5e3dd152013-06-12 20:52:10 +03007478#define CHAN2G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007479 .band = NL80211_BAND_2GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007480 .hw_value = (_channel), \
7481 .center_freq = (_freq), \
7482 .flags = (_flags), \
7483 .max_antenna_gain = 0, \
7484 .max_power = 30, \
7485}
7486
7487#define CHAN5G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007488 .band = NL80211_BAND_5GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007489 .hw_value = (_channel), \
7490 .center_freq = (_freq), \
7491 .flags = (_flags), \
7492 .max_antenna_gain = 0, \
7493 .max_power = 30, \
7494}
7495
7496static const struct ieee80211_channel ath10k_2ghz_channels[] = {
7497 CHAN2G(1, 2412, 0),
7498 CHAN2G(2, 2417, 0),
7499 CHAN2G(3, 2422, 0),
7500 CHAN2G(4, 2427, 0),
7501 CHAN2G(5, 2432, 0),
7502 CHAN2G(6, 2437, 0),
7503 CHAN2G(7, 2442, 0),
7504 CHAN2G(8, 2447, 0),
7505 CHAN2G(9, 2452, 0),
7506 CHAN2G(10, 2457, 0),
7507 CHAN2G(11, 2462, 0),
7508 CHAN2G(12, 2467, 0),
7509 CHAN2G(13, 2472, 0),
7510 CHAN2G(14, 2484, 0),
7511};
7512
7513static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02007514 CHAN5G(36, 5180, 0),
7515 CHAN5G(40, 5200, 0),
7516 CHAN5G(44, 5220, 0),
7517 CHAN5G(48, 5240, 0),
7518 CHAN5G(52, 5260, 0),
7519 CHAN5G(56, 5280, 0),
7520 CHAN5G(60, 5300, 0),
7521 CHAN5G(64, 5320, 0),
7522 CHAN5G(100, 5500, 0),
7523 CHAN5G(104, 5520, 0),
7524 CHAN5G(108, 5540, 0),
7525 CHAN5G(112, 5560, 0),
7526 CHAN5G(116, 5580, 0),
7527 CHAN5G(120, 5600, 0),
7528 CHAN5G(124, 5620, 0),
7529 CHAN5G(128, 5640, 0),
7530 CHAN5G(132, 5660, 0),
7531 CHAN5G(136, 5680, 0),
7532 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07007533 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02007534 CHAN5G(149, 5745, 0),
7535 CHAN5G(153, 5765, 0),
7536 CHAN5G(157, 5785, 0),
7537 CHAN5G(161, 5805, 0),
7538 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03007539};
7540
Michal Kaziore7b54192014-08-07 11:03:27 +02007541struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007542{
7543 struct ieee80211_hw *hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007544 struct ieee80211_ops *ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007545 struct ath10k *ar;
7546
Michal Kazior4ca18072016-07-18 23:22:18 +03007547 ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);
7548 if (!ops)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007549 return NULL;
7550
Michal Kazior4ca18072016-07-18 23:22:18 +03007551 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);
7552 if (!hw) {
7553 kfree(ops);
7554 return NULL;
7555 }
7556
Kalle Valo5e3dd152013-06-12 20:52:10 +03007557 ar = hw->priv;
7558 ar->hw = hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007559 ar->ops = ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007560
7561 return ar;
7562}
7563
7564void ath10k_mac_destroy(struct ath10k *ar)
7565{
Michal Kazior4ca18072016-07-18 23:22:18 +03007566 struct ieee80211_ops *ops = ar->ops;
7567
Kalle Valo5e3dd152013-06-12 20:52:10 +03007568 ieee80211_free_hw(ar->hw);
Michal Kazior4ca18072016-07-18 23:22:18 +03007569 kfree(ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007570}
7571
7572static const struct ieee80211_iface_limit ath10k_if_limits[] = {
7573 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307574 .max = 8,
7575 .types = BIT(NL80211_IFTYPE_STATION)
7576 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02007577 },
7578 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307579 .max = 3,
7580 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02007581 },
7582 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307583 .max = 1,
7584 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01007585 },
7586 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307587 .max = 7,
7588 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007589#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307590 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007591#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02007592 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007593};
7594
Bartosz Markowskif2595092013-12-10 16:20:39 +01007595static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007596 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307597 .max = 8,
7598 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007599#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307600 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007601#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007602 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307603 {
7604 .max = 1,
7605 .types = BIT(NL80211_IFTYPE_STATION)
7606 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007607};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007608
7609static const struct ieee80211_iface_combination ath10k_if_comb[] = {
7610 {
7611 .limits = ath10k_if_limits,
7612 .n_limits = ARRAY_SIZE(ath10k_if_limits),
7613 .max_interfaces = 8,
7614 .num_different_channels = 1,
7615 .beacon_int_infra_match = true,
7616 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01007617};
7618
7619static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007620 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01007621 .limits = ath10k_10x_if_limits,
7622 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007623 .max_interfaces = 8,
7624 .num_different_channels = 1,
7625 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01007626#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007627 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7628 BIT(NL80211_CHAN_WIDTH_20) |
7629 BIT(NL80211_CHAN_WIDTH_40) |
7630 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007631#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01007632 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007633};
7634
Michal Kaziorcf327842015-03-31 10:26:25 +00007635static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
7636 {
7637 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02007638 .types = BIT(NL80211_IFTYPE_STATION),
7639 },
7640 {
7641 .max = 2,
7642 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007643#ifdef CONFIG_MAC80211_MESH
7644 BIT(NL80211_IFTYPE_MESH_POINT) |
7645#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00007646 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7647 BIT(NL80211_IFTYPE_P2P_GO),
7648 },
7649 {
7650 .max = 1,
7651 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7652 },
7653};
7654
Michal Kaziored25b112015-07-09 13:08:39 +02007655static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
7656 {
7657 .max = 2,
7658 .types = BIT(NL80211_IFTYPE_STATION),
7659 },
7660 {
7661 .max = 2,
7662 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
7663 },
7664 {
7665 .max = 1,
7666 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007667#ifdef CONFIG_MAC80211_MESH
7668 BIT(NL80211_IFTYPE_MESH_POINT) |
7669#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007670 BIT(NL80211_IFTYPE_P2P_GO),
7671 },
7672 {
7673 .max = 1,
7674 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7675 },
7676};
7677
Michal Kaziorcf327842015-03-31 10:26:25 +00007678static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7679 {
7680 .max = 1,
7681 .types = BIT(NL80211_IFTYPE_STATION),
7682 },
7683 {
7684 .max = 1,
7685 .types = BIT(NL80211_IFTYPE_ADHOC),
7686 },
7687};
7688
7689/* FIXME: This is not thouroughly tested. These combinations may over- or
7690 * underestimate hw/fw capabilities.
7691 */
7692static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7693 {
7694 .limits = ath10k_tlv_if_limit,
7695 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007696 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007697 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7698 },
7699 {
7700 .limits = ath10k_tlv_if_limit_ibss,
7701 .num_different_channels = 1,
7702 .max_interfaces = 2,
7703 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7704 },
7705};
7706
7707static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7708 {
7709 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007710 .num_different_channels = 1,
7711 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007712 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7713 },
7714 {
Michal Kaziored25b112015-07-09 13:08:39 +02007715 .limits = ath10k_tlv_qcs_if_limit,
7716 .num_different_channels = 2,
7717 .max_interfaces = 4,
7718 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7719 },
7720 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007721 .limits = ath10k_tlv_if_limit_ibss,
7722 .num_different_channels = 1,
7723 .max_interfaces = 2,
7724 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7725 },
7726};
7727
Raja Manicf36fef2015-06-22 20:22:25 +05307728static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
7729 {
7730 .max = 1,
7731 .types = BIT(NL80211_IFTYPE_STATION),
7732 },
7733 {
7734 .max = 16,
7735 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007736#ifdef CONFIG_MAC80211_MESH
7737 | BIT(NL80211_IFTYPE_MESH_POINT)
7738#endif
Raja Manicf36fef2015-06-22 20:22:25 +05307739 },
7740};
7741
7742static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
7743 {
7744 .limits = ath10k_10_4_if_limits,
7745 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
7746 .max_interfaces = 16,
7747 .num_different_channels = 1,
7748 .beacon_int_infra_match = true,
7749#ifdef CONFIG_ATH10K_DFS_CERTIFIED
7750 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7751 BIT(NL80211_CHAN_WIDTH_20) |
7752 BIT(NL80211_CHAN_WIDTH_40) |
7753 BIT(NL80211_CHAN_WIDTH_80),
7754#endif
7755 },
7756};
7757
Kalle Valo5e3dd152013-06-12 20:52:10 +03007758static void ath10k_get_arvif_iter(void *data, u8 *mac,
7759 struct ieee80211_vif *vif)
7760{
7761 struct ath10k_vif_iter *arvif_iter = data;
7762 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7763
7764 if (arvif->vdev_id == arvif_iter->vdev_id)
7765 arvif_iter->arvif = arvif;
7766}
7767
7768struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
7769{
7770 struct ath10k_vif_iter arvif_iter;
7771 u32 flags;
7772
7773 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
7774 arvif_iter.vdev_id = vdev_id;
7775
7776 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
7777 ieee80211_iterate_active_interfaces_atomic(ar->hw,
7778 flags,
7779 ath10k_get_arvif_iter,
7780 &arvif_iter);
7781 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007782 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007783 return NULL;
7784 }
7785
7786 return arvif_iter.arvif;
7787}
7788
7789int ath10k_mac_register(struct ath10k *ar)
7790{
Johannes Berg3cb10942015-01-22 21:38:45 +01007791 static const u32 cipher_suites[] = {
7792 WLAN_CIPHER_SUITE_WEP40,
7793 WLAN_CIPHER_SUITE_WEP104,
7794 WLAN_CIPHER_SUITE_TKIP,
7795 WLAN_CIPHER_SUITE_CCMP,
7796 WLAN_CIPHER_SUITE_AES_CMAC,
7797 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03007798 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007799 void *channels;
7800 int ret;
7801
7802 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
7803
7804 SET_IEEE80211_DEV(ar->hw, ar->dev);
7805
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00007806 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
7807 ARRAY_SIZE(ath10k_5ghz_channels)) !=
7808 ATH10K_NUM_CHANS);
7809
Kalle Valo5e3dd152013-06-12 20:52:10 +03007810 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
7811 channels = kmemdup(ath10k_2ghz_channels,
7812 sizeof(ath10k_2ghz_channels),
7813 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02007814 if (!channels) {
7815 ret = -ENOMEM;
7816 goto err_free;
7817 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007818
Johannes Berg57fbcce2016-04-12 15:56:15 +02007819 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007820 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
7821 band->channels = channels;
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +03007822
7823 if (ar->hw_params.cck_rate_map_rev2) {
7824 band->n_bitrates = ath10k_g_rates_rev2_size;
7825 band->bitrates = ath10k_g_rates_rev2;
7826 } else {
7827 band->n_bitrates = ath10k_g_rates_size;
7828 band->bitrates = ath10k_g_rates;
7829 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007830
Johannes Berg57fbcce2016-04-12 15:56:15 +02007831 ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007832 }
7833
7834 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
7835 channels = kmemdup(ath10k_5ghz_channels,
7836 sizeof(ath10k_5ghz_channels),
7837 GFP_KERNEL);
7838 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02007839 ret = -ENOMEM;
7840 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007841 }
7842
Johannes Berg57fbcce2016-04-12 15:56:15 +02007843 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007844 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
7845 band->channels = channels;
7846 band->n_bitrates = ath10k_a_rates_size;
7847 band->bitrates = ath10k_a_rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02007848 ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007849 }
7850
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05307851 ath10k_mac_setup_ht_vht_cap(ar);
7852
Kalle Valo5e3dd152013-06-12 20:52:10 +03007853 ar->hw->wiphy->interface_modes =
7854 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007855 BIT(NL80211_IFTYPE_AP) |
7856 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01007857
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05307858 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
7859 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03007860
Kalle Valoc4cdf752016-04-20 19:45:18 +03007861 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))
Bartosz Markowskid3541812013-12-10 16:20:40 +01007862 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01007863 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01007864 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7865 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007866
Johannes Berg30686bf2015-06-02 21:39:54 +02007867 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
7868 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
7869 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
7870 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
7871 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
7872 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
7873 ieee80211_hw_set(ar->hw, AP_LINK_PS);
7874 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02007875 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
7876 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
7877 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
7878 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
7879 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
7880 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007881
David Liuccec9032015-07-24 20:25:32 +03007882 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7883 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
7884
Eliad Peller0d8614b2014-09-10 14:07:36 +03007885 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00007886 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03007887
Kalle Valo5e3dd152013-06-12 20:52:10 +03007888 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03007889 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007890
7891 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02007892 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
7893 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007894 }
7895
7896 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
7897 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
7898
7899 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01007900 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02007901 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007902
Kalle Valo5e3dd152013-06-12 20:52:10 +03007903 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
7904
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02007905 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
7906 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
7907
7908 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
7909 * that userspace (e.g. wpa_supplicant/hostapd) can generate
7910 * correct Probe Responses. This is more of a hack advert..
7911 */
7912 ar->hw->wiphy->probe_resp_offload |=
7913 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
7914 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
7915 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
7916 }
7917
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03007918 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
7919 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7920
Kalle Valo5e3dd152013-06-12 20:52:10 +03007921 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01007922 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007923 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
7924
7925 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05307926 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
7927 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02007928
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01007929 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
7930
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007931 ret = ath10k_wow_init(ar);
7932 if (ret) {
7933 ath10k_warn(ar, "failed to init wow: %d\n", ret);
7934 goto err_free;
7935 }
7936
Janusz Dziedzicc7025342015-06-15 14:46:41 +03007937 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
7938
Kalle Valo5e3dd152013-06-12 20:52:10 +03007939 /*
7940 * on LL hardware queues are managed entirely by the FW
7941 * so we only advertise to mac we can do the queues thing
7942 */
Michal Kazior96d828d2015-03-31 10:26:23 +00007943 ar->hw->queues = IEEE80211_MAX_QUEUES;
7944
7945 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
7946 * something that vdev_ids can't reach so that we don't stop the queue
7947 * accidentally.
7948 */
7949 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007950
Kalle Valobf3c13a2016-04-20 19:45:33 +03007951 switch (ar->running_fw->fw_file.wmi_op_version) {
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007952 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01007953 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
7954 ar->hw->wiphy->n_iface_combinations =
7955 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03007956 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007957 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00007958 case ATH10K_FW_WMI_OP_VERSION_TLV:
7959 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
7960 ar->hw->wiphy->iface_combinations =
7961 ath10k_tlv_qcs_if_comb;
7962 ar->hw->wiphy->n_iface_combinations =
7963 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
7964 } else {
7965 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
7966 ar->hw->wiphy->n_iface_combinations =
7967 ARRAY_SIZE(ath10k_tlv_if_comb);
7968 }
7969 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
7970 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007971 case ATH10K_FW_WMI_OP_VERSION_10_1:
7972 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02007973 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007974 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
7975 ar->hw->wiphy->n_iface_combinations =
7976 ARRAY_SIZE(ath10k_10x_if_comb);
7977 break;
Raja Mani9bd21322015-06-22 20:10:09 +05307978 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05307979 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
7980 ar->hw->wiphy->n_iface_combinations =
7981 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05307982 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007983 case ATH10K_FW_WMI_OP_VERSION_UNSET:
7984 case ATH10K_FW_WMI_OP_VERSION_MAX:
7985 WARN_ON(1);
7986 ret = -EINVAL;
7987 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01007988 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007989
David Liuccec9032015-07-24 20:25:32 +03007990 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7991 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02007992
Masahiro Yamada97f26452016-08-03 13:45:50 -07007993 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007994 /* Init ath dfs pattern detector */
7995 ar->ath_common.debug_mask = ATH_DBG_DFS;
7996 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
7997 NL80211_DFS_UNSET);
7998
7999 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02008000 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008001 }
8002
Michal Kazior4ca18072016-07-18 23:22:18 +03008003 /* Current wake_tx_queue implementation imposes a significant
8004 * performance penalty in some setups. The tx scheduling code needs
8005 * more work anyway so disable the wake_tx_queue unless firmware
8006 * supports the pull-push mechanism.
8007 */
8008 if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,
8009 ar->running_fw->fw_file.fw_features))
8010 ar->ops->wake_tx_queue = NULL;
8011
Kalle Valo5e3dd152013-06-12 20:52:10 +03008012 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
8013 ath10k_reg_notifier);
8014 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008015 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008016 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008017 }
8018
Johannes Berg3cb10942015-01-22 21:38:45 +01008019 ar->hw->wiphy->cipher_suites = cipher_suites;
8020 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
8021
Kalle Valo5e3dd152013-06-12 20:52:10 +03008022 ret = ieee80211_register_hw(ar->hw);
8023 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008024 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008025 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008026 }
8027
8028 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
8029 ret = regulatory_hint(ar->hw->wiphy,
8030 ar->ath_common.regulatory.alpha2);
8031 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02008032 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008033 }
8034
8035 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02008036
8037err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03008038 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07008039
8040err_dfs_detector_exit:
Masahiro Yamada97f26452016-08-03 13:45:50 -07008041 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Jeff Johnson0e339442015-10-08 09:15:53 -07008042 ar->dfs_detector->exit(ar->dfs_detector);
8043
Michal Kaziord6015b22013-07-22 14:13:30 +02008044err_free:
Johannes Berg57fbcce2016-04-12 15:56:15 +02008045 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8046 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Michal Kaziord6015b22013-07-22 14:13:30 +02008047
Jeff Johnson0e339442015-10-08 09:15:53 -07008048 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008049 return ret;
8050}
8051
8052void ath10k_mac_unregister(struct ath10k *ar)
8053{
8054 ieee80211_unregister_hw(ar->hw);
8055
Masahiro Yamada97f26452016-08-03 13:45:50 -07008056 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008057 ar->dfs_detector->exit(ar->dfs_detector);
8058
Johannes Berg57fbcce2016-04-12 15:56:15 +02008059 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8060 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008061
8062 SET_IEEE80211_DEV(ar->hw, NULL);
8063}