blob: c6c4ae708c156c2ec9034501e371b304ae716cbf [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) {
711 ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n",
712 addr, vdev_id);
713 ath10k_wmi_peer_delete(ar, vdev_id, addr);
714 spin_unlock_bh(&ar->data_lock);
715 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;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300805
806 lockdep_assert_held(&ar->conf_mutex);
807
808 spin_lock_bh(&ar->data_lock);
809 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
810 if (peer->vdev_id != vdev_id)
811 continue;
812
Michal Kazior7aa7a722014-08-25 12:09:38 +0200813 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300814 peer->addr, vdev_id);
815
Michal Kazior69427262016-03-06 16:14:30 +0200816 for_each_set_bit(peer_id, peer->peer_ids,
817 ATH10K_MAX_NUM_PEER_IDS) {
818 ar->peer_map[peer_id] = NULL;
819 }
820
Kalle Valo5e3dd152013-06-12 20:52:10 +0300821 list_del(&peer->list);
822 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100823 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300824 }
825 spin_unlock_bh(&ar->data_lock);
826}
827
Michal Kaziora96d7742013-07-16 09:38:56 +0200828static void ath10k_peer_cleanup_all(struct ath10k *ar)
829{
830 struct ath10k_peer *peer, *tmp;
831
832 lockdep_assert_held(&ar->conf_mutex);
833
834 spin_lock_bh(&ar->data_lock);
835 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
836 list_del(&peer->list);
837 kfree(peer);
838 }
839 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100840
841 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100842 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200843}
844
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300845static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
846 struct ieee80211_sta *sta,
847 enum wmi_tdls_peer_state state)
848{
849 int ret;
850 struct wmi_tdls_peer_update_cmd_arg arg = {};
851 struct wmi_tdls_peer_capab_arg cap = {};
852 struct wmi_channel_arg chan_arg = {};
853
854 lockdep_assert_held(&ar->conf_mutex);
855
856 arg.vdev_id = vdev_id;
857 arg.peer_state = state;
858 ether_addr_copy(arg.addr, sta->addr);
859
860 cap.peer_max_sp = sta->max_sp;
861 cap.peer_uapsd_queues = sta->uapsd_queues;
862
863 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
864 !sta->tdls_initiator)
865 cap.is_peer_responder = 1;
866
867 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
868 if (ret) {
869 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
870 arg.addr, vdev_id, ret);
871 return ret;
872 }
873
874 return 0;
875}
876
Kalle Valo5e3dd152013-06-12 20:52:10 +0300877/************************/
878/* Interface management */
879/************************/
880
Michal Kazior64badcb2014-09-18 11:18:02 +0300881void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
882{
883 struct ath10k *ar = arvif->ar;
884
885 lockdep_assert_held(&ar->data_lock);
886
887 if (!arvif->beacon)
888 return;
889
890 if (!arvif->beacon_buf)
891 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
892 arvif->beacon->len, DMA_TO_DEVICE);
893
Michal Kazioraf213192015-01-29 14:29:52 +0200894 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
895 arvif->beacon_state != ATH10K_BEACON_SENT))
896 return;
897
Michal Kazior64badcb2014-09-18 11:18:02 +0300898 dev_kfree_skb_any(arvif->beacon);
899
900 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200901 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300902}
903
904static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
905{
906 struct ath10k *ar = arvif->ar;
907
908 lockdep_assert_held(&ar->data_lock);
909
910 ath10k_mac_vif_beacon_free(arvif);
911
912 if (arvif->beacon_buf) {
913 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
914 arvif->beacon_buf, arvif->beacon_paddr);
915 arvif->beacon_buf = NULL;
916 }
917}
918
Kalle Valo5e3dd152013-06-12 20:52:10 +0300919static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
920{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300921 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300922
Michal Kazior548db542013-07-05 16:15:15 +0300923 lockdep_assert_held(&ar->conf_mutex);
924
Michal Kazior7962b0d2014-10-28 10:34:38 +0100925 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
926 return -ESHUTDOWN;
927
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300928 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
929 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
930 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300931 return -ETIMEDOUT;
932
933 return 0;
934}
935
Michal Kazior1bbc0972014-04-08 09:45:47 +0300936static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300937{
Michal Kazior500ff9f2015-03-31 10:26:21 +0000938 struct cfg80211_chan_def *chandef = NULL;
Maninder Singh19be9e92015-07-16 09:25:33 +0530939 struct ieee80211_channel *channel = NULL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300940 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300941 int ret = 0;
942
943 lockdep_assert_held(&ar->conf_mutex);
944
Michal Kazior500ff9f2015-03-31 10:26:21 +0000945 ieee80211_iter_chan_contexts_atomic(ar->hw,
946 ath10k_mac_get_any_chandef_iter,
947 &chandef);
948 if (WARN_ON_ONCE(!chandef))
949 return -ENOENT;
950
951 channel = chandef->chan;
952
Kalle Valo5e3dd152013-06-12 20:52:10 +0300953 arg.vdev_id = vdev_id;
954 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +0100955 arg.channel.band_center_freq1 = chandef->center_freq1;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300956
957 /* TODO setup this dynamically, what in case we
958 don't have any vifs? */
Michal Kaziorc930f742014-01-23 11:38:25 +0100959 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200960 arg.channel.chan_radar =
961 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300962
Michal Kazior89c5c842013-10-23 04:02:13 -0700963 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -0700964 arg.channel.max_power = channel->max_power * 2;
965 arg.channel.max_reg_power = channel->max_reg_power * 2;
966 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300967
Michal Kazior7962b0d2014-10-28 10:34:38 +0100968 reinit_completion(&ar->vdev_setup_done);
969
Kalle Valo5e3dd152013-06-12 20:52:10 +0300970 ret = ath10k_wmi_vdev_start(ar, &arg);
971 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200972 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200973 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300974 return ret;
975 }
976
977 ret = ath10k_vdev_setup_sync(ar);
978 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +0200979 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200980 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300981 return ret;
982 }
983
984 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
985 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200986 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200987 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300988 goto vdev_stop;
989 }
990
991 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300992
Michal Kazior7aa7a722014-08-25 12:09:38 +0200993 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +0300994 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300995 return 0;
996
997vdev_stop:
998 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
999 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001000 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001001 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001002
1003 return ret;
1004}
1005
Michal Kazior1bbc0972014-04-08 09:45:47 +03001006static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001007{
1008 int ret = 0;
1009
1010 lockdep_assert_held(&ar->conf_mutex);
1011
Marek Puzyniak52fa0192013-09-24 14:06:24 +02001012 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
1013 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001014 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001015 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001016
Michal Kazior7962b0d2014-10-28 10:34:38 +01001017 reinit_completion(&ar->vdev_setup_done);
1018
Kalle Valo5e3dd152013-06-12 20:52:10 +03001019 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1020 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001021 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001022 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001023
1024 ret = ath10k_vdev_setup_sync(ar);
1025 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +02001026 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001027 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001028
Michal Kazior7aa7a722014-08-25 12:09:38 +02001029 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001030 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001031 return ret;
1032}
1033
Michal Kazior1bbc0972014-04-08 09:45:47 +03001034static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001035{
1036 int bit, ret = 0;
1037
1038 lockdep_assert_held(&ar->conf_mutex);
1039
Ben Greeara9aefb32014-08-12 11:02:19 +03001040 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001041 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03001042 return -ENOMEM;
1043 }
1044
Ben Greear16c11172014-09-23 14:17:16 -07001045 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +03001046
Ben Greear16c11172014-09-23 14:17:16 -07001047 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001048
1049 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
1050 WMI_VDEV_TYPE_MONITOR,
1051 0, ar->mac_addr);
1052 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001053 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001054 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +03001055 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001056 }
1057
Ben Greear16c11172014-09-23 14:17:16 -07001058 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +02001059 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001060 ar->monitor_vdev_id);
1061
Kalle Valo5e3dd152013-06-12 20:52:10 +03001062 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001063}
1064
Michal Kazior1bbc0972014-04-08 09:45:47 +03001065static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001066{
1067 int ret = 0;
1068
1069 lockdep_assert_held(&ar->conf_mutex);
1070
Kalle Valo5e3dd152013-06-12 20:52:10 +03001071 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
1072 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001073 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001074 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001075 return ret;
1076 }
1077
Ben Greear16c11172014-09-23 14:17:16 -07001078 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001079
Michal Kazior7aa7a722014-08-25 12:09:38 +02001080 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001081 ar->monitor_vdev_id);
1082 return ret;
1083}
1084
Michal Kazior1bbc0972014-04-08 09:45:47 +03001085static int ath10k_monitor_start(struct ath10k *ar)
1086{
1087 int ret;
1088
1089 lockdep_assert_held(&ar->conf_mutex);
1090
Michal Kazior1bbc0972014-04-08 09:45:47 +03001091 ret = ath10k_monitor_vdev_create(ar);
1092 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001093 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001094 return ret;
1095 }
1096
1097 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
1098 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001099 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001100 ath10k_monitor_vdev_delete(ar);
1101 return ret;
1102 }
1103
1104 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001105 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +03001106
1107 return 0;
1108}
1109
Michal Kazior19337472014-08-28 12:58:16 +02001110static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +03001111{
1112 int ret;
1113
1114 lockdep_assert_held(&ar->conf_mutex);
1115
Michal Kazior1bbc0972014-04-08 09:45:47 +03001116 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001117 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001118 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001119 return ret;
1120 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001121
1122 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001123 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001124 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001125 return ret;
1126 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001127
1128 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001129 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +02001130
1131 return 0;
1132}
1133
Michal Kazior500ff9f2015-03-31 10:26:21 +00001134static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1135{
1136 int num_ctx;
1137
1138 /* At least one chanctx is required to derive a channel to start
1139 * monitor vdev on.
1140 */
1141 num_ctx = ath10k_mac_num_chanctxs(ar);
1142 if (num_ctx == 0)
1143 return false;
1144
1145 /* If there's already an existing special monitor interface then don't
1146 * bother creating another monitor vdev.
1147 */
1148 if (ar->monitor_arvif)
1149 return false;
1150
1151 return ar->monitor ||
Bob Copeland0d031c82015-09-09 12:47:34 -04001152 ar->filter_flags & FIF_OTHER_BSS ||
Michal Kazior500ff9f2015-03-31 10:26:21 +00001153 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1154}
1155
1156static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1157{
1158 int num_ctx;
1159
1160 num_ctx = ath10k_mac_num_chanctxs(ar);
1161
1162 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1163 * shouldn't allow this but make sure to prevent handling the following
1164 * case anyway since multi-channel DFS hasn't been tested at all.
1165 */
1166 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1167 return false;
1168
1169 return true;
1170}
1171
Michal Kazior19337472014-08-28 12:58:16 +02001172static int ath10k_monitor_recalc(struct ath10k *ar)
1173{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001174 bool needed;
1175 bool allowed;
1176 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001177
1178 lockdep_assert_held(&ar->conf_mutex);
1179
Michal Kazior500ff9f2015-03-31 10:26:21 +00001180 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1181 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001182
1183 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001184 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1185 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001186
Michal Kazior500ff9f2015-03-31 10:26:21 +00001187 if (WARN_ON(needed && !allowed)) {
1188 if (ar->monitor_started) {
1189 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1190
1191 ret = ath10k_monitor_stop(ar);
1192 if (ret)
Kalle Valo2a995082015-10-05 17:56:37 +03001193 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",
1194 ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001195 /* not serious */
1196 }
1197
1198 return -EPERM;
1199 }
1200
1201 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001202 return 0;
1203
Michal Kazior500ff9f2015-03-31 10:26:21 +00001204 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001205 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001206 else
1207 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001208}
1209
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001210static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1211{
1212 struct ath10k *ar = arvif->ar;
1213 u32 vdev_param, rts_cts = 0;
1214
1215 lockdep_assert_held(&ar->conf_mutex);
1216
1217 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1218
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001219 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001220
1221 if (arvif->num_legacy_stations > 0)
1222 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1223 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001224 else
1225 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1226 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001227
1228 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1229 rts_cts);
1230}
1231
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001232static int ath10k_start_cac(struct ath10k *ar)
1233{
1234 int ret;
1235
1236 lockdep_assert_held(&ar->conf_mutex);
1237
1238 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1239
Michal Kazior19337472014-08-28 12:58:16 +02001240 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001241 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001242 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001243 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1244 return ret;
1245 }
1246
Michal Kazior7aa7a722014-08-25 12:09:38 +02001247 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001248 ar->monitor_vdev_id);
1249
1250 return 0;
1251}
1252
1253static int ath10k_stop_cac(struct ath10k *ar)
1254{
1255 lockdep_assert_held(&ar->conf_mutex);
1256
1257 /* CAC is not running - do nothing */
1258 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1259 return 0;
1260
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001261 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001262 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001263
Michal Kazior7aa7a722014-08-25 12:09:38 +02001264 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001265
1266 return 0;
1267}
1268
Michal Kazior500ff9f2015-03-31 10:26:21 +00001269static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1270 struct ieee80211_chanctx_conf *conf,
1271 void *data)
1272{
1273 bool *ret = data;
1274
1275 if (!*ret && conf->radar_enabled)
1276 *ret = true;
1277}
1278
1279static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1280{
1281 bool has_radar = false;
1282
1283 ieee80211_iter_chan_contexts_atomic(ar->hw,
1284 ath10k_mac_has_radar_iter,
1285 &has_radar);
1286
1287 return has_radar;
1288}
1289
Michal Kaziord6500972014-04-08 09:56:09 +03001290static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001291{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001292 int ret;
1293
1294 lockdep_assert_held(&ar->conf_mutex);
1295
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001296 ath10k_stop_cac(ar);
1297
Michal Kazior500ff9f2015-03-31 10:26:21 +00001298 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001299 return;
1300
Michal Kaziord6500972014-04-08 09:56:09 +03001301 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001302 return;
1303
1304 ret = ath10k_start_cac(ar);
1305 if (ret) {
1306 /*
1307 * Not possible to start CAC on current channel so starting
1308 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1309 * by indicating that radar was detected.
1310 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001311 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001312 ieee80211_radar_detected(ar->hw);
1313 }
1314}
1315
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301316static int ath10k_vdev_stop(struct ath10k_vif *arvif)
Michal Kazior72654fa2014-04-08 09:56:09 +03001317{
1318 struct ath10k *ar = arvif->ar;
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301319 int ret;
1320
1321 lockdep_assert_held(&ar->conf_mutex);
1322
1323 reinit_completion(&ar->vdev_setup_done);
1324
1325 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1326 if (ret) {
1327 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1328 arvif->vdev_id, ret);
1329 return ret;
1330 }
1331
1332 ret = ath10k_vdev_setup_sync(ar);
1333 if (ret) {
1334 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
1335 arvif->vdev_id, ret);
1336 return ret;
1337 }
1338
1339 WARN_ON(ar->num_started_vdevs == 0);
1340
1341 if (ar->num_started_vdevs != 0) {
1342 ar->num_started_vdevs--;
1343 ath10k_recalc_radar_detection(ar);
1344 }
1345
1346 return ret;
1347}
1348
Michal Kazior500ff9f2015-03-31 10:26:21 +00001349static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1350 const struct cfg80211_chan_def *chandef,
1351 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001352{
1353 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001354 struct wmi_vdev_start_request_arg arg = {};
1355 int ret = 0;
1356
1357 lockdep_assert_held(&ar->conf_mutex);
1358
1359 reinit_completion(&ar->vdev_setup_done);
1360
1361 arg.vdev_id = arvif->vdev_id;
1362 arg.dtim_period = arvif->dtim_period;
1363 arg.bcn_intval = arvif->beacon_interval;
1364
1365 arg.channel.freq = chandef->chan->center_freq;
1366 arg.channel.band_center_freq1 = chandef->center_freq1;
1367 arg.channel.mode = chan_to_phymode(chandef);
1368
1369 arg.channel.min_power = 0;
1370 arg.channel.max_power = chandef->chan->max_power * 2;
1371 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1372 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1373
1374 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1375 arg.ssid = arvif->u.ap.ssid;
1376 arg.ssid_len = arvif->u.ap.ssid_len;
1377 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1378
1379 /* For now allow DFS for AP mode */
1380 arg.channel.chan_radar =
1381 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1382 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1383 arg.ssid = arvif->vif->bss_conf.ssid;
1384 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1385 }
1386
Michal Kazior7aa7a722014-08-25 12:09:38 +02001387 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001388 "mac vdev %d start center_freq %d phymode %s\n",
1389 arg.vdev_id, arg.channel.freq,
1390 ath10k_wmi_phymode_str(arg.channel.mode));
1391
Michal Kaziordc55e302014-07-29 12:53:36 +03001392 if (restart)
1393 ret = ath10k_wmi_vdev_restart(ar, &arg);
1394 else
1395 ret = ath10k_wmi_vdev_start(ar, &arg);
1396
Michal Kazior72654fa2014-04-08 09:56:09 +03001397 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001398 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001399 arg.vdev_id, ret);
1400 return ret;
1401 }
1402
1403 ret = ath10k_vdev_setup_sync(ar);
1404 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001405 ath10k_warn(ar,
1406 "failed to synchronize setup for vdev %i restart %d: %d\n",
1407 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001408 return ret;
1409 }
1410
Michal Kaziord6500972014-04-08 09:56:09 +03001411 ar->num_started_vdevs++;
1412 ath10k_recalc_radar_detection(ar);
1413
Michal Kazior72654fa2014-04-08 09:56:09 +03001414 return ret;
1415}
1416
Michal Kazior500ff9f2015-03-31 10:26:21 +00001417static int ath10k_vdev_start(struct ath10k_vif *arvif,
1418 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001419{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001420 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001421}
1422
Michal Kazior500ff9f2015-03-31 10:26:21 +00001423static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1424 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001425{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001426 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kazior72654fa2014-04-08 09:56:09 +03001427}
1428
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001429static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1430 struct sk_buff *bcn)
1431{
1432 struct ath10k *ar = arvif->ar;
1433 struct ieee80211_mgmt *mgmt;
1434 const u8 *p2p_ie;
1435 int ret;
1436
Peter Oh08c27be2016-01-28 13:54:09 -08001437 if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001438 return 0;
1439
1440 mgmt = (void *)bcn->data;
1441 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1442 mgmt->u.beacon.variable,
1443 bcn->len - (mgmt->u.beacon.variable -
1444 bcn->data));
1445 if (!p2p_ie)
1446 return -ENOENT;
1447
1448 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1449 if (ret) {
1450 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1451 arvif->vdev_id, ret);
1452 return ret;
1453 }
1454
1455 return 0;
1456}
1457
1458static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1459 u8 oui_type, size_t ie_offset)
1460{
1461 size_t len;
1462 const u8 *next;
1463 const u8 *end;
1464 u8 *ie;
1465
1466 if (WARN_ON(skb->len < ie_offset))
1467 return -EINVAL;
1468
1469 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1470 skb->data + ie_offset,
1471 skb->len - ie_offset);
1472 if (!ie)
1473 return -ENOENT;
1474
1475 len = ie[1] + 2;
1476 end = skb->data + skb->len;
1477 next = ie + len;
1478
1479 if (WARN_ON(next > end))
1480 return -EINVAL;
1481
1482 memmove(ie, next, end - next);
1483 skb_trim(skb, skb->len - len);
1484
1485 return 0;
1486}
1487
1488static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1489{
1490 struct ath10k *ar = arvif->ar;
1491 struct ieee80211_hw *hw = ar->hw;
1492 struct ieee80211_vif *vif = arvif->vif;
1493 struct ieee80211_mutable_offsets offs = {};
1494 struct sk_buff *bcn;
1495 int ret;
1496
1497 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1498 return 0;
1499
Michal Kazior81a9a172015-03-05 16:02:17 +02001500 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1501 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1502 return 0;
1503
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001504 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1505 if (!bcn) {
1506 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1507 return -EPERM;
1508 }
1509
1510 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1511 if (ret) {
1512 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1513 kfree_skb(bcn);
1514 return ret;
1515 }
1516
1517 /* P2P IE is inserted by firmware automatically (as configured above)
1518 * so remove it from the base beacon template to avoid duplicate P2P
1519 * IEs in beacon frames.
1520 */
1521 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1522 offsetof(struct ieee80211_mgmt,
1523 u.beacon.variable));
1524
1525 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1526 0, NULL, 0);
1527 kfree_skb(bcn);
1528
1529 if (ret) {
1530 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1531 ret);
1532 return ret;
1533 }
1534
1535 return 0;
1536}
1537
1538static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1539{
1540 struct ath10k *ar = arvif->ar;
1541 struct ieee80211_hw *hw = ar->hw;
1542 struct ieee80211_vif *vif = arvif->vif;
1543 struct sk_buff *prb;
1544 int ret;
1545
1546 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1547 return 0;
1548
Michal Kazior81a9a172015-03-05 16:02:17 +02001549 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1550 return 0;
1551
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001552 prb = ieee80211_proberesp_get(hw, vif);
1553 if (!prb) {
1554 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1555 return -EPERM;
1556 }
1557
1558 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1559 kfree_skb(prb);
1560
1561 if (ret) {
1562 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1563 ret);
1564 return ret;
1565 }
1566
1567 return 0;
1568}
1569
Michal Kazior500ff9f2015-03-31 10:26:21 +00001570static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1571{
1572 struct ath10k *ar = arvif->ar;
1573 struct cfg80211_chan_def def;
1574 int ret;
1575
1576 /* When originally vdev is started during assign_vif_chanctx() some
1577 * information is missing, notably SSID. Firmware revisions with beacon
1578 * offloading require the SSID to be provided during vdev (re)start to
1579 * handle hidden SSID properly.
1580 *
1581 * Vdev restart must be done after vdev has been both started and
1582 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1583 * deliver vdev restart response event causing timeouts during vdev
1584 * syncing in ath10k.
1585 *
1586 * Note: The vdev down/up and template reinstallation could be skipped
1587 * since only wmi-tlv firmware are known to have beacon offload and
1588 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1589 * response delivery. It's probably more robust to keep it as is.
1590 */
1591 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1592 return 0;
1593
1594 if (WARN_ON(!arvif->is_started))
1595 return -EINVAL;
1596
1597 if (WARN_ON(!arvif->is_up))
1598 return -EINVAL;
1599
1600 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1601 return -EINVAL;
1602
1603 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1604 if (ret) {
1605 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1606 arvif->vdev_id, ret);
1607 return ret;
1608 }
1609
1610 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1611 * firmware will crash upon vdev up.
1612 */
1613
1614 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1615 if (ret) {
1616 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1617 return ret;
1618 }
1619
1620 ret = ath10k_mac_setup_prb_tmpl(arvif);
1621 if (ret) {
1622 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1623 return ret;
1624 }
1625
1626 ret = ath10k_vdev_restart(arvif, &def);
1627 if (ret) {
1628 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1629 arvif->vdev_id, ret);
1630 return ret;
1631 }
1632
1633 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1634 arvif->bssid);
1635 if (ret) {
1636 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1637 arvif->vdev_id, ret);
1638 return ret;
1639 }
1640
1641 return 0;
1642}
1643
Kalle Valo5e3dd152013-06-12 20:52:10 +03001644static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001645 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001646{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001647 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001648 int ret = 0;
1649
Michal Kazior548db542013-07-05 16:15:15 +03001650 lockdep_assert_held(&arvif->ar->conf_mutex);
1651
Kalle Valo5e3dd152013-06-12 20:52:10 +03001652 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001653 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1654 if (ret)
1655 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1656 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001657
Michal Kaziorc930f742014-01-23 11:38:25 +01001658 arvif->is_up = false;
1659
Michal Kazior748afc42014-01-23 12:48:21 +01001660 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001661 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001662 spin_unlock_bh(&arvif->ar->data_lock);
1663
Kalle Valo5e3dd152013-06-12 20:52:10 +03001664 return;
1665 }
1666
1667 arvif->tx_seq_no = 0x1000;
1668
Michal Kaziorc930f742014-01-23 11:38:25 +01001669 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001670 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001671
1672 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1673 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001674 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001675 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001676 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001677 return;
1678 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001679
Michal Kaziorc930f742014-01-23 11:38:25 +01001680 arvif->is_up = true;
1681
Michal Kazior500ff9f2015-03-31 10:26:21 +00001682 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1683 if (ret) {
1684 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1685 arvif->vdev_id, ret);
1686 return;
1687 }
1688
Michal Kazior7aa7a722014-08-25 12:09:38 +02001689 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001690}
1691
1692static void ath10k_control_ibss(struct ath10k_vif *arvif,
1693 struct ieee80211_bss_conf *info,
1694 const u8 self_peer[ETH_ALEN])
1695{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001696 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001697 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001698 int ret = 0;
1699
Michal Kazior548db542013-07-05 16:15:15 +03001700 lockdep_assert_held(&arvif->ar->conf_mutex);
1701
Kalle Valo5e3dd152013-06-12 20:52:10 +03001702 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001703 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001704 return;
1705
Joe Perches93803b32015-03-02 19:54:49 -08001706 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001707
1708 return;
1709 }
1710
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001711 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1712 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001713 ATH10K_DEFAULT_ATIM);
1714 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001715 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001716 arvif->vdev_id, ret);
1717}
1718
Michal Kazior9f9b5742014-12-12 12:41:36 +01001719static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1720{
1721 struct ath10k *ar = arvif->ar;
1722 u32 param;
1723 u32 value;
1724 int ret;
1725
1726 lockdep_assert_held(&arvif->ar->conf_mutex);
1727
1728 if (arvif->u.sta.uapsd)
1729 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1730 else
1731 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1732
1733 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1734 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1735 if (ret) {
1736 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1737 value, arvif->vdev_id, ret);
1738 return ret;
1739 }
1740
1741 return 0;
1742}
1743
1744static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1745{
1746 struct ath10k *ar = arvif->ar;
1747 u32 param;
1748 u32 value;
1749 int ret;
1750
1751 lockdep_assert_held(&arvif->ar->conf_mutex);
1752
1753 if (arvif->u.sta.uapsd)
1754 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1755 else
1756 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1757
1758 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1759 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1760 param, value);
1761 if (ret) {
1762 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1763 value, arvif->vdev_id, ret);
1764 return ret;
1765 }
1766
1767 return 0;
1768}
1769
Michal Kazior424f2632015-07-09 13:08:35 +02001770static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001771{
1772 struct ath10k_vif *arvif;
1773 int num = 0;
1774
1775 lockdep_assert_held(&ar->conf_mutex);
1776
1777 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001778 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001779 num++;
1780
1781 return num;
1782}
1783
Michal Kaziorad088bf2013-10-16 15:44:46 +03001784static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001785{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001786 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001787 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001788 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001789 enum wmi_sta_powersave_param param;
1790 enum wmi_sta_ps_mode psmode;
1791 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001792 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001793 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001794
Michal Kazior548db542013-07-05 16:15:15 +03001795 lockdep_assert_held(&arvif->ar->conf_mutex);
1796
Michal Kaziorad088bf2013-10-16 15:44:46 +03001797 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1798 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001799
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001800 enable_ps = arvif->ps;
1801
Michal Kazior424f2632015-07-09 13:08:35 +02001802 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001803 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
Kalle Valoc4cdf752016-04-20 19:45:18 +03001804 ar->running_fw->fw_file.fw_features)) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001805 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1806 arvif->vdev_id);
1807 enable_ps = false;
1808 }
1809
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001810 if (!arvif->is_started) {
1811 /* mac80211 can update vif powersave state while disconnected.
1812 * Firmware doesn't behave nicely and consumes more power than
1813 * necessary if PS is disabled on a non-started vdev. Hence
1814 * force-enable PS for non-running vdevs.
1815 */
1816 psmode = WMI_STA_PS_MODE_ENABLED;
1817 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001818 psmode = WMI_STA_PS_MODE_ENABLED;
1819 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1820
Michal Kazior526549a2014-12-12 12:41:37 +01001821 ps_timeout = conf->dynamic_ps_timeout;
1822 if (ps_timeout == 0) {
1823 /* Firmware doesn't like 0 */
1824 ps_timeout = ieee80211_tu_to_usec(
1825 vif->bss_conf.beacon_int) / 1000;
1826 }
1827
Michal Kaziorad088bf2013-10-16 15:44:46 +03001828 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001829 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001830 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001831 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001832 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001833 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001834 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001835 } else {
1836 psmode = WMI_STA_PS_MODE_DISABLED;
1837 }
1838
Michal Kazior7aa7a722014-08-25 12:09:38 +02001839 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001840 arvif->vdev_id, psmode ? "enable" : "disable");
1841
Michal Kaziorad088bf2013-10-16 15:44:46 +03001842 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1843 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001844 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001845 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001846 return ret;
1847 }
1848
1849 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001850}
1851
Michal Kazior46725b152015-01-28 09:57:49 +02001852static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1853{
1854 struct ath10k *ar = arvif->ar;
1855 struct wmi_sta_keepalive_arg arg = {};
1856 int ret;
1857
1858 lockdep_assert_held(&arvif->ar->conf_mutex);
1859
1860 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1861 return 0;
1862
1863 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1864 return 0;
1865
1866 /* Some firmware revisions have a bug and ignore the `enabled` field.
1867 * Instead use the interval to disable the keepalive.
1868 */
1869 arg.vdev_id = arvif->vdev_id;
1870 arg.enabled = 1;
1871 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1872 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1873
1874 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1875 if (ret) {
1876 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1877 arvif->vdev_id, ret);
1878 return ret;
1879 }
1880
1881 return 0;
1882}
1883
Michal Kazior81a9a172015-03-05 16:02:17 +02001884static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1885{
1886 struct ath10k *ar = arvif->ar;
1887 struct ieee80211_vif *vif = arvif->vif;
1888 int ret;
1889
Michal Kazior8513d952015-03-09 14:19:24 +01001890 lockdep_assert_held(&arvif->ar->conf_mutex);
1891
1892 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1893 return;
1894
Michal Kazior81a9a172015-03-05 16:02:17 +02001895 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1896 return;
1897
1898 if (!vif->csa_active)
1899 return;
1900
1901 if (!arvif->is_up)
1902 return;
1903
1904 if (!ieee80211_csa_is_complete(vif)) {
1905 ieee80211_csa_update_counter(vif);
1906
1907 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1908 if (ret)
1909 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1910 ret);
1911
1912 ret = ath10k_mac_setup_prb_tmpl(arvif);
1913 if (ret)
1914 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1915 ret);
1916 } else {
1917 ieee80211_csa_finish(vif);
1918 }
1919}
1920
1921static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1922{
1923 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1924 ap_csa_work);
1925 struct ath10k *ar = arvif->ar;
1926
1927 mutex_lock(&ar->conf_mutex);
1928 ath10k_mac_vif_ap_csa_count_down(arvif);
1929 mutex_unlock(&ar->conf_mutex);
1930}
1931
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001932static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1933 struct ieee80211_vif *vif)
1934{
1935 struct sk_buff *skb = data;
1936 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1937 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1938
1939 if (vif->type != NL80211_IFTYPE_STATION)
1940 return;
1941
1942 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1943 return;
1944
1945 cancel_delayed_work(&arvif->connection_loss_work);
1946}
1947
1948void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
1949{
1950 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1951 IEEE80211_IFACE_ITER_NORMAL,
1952 ath10k_mac_handle_beacon_iter,
1953 skb);
1954}
1955
1956static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
1957 struct ieee80211_vif *vif)
1958{
1959 u32 *vdev_id = data;
1960 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1961 struct ath10k *ar = arvif->ar;
1962 struct ieee80211_hw *hw = ar->hw;
1963
1964 if (arvif->vdev_id != *vdev_id)
1965 return;
1966
1967 if (!arvif->is_up)
1968 return;
1969
1970 ieee80211_beacon_loss(vif);
1971
1972 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
1973 * (done by mac80211) succeeds but beacons do not resume then it
1974 * doesn't make sense to continue operation. Queue connection loss work
1975 * which can be cancelled when beacon is received.
1976 */
1977 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
1978 ATH10K_CONNECTION_LOSS_HZ);
1979}
1980
1981void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
1982{
1983 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1984 IEEE80211_IFACE_ITER_NORMAL,
1985 ath10k_mac_handle_beacon_miss_iter,
1986 &vdev_id);
1987}
1988
1989static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
1990{
1991 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1992 connection_loss_work.work);
1993 struct ieee80211_vif *vif = arvif->vif;
1994
1995 if (!arvif->is_up)
1996 return;
1997
1998 ieee80211_connection_loss(vif);
1999}
2000
Kalle Valo5e3dd152013-06-12 20:52:10 +03002001/**********************/
2002/* Station management */
2003/**********************/
2004
Michal Kazior590922a2014-10-21 10:10:29 +03002005static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
2006 struct ieee80211_vif *vif)
2007{
2008 /* Some firmware revisions have unstable STA powersave when listen
2009 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
2010 * generate NullFunc frames properly even if buffered frames have been
2011 * indicated in Beacon TIM. Firmware would seldom wake up to pull
2012 * buffered frames. Often pinging the device from AP would simply fail.
2013 *
2014 * As a workaround set it to 1.
2015 */
2016 if (vif->type == NL80211_IFTYPE_STATION)
2017 return 1;
2018
2019 return ar->hw->conf.listen_interval;
2020}
2021
Kalle Valo5e3dd152013-06-12 20:52:10 +03002022static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002023 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002024 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002025 struct wmi_peer_assoc_complete_arg *arg)
2026{
Michal Kazior590922a2014-10-21 10:10:29 +03002027 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorc51880e2015-03-30 09:51:57 +03002028 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03002029
Michal Kazior548db542013-07-05 16:15:15 +03002030 lockdep_assert_held(&ar->conf_mutex);
2031
Michal Kaziorc51880e2015-03-30 09:51:57 +03002032 if (vif->type == NL80211_IFTYPE_STATION)
2033 aid = vif->bss_conf.aid;
2034 else
2035 aid = sta->aid;
2036
Kalle Valob25f32c2014-09-14 12:50:49 +03002037 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002038 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002039 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002040 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03002041 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002042 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03002043 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002044}
2045
2046static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002047 struct ieee80211_vif *vif,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002048 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002049 struct wmi_peer_assoc_complete_arg *arg)
2050{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002051 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002052 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002053 struct cfg80211_bss *bss;
2054 const u8 *rsnie = NULL;
2055 const u8 *wpaie = NULL;
2056
Michal Kazior548db542013-07-05 16:15:15 +03002057 lockdep_assert_held(&ar->conf_mutex);
2058
Michal Kazior500ff9f2015-03-31 10:26:21 +00002059 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2060 return;
2061
2062 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
2063 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002064 if (bss) {
2065 const struct cfg80211_bss_ies *ies;
2066
2067 rcu_read_lock();
2068 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
2069
2070 ies = rcu_dereference(bss->ies);
2071
2072 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03002073 WLAN_OUI_TYPE_MICROSOFT_WPA,
2074 ies->data,
2075 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002076 rcu_read_unlock();
2077 cfg80211_put_bss(ar->hw->wiphy, bss);
2078 }
2079
2080 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2081 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002082 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002083 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002084 }
2085
2086 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002087 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002088 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002089 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002090
2091 if (sta->mfp &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03002092 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT,
2093 ar->running_fw->fw_file.fw_features)) {
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002094 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002095 }
2096}
2097
2098static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002099 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002100 struct ieee80211_sta *sta,
2101 struct wmi_peer_assoc_complete_arg *arg)
2102{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002103 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002104 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002105 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002106 const struct ieee80211_supported_band *sband;
2107 const struct ieee80211_rate *rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002108 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002109 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002110 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002111 int i;
2112
Michal Kazior548db542013-07-05 16:15:15 +03002113 lockdep_assert_held(&ar->conf_mutex);
2114
Michal Kazior500ff9f2015-03-31 10:26:21 +00002115 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2116 return;
2117
Michal Kazior45c9abc2015-04-21 20:42:58 +03002118 band = def.chan->band;
2119 sband = ar->hw->wiphy->bands[band];
2120 ratemask = sta->supp_rates[band];
2121 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002122 rates = sband->bitrates;
2123
2124 rateset->num_rates = 0;
2125
2126 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2127 if (!(ratemask & 1))
2128 continue;
2129
Michal Kazior486017c2015-03-30 09:51:54 +03002130 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2131 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002132 rateset->num_rates++;
2133 }
2134}
2135
Michal Kazior45c9abc2015-04-21 20:42:58 +03002136static bool
2137ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2138{
2139 int nss;
2140
2141 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2142 if (ht_mcs_mask[nss])
2143 return false;
2144
2145 return true;
2146}
2147
2148static bool
2149ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2150{
2151 int nss;
2152
2153 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2154 if (vht_mcs_mask[nss])
2155 return false;
2156
2157 return true;
2158}
2159
Kalle Valo5e3dd152013-06-12 20:52:10 +03002160static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002161 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002162 struct ieee80211_sta *sta,
2163 struct wmi_peer_assoc_complete_arg *arg)
2164{
2165 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002166 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2167 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002168 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002169 const u8 *ht_mcs_mask;
2170 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002171 int i, n;
2172 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002173 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002174
Michal Kazior548db542013-07-05 16:15:15 +03002175 lockdep_assert_held(&ar->conf_mutex);
2176
Michal Kazior45c9abc2015-04-21 20:42:58 +03002177 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2178 return;
2179
Kalle Valo5e3dd152013-06-12 20:52:10 +03002180 if (!ht_cap->ht_supported)
2181 return;
2182
Michal Kazior45c9abc2015-04-21 20:42:58 +03002183 band = def.chan->band;
2184 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2185 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2186
2187 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2188 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2189 return;
2190
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002191 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002192 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2193 ht_cap->ampdu_factor)) - 1;
2194
2195 arg->peer_mpdu_density =
2196 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2197
2198 arg->peer_ht_caps = ht_cap->cap;
2199 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2200
2201 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002202 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002203
2204 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002205 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002206 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2207 }
2208
Michal Kazior45c9abc2015-04-21 20:42:58 +03002209 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2210 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2211 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002212
Michal Kazior45c9abc2015-04-21 20:42:58 +03002213 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2214 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2215 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002216
2217 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2218 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002219 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002220 }
2221
2222 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002223 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2224 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2225 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2226 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002227 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002228 }
2229
Kalle Valo5e3dd152013-06-12 20:52:10 +03002230 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2231 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2232 else if (ht_cap->mcs.rx_mask[1])
2233 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2234
Michal Kazior45c9abc2015-04-21 20:42:58 +03002235 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2236 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2237 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2238 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002239 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002240 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002241
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002242 /*
2243 * This is a workaround for HT-enabled STAs which break the spec
2244 * and have no HT capabilities RX mask (no HT RX MCS map).
2245 *
2246 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2247 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2248 *
2249 * Firmware asserts if such situation occurs.
2250 */
2251 if (n == 0) {
2252 arg->peer_ht_rates.num_rates = 8;
2253 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2254 arg->peer_ht_rates.rates[i] = i;
2255 } else {
2256 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002257 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002258 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002259
Michal Kazior7aa7a722014-08-25 12:09:38 +02002260 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002261 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002262 arg->peer_ht_rates.num_rates,
2263 arg->peer_num_spatial_streams);
2264}
2265
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002266static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2267 struct ath10k_vif *arvif,
2268 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002269{
2270 u32 uapsd = 0;
2271 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002272 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002273
Michal Kazior548db542013-07-05 16:15:15 +03002274 lockdep_assert_held(&ar->conf_mutex);
2275
Kalle Valo5e3dd152013-06-12 20:52:10 +03002276 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002277 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002278 sta->uapsd_queues, sta->max_sp);
2279
Kalle Valo5e3dd152013-06-12 20:52:10 +03002280 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2281 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2282 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2283 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2284 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2285 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2286 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2287 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2288 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2289 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2290 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2291 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2292
Kalle Valo5e3dd152013-06-12 20:52:10 +03002293 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2294 max_sp = sta->max_sp;
2295
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002296 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2297 sta->addr,
2298 WMI_AP_PS_PEER_PARAM_UAPSD,
2299 uapsd);
2300 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002301 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002302 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002303 return ret;
2304 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002305
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002306 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2307 sta->addr,
2308 WMI_AP_PS_PEER_PARAM_MAX_SP,
2309 max_sp);
2310 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002311 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002312 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002313 return ret;
2314 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002315
2316 /* TODO setup this based on STA listen interval and
2317 beacon interval. Currently we don't know
2318 sta->listen_interval - mac80211 patch required.
2319 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002320 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002321 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2322 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002323 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002324 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002325 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002326 return ret;
2327 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002328 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002329
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002330 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002331}
2332
Michal Kazior45c9abc2015-04-21 20:42:58 +03002333static u16
2334ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2335 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2336{
2337 int idx_limit;
2338 int nss;
2339 u16 mcs_map;
2340 u16 mcs;
2341
2342 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2343 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2344 vht_mcs_limit[nss];
2345
2346 if (mcs_map)
2347 idx_limit = fls(mcs_map) - 1;
2348 else
2349 idx_limit = -1;
2350
2351 switch (idx_limit) {
2352 case 0: /* fall through */
2353 case 1: /* fall through */
2354 case 2: /* fall through */
2355 case 3: /* fall through */
2356 case 4: /* fall through */
2357 case 5: /* fall through */
2358 case 6: /* fall through */
2359 default:
2360 /* see ath10k_mac_can_set_bitrate_mask() */
2361 WARN_ON(1);
2362 /* fall through */
2363 case -1:
2364 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2365 break;
2366 case 7:
2367 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2368 break;
2369 case 8:
2370 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2371 break;
2372 case 9:
2373 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2374 break;
2375 }
2376
2377 tx_mcs_set &= ~(0x3 << (nss * 2));
2378 tx_mcs_set |= mcs << (nss * 2);
2379 }
2380
2381 return tx_mcs_set;
2382}
2383
Kalle Valo5e3dd152013-06-12 20:52:10 +03002384static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002385 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002386 struct ieee80211_sta *sta,
2387 struct wmi_peer_assoc_complete_arg *arg)
2388{
2389 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002390 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002391 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002392 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002393 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002394 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002395
Michal Kazior500ff9f2015-03-31 10:26:21 +00002396 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2397 return;
2398
Kalle Valo5e3dd152013-06-12 20:52:10 +03002399 if (!vht_cap->vht_supported)
2400 return;
2401
Michal Kazior45c9abc2015-04-21 20:42:58 +03002402 band = def.chan->band;
2403 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2404
2405 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2406 return;
2407
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002408 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002409
Johannes Berg57fbcce2016-04-12 15:56:15 +02002410 if (def.chan->band == NL80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002411 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002412
Kalle Valo5e3dd152013-06-12 20:52:10 +03002413 arg->peer_vht_caps = vht_cap->cap;
2414
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002415 ampdu_factor = (vht_cap->cap &
2416 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2417 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2418
2419 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2420 * zero in VHT IE. Using it would result in degraded throughput.
2421 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2422 * it if VHT max_mpdu is smaller. */
2423 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2424 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2425 ampdu_factor)) - 1);
2426
Kalle Valo5e3dd152013-06-12 20:52:10 +03002427 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002428 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002429
2430 arg->peer_vht_rates.rx_max_rate =
2431 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2432 arg->peer_vht_rates.rx_mcs_set =
2433 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2434 arg->peer_vht_rates.tx_max_rate =
2435 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002436 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2437 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002438
Michal Kazior7aa7a722014-08-25 12:09:38 +02002439 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002440 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002441}
2442
2443static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002444 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002445 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002446 struct wmi_peer_assoc_complete_arg *arg)
2447{
Michal Kazior590922a2014-10-21 10:10:29 +03002448 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2449
Kalle Valo5e3dd152013-06-12 20:52:10 +03002450 switch (arvif->vdev_type) {
2451 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002452 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002453 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002454
2455 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002456 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002457 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2458 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002459 break;
2460 case WMI_VDEV_TYPE_STA:
Michal Kazior590922a2014-10-21 10:10:29 +03002461 if (vif->bss_conf.qos)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002462 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002463 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002464 case WMI_VDEV_TYPE_IBSS:
2465 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002466 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002467 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002468 default:
2469 break;
2470 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002471
2472 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002473 sta->addr, !!(arg->peer_flags &
2474 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002475}
2476
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002477static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002478{
Johannes Berg57fbcce2016-04-12 15:56:15 +02002479 return sta->supp_rates[NL80211_BAND_2GHZ] >>
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002480 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002481}
2482
Kalle Valo5e3dd152013-06-12 20:52:10 +03002483static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002484 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002485 struct ieee80211_sta *sta,
2486 struct wmi_peer_assoc_complete_arg *arg)
2487{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002488 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002489 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002490 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002491 const u8 *ht_mcs_mask;
2492 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002493 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2494
Michal Kazior500ff9f2015-03-31 10:26:21 +00002495 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2496 return;
2497
Michal Kazior45c9abc2015-04-21 20:42:58 +03002498 band = def.chan->band;
2499 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2500 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2501
2502 switch (band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02002503 case NL80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002504 if (sta->vht_cap.vht_supported &&
2505 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002506 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2507 phymode = MODE_11AC_VHT40;
2508 else
2509 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002510 } else if (sta->ht_cap.ht_supported &&
2511 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002512 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2513 phymode = MODE_11NG_HT40;
2514 else
2515 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002516 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002517 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002518 } else {
2519 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002520 }
2521
2522 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002523 case NL80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002524 /*
2525 * Check VHT first.
2526 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002527 if (sta->vht_cap.vht_supported &&
2528 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002529 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2530 phymode = MODE_11AC_VHT80;
2531 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2532 phymode = MODE_11AC_VHT40;
2533 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2534 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002535 } else if (sta->ht_cap.ht_supported &&
2536 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2537 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002538 phymode = MODE_11NA_HT40;
2539 else
2540 phymode = MODE_11NA_HT20;
2541 } else {
2542 phymode = MODE_11A;
2543 }
2544
2545 break;
2546 default:
2547 break;
2548 }
2549
Michal Kazior7aa7a722014-08-25 12:09:38 +02002550 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002551 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002552
Kalle Valo5e3dd152013-06-12 20:52:10 +03002553 arg->peer_phymode = phymode;
2554 WARN_ON(phymode == MODE_UNKNOWN);
2555}
2556
Kalle Valob9ada652013-10-16 15:44:46 +03002557static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002558 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002559 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002560 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002561{
Michal Kazior548db542013-07-05 16:15:15 +03002562 lockdep_assert_held(&ar->conf_mutex);
2563
Kalle Valob9ada652013-10-16 15:44:46 +03002564 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002565
Michal Kazior590922a2014-10-21 10:10:29 +03002566 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002567 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002568 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002569 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002570 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002571 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2572 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002573
Kalle Valob9ada652013-10-16 15:44:46 +03002574 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002575}
2576
Michal Kazior90046f52014-02-14 14:45:51 +01002577static const u32 ath10k_smps_map[] = {
2578 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2579 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2580 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2581 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2582};
2583
2584static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2585 const u8 *addr,
2586 const struct ieee80211_sta_ht_cap *ht_cap)
2587{
2588 int smps;
2589
2590 if (!ht_cap->ht_supported)
2591 return 0;
2592
2593 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2594 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2595
2596 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2597 return -EINVAL;
2598
2599 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2600 WMI_PEER_SMPS_STATE,
2601 ath10k_smps_map[smps]);
2602}
2603
Michal Kazior139e1702015-02-15 16:50:42 +02002604static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2605 struct ieee80211_vif *vif,
2606 struct ieee80211_sta_vht_cap vht_cap)
2607{
2608 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2609 int ret;
2610 u32 param;
2611 u32 value;
2612
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302613 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2614 return 0;
2615
Michal Kazior139e1702015-02-15 16:50:42 +02002616 if (!(ar->vht_cap_info &
2617 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2618 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2619 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2620 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2621 return 0;
2622
2623 param = ar->wmi.vdev_param->txbf;
2624 value = 0;
2625
2626 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2627 return 0;
2628
2629 /* The following logic is correct. If a remote STA advertises support
2630 * for being a beamformer then we should enable us being a beamformee.
2631 */
2632
2633 if (ar->vht_cap_info &
2634 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2635 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2636 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2637 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2638
2639 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2640 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2641 }
2642
2643 if (ar->vht_cap_info &
2644 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2645 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2646 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2647 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2648
2649 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2650 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2651 }
2652
2653 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2654 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2655
2656 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2657 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2658
2659 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2660 if (ret) {
2661 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2662 value, ret);
2663 return ret;
2664 }
2665
2666 return 0;
2667}
2668
Kalle Valo5e3dd152013-06-12 20:52:10 +03002669/* can be called only in mac80211 callbacks due to `key_count` usage */
2670static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2671 struct ieee80211_vif *vif,
2672 struct ieee80211_bss_conf *bss_conf)
2673{
2674 struct ath10k *ar = hw->priv;
2675 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002676 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002677 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002678 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002679 struct ieee80211_sta *ap_sta;
2680 int ret;
2681
Michal Kazior548db542013-07-05 16:15:15 +03002682 lockdep_assert_held(&ar->conf_mutex);
2683
Michal Kazior077efc82014-10-21 10:10:29 +03002684 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2685 arvif->vdev_id, arvif->bssid, arvif->aid);
2686
Kalle Valo5e3dd152013-06-12 20:52:10 +03002687 rcu_read_lock();
2688
2689 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2690 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002691 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002692 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002693 rcu_read_unlock();
2694 return;
2695 }
2696
Michal Kazior90046f52014-02-14 14:45:51 +01002697 /* ap_sta must be accessed only within rcu section which must be left
2698 * before calling ath10k_setup_peer_smps() which might sleep. */
2699 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002700 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002701
Michal Kazior590922a2014-10-21 10:10:29 +03002702 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002703 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002704 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002705 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002706 rcu_read_unlock();
2707 return;
2708 }
2709
2710 rcu_read_unlock();
2711
Kalle Valob9ada652013-10-16 15:44:46 +03002712 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2713 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002714 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002715 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002716 return;
2717 }
2718
Michal Kazior90046f52014-02-14 14:45:51 +01002719 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2720 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002721 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002722 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002723 return;
2724 }
2725
Michal Kazior139e1702015-02-15 16:50:42 +02002726 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2727 if (ret) {
2728 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2729 arvif->vdev_id, bss_conf->bssid, ret);
2730 return;
2731 }
2732
Michal Kazior7aa7a722014-08-25 12:09:38 +02002733 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002734 "mac vdev %d up (associated) bssid %pM aid %d\n",
2735 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2736
Michal Kazior077efc82014-10-21 10:10:29 +03002737 WARN_ON(arvif->is_up);
2738
Michal Kaziorc930f742014-01-23 11:38:25 +01002739 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002740 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002741
2742 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2743 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002744 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002745 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002746 return;
2747 }
2748
2749 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002750
2751 /* Workaround: Some firmware revisions (tested with qca6174
2752 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2753 * poked with peer param command.
2754 */
2755 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2756 WMI_PEER_DUMMY_VAR, 1);
2757 if (ret) {
2758 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2759 arvif->bssid, arvif->vdev_id, ret);
2760 return;
2761 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002762}
2763
Kalle Valo5e3dd152013-06-12 20:52:10 +03002764static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2765 struct ieee80211_vif *vif)
2766{
2767 struct ath10k *ar = hw->priv;
2768 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002769 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002770 int ret;
2771
Michal Kazior548db542013-07-05 16:15:15 +03002772 lockdep_assert_held(&ar->conf_mutex);
2773
Michal Kazior077efc82014-10-21 10:10:29 +03002774 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2775 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002776
Kalle Valo5e3dd152013-06-12 20:52:10 +03002777 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002778 if (ret)
2779 ath10k_warn(ar, "faield to down vdev %i: %d\n",
2780 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002781
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002782 arvif->def_wep_key_idx = -1;
2783
Michal Kazior139e1702015-02-15 16:50:42 +02002784 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2785 if (ret) {
2786 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2787 arvif->vdev_id, ret);
2788 return;
2789 }
2790
Michal Kaziorc930f742014-01-23 11:38:25 +01002791 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002792
2793 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002794}
2795
Michal Kazior590922a2014-10-21 10:10:29 +03002796static int ath10k_station_assoc(struct ath10k *ar,
2797 struct ieee80211_vif *vif,
2798 struct ieee80211_sta *sta,
2799 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002800{
Michal Kazior590922a2014-10-21 10:10:29 +03002801 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002802 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002803 int ret = 0;
2804
Michal Kazior548db542013-07-05 16:15:15 +03002805 lockdep_assert_held(&ar->conf_mutex);
2806
Michal Kazior590922a2014-10-21 10:10:29 +03002807 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002808 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002809 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002810 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002811 return ret;
2812 }
2813
2814 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2815 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002816 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002817 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002818 return ret;
2819 }
2820
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002821 /* Re-assoc is run only to update supported rates for given station. It
2822 * doesn't make much sense to reconfigure the peer completely.
2823 */
2824 if (!reassoc) {
2825 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2826 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002827 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002828 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002829 arvif->vdev_id, ret);
2830 return ret;
2831 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002832
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002833 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2834 if (ret) {
2835 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2836 sta->addr, arvif->vdev_id, ret);
2837 return ret;
2838 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002839
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002840 if (!sta->wme) {
2841 arvif->num_legacy_stations++;
2842 ret = ath10k_recalc_rtscts_prot(arvif);
2843 if (ret) {
2844 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2845 arvif->vdev_id, ret);
2846 return ret;
2847 }
2848 }
2849
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002850 /* Plumb cached keys only for static WEP */
2851 if (arvif->def_wep_key_idx != -1) {
2852 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2853 if (ret) {
2854 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2855 arvif->vdev_id, ret);
2856 return ret;
2857 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002858 }
2859 }
2860
Kalle Valo5e3dd152013-06-12 20:52:10 +03002861 return ret;
2862}
2863
Michal Kazior590922a2014-10-21 10:10:29 +03002864static int ath10k_station_disassoc(struct ath10k *ar,
2865 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002866 struct ieee80211_sta *sta)
2867{
Michal Kazior590922a2014-10-21 10:10:29 +03002868 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002869 int ret = 0;
2870
2871 lockdep_assert_held(&ar->conf_mutex);
2872
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002873 if (!sta->wme) {
2874 arvif->num_legacy_stations--;
2875 ret = ath10k_recalc_rtscts_prot(arvif);
2876 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002877 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002878 arvif->vdev_id, ret);
2879 return ret;
2880 }
2881 }
2882
Kalle Valo5e3dd152013-06-12 20:52:10 +03002883 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2884 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002885 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002886 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002887 return ret;
2888 }
2889
2890 return ret;
2891}
2892
2893/**************/
2894/* Regulatory */
2895/**************/
2896
2897static int ath10k_update_channel_list(struct ath10k *ar)
2898{
2899 struct ieee80211_hw *hw = ar->hw;
2900 struct ieee80211_supported_band **bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002901 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002902 struct ieee80211_channel *channel;
2903 struct wmi_scan_chan_list_arg arg = {0};
2904 struct wmi_channel_arg *ch;
2905 bool passive;
2906 int len;
2907 int ret;
2908 int i;
2909
Michal Kazior548db542013-07-05 16:15:15 +03002910 lockdep_assert_held(&ar->conf_mutex);
2911
Kalle Valo5e3dd152013-06-12 20:52:10 +03002912 bands = hw->wiphy->bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002913 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002914 if (!bands[band])
2915 continue;
2916
2917 for (i = 0; i < bands[band]->n_channels; i++) {
2918 if (bands[band]->channels[i].flags &
2919 IEEE80211_CHAN_DISABLED)
2920 continue;
2921
2922 arg.n_channels++;
2923 }
2924 }
2925
2926 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2927 arg.channels = kzalloc(len, GFP_KERNEL);
2928 if (!arg.channels)
2929 return -ENOMEM;
2930
2931 ch = arg.channels;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002932 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002933 if (!bands[band])
2934 continue;
2935
2936 for (i = 0; i < bands[band]->n_channels; i++) {
2937 channel = &bands[band]->channels[i];
2938
2939 if (channel->flags & IEEE80211_CHAN_DISABLED)
2940 continue;
2941
2942 ch->allow_ht = true;
2943
2944 /* FIXME: when should we really allow VHT? */
2945 ch->allow_vht = true;
2946
2947 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002948 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002949
2950 ch->ht40plus =
2951 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2952
Marek Puzyniake8a50f82013-11-20 09:59:47 +02002953 ch->chan_radar =
2954 !!(channel->flags & IEEE80211_CHAN_RADAR);
2955
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002956 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002957 ch->passive = passive;
2958
2959 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02002960 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07002961 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07002962 ch->max_power = channel->max_power * 2;
2963 ch->max_reg_power = channel->max_reg_power * 2;
2964 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002965 ch->reg_class_id = 0; /* FIXME */
2966
2967 /* FIXME: why use only legacy modes, why not any
2968 * HT/VHT modes? Would that even make any
2969 * difference? */
Johannes Berg57fbcce2016-04-12 15:56:15 +02002970 if (channel->band == NL80211_BAND_2GHZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002971 ch->mode = MODE_11G;
2972 else
2973 ch->mode = MODE_11A;
2974
2975 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
2976 continue;
2977
Michal Kazior7aa7a722014-08-25 12:09:38 +02002978 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002979 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
2980 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002981 ch->freq, ch->max_power, ch->max_reg_power,
2982 ch->max_antenna_gain, ch->mode);
2983
2984 ch++;
2985 }
2986 }
2987
2988 ret = ath10k_wmi_scan_chan_list(ar, &arg);
2989 kfree(arg.channels);
2990
2991 return ret;
2992}
2993
Marek Puzyniak821af6a2014-03-21 17:46:57 +02002994static enum wmi_dfs_region
2995ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
2996{
2997 switch (dfs_region) {
2998 case NL80211_DFS_UNSET:
2999 return WMI_UNINIT_DFS_DOMAIN;
3000 case NL80211_DFS_FCC:
3001 return WMI_FCC_DFS_DOMAIN;
3002 case NL80211_DFS_ETSI:
3003 return WMI_ETSI_DFS_DOMAIN;
3004 case NL80211_DFS_JP:
3005 return WMI_MKK4_DFS_DOMAIN;
3006 }
3007 return WMI_UNINIT_DFS_DOMAIN;
3008}
3009
Michal Kaziorf7843d72013-07-16 09:38:52 +02003010static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003011{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003012 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003013 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003014 enum wmi_dfs_region wmi_dfs_reg;
3015 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003016
Michal Kaziorf7843d72013-07-16 09:38:52 +02003017 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003018
3019 ret = ath10k_update_channel_list(ar);
3020 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003021 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003022
3023 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003024
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003025 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
3026 nl_dfs_reg = ar->dfs_detector->region;
3027 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
3028 } else {
3029 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
3030 }
3031
Kalle Valo5e3dd152013-06-12 20:52:10 +03003032 /* Target allows setting up per-band regdomain but ath_common provides
3033 * a combined one only */
3034 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02003035 regpair->reg_domain,
3036 regpair->reg_domain, /* 2ghz */
3037 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003038 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003039 regpair->reg_5ghz_ctl,
3040 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003041 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003042 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02003043}
Michal Kazior548db542013-07-05 16:15:15 +03003044
Michal Kaziorf7843d72013-07-16 09:38:52 +02003045static void ath10k_reg_notifier(struct wiphy *wiphy,
3046 struct regulatory_request *request)
3047{
3048 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
3049 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003050 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003051
3052 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3053
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003054 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003055 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003056 request->dfs_region);
3057 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3058 request->dfs_region);
3059 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003060 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003061 request->dfs_region);
3062 }
3063
Michal Kaziorf7843d72013-07-16 09:38:52 +02003064 mutex_lock(&ar->conf_mutex);
3065 if (ar->state == ATH10K_STATE_ON)
3066 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003067 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003068}
3069
3070/***************/
3071/* TX handlers */
3072/***************/
3073
Michal Kaziora30c7d02016-03-06 16:14:23 +02003074enum ath10k_mac_tx_path {
3075 ATH10K_MAC_TX_HTT,
3076 ATH10K_MAC_TX_HTT_MGMT,
3077 ATH10K_MAC_TX_WMI_MGMT,
3078 ATH10K_MAC_TX_UNKNOWN,
3079};
3080
Michal Kazior96d828d2015-03-31 10:26:23 +00003081void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3082{
3083 lockdep_assert_held(&ar->htt.tx_lock);
3084
3085 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3086 ar->tx_paused |= BIT(reason);
3087 ieee80211_stop_queues(ar->hw);
3088}
3089
3090static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3091 struct ieee80211_vif *vif)
3092{
3093 struct ath10k *ar = data;
3094 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3095
3096 if (arvif->tx_paused)
3097 return;
3098
3099 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3100}
3101
3102void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3103{
3104 lockdep_assert_held(&ar->htt.tx_lock);
3105
3106 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3107 ar->tx_paused &= ~BIT(reason);
3108
3109 if (ar->tx_paused)
3110 return;
3111
3112 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3113 IEEE80211_IFACE_ITER_RESUME_ALL,
3114 ath10k_mac_tx_unlock_iter,
3115 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003116
3117 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003118}
3119
3120void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3121{
3122 struct ath10k *ar = arvif->ar;
3123
3124 lockdep_assert_held(&ar->htt.tx_lock);
3125
3126 WARN_ON(reason >= BITS_PER_LONG);
3127 arvif->tx_paused |= BIT(reason);
3128 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3129}
3130
3131void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3132{
3133 struct ath10k *ar = arvif->ar;
3134
3135 lockdep_assert_held(&ar->htt.tx_lock);
3136
3137 WARN_ON(reason >= BITS_PER_LONG);
3138 arvif->tx_paused &= ~BIT(reason);
3139
3140 if (ar->tx_paused)
3141 return;
3142
3143 if (arvif->tx_paused)
3144 return;
3145
3146 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3147}
3148
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003149static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3150 enum wmi_tlv_tx_pause_id pause_id,
3151 enum wmi_tlv_tx_pause_action action)
3152{
3153 struct ath10k *ar = arvif->ar;
3154
3155 lockdep_assert_held(&ar->htt.tx_lock);
3156
Michal Kazioracd0b272015-07-09 13:08:38 +02003157 switch (action) {
3158 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3159 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003160 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003161 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3162 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3163 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003164 default:
Michal Kazioracd0b272015-07-09 13:08:38 +02003165 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
3166 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003167 break;
3168 }
3169}
3170
3171struct ath10k_mac_tx_pause {
3172 u32 vdev_id;
3173 enum wmi_tlv_tx_pause_id pause_id;
3174 enum wmi_tlv_tx_pause_action action;
3175};
3176
3177static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3178 struct ieee80211_vif *vif)
3179{
3180 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3181 struct ath10k_mac_tx_pause *arg = data;
3182
Michal Kazioracd0b272015-07-09 13:08:38 +02003183 if (arvif->vdev_id != arg->vdev_id)
3184 return;
3185
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003186 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3187}
3188
Michal Kazioracd0b272015-07-09 13:08:38 +02003189void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3190 enum wmi_tlv_tx_pause_id pause_id,
3191 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003192{
3193 struct ath10k_mac_tx_pause arg = {
3194 .vdev_id = vdev_id,
3195 .pause_id = pause_id,
3196 .action = action,
3197 };
3198
3199 spin_lock_bh(&ar->htt.tx_lock);
3200 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3201 IEEE80211_IFACE_ITER_RESUME_ALL,
3202 ath10k_mac_handle_tx_pause_iter,
3203 &arg);
3204 spin_unlock_bh(&ar->htt.tx_lock);
3205}
3206
Michal Kaziord740d8f2015-03-30 09:51:51 +03003207static enum ath10k_hw_txrx_mode
Michal Kazior6a2636d2015-11-18 06:59:16 +01003208ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3209 struct ieee80211_vif *vif,
3210 struct ieee80211_sta *sta,
3211 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003212{
3213 const struct ieee80211_hdr *hdr = (void *)skb->data;
3214 __le16 fc = hdr->frame_control;
3215
3216 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3217 return ATH10K_HW_TXRX_RAW;
3218
3219 if (ieee80211_is_mgmt(fc))
3220 return ATH10K_HW_TXRX_MGMT;
3221
3222 /* Workaround:
3223 *
3224 * NullFunc frames are mostly used to ping if a client or AP are still
3225 * reachable and responsive. This implies tx status reports must be
3226 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3227 * come to a conclusion that the other end disappeared and tear down
3228 * BSS connection or it can never disconnect from BSS/client (which is
3229 * the case).
3230 *
3231 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3232 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3233 * which seems to deliver correct tx reports for NullFunc frames. The
3234 * downside of using it is it ignores client powersave state so it can
3235 * end up disconnecting sleeping clients in AP mode. It should fix STA
3236 * mode though because AP don't sleep.
3237 */
3238 if (ar->htt.target_version_major < 3 &&
3239 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03003240 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3241 ar->running_fw->fw_file.fw_features))
Michal Kaziord740d8f2015-03-30 09:51:51 +03003242 return ATH10K_HW_TXRX_MGMT;
3243
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003244 /* Workaround:
3245 *
3246 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3247 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3248 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003249 *
3250 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003251 */
3252 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3253 return ATH10K_HW_TXRX_ETHERNET;
3254
David Liuccec9032015-07-24 20:25:32 +03003255 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3256 return ATH10K_HW_TXRX_RAW;
3257
Michal Kaziord740d8f2015-03-30 09:51:51 +03003258 return ATH10K_HW_TXRX_NATIVE_WIFI;
3259}
3260
David Liuccec9032015-07-24 20:25:32 +03003261static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003262 struct sk_buff *skb)
3263{
3264 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3265 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003266 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3267 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003268
3269 if (!ieee80211_has_protected(hdr->frame_control))
3270 return false;
3271
David Liuccec9032015-07-24 20:25:32 +03003272 if ((info->flags & mask) == mask)
3273 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003274
David Liuccec9032015-07-24 20:25:32 +03003275 if (vif)
3276 return !ath10k_vif_to_arvif(vif)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003277
David Liuccec9032015-07-24 20:25:32 +03003278 return true;
3279}
3280
Michal Kazior4b604552014-07-21 21:03:09 +03003281/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3282 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003283 */
Michal Kazior4b604552014-07-21 21:03:09 +03003284static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003285{
3286 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003287 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003288 u8 *qos_ctl;
3289
3290 if (!ieee80211_is_data_qos(hdr->frame_control))
3291 return;
3292
3293 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003294 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3295 skb->data, (void *)qos_ctl - (void *)skb->data);
3296 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003297
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003298 /* Some firmware revisions don't handle sending QoS NullFunc well.
3299 * These frames are mainly used for CQM purposes so it doesn't really
3300 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003301 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003302 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003303 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003304 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003305
3306 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003307}
3308
Michal Kaziord740d8f2015-03-30 09:51:51 +03003309static void ath10k_tx_h_8023(struct sk_buff *skb)
3310{
3311 struct ieee80211_hdr *hdr;
3312 struct rfc1042_hdr *rfc1042;
3313 struct ethhdr *eth;
3314 size_t hdrlen;
3315 u8 da[ETH_ALEN];
3316 u8 sa[ETH_ALEN];
3317 __be16 type;
3318
3319 hdr = (void *)skb->data;
3320 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3321 rfc1042 = (void *)skb->data + hdrlen;
3322
3323 ether_addr_copy(da, ieee80211_get_DA(hdr));
3324 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3325 type = rfc1042->snap_type;
3326
3327 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3328 skb_push(skb, sizeof(*eth));
3329
3330 eth = (void *)skb->data;
3331 ether_addr_copy(eth->h_dest, da);
3332 ether_addr_copy(eth->h_source, sa);
3333 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003334}
3335
Michal Kazior4b604552014-07-21 21:03:09 +03003336static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3337 struct ieee80211_vif *vif,
3338 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003339{
3340 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003341 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3342
3343 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003344 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003345 return;
3346
3347 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3348 spin_lock_bh(&ar->data_lock);
3349 if (arvif->u.ap.noa_data)
3350 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3351 GFP_ATOMIC))
3352 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3353 arvif->u.ap.noa_data,
3354 arvif->u.ap.noa_len);
3355 spin_unlock_bh(&ar->data_lock);
3356 }
3357}
3358
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003359static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3360 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003361 struct ieee80211_txq *txq,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003362 struct sk_buff *skb)
3363{
3364 struct ieee80211_hdr *hdr = (void *)skb->data;
3365 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3366
3367 cb->flags = 0;
3368 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3369 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3370
3371 if (ieee80211_is_mgmt(hdr->frame_control))
3372 cb->flags |= ATH10K_SKB_F_MGMT;
3373
3374 if (ieee80211_is_data_qos(hdr->frame_control))
3375 cb->flags |= ATH10K_SKB_F_QOS;
3376
3377 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003378 cb->txq = txq;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003379}
3380
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303381bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003382{
3383 /* FIXME: Not really sure since when the behaviour changed. At some
3384 * point new firmware stopped requiring creation of peer entries for
3385 * offchannel tx (and actually creating them causes issues with wmi-htc
3386 * tx credit replenishment and reliability). Assuming it's at least 3.4
3387 * because that's when the `freq` was introduced to TX_FRM HTT command.
3388 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303389 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303390 ar->htt.target_version_minor >= 4 &&
Kalle Valo77561f92016-04-20 19:45:47 +03003391 ar->running_fw->fw_file.htt_op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003392}
3393
Michal Kaziord740d8f2015-03-30 09:51:51 +03003394static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003395{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003396 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003397 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003398
Michal Kaziord740d8f2015-03-30 09:51:51 +03003399 spin_lock_bh(&ar->data_lock);
3400
3401 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3402 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3403 ret = -ENOSPC;
3404 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003405 }
3406
Michal Kaziord740d8f2015-03-30 09:51:51 +03003407 __skb_queue_tail(q, skb);
3408 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3409
3410unlock:
3411 spin_unlock_bh(&ar->data_lock);
3412
3413 return ret;
3414}
3415
Michal Kaziora30c7d02016-03-06 16:14:23 +02003416static enum ath10k_mac_tx_path
3417ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3418 struct sk_buff *skb,
3419 enum ath10k_hw_txrx_mode txmode)
3420{
3421 switch (txmode) {
3422 case ATH10K_HW_TXRX_RAW:
3423 case ATH10K_HW_TXRX_NATIVE_WIFI:
3424 case ATH10K_HW_TXRX_ETHERNET:
3425 return ATH10K_MAC_TX_HTT;
3426 case ATH10K_HW_TXRX_MGMT:
3427 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Kalle Valoc4cdf752016-04-20 19:45:18 +03003428 ar->running_fw->fw_file.fw_features))
Michal Kaziora30c7d02016-03-06 16:14:23 +02003429 return ATH10K_MAC_TX_WMI_MGMT;
3430 else if (ar->htt.target_version_major >= 3)
3431 return ATH10K_MAC_TX_HTT;
3432 else
3433 return ATH10K_MAC_TX_HTT_MGMT;
3434 }
3435
3436 return ATH10K_MAC_TX_UNKNOWN;
3437}
3438
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003439static int ath10k_mac_tx_submit(struct ath10k *ar,
3440 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003441 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003442 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003443{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003444 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003445 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003446
3447 switch (txpath) {
3448 case ATH10K_MAC_TX_HTT:
Michal Kazior8a933962015-11-18 06:59:17 +01003449 ret = ath10k_htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003450 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003451 case ATH10K_MAC_TX_HTT_MGMT:
3452 ret = ath10k_htt_mgmt_tx(htt, skb);
3453 break;
3454 case ATH10K_MAC_TX_WMI_MGMT:
3455 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3456 break;
3457 case ATH10K_MAC_TX_UNKNOWN:
3458 WARN_ON_ONCE(1);
3459 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003460 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003461 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003462
3463 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003464 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3465 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003466 ieee80211_free_txskb(ar->hw, skb);
3467 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003468
3469 return ret;
3470}
3471
3472/* This function consumes the sk_buff regardless of return value as far as
3473 * caller is concerned so no freeing is necessary afterwards.
3474 */
3475static int ath10k_mac_tx(struct ath10k *ar,
3476 struct ieee80211_vif *vif,
3477 struct ieee80211_sta *sta,
3478 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003479 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003480 struct sk_buff *skb)
3481{
3482 struct ieee80211_hw *hw = ar->hw;
3483 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3484 int ret;
3485
3486 /* We should disable CCK RATE due to P2P */
3487 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3488 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3489
3490 switch (txmode) {
3491 case ATH10K_HW_TXRX_MGMT:
3492 case ATH10K_HW_TXRX_NATIVE_WIFI:
3493 ath10k_tx_h_nwifi(hw, skb);
3494 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3495 ath10k_tx_h_seq_no(vif, skb);
3496 break;
3497 case ATH10K_HW_TXRX_ETHERNET:
3498 ath10k_tx_h_8023(skb);
3499 break;
3500 case ATH10K_HW_TXRX_RAW:
3501 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3502 WARN_ON_ONCE(1);
3503 ieee80211_free_txskb(hw, skb);
3504 return -ENOTSUPP;
3505 }
3506 }
3507
3508 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3509 if (!ath10k_mac_tx_frm_has_freq(ar)) {
3510 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
3511 skb);
3512
3513 skb_queue_tail(&ar->offchan_tx_queue, skb);
3514 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3515 return 0;
3516 }
3517 }
3518
Michal Kazior6421969f2016-03-06 16:14:25 +02003519 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003520 if (ret) {
3521 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3522 return ret;
3523 }
3524
3525 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003526}
3527
3528void ath10k_offchan_tx_purge(struct ath10k *ar)
3529{
3530 struct sk_buff *skb;
3531
3532 for (;;) {
3533 skb = skb_dequeue(&ar->offchan_tx_queue);
3534 if (!skb)
3535 break;
3536
3537 ieee80211_free_txskb(ar->hw, skb);
3538 }
3539}
3540
3541void ath10k_offchan_tx_work(struct work_struct *work)
3542{
3543 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3544 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003545 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003546 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003547 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003548 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003549 struct ieee80211_vif *vif;
3550 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003551 struct sk_buff *skb;
3552 const u8 *peer_addr;
3553 int vdev_id;
3554 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003555 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003556 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003557
3558 /* FW requirement: We must create a peer before FW will send out
3559 * an offchannel frame. Otherwise the frame will be stuck and
3560 * never transmitted. We delete the peer upon tx completion.
3561 * It is unlikely that a peer for offchannel tx will already be
3562 * present. However it may be in some rare cases so account for that.
3563 * Otherwise we might remove a legitimate peer and break stuff. */
3564
3565 for (;;) {
3566 skb = skb_dequeue(&ar->offchan_tx_queue);
3567 if (!skb)
3568 break;
3569
3570 mutex_lock(&ar->conf_mutex);
3571
Michal Kazior7aa7a722014-08-25 12:09:38 +02003572 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003573 skb);
3574
3575 hdr = (struct ieee80211_hdr *)skb->data;
3576 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003577
3578 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003579 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003580 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3581 spin_unlock_bh(&ar->data_lock);
3582
3583 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003584 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003585 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003586 peer_addr, vdev_id);
3587
3588 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003589 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3590 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003591 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003592 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003593 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003594 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003595 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003596 }
3597
3598 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003599 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003600 ar->offchan_tx_skb = skb;
3601 spin_unlock_bh(&ar->data_lock);
3602
Michal Kazior8a933962015-11-18 06:59:17 +01003603 /* It's safe to access vif and sta - conf_mutex guarantees that
3604 * sta_state() and remove_interface() are locked exclusively
3605 * out wrt to this offchannel worker.
3606 */
3607 arvif = ath10k_get_arvif(ar, vdev_id);
3608 if (arvif) {
3609 vif = arvif->vif;
3610 sta = ieee80211_find_sta(vif, peer_addr);
3611 } else {
3612 vif = NULL;
3613 sta = NULL;
3614 }
3615
3616 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003617 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003618
Michal Kazior6421969f2016-03-06 16:14:25 +02003619 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003620 if (ret) {
3621 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3622 ret);
3623 /* not serious */
3624 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003625
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003626 time_left =
3627 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3628 if (time_left == 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003629 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003630 skb);
3631
Michal Kazioradaeed72015-08-05 12:15:23 +02003632 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003633 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3634 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003635 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003636 peer_addr, vdev_id, ret);
3637 }
3638
3639 mutex_unlock(&ar->conf_mutex);
3640 }
3641}
3642
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003643void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3644{
3645 struct sk_buff *skb;
3646
3647 for (;;) {
3648 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3649 if (!skb)
3650 break;
3651
3652 ieee80211_free_txskb(ar->hw, skb);
3653 }
3654}
3655
3656void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3657{
3658 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3659 struct sk_buff *skb;
3660 int ret;
3661
3662 for (;;) {
3663 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3664 if (!skb)
3665 break;
3666
3667 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003668 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003669 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003670 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003671 ieee80211_free_txskb(ar->hw, skb);
3672 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003673 }
3674}
3675
Michal Kazior29946872016-03-06 16:14:34 +02003676static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3677{
Bob Copelanda66cd732016-06-29 19:29:25 +03003678 struct ath10k_txq *artxq;
Michal Kazior29946872016-03-06 16:14:34 +02003679
3680 if (!txq)
3681 return;
3682
Bob Copelanda66cd732016-06-29 19:29:25 +03003683 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003684 INIT_LIST_HEAD(&artxq->list);
3685}
3686
3687static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3688{
Bob Copelanda66cd732016-06-29 19:29:25 +03003689 struct ath10k_txq *artxq;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003690 struct ath10k_skb_cb *cb;
3691 struct sk_buff *msdu;
3692 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003693
3694 if (!txq)
3695 return;
3696
Bob Copelanda66cd732016-06-29 19:29:25 +03003697 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003698 spin_lock_bh(&ar->txqs_lock);
3699 if (!list_empty(&artxq->list))
3700 list_del_init(&artxq->list);
3701 spin_unlock_bh(&ar->txqs_lock);
Michal Kaziordd4717b2016-03-06 16:14:39 +02003702
3703 spin_lock_bh(&ar->htt.tx_lock);
3704 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3705 cb = ATH10K_SKB_CB(msdu);
3706 if (cb->txq == txq)
3707 cb->txq = NULL;
3708 }
3709 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003710}
3711
Michal Kazior426e10e2016-03-06 16:14:43 +02003712struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
3713 u16 peer_id,
3714 u8 tid)
3715{
3716 struct ath10k_peer *peer;
3717
3718 lockdep_assert_held(&ar->data_lock);
3719
3720 peer = ar->peer_map[peer_id];
3721 if (!peer)
3722 return NULL;
3723
3724 if (peer->sta)
3725 return peer->sta->txq[tid];
3726 else if (peer->vif)
3727 return peer->vif->txq;
3728 else
3729 return NULL;
3730}
3731
Michal Kazior29946872016-03-06 16:14:34 +02003732static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3733 struct ieee80211_txq *txq)
3734{
Michal Kazior426e10e2016-03-06 16:14:43 +02003735 struct ath10k *ar = hw->priv;
3736 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3737
3738 /* No need to get locks */
3739
3740 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3741 return true;
3742
3743 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3744 return true;
3745
3746 if (artxq->num_fw_queued < artxq->num_push_allowed)
3747 return true;
3748
3749 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003750}
3751
Michal Kazior426e10e2016-03-06 16:14:43 +02003752int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3753 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02003754{
Michal Kazior29946872016-03-06 16:14:34 +02003755 struct ath10k *ar = hw->priv;
3756 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003757 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003758 struct ieee80211_vif *vif = txq->vif;
3759 struct ieee80211_sta *sta = txq->sta;
3760 enum ath10k_hw_txrx_mode txmode;
3761 enum ath10k_mac_tx_path txpath;
3762 struct sk_buff *skb;
Michal Kazior426e10e2016-03-06 16:14:43 +02003763 size_t skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003764 int ret;
3765
3766 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303767 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003768 spin_unlock_bh(&ar->htt.tx_lock);
3769
3770 if (ret)
3771 return ret;
3772
3773 skb = ieee80211_tx_dequeue(hw, txq);
3774 if (!skb) {
3775 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303776 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003777 spin_unlock_bh(&ar->htt.tx_lock);
3778
3779 return -ENOENT;
3780 }
3781
Michal Kaziordd4717b2016-03-06 16:14:39 +02003782 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Michal Kazior29946872016-03-06 16:14:34 +02003783
Michal Kazior426e10e2016-03-06 16:14:43 +02003784 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02003785 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
3786 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
3787
3788 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
3789 if (unlikely(ret)) {
3790 ath10k_warn(ar, "failed to push frame: %d\n", ret);
3791
3792 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303793 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003794 spin_unlock_bh(&ar->htt.tx_lock);
3795
3796 return ret;
3797 }
3798
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003799 spin_lock_bh(&ar->htt.tx_lock);
3800 artxq->num_fw_queued++;
3801 spin_unlock_bh(&ar->htt.tx_lock);
3802
Michal Kazior426e10e2016-03-06 16:14:43 +02003803 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003804}
3805
3806void ath10k_mac_tx_push_pending(struct ath10k *ar)
3807{
3808 struct ieee80211_hw *hw = ar->hw;
3809 struct ieee80211_txq *txq;
3810 struct ath10k_txq *artxq;
3811 struct ath10k_txq *last;
3812 int ret;
3813 int max;
3814
Michal Kazior7a0adc82016-05-23 23:12:45 +03003815 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
3816 return;
3817
Michal Kazior29946872016-03-06 16:14:34 +02003818 spin_lock_bh(&ar->txqs_lock);
3819 rcu_read_lock();
3820
3821 last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
3822 while (!list_empty(&ar->txqs)) {
3823 artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
3824 txq = container_of((void *)artxq, struct ieee80211_txq,
3825 drv_priv);
3826
3827 /* Prevent aggressive sta/tid taking over tx queue */
3828 max = 16;
Michal Kazior750eeed2016-03-17 10:51:05 +01003829 ret = 0;
3830 while (ath10k_mac_tx_can_push(hw, txq) && max--) {
Michal Kazior29946872016-03-06 16:14:34 +02003831 ret = ath10k_mac_tx_push_txq(hw, txq);
3832 if (ret < 0)
3833 break;
3834 }
3835
3836 list_del_init(&artxq->list);
Michal Kazior9d71d472016-03-17 10:51:04 +01003837 if (ret != -ENOENT)
3838 list_add_tail(&artxq->list, &ar->txqs);
3839
Michal Kaziorc1a43d92016-03-06 16:14:36 +02003840 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02003841
Michal Kazior9d71d472016-03-17 10:51:04 +01003842 if (artxq == last || (ret < 0 && ret != -ENOENT))
Michal Kazior29946872016-03-06 16:14:34 +02003843 break;
Michal Kazior29946872016-03-06 16:14:34 +02003844 }
3845
3846 rcu_read_unlock();
3847 spin_unlock_bh(&ar->txqs_lock);
3848}
3849
Kalle Valo5e3dd152013-06-12 20:52:10 +03003850/************/
3851/* Scanning */
3852/************/
3853
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003854void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003855{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003856 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003857
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003858 switch (ar->scan.state) {
3859 case ATH10K_SCAN_IDLE:
3860 break;
3861 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01003862 case ATH10K_SCAN_ABORTING:
3863 if (!ar->scan.is_roc)
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003864 ieee80211_scan_completed(ar->hw,
3865 (ar->scan.state ==
3866 ATH10K_SCAN_ABORTING));
Michal Kaziord710e752015-07-09 13:08:36 +02003867 else if (ar->scan.roc_notify)
3868 ieee80211_remain_on_channel_expired(ar->hw);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003869 /* fall through */
3870 case ATH10K_SCAN_STARTING:
3871 ar->scan.state = ATH10K_SCAN_IDLE;
3872 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01003873 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003874 ath10k_offchan_tx_purge(ar);
3875 cancel_delayed_work(&ar->scan.timeout);
3876 complete_all(&ar->scan.completed);
3877 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003878 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003879}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003880
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003881void ath10k_scan_finish(struct ath10k *ar)
3882{
3883 spin_lock_bh(&ar->data_lock);
3884 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003885 spin_unlock_bh(&ar->data_lock);
3886}
3887
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003888static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003889{
3890 struct wmi_stop_scan_arg arg = {
3891 .req_id = 1, /* FIXME */
3892 .req_type = WMI_SCAN_STOP_ONE,
3893 .u.scan_id = ATH10K_SCAN_ID,
3894 };
3895 int ret;
3896
3897 lockdep_assert_held(&ar->conf_mutex);
3898
Kalle Valo5e3dd152013-06-12 20:52:10 +03003899 ret = ath10k_wmi_stop_scan(ar, &arg);
3900 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003901 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003902 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003903 }
3904
Kalle Valo14e105c2016-04-13 14:13:21 +03003905 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003906 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003907 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003908 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003909 } else if (ret > 0) {
3910 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003911 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003912
3913out:
3914 /* Scan state should be updated upon scan completion but in case
3915 * firmware fails to deliver the event (for whatever reason) it is
3916 * desired to clean up scan state anyway. Firmware may have just
3917 * dropped the scan completion event delivery due to transport pipe
3918 * being overflown with data and/or it can recover on its own before
3919 * next scan request is submitted.
3920 */
3921 spin_lock_bh(&ar->data_lock);
3922 if (ar->scan.state != ATH10K_SCAN_IDLE)
3923 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003924 spin_unlock_bh(&ar->data_lock);
3925
3926 return ret;
3927}
3928
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003929static void ath10k_scan_abort(struct ath10k *ar)
3930{
3931 int ret;
3932
3933 lockdep_assert_held(&ar->conf_mutex);
3934
3935 spin_lock_bh(&ar->data_lock);
3936
3937 switch (ar->scan.state) {
3938 case ATH10K_SCAN_IDLE:
3939 /* This can happen if timeout worker kicked in and called
3940 * abortion while scan completion was being processed.
3941 */
3942 break;
3943 case ATH10K_SCAN_STARTING:
3944 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02003945 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003946 ath10k_scan_state_str(ar->scan.state),
3947 ar->scan.state);
3948 break;
3949 case ATH10K_SCAN_RUNNING:
3950 ar->scan.state = ATH10K_SCAN_ABORTING;
3951 spin_unlock_bh(&ar->data_lock);
3952
3953 ret = ath10k_scan_stop(ar);
3954 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003955 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003956
3957 spin_lock_bh(&ar->data_lock);
3958 break;
3959 }
3960
3961 spin_unlock_bh(&ar->data_lock);
3962}
3963
3964void ath10k_scan_timeout_work(struct work_struct *work)
3965{
3966 struct ath10k *ar = container_of(work, struct ath10k,
3967 scan.timeout.work);
3968
3969 mutex_lock(&ar->conf_mutex);
3970 ath10k_scan_abort(ar);
3971 mutex_unlock(&ar->conf_mutex);
3972}
3973
Kalle Valo5e3dd152013-06-12 20:52:10 +03003974static int ath10k_start_scan(struct ath10k *ar,
3975 const struct wmi_start_scan_arg *arg)
3976{
3977 int ret;
3978
3979 lockdep_assert_held(&ar->conf_mutex);
3980
3981 ret = ath10k_wmi_start_scan(ar, arg);
3982 if (ret)
3983 return ret;
3984
Kalle Valo14e105c2016-04-13 14:13:21 +03003985 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003986 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003987 ret = ath10k_scan_stop(ar);
3988 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003989 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003990
3991 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003992 }
3993
Ben Greear2f9eec02015-02-15 16:50:38 +02003994 /* If we failed to start the scan, return error code at
3995 * this point. This is probably due to some issue in the
3996 * firmware, but no need to wedge the driver due to that...
3997 */
3998 spin_lock_bh(&ar->data_lock);
3999 if (ar->scan.state == ATH10K_SCAN_IDLE) {
4000 spin_unlock_bh(&ar->data_lock);
4001 return -EINVAL;
4002 }
4003 spin_unlock_bh(&ar->data_lock);
4004
Kalle Valo5e3dd152013-06-12 20:52:10 +03004005 return 0;
4006}
4007
4008/**********************/
4009/* mac80211 callbacks */
4010/**********************/
4011
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004012static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4013 struct ieee80211_tx_control *control,
4014 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004015{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004016 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02004017 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03004018 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4019 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004020 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02004021 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02004022 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01004023 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02004024 enum ath10k_mac_tx_path txpath;
4025 bool is_htt;
4026 bool is_mgmt;
4027 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004028 int ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004029
Michal Kaziordd4717b2016-03-06 16:14:39 +02004030 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004031
Michal Kazior8a933962015-11-18 06:59:17 +01004032 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004033 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
4034 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
4035 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304036 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004037
Michal Kazior6421969f2016-03-06 16:14:25 +02004038 if (is_htt) {
4039 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004040 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4041
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304042 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004043 if (ret) {
4044 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4045 ret);
4046 spin_unlock_bh(&ar->htt.tx_lock);
4047 ieee80211_free_txskb(ar->hw, skb);
4048 return;
4049 }
4050
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304051 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4052 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304053 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4054 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304055 ath10k_htt_tx_dec_pending(htt);
4056 spin_unlock_bh(&ar->htt.tx_lock);
4057 ieee80211_free_txskb(ar->hw, skb);
4058 return;
4059 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004060 spin_unlock_bh(&ar->htt.tx_lock);
4061 }
4062
4063 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
4064 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004065 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004066 if (is_htt) {
4067 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304068 ath10k_htt_tx_dec_pending(htt);
4069 if (is_mgmt)
4070 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004071 spin_unlock_bh(&ar->htt.tx_lock);
4072 }
4073 return;
4074 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004075}
4076
Michal Kazior29946872016-03-06 16:14:34 +02004077static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4078 struct ieee80211_txq *txq)
4079{
4080 struct ath10k *ar = hw->priv;
4081 struct ath10k_txq *artxq = (void *)txq->drv_priv;
4082
Michal Kazior750eeed2016-03-17 10:51:05 +01004083 spin_lock_bh(&ar->txqs_lock);
4084 if (list_empty(&artxq->list))
4085 list_add_tail(&artxq->list, &ar->txqs);
4086 spin_unlock_bh(&ar->txqs_lock);
Michal Kazior29946872016-03-06 16:14:34 +02004087
Michal Kazior7a0adc82016-05-23 23:12:45 +03004088 ath10k_mac_tx_push_pending(ar);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004089 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02004090}
4091
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004092/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004093void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004094{
4095 /* make sure rcu-protected mac80211 tx path itself is drained */
4096 synchronize_net();
4097
4098 ath10k_offchan_tx_purge(ar);
4099 ath10k_mgmt_over_wmi_tx_purge(ar);
4100
4101 cancel_work_sync(&ar->offchan_tx_work);
4102 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4103}
4104
Michal Kazioraffd3212013-07-16 09:54:35 +02004105void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004106{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004107 struct ath10k_vif *arvif;
4108
Michal Kazior818bdd12013-07-16 09:38:57 +02004109 lockdep_assert_held(&ar->conf_mutex);
4110
Michal Kazior19337472014-08-28 12:58:16 +02004111 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4112 ar->filter_flags = 0;
4113 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004114 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004115
4116 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004117 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004118
4119 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004120 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004121
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004122 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004123 ath10k_peer_cleanup_all(ar);
4124 ath10k_core_stop(ar);
4125 ath10k_hif_power_down(ar);
4126
4127 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004128 list_for_each_entry(arvif, &ar->arvifs, list)
4129 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004130 spin_unlock_bh(&ar->data_lock);
4131}
4132
Ben Greear46acf7b2014-05-16 17:15:38 +03004133static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4134{
4135 struct ath10k *ar = hw->priv;
4136
4137 mutex_lock(&ar->conf_mutex);
4138
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304139 *tx_ant = ar->cfg_tx_chainmask;
4140 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03004141
4142 mutex_unlock(&ar->conf_mutex);
4143
4144 return 0;
4145}
4146
Ben Greear5572a952014-11-24 16:22:10 +02004147static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4148{
4149 /* It is not clear that allowing gaps in chainmask
4150 * is helpful. Probably it will not do what user
4151 * is hoping for, so warn in that case.
4152 */
4153 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4154 return;
4155
4156 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4157 dbg, cm);
4158}
4159
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304160static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4161{
4162 int nsts = ar->vht_cap_info;
4163
4164 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4165 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4166
4167 /* If firmware does not deliver to host number of space-time
4168 * streams supported, assume it support up to 4 BF STS and return
4169 * the value for VHT CAP: nsts-1)
4170 */
4171 if (nsts == 0)
4172 return 3;
4173
4174 return nsts;
4175}
4176
4177static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4178{
4179 int sound_dim = ar->vht_cap_info;
4180
4181 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4182 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4183
4184 /* If the sounding dimension is not advertised by the firmware,
4185 * let's use a default value of 1
4186 */
4187 if (sound_dim == 0)
4188 return 1;
4189
4190 return sound_dim;
4191}
4192
4193static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4194{
4195 struct ieee80211_sta_vht_cap vht_cap = {0};
4196 u16 mcs_map;
4197 u32 val;
4198 int i;
4199
4200 vht_cap.vht_supported = 1;
4201 vht_cap.cap = ar->vht_cap_info;
4202
4203 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4204 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4205 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4206 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4207 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4208
4209 vht_cap.cap |= val;
4210 }
4211
4212 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4213 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4214 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4215 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4216 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4217
4218 vht_cap.cap |= val;
4219 }
4220
4221 mcs_map = 0;
4222 for (i = 0; i < 8; i++) {
4223 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4224 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4225 else
4226 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4227 }
4228
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004229 if (ar->cfg_tx_chainmask <= 1)
4230 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4231
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304232 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4233 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4234
4235 return vht_cap;
4236}
4237
4238static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4239{
4240 int i;
4241 struct ieee80211_sta_ht_cap ht_cap = {0};
4242
4243 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4244 return ht_cap;
4245
4246 ht_cap.ht_supported = 1;
4247 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4248 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4249 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4250 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004251 ht_cap.cap |=
4252 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304253
4254 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4255 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4256
4257 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4258 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4259
4260 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4261 u32 smps;
4262
4263 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4264 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4265
4266 ht_cap.cap |= smps;
4267 }
4268
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004269 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304270 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4271
4272 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4273 u32 stbc;
4274
4275 stbc = ar->ht_cap_info;
4276 stbc &= WMI_HT_CAP_RX_STBC;
4277 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4278 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4279 stbc &= IEEE80211_HT_CAP_RX_STBC;
4280
4281 ht_cap.cap |= stbc;
4282 }
4283
4284 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
4285 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4286
4287 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4288 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4289
4290 /* max AMSDU is implicitly taken from vht_cap_info */
4291 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4292 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4293
4294 for (i = 0; i < ar->num_rf_chains; i++) {
4295 if (ar->cfg_rx_chainmask & BIT(i))
4296 ht_cap.mcs.rx_mask[i] = 0xFF;
4297 }
4298
4299 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4300
4301 return ht_cap;
4302}
4303
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304304static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4305{
4306 struct ieee80211_supported_band *band;
4307 struct ieee80211_sta_vht_cap vht_cap;
4308 struct ieee80211_sta_ht_cap ht_cap;
4309
4310 ht_cap = ath10k_get_ht_cap(ar);
4311 vht_cap = ath10k_create_vht_cap(ar);
4312
4313 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004314 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304315 band->ht_cap = ht_cap;
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304316 }
4317 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004318 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304319 band->ht_cap = ht_cap;
4320 band->vht_cap = vht_cap;
4321 }
4322}
4323
Ben Greear46acf7b2014-05-16 17:15:38 +03004324static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4325{
4326 int ret;
4327
4328 lockdep_assert_held(&ar->conf_mutex);
4329
Ben Greear5572a952014-11-24 16:22:10 +02004330 ath10k_check_chain_mask(ar, tx_ant, "tx");
4331 ath10k_check_chain_mask(ar, rx_ant, "rx");
4332
Ben Greear46acf7b2014-05-16 17:15:38 +03004333 ar->cfg_tx_chainmask = tx_ant;
4334 ar->cfg_rx_chainmask = rx_ant;
4335
4336 if ((ar->state != ATH10K_STATE_ON) &&
4337 (ar->state != ATH10K_STATE_RESTARTED))
4338 return 0;
4339
4340 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4341 tx_ant);
4342 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004343 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004344 ret, tx_ant);
4345 return ret;
4346 }
4347
4348 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4349 rx_ant);
4350 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004351 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004352 ret, rx_ant);
4353 return ret;
4354 }
4355
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304356 /* Reload HT/VHT capability */
4357 ath10k_mac_setup_ht_vht_cap(ar);
4358
Ben Greear46acf7b2014-05-16 17:15:38 +03004359 return 0;
4360}
4361
4362static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4363{
4364 struct ath10k *ar = hw->priv;
4365 int ret;
4366
4367 mutex_lock(&ar->conf_mutex);
4368 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4369 mutex_unlock(&ar->conf_mutex);
4370 return ret;
4371}
4372
Kalle Valo5e3dd152013-06-12 20:52:10 +03004373static int ath10k_start(struct ieee80211_hw *hw)
4374{
4375 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304376 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004377 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004378
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004379 /*
4380 * This makes sense only when restarting hw. It is harmless to call
Mohammed Shafi Shajakhan6dfdbfc2016-04-26 14:41:36 +03004381 * unconditionally. This is necessary to make sure no HTT/WMI tx
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004382 * commands will be submitted while restarting.
4383 */
4384 ath10k_drain_tx(ar);
4385
Michal Kazior548db542013-07-05 16:15:15 +03004386 mutex_lock(&ar->conf_mutex);
4387
Michal Kaziorc5058f52014-05-26 12:46:03 +03004388 switch (ar->state) {
4389 case ATH10K_STATE_OFF:
4390 ar->state = ATH10K_STATE_ON;
4391 break;
4392 case ATH10K_STATE_RESTARTING:
4393 ath10k_halt(ar);
4394 ar->state = ATH10K_STATE_RESTARTED;
4395 break;
4396 case ATH10K_STATE_ON:
4397 case ATH10K_STATE_RESTARTED:
4398 case ATH10K_STATE_WEDGED:
4399 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004400 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004401 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004402 case ATH10K_STATE_UTF:
4403 ret = -EBUSY;
4404 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004405 }
4406
4407 ret = ath10k_hif_power_up(ar);
4408 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004409 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004410 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004411 }
4412
Kalle Valo7ebf7212016-04-20 19:44:51 +03004413 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
4414 &ar->normal_mode_fw);
Michal Kazior818bdd12013-07-16 09:38:57 +02004415 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004416 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004417 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004418 }
4419
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304420 param = ar->wmi.pdev_param->pmf_qos;
4421 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004422 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004423 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004424 goto err_core_stop;
4425 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004426
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304427 param = ar->wmi.pdev_param->dynamic_bw;
4428 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004429 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004430 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004431 goto err_core_stop;
4432 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004433
Michal Kaziorcf327842015-03-31 10:26:25 +00004434 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4435 ret = ath10k_wmi_adaptive_qcs(ar, true);
4436 if (ret) {
4437 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4438 ret);
4439 goto err_core_stop;
4440 }
4441 }
4442
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004443 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304444 param = ar->wmi.pdev_param->burst_enable;
4445 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004446 if (ret) {
4447 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4448 goto err_core_stop;
4449 }
4450 }
4451
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304452 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7b2014-05-16 17:15:38 +03004453
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004454 /*
4455 * By default FW set ARP frames ac to voice (6). In that case ARP
4456 * exchange is not working properly for UAPSD enabled AP. ARP requests
4457 * which arrives with access category 0 are processed by network stack
4458 * and send back with access category 0, but FW changes access category
4459 * to 6. Set ARP frames access category to best effort (0) solves
4460 * this problem.
4461 */
4462
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304463 param = ar->wmi.pdev_param->arp_ac_override;
4464 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004465 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004466 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004467 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004468 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004469 }
4470
Maharaja62f77f02015-10-21 11:49:18 +03004471 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
Kalle Valoc4cdf752016-04-20 19:45:18 +03004472 ar->running_fw->fw_file.fw_features)) {
Maharaja62f77f02015-10-21 11:49:18 +03004473 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4474 WMI_CCA_DETECT_LEVEL_AUTO,
4475 WMI_CCA_DETECT_MARGIN_AUTO);
4476 if (ret) {
4477 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4478 ret);
4479 goto err_core_stop;
4480 }
4481 }
4482
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304483 param = ar->wmi.pdev_param->ani_enable;
4484 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304485 if (ret) {
4486 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4487 ret);
4488 goto err_core_stop;
4489 }
4490
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304491 ar->ani_enabled = true;
4492
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304493 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304494 param = ar->wmi.pdev_param->peer_stats_update_period;
4495 ret = ath10k_wmi_pdev_set_param(ar, param,
4496 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4497 if (ret) {
4498 ath10k_warn(ar,
4499 "failed to set peer stats period : %d\n",
4500 ret);
4501 goto err_core_stop;
4502 }
4503 }
4504
Rajkumar Manoharan39136242016-05-27 20:15:59 +05304505 param = ar->wmi.pdev_param->enable_btcoex;
4506 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
4507 test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
4508 ar->running_fw->fw_file.fw_features)) {
4509 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4510 if (ret) {
4511 ath10k_warn(ar,
4512 "failed to set btcoex param: %d\n", ret);
4513 goto err_core_stop;
4514 }
4515 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
4516 }
4517
Michal Kaziord6500972014-04-08 09:56:09 +03004518 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004519 ath10k_regd_update(ar);
4520
Simon Wunderlich855aed12014-08-02 09:12:54 +03004521 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304522 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004523
Michal Kaziorae254432014-05-26 12:46:02 +03004524 mutex_unlock(&ar->conf_mutex);
4525 return 0;
4526
4527err_core_stop:
4528 ath10k_core_stop(ar);
4529
4530err_power_down:
4531 ath10k_hif_power_down(ar);
4532
4533err_off:
4534 ar->state = ATH10K_STATE_OFF;
4535
4536err:
Michal Kazior548db542013-07-05 16:15:15 +03004537 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004538 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004539}
4540
4541static void ath10k_stop(struct ieee80211_hw *hw)
4542{
4543 struct ath10k *ar = hw->priv;
4544
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004545 ath10k_drain_tx(ar);
4546
Michal Kazior548db542013-07-05 16:15:15 +03004547 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004548 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004549 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004550 ar->state = ATH10K_STATE_OFF;
4551 }
Michal Kazior548db542013-07-05 16:15:15 +03004552 mutex_unlock(&ar->conf_mutex);
4553
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004554 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004555 cancel_work_sync(&ar->restart_work);
4556}
4557
Michal Kaziorad088bf2013-10-16 15:44:46 +03004558static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004559{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004560 struct ath10k_vif *arvif;
4561 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004562
4563 lockdep_assert_held(&ar->conf_mutex);
4564
Michal Kaziorad088bf2013-10-16 15:44:46 +03004565 list_for_each_entry(arvif, &ar->arvifs, list) {
4566 ret = ath10k_mac_vif_setup_ps(arvif);
4567 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004568 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004569 break;
4570 }
4571 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004572
Michal Kaziorad088bf2013-10-16 15:44:46 +03004573 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004574}
4575
Michal Kazior7d9d5582014-10-21 10:40:15 +03004576static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4577{
4578 int ret;
4579 u32 param;
4580
4581 lockdep_assert_held(&ar->conf_mutex);
4582
4583 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4584
4585 param = ar->wmi.pdev_param->txpower_limit2g;
4586 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4587 if (ret) {
4588 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4589 txpower, ret);
4590 return ret;
4591 }
4592
4593 param = ar->wmi.pdev_param->txpower_limit5g;
4594 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4595 if (ret) {
4596 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4597 txpower, ret);
4598 return ret;
4599 }
4600
4601 return 0;
4602}
4603
4604static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4605{
4606 struct ath10k_vif *arvif;
4607 int ret, txpower = -1;
4608
4609 lockdep_assert_held(&ar->conf_mutex);
4610
4611 list_for_each_entry(arvif, &ar->arvifs, list) {
4612 WARN_ON(arvif->txpower < 0);
4613
4614 if (txpower == -1)
4615 txpower = arvif->txpower;
4616 else
4617 txpower = min(txpower, arvif->txpower);
4618 }
4619
4620 if (WARN_ON(txpower == -1))
4621 return -EINVAL;
4622
4623 ret = ath10k_mac_txpower_setup(ar, txpower);
4624 if (ret) {
4625 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4626 txpower, ret);
4627 return ret;
4628 }
4629
4630 return 0;
4631}
4632
Kalle Valo5e3dd152013-06-12 20:52:10 +03004633static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4634{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004635 struct ath10k *ar = hw->priv;
4636 struct ieee80211_conf *conf = &hw->conf;
4637 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004638
4639 mutex_lock(&ar->conf_mutex);
4640
Michal Kazioraffd3212013-07-16 09:54:35 +02004641 if (changed & IEEE80211_CONF_CHANGE_PS)
4642 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004643
4644 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004645 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4646 ret = ath10k_monitor_recalc(ar);
4647 if (ret)
4648 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004649 }
4650
4651 mutex_unlock(&ar->conf_mutex);
4652 return ret;
4653}
4654
Ben Greear5572a952014-11-24 16:22:10 +02004655static u32 get_nss_from_chainmask(u16 chain_mask)
4656{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05304657 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02004658 return 4;
4659 else if ((chain_mask & 0x7) == 0x7)
4660 return 3;
4661 else if ((chain_mask & 0x3) == 0x3)
4662 return 2;
4663 return 1;
4664}
4665
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304666static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4667{
4668 u32 value = 0;
4669 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004670 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004671 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304672
4673 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4674 return 0;
4675
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004676 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304677 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4678 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004679 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304680
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004681 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304682 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4683 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004684 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304685
4686 if (!value)
4687 return 0;
4688
4689 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4690 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4691
4692 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4693 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4694 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4695
4696 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4697 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4698
4699 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4700 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4701 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4702
4703 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4704 ar->wmi.vdev_param->txbf, value);
4705}
4706
Kalle Valo5e3dd152013-06-12 20:52:10 +03004707/*
4708 * TODO:
4709 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4710 * because we will send mgmt frames without CCK. This requirement
4711 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4712 * in the TX packet.
4713 */
4714static int ath10k_add_interface(struct ieee80211_hw *hw,
4715 struct ieee80211_vif *vif)
4716{
4717 struct ath10k *ar = hw->priv;
4718 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004719 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004720 enum wmi_sta_powersave_param param;
4721 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004722 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004723 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004724 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004725 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004726
Johannes Berg848955c2014-11-11 12:48:42 +01004727 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4728
Kalle Valo5e3dd152013-06-12 20:52:10 +03004729 mutex_lock(&ar->conf_mutex);
4730
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004731 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02004732 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004733
Kalle Valo5e3dd152013-06-12 20:52:10 +03004734 arvif->ar = ar;
4735 arvif->vif = vif;
4736
Ben Greeare63b33f2013-10-22 14:54:14 -07004737 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004738 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004739 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4740 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004741
Michal Kazior45c9abc2015-04-21 20:42:58 +03004742 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4743 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4744 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4745 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4746 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4747 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4748 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004749
Michal Kaziore04cafb2015-08-05 12:15:24 +02004750 if (ar->num_peers >= ar->max_num_peers) {
4751 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004752 ret = -ENOBUFS;
4753 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004754 }
4755
Ben Greeara9aefb32014-08-12 11:02:19 +03004756 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004757 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004758 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03004759 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004760 }
Ben Greear16c11172014-09-23 14:17:16 -07004761 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004762
Ben Greear16c11172014-09-23 14:17:16 -07004763 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4764 bit, ar->free_vdev_map);
4765
4766 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004767 arvif->vdev_subtype =
4768 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004769
Kalle Valo5e3dd152013-06-12 20:52:10 +03004770 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004771 case NL80211_IFTYPE_P2P_DEVICE:
4772 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004773 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4774 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01004775 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004776 case NL80211_IFTYPE_UNSPECIFIED:
4777 case NL80211_IFTYPE_STATION:
4778 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4779 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004780 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4781 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004782 break;
4783 case NL80211_IFTYPE_ADHOC:
4784 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4785 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004786 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08004787 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08004788 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4789 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08004790 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004791 ret = -EINVAL;
4792 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
4793 goto err;
4794 }
4795 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4796 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004797 case NL80211_IFTYPE_AP:
4798 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4799
4800 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004801 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4802 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004803 break;
4804 case NL80211_IFTYPE_MONITOR:
4805 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4806 break;
4807 default:
4808 WARN_ON(1);
4809 break;
4810 }
4811
Michal Kazior96d828d2015-03-31 10:26:23 +00004812 /* Using vdev_id as queue number will make it very easy to do per-vif
4813 * tx queue locking. This shouldn't wrap due to interface combinations
4814 * but do a modulo for correctness sake and prevent using offchannel tx
4815 * queues for regular vif tx.
4816 */
4817 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4818 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4819 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4820
Michal Kazior64badcb2014-09-18 11:18:02 +03004821 /* Some firmware revisions don't wait for beacon tx completion before
4822 * sending another SWBA event. This could lead to hardware using old
4823 * (freed) beacon data in some cases, e.g. tx credit starvation
4824 * combined with missed TBTT. This is very very rare.
4825 *
4826 * On non-IOMMU-enabled hosts this could be a possible security issue
4827 * because hw could beacon some random data on the air. On
4828 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4829 * device would crash.
4830 *
4831 * Since there are no beacon tx completions (implicit nor explicit)
4832 * propagated to host the only workaround for this is to allocate a
4833 * DMA-coherent buffer for a lifetime of a vif and use it for all
4834 * beacon tx commands. Worst case for this approach is some beacons may
4835 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4836 */
4837 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004838 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03004839 vif->type == NL80211_IFTYPE_AP) {
4840 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4841 IEEE80211_MAX_FRAME_LEN,
4842 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304843 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004844 if (!arvif->beacon_buf) {
4845 ret = -ENOMEM;
4846 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4847 ret);
4848 goto err;
4849 }
4850 }
David Liuccec9032015-07-24 20:25:32 +03004851 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
4852 arvif->nohwcrypt = true;
4853
4854 if (arvif->nohwcrypt &&
4855 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4856 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
4857 goto err;
4858 }
Michal Kazior64badcb2014-09-18 11:18:02 +03004859
4860 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4861 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4862 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004863
4864 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4865 arvif->vdev_subtype, vif->addr);
4866 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004867 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004868 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004869 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004870 }
4871
Ben Greear16c11172014-09-23 14:17:16 -07004872 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Michal Kazior05791192013-10-16 15:44:45 +03004873 list_add(&arvif->list, &ar->arvifs);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004874
Michal Kazior46725b152015-01-28 09:57:49 +02004875 /* It makes no sense to have firmware do keepalives. mac80211 already
4876 * takes care of this with idle connection polling.
4877 */
4878 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004879 if (ret) {
Michal Kazior46725b152015-01-28 09:57:49 +02004880 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004881 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004882 goto err_vdev_delete;
4883 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004884
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004885 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004886
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004887 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4888 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004889 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004890 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03004891 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004892 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004893 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004894 goto err_vdev_delete;
4895 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004896
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05304897 /* Configuring number of spatial stream for monitor interface is causing
4898 * target assert in qca9888 and qca6174.
4899 */
4900 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02004901 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
4902
4903 vdev_param = ar->wmi.vdev_param->nss;
4904 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4905 nss);
4906 if (ret) {
4907 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
4908 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
4909 ret);
4910 goto err_vdev_delete;
4911 }
4912 }
4913
Michal Kaziore57e0572015-03-24 13:14:03 +00004914 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
4915 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02004916 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
4917 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004918 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00004919 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004920 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004921 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004922 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004923
4924 spin_lock_bh(&ar->data_lock);
4925
4926 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
4927 if (!peer) {
4928 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
4929 vif->addr, arvif->vdev_id);
4930 spin_unlock_bh(&ar->data_lock);
4931 ret = -ENOENT;
4932 goto err_peer_delete;
4933 }
4934
4935 arvif->peer_id = find_first_bit(peer->peer_ids,
4936 ATH10K_MAX_NUM_PEER_IDS);
4937
4938 spin_unlock_bh(&ar->data_lock);
4939 } else {
4940 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00004941 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01004942
Michal Kaziore57e0572015-03-24 13:14:03 +00004943 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02004944 ret = ath10k_mac_set_kickout(arvif);
4945 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004946 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004947 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02004948 goto err_peer_delete;
4949 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004950 }
4951
4952 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
4953 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
4954 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
4955 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
4956 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004957 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004958 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004959 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004960 goto err_peer_delete;
4961 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004962
Michal Kazior9f9b5742014-12-12 12:41:36 +01004963 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004964 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004965 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004966 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004967 goto err_peer_delete;
4968 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004969
Michal Kazior9f9b5742014-12-12 12:41:36 +01004970 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004971 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01004972 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004973 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004974 goto err_peer_delete;
4975 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004976 }
4977
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304978 ret = ath10k_mac_set_txbf_conf(arvif);
4979 if (ret) {
4980 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
4981 arvif->vdev_id, ret);
4982 goto err_peer_delete;
4983 }
4984
Michal Kazior424121c2013-07-22 14:13:31 +02004985 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004986 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004987 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03004988 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004989 goto err_peer_delete;
4990 }
Michal Kazior679c54a2013-07-05 16:15:04 +03004991
Michal Kazior7d9d5582014-10-21 10:40:15 +03004992 arvif->txpower = vif->bss_conf.txpower;
4993 ret = ath10k_mac_txpower_recalc(ar);
4994 if (ret) {
4995 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
4996 goto err_peer_delete;
4997 }
4998
Michal Kazior500ff9f2015-03-31 10:26:21 +00004999 if (vif->type == NL80211_IFTYPE_MONITOR) {
5000 ar->monitor_arvif = arvif;
5001 ret = ath10k_monitor_recalc(ar);
5002 if (ret) {
5003 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5004 goto err_peer_delete;
5005 }
5006 }
5007
Michal Kazior6d2d51e2015-08-07 09:08:21 +02005008 spin_lock_bh(&ar->htt.tx_lock);
5009 if (!ar->tx_paused)
5010 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
5011 spin_unlock_bh(&ar->htt.tx_lock);
5012
Kalle Valo5e3dd152013-06-12 20:52:10 +03005013 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005014 return 0;
5015
5016err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00005017 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5018 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14a2013-10-16 15:44:45 +03005019 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
5020
5021err_vdev_delete:
5022 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07005023 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03005024 list_del(&arvif->list);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005025
5026err:
Michal Kazior64badcb2014-09-18 11:18:02 +03005027 if (arvif->beacon_buf) {
5028 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
5029 arvif->beacon_buf, arvif->beacon_paddr);
5030 arvif->beacon_buf = NULL;
5031 }
5032
Michal Kazior9dad14a2013-10-16 15:44:45 +03005033 mutex_unlock(&ar->conf_mutex);
5034
Kalle Valo5e3dd152013-06-12 20:52:10 +03005035 return ret;
5036}
5037
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005038static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
5039{
5040 int i;
5041
5042 for (i = 0; i < BITS_PER_LONG; i++)
5043 ath10k_mac_vif_tx_unlock(arvif, i);
5044}
5045
Kalle Valo5e3dd152013-06-12 20:52:10 +03005046static void ath10k_remove_interface(struct ieee80211_hw *hw,
5047 struct ieee80211_vif *vif)
5048{
5049 struct ath10k *ar = hw->priv;
5050 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior69427262016-03-06 16:14:30 +02005051 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005052 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005053 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005054
Michal Kazior81a9a172015-03-05 16:02:17 +02005055 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005056 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005057
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305058 mutex_lock(&ar->conf_mutex);
5059
Michal Kaziored543882013-09-13 14:16:56 +02005060 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03005061 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02005062 spin_unlock_bh(&ar->data_lock);
5063
Simon Wunderlich855aed12014-08-02 09:12:54 +03005064 ret = ath10k_spectral_vif_stop(arvif);
5065 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005066 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005067 arvif->vdev_id, ret);
5068
Ben Greear16c11172014-09-23 14:17:16 -07005069 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03005070 list_del(&arvif->list);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005071
Michal Kaziore57e0572015-03-24 13:14:03 +00005072 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5073 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005074 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5075 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005076 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005077 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005078 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005079
5080 kfree(arvif->u.ap.noa_data);
5081 }
5082
Michal Kazior7aa7a722014-08-25 12:09:38 +02005083 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005084 arvif->vdev_id);
5085
Kalle Valo5e3dd152013-06-12 20:52:10 +03005086 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5087 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005088 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005089 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005090
Michal Kazior2c512052015-02-15 16:50:40 +02005091 /* Some firmware revisions don't notify host about self-peer removal
5092 * until after associated vdev is deleted.
5093 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005094 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5095 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005096 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5097 vif->addr);
5098 if (ret)
5099 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5100 arvif->vdev_id, ret);
5101
5102 spin_lock_bh(&ar->data_lock);
5103 ar->num_peers--;
5104 spin_unlock_bh(&ar->data_lock);
5105 }
5106
Michal Kazior69427262016-03-06 16:14:30 +02005107 spin_lock_bh(&ar->data_lock);
5108 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5109 peer = ar->peer_map[i];
5110 if (!peer)
5111 continue;
5112
5113 if (peer->vif == vif) {
5114 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5115 vif->addr, arvif->vdev_id);
5116 peer->vif = NULL;
5117 }
5118 }
5119 spin_unlock_bh(&ar->data_lock);
5120
Kalle Valo5e3dd152013-06-12 20:52:10 +03005121 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005122 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005123
Michal Kazior500ff9f2015-03-31 10:26:21 +00005124 if (vif->type == NL80211_IFTYPE_MONITOR) {
5125 ar->monitor_arvif = NULL;
5126 ret = ath10k_monitor_recalc(ar);
5127 if (ret)
5128 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5129 }
5130
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005131 spin_lock_bh(&ar->htt.tx_lock);
5132 ath10k_mac_vif_tx_unlock_all(arvif);
5133 spin_unlock_bh(&ar->htt.tx_lock);
5134
Michal Kazior29946872016-03-06 16:14:34 +02005135 ath10k_mac_txq_unref(ar, vif->txq);
5136
Kalle Valo5e3dd152013-06-12 20:52:10 +03005137 mutex_unlock(&ar->conf_mutex);
5138}
5139
5140/*
5141 * FIXME: Has to be verified.
5142 */
5143#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005144 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005145 FIF_CONTROL | \
5146 FIF_PSPOLL | \
5147 FIF_OTHER_BSS | \
5148 FIF_BCN_PRBRESP_PROMISC | \
5149 FIF_PROBE_REQ | \
5150 FIF_FCSFAIL)
5151
5152static void ath10k_configure_filter(struct ieee80211_hw *hw,
5153 unsigned int changed_flags,
5154 unsigned int *total_flags,
5155 u64 multicast)
5156{
5157 struct ath10k *ar = hw->priv;
5158 int ret;
5159
5160 mutex_lock(&ar->conf_mutex);
5161
5162 changed_flags &= SUPPORTED_FILTERS;
5163 *total_flags &= SUPPORTED_FILTERS;
5164 ar->filter_flags = *total_flags;
5165
Michal Kazior19337472014-08-28 12:58:16 +02005166 ret = ath10k_monitor_recalc(ar);
5167 if (ret)
5168 ath10k_warn(ar, "failed to recalc montior: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005169
5170 mutex_unlock(&ar->conf_mutex);
5171}
5172
5173static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5174 struct ieee80211_vif *vif,
5175 struct ieee80211_bss_conf *info,
5176 u32 changed)
5177{
5178 struct ath10k *ar = hw->priv;
5179 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5180 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03005181 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005182
5183 mutex_lock(&ar->conf_mutex);
5184
5185 if (changed & BSS_CHANGED_IBSS)
5186 ath10k_control_ibss(arvif, info, vif->addr);
5187
5188 if (changed & BSS_CHANGED_BEACON_INT) {
5189 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005190 vdev_param = ar->wmi.vdev_param->beacon_interval;
5191 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005192 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005193 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005194 "mac vdev %d beacon_interval %d\n",
5195 arvif->vdev_id, arvif->beacon_interval);
5196
Kalle Valo5e3dd152013-06-12 20:52:10 +03005197 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005198 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005199 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005200 }
5201
5202 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005203 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005204 "vdev %d set beacon tx mode to staggered\n",
5205 arvif->vdev_id);
5206
Bartosz Markowski226a3392013-09-26 17:47:16 +02005207 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5208 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005209 WMI_BEACON_STAGGERED_MODE);
5210 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005211 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005212 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005213
5214 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5215 if (ret)
5216 ath10k_warn(ar, "failed to update beacon template: %d\n",
5217 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005218
5219 if (ieee80211_vif_is_mesh(vif)) {
5220 /* mesh doesn't use SSID but firmware needs it */
5221 strncpy(arvif->u.ap.ssid, "mesh",
5222 sizeof(arvif->u.ap.ssid));
5223 arvif->u.ap.ssid_len = 4;
5224 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005225 }
5226
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005227 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5228 ret = ath10k_mac_setup_prb_tmpl(arvif);
5229 if (ret)
5230 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5231 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005232 }
5233
Michal Kaziorba2479f2015-01-24 12:14:51 +02005234 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005235 arvif->dtim_period = info->dtim_period;
5236
Michal Kazior7aa7a722014-08-25 12:09:38 +02005237 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005238 "mac vdev %d dtim_period %d\n",
5239 arvif->vdev_id, arvif->dtim_period);
5240
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005241 vdev_param = ar->wmi.vdev_param->dtim_period;
5242 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005243 arvif->dtim_period);
5244 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005245 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005246 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005247 }
5248
5249 if (changed & BSS_CHANGED_SSID &&
5250 vif->type == NL80211_IFTYPE_AP) {
5251 arvif->u.ap.ssid_len = info->ssid_len;
5252 if (info->ssid_len)
5253 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5254 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5255 }
5256
Michal Kazior077efc82014-10-21 10:10:29 +03005257 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5258 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005259
5260 if (changed & BSS_CHANGED_BEACON_ENABLED)
5261 ath10k_control_beaconing(arvif, info);
5262
5263 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005264 arvif->use_cts_prot = info->use_cts_prot;
Michal Kazior7aa7a722014-08-25 12:09:38 +02005265 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005266 arvif->vdev_id, info->use_cts_prot);
Kalle Valo60c3daa2013-09-08 17:56:07 +03005267
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005268 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005269 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005270 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005271 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005272
5273 vdev_param = ar->wmi.vdev_param->protection_mode;
5274 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5275 info->use_cts_prot ? 1 : 0);
5276 if (ret)
5277 ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
Kalle Valo617b0f42015-10-05 17:56:35 +03005278 info->use_cts_prot, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005279 }
5280
5281 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005282 if (info->use_short_slot)
5283 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5284
5285 else
5286 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5287
Michal Kazior7aa7a722014-08-25 12:09:38 +02005288 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005289 arvif->vdev_id, slottime);
5290
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005291 vdev_param = ar->wmi.vdev_param->slot_time;
5292 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005293 slottime);
5294 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005295 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005296 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005297 }
5298
5299 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005300 if (info->use_short_preamble)
5301 preamble = WMI_VDEV_PREAMBLE_SHORT;
5302 else
5303 preamble = WMI_VDEV_PREAMBLE_LONG;
5304
Michal Kazior7aa7a722014-08-25 12:09:38 +02005305 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005306 "mac vdev %d preamble %dn",
5307 arvif->vdev_id, preamble);
5308
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005309 vdev_param = ar->wmi.vdev_param->preamble;
5310 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005311 preamble);
5312 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005313 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005314 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005315 }
5316
5317 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005318 if (info->assoc) {
5319 /* Workaround: Make sure monitor vdev is not running
5320 * when associating to prevent some firmware revisions
5321 * (e.g. 10.1 and 10.2) from crashing.
5322 */
5323 if (ar->monitor_started)
5324 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005325 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005326 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005327 } else {
5328 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005329 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005330 }
5331
Michal Kazior7d9d5582014-10-21 10:40:15 +03005332 if (changed & BSS_CHANGED_TXPOWER) {
5333 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5334 arvif->vdev_id, info->txpower);
5335
5336 arvif->txpower = info->txpower;
5337 ret = ath10k_mac_txpower_recalc(ar);
5338 if (ret)
5339 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5340 }
5341
Michal Kaziorbf14e652014-12-12 12:41:38 +01005342 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005343 arvif->ps = vif->bss_conf.ps;
5344
5345 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005346 if (ret)
5347 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5348 arvif->vdev_id, ret);
5349 }
5350
Kalle Valo5e3dd152013-06-12 20:52:10 +03005351 mutex_unlock(&ar->conf_mutex);
5352}
5353
5354static int ath10k_hw_scan(struct ieee80211_hw *hw,
5355 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005356 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005357{
5358 struct ath10k *ar = hw->priv;
5359 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02005360 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005361 struct wmi_start_scan_arg arg;
5362 int ret = 0;
5363 int i;
5364
5365 mutex_lock(&ar->conf_mutex);
5366
5367 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005368 switch (ar->scan.state) {
5369 case ATH10K_SCAN_IDLE:
5370 reinit_completion(&ar->scan.started);
5371 reinit_completion(&ar->scan.completed);
5372 ar->scan.state = ATH10K_SCAN_STARTING;
5373 ar->scan.is_roc = false;
5374 ar->scan.vdev_id = arvif->vdev_id;
5375 ret = 0;
5376 break;
5377 case ATH10K_SCAN_STARTING:
5378 case ATH10K_SCAN_RUNNING:
5379 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005380 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005381 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005382 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005383 spin_unlock_bh(&ar->data_lock);
5384
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005385 if (ret)
5386 goto exit;
5387
Kalle Valo5e3dd152013-06-12 20:52:10 +03005388 memset(&arg, 0, sizeof(arg));
5389 ath10k_wmi_start_scan_init(ar, &arg);
5390 arg.vdev_id = arvif->vdev_id;
5391 arg.scan_id = ATH10K_SCAN_ID;
5392
Kalle Valo5e3dd152013-06-12 20:52:10 +03005393 if (req->ie_len) {
5394 arg.ie_len = req->ie_len;
5395 memcpy(arg.ie, req->ie, arg.ie_len);
5396 }
5397
5398 if (req->n_ssids) {
5399 arg.n_ssids = req->n_ssids;
5400 for (i = 0; i < arg.n_ssids; i++) {
5401 arg.ssids[i].len = req->ssids[i].ssid_len;
5402 arg.ssids[i].ssid = req->ssids[i].ssid;
5403 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005404 } else {
5405 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005406 }
5407
5408 if (req->n_channels) {
5409 arg.n_channels = req->n_channels;
5410 for (i = 0; i < arg.n_channels; i++)
5411 arg.channels[i] = req->channels[i]->center_freq;
5412 }
5413
5414 ret = ath10k_start_scan(ar, &arg);
5415 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005416 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005417 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005418 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005419 spin_unlock_bh(&ar->data_lock);
5420 }
5421
Michal Kazior634349b2015-09-03 10:43:45 +02005422 /* Add a 200ms margin to account for event/command processing */
5423 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5424 msecs_to_jiffies(arg.max_scan_time +
5425 200));
5426
Kalle Valo5e3dd152013-06-12 20:52:10 +03005427exit:
5428 mutex_unlock(&ar->conf_mutex);
5429 return ret;
5430}
5431
5432static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5433 struct ieee80211_vif *vif)
5434{
5435 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005436
5437 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005438 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005439 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01005440
5441 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005442}
5443
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005444static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
5445 struct ath10k_vif *arvif,
5446 enum set_key_cmd cmd,
5447 struct ieee80211_key_conf *key)
5448{
5449 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
5450 int ret;
5451
5452 /* 10.1 firmware branch requires default key index to be set to group
5453 * key index after installing it. Otherwise FW/HW Txes corrupted
5454 * frames with multi-vif APs. This is not required for main firmware
5455 * branch (e.g. 636).
5456 *
Michal Kazior8461baf2015-04-10 13:23:22 +00005457 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
5458 *
5459 * FIXME: It remains unknown if this is required for multi-vif STA
5460 * interfaces on 10.1.
5461 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005462
Michal Kazior8461baf2015-04-10 13:23:22 +00005463 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
5464 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005465 return;
5466
5467 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
5468 return;
5469
5470 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
5471 return;
5472
5473 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5474 return;
5475
5476 if (cmd != SET_KEY)
5477 return;
5478
5479 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5480 key->keyidx);
5481 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005482 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005483 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005484}
5485
Kalle Valo5e3dd152013-06-12 20:52:10 +03005486static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5487 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5488 struct ieee80211_key_conf *key)
5489{
5490 struct ath10k *ar = hw->priv;
5491 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5492 struct ath10k_peer *peer;
5493 const u8 *peer_addr;
5494 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5495 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5496 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005497 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005498 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005499 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005500
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005501 /* this one needs to be done in software */
5502 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
5503 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005504
David Liuccec9032015-07-24 20:25:32 +03005505 if (arvif->nohwcrypt)
5506 return 1;
5507
Kalle Valo5e3dd152013-06-12 20:52:10 +03005508 if (key->keyidx > WMI_MAX_KEY_INDEX)
5509 return -ENOSPC;
5510
5511 mutex_lock(&ar->conf_mutex);
5512
5513 if (sta)
5514 peer_addr = sta->addr;
5515 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5516 peer_addr = vif->bss_conf.bssid;
5517 else
5518 peer_addr = vif->addr;
5519
5520 key->hw_key_idx = key->keyidx;
5521
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005522 if (is_wep) {
5523 if (cmd == SET_KEY)
5524 arvif->wep_keys[key->keyidx] = key;
5525 else
5526 arvif->wep_keys[key->keyidx] = NULL;
5527 }
5528
Kalle Valo5e3dd152013-06-12 20:52:10 +03005529 /* the peer should not disappear in mid-way (unless FW goes awry) since
5530 * we already hold conf_mutex. we just make sure its there now. */
5531 spin_lock_bh(&ar->data_lock);
5532 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5533 spin_unlock_bh(&ar->data_lock);
5534
5535 if (!peer) {
5536 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005537 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005538 peer_addr);
5539 ret = -EOPNOTSUPP;
5540 goto exit;
5541 } else {
5542 /* if the peer doesn't exist there is no key to disable
5543 * anymore */
5544 goto exit;
5545 }
5546 }
5547
Michal Kazior7cc45732015-03-09 14:24:17 +01005548 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5549 flags |= WMI_KEY_PAIRWISE;
5550 else
5551 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005552
Kalle Valo5e3dd152013-06-12 20:52:10 +03005553 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005554 if (cmd == DISABLE_KEY)
5555 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005556
Michal Kaziorad325cb2015-02-18 14:02:27 +01005557 /* When WEP keys are uploaded it's possible that there are
5558 * stations associated already (e.g. when merging) without any
5559 * keys. Static WEP needs an explicit per-peer key upload.
5560 */
5561 if (vif->type == NL80211_IFTYPE_ADHOC &&
5562 cmd == SET_KEY)
5563 ath10k_mac_vif_update_wep_key(arvif, key);
5564
Michal Kazior370e5672015-02-18 14:02:26 +01005565 /* 802.1x never sets the def_wep_key_idx so each set_key()
5566 * call changes default tx key.
5567 *
5568 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5569 * after first set_key().
5570 */
5571 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5572 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005573 }
5574
Michal Kazior370e5672015-02-18 14:02:26 +01005575 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005576 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005577 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005578 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005579 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005580 goto exit;
5581 }
5582
Michal Kazior29a10002015-04-10 13:05:58 +00005583 /* mac80211 sets static WEP keys as groupwise while firmware requires
5584 * them to be installed twice as both pairwise and groupwise.
5585 */
5586 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5587 flags2 = flags;
5588 flags2 &= ~WMI_KEY_GROUP;
5589 flags2 |= WMI_KEY_PAIRWISE;
5590
5591 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5592 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005593 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005594 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5595 arvif->vdev_id, peer_addr, ret);
5596 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5597 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005598 if (ret2) {
5599 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005600 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5601 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005602 }
Michal Kazior29a10002015-04-10 13:05:58 +00005603 goto exit;
5604 }
5605 }
5606
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005607 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5608
Kalle Valo5e3dd152013-06-12 20:52:10 +03005609 spin_lock_bh(&ar->data_lock);
5610 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5611 if (peer && cmd == SET_KEY)
5612 peer->keys[key->keyidx] = key;
5613 else if (peer && cmd == DISABLE_KEY)
5614 peer->keys[key->keyidx] = NULL;
5615 else if (peer == NULL)
5616 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005617 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005618 spin_unlock_bh(&ar->data_lock);
5619
5620exit:
5621 mutex_unlock(&ar->conf_mutex);
5622 return ret;
5623}
5624
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005625static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5626 struct ieee80211_vif *vif,
5627 int keyidx)
5628{
5629 struct ath10k *ar = hw->priv;
5630 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5631 int ret;
5632
5633 mutex_lock(&arvif->ar->conf_mutex);
5634
5635 if (arvif->ar->state != ATH10K_STATE_ON)
5636 goto unlock;
5637
5638 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5639 arvif->vdev_id, keyidx);
5640
5641 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5642 arvif->vdev_id,
5643 arvif->ar->wmi.vdev_param->def_keyid,
5644 keyidx);
5645
5646 if (ret) {
5647 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5648 arvif->vdev_id,
5649 ret);
5650 goto unlock;
5651 }
5652
5653 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005654
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005655unlock:
5656 mutex_unlock(&arvif->ar->conf_mutex);
5657}
5658
Michal Kazior9797feb2014-02-14 14:49:48 +01005659static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5660{
5661 struct ath10k *ar;
5662 struct ath10k_vif *arvif;
5663 struct ath10k_sta *arsta;
5664 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005665 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02005666 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005667 const u8 *ht_mcs_mask;
5668 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005669 u32 changed, bw, nss, smps;
5670 int err;
5671
5672 arsta = container_of(wk, struct ath10k_sta, update_wk);
5673 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5674 arvif = arsta->arvif;
5675 ar = arvif->ar;
5676
Michal Kazior45c9abc2015-04-21 20:42:58 +03005677 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5678 return;
5679
5680 band = def.chan->band;
5681 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5682 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5683
Michal Kazior9797feb2014-02-14 14:49:48 +01005684 spin_lock_bh(&ar->data_lock);
5685
5686 changed = arsta->changed;
5687 arsta->changed = 0;
5688
5689 bw = arsta->bw;
5690 nss = arsta->nss;
5691 smps = arsta->smps;
5692
5693 spin_unlock_bh(&ar->data_lock);
5694
5695 mutex_lock(&ar->conf_mutex);
5696
Michal Kazior45c9abc2015-04-21 20:42:58 +03005697 nss = max_t(u32, 1, nss);
5698 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
5699 ath10k_mac_max_vht_nss(vht_mcs_mask)));
5700
Michal Kazior9797feb2014-02-14 14:49:48 +01005701 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005702 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005703 sta->addr, bw);
5704
5705 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5706 WMI_PEER_CHAN_WIDTH, bw);
5707 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005708 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005709 sta->addr, bw, err);
5710 }
5711
5712 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005713 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005714 sta->addr, nss);
5715
5716 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5717 WMI_PEER_NSS, nss);
5718 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005719 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005720 sta->addr, nss, err);
5721 }
5722
5723 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005724 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005725 sta->addr, smps);
5726
5727 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5728 WMI_PEER_SMPS_STATE, smps);
5729 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005730 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005731 sta->addr, smps, err);
5732 }
5733
Janusz Dziedzic55884c02014-12-17 12:30:02 +02005734 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
5735 changed & IEEE80211_RC_NSS_CHANGED) {
5736 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005737 sta->addr);
5738
Michal Kazior590922a2014-10-21 10:10:29 +03005739 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005740 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005741 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005742 sta->addr);
5743 }
5744
Michal Kazior9797feb2014-02-14 14:49:48 +01005745 mutex_unlock(&ar->conf_mutex);
5746}
5747
Marek Puzyniak7c354242015-03-30 09:51:52 +03005748static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
5749 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005750{
5751 struct ath10k *ar = arvif->ar;
5752
5753 lockdep_assert_held(&ar->conf_mutex);
5754
Marek Puzyniak7c354242015-03-30 09:51:52 +03005755 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005756 return 0;
5757
5758 if (ar->num_stations >= ar->max_num_stations)
5759 return -ENOBUFS;
5760
5761 ar->num_stations++;
5762
5763 return 0;
5764}
5765
Marek Puzyniak7c354242015-03-30 09:51:52 +03005766static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
5767 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005768{
5769 struct ath10k *ar = arvif->ar;
5770
5771 lockdep_assert_held(&ar->conf_mutex);
5772
Marek Puzyniak7c354242015-03-30 09:51:52 +03005773 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005774 return;
5775
5776 ar->num_stations--;
5777}
5778
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005779struct ath10k_mac_tdls_iter_data {
5780 u32 num_tdls_stations;
5781 struct ieee80211_vif *curr_vif;
5782};
5783
5784static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5785 struct ieee80211_sta *sta)
5786{
5787 struct ath10k_mac_tdls_iter_data *iter_data = data;
5788 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5789 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5790
5791 if (sta->tdls && sta_vif == iter_data->curr_vif)
5792 iter_data->num_tdls_stations++;
5793}
5794
5795static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5796 struct ieee80211_vif *vif)
5797{
5798 struct ath10k_mac_tdls_iter_data data = {};
5799
5800 data.curr_vif = vif;
5801
5802 ieee80211_iterate_stations_atomic(hw,
5803 ath10k_mac_tdls_vif_stations_count_iter,
5804 &data);
5805 return data.num_tdls_stations;
5806}
5807
5808static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5809 struct ieee80211_vif *vif)
5810{
5811 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5812 int *num_tdls_vifs = data;
5813
5814 if (vif->type != NL80211_IFTYPE_STATION)
5815 return;
5816
5817 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5818 (*num_tdls_vifs)++;
5819}
5820
5821static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5822{
5823 int num_tdls_vifs = 0;
5824
5825 ieee80211_iterate_active_interfaces_atomic(hw,
5826 IEEE80211_IFACE_ITER_NORMAL,
5827 ath10k_mac_tdls_vifs_count_iter,
5828 &num_tdls_vifs);
5829 return num_tdls_vifs;
5830}
5831
Kalle Valo5e3dd152013-06-12 20:52:10 +03005832static int ath10k_sta_state(struct ieee80211_hw *hw,
5833 struct ieee80211_vif *vif,
5834 struct ieee80211_sta *sta,
5835 enum ieee80211_sta_state old_state,
5836 enum ieee80211_sta_state new_state)
5837{
5838 struct ath10k *ar = hw->priv;
5839 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005840 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005841 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005842 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02005843 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005844
Michal Kazior76f90022014-02-25 09:29:57 +02005845 if (old_state == IEEE80211_STA_NOTEXIST &&
5846 new_state == IEEE80211_STA_NONE) {
5847 memset(arsta, 0, sizeof(*arsta));
5848 arsta->arvif = arvif;
5849 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02005850
5851 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5852 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02005853 }
5854
Michal Kazior9797feb2014-02-14 14:49:48 +01005855 /* cancel must be done outside the mutex to avoid deadlock */
5856 if ((old_state == IEEE80211_STA_NONE &&
5857 new_state == IEEE80211_STA_NOTEXIST))
5858 cancel_work_sync(&arsta->update_wk);
5859
Kalle Valo5e3dd152013-06-12 20:52:10 +03005860 mutex_lock(&ar->conf_mutex);
5861
5862 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005863 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005864 /*
5865 * New station addition.
5866 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005867 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5868 u32 num_tdls_stations;
5869 u32 num_tdls_vifs;
5870
Michal Kaziorcfd10612014-11-25 15:16:05 +01005871 ath10k_dbg(ar, ATH10K_DBG_MAC,
5872 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5873 arvif->vdev_id, sta->addr,
5874 ar->num_stations + 1, ar->max_num_stations,
5875 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005876
Marek Puzyniak7c354242015-03-30 09:51:52 +03005877 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005878 if (ret) {
5879 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5880 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005881 goto exit;
5882 }
5883
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005884 if (sta->tdls)
5885 peer_type = WMI_PEER_TYPE_TDLS;
5886
Michal Kazior69427262016-03-06 16:14:30 +02005887 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
5888 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005889 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005890 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 -08005891 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005892 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005893 goto exit;
5894 }
Michal Kazior077efc82014-10-21 10:10:29 +03005895
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005896 spin_lock_bh(&ar->data_lock);
5897
5898 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
5899 if (!peer) {
5900 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5901 vif->addr, arvif->vdev_id);
5902 spin_unlock_bh(&ar->data_lock);
5903 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5904 ath10k_mac_dec_num_stations(arvif, sta);
5905 ret = -ENOENT;
5906 goto exit;
5907 }
5908
5909 arsta->peer_id = find_first_bit(peer->peer_ids,
5910 ATH10K_MAX_NUM_PEER_IDS);
5911
5912 spin_unlock_bh(&ar->data_lock);
5913
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005914 if (!sta->tdls)
5915 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03005916
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005917 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
5918 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
5919
5920 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
5921 num_tdls_stations == 0) {
5922 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
5923 arvif->vdev_id, ar->max_num_tdls_vdevs);
5924 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5925 ath10k_mac_dec_num_stations(arvif, sta);
5926 ret = -ENOBUFS;
5927 goto exit;
5928 }
5929
5930 if (num_tdls_stations == 0) {
5931 /* This is the first tdls peer in current vif */
5932 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
5933
5934 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5935 state);
Michal Kazior077efc82014-10-21 10:10:29 +03005936 if (ret) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005937 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
Michal Kazior077efc82014-10-21 10:10:29 +03005938 arvif->vdev_id, ret);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005939 ath10k_peer_delete(ar, arvif->vdev_id,
5940 sta->addr);
5941 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03005942 goto exit;
5943 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005944 }
Michal Kazior077efc82014-10-21 10:10:29 +03005945
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005946 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
5947 WMI_TDLS_PEER_STATE_PEERING);
5948 if (ret) {
5949 ath10k_warn(ar,
5950 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
5951 sta->addr, arvif->vdev_id, ret);
5952 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5953 ath10k_mac_dec_num_stations(arvif, sta);
5954
5955 if (num_tdls_stations != 0)
5956 goto exit;
5957 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
5958 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03005959 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005960 } else if ((old_state == IEEE80211_STA_NONE &&
5961 new_state == IEEE80211_STA_NOTEXIST)) {
5962 /*
5963 * Existing station deletion.
5964 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005965 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005966 "mac vdev %d peer delete %pM (sta gone)\n",
5967 arvif->vdev_id, sta->addr);
Michal Kazior077efc82014-10-21 10:10:29 +03005968
Kalle Valo5e3dd152013-06-12 20:52:10 +03005969 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5970 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005971 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005972 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005973
Marek Puzyniak7c354242015-03-30 09:51:52 +03005974 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005975
Michal Kazior69427262016-03-06 16:14:30 +02005976 spin_lock_bh(&ar->data_lock);
5977 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5978 peer = ar->peer_map[i];
5979 if (!peer)
5980 continue;
5981
5982 if (peer->sta == sta) {
5983 ath10k_warn(ar, "found sta peer %pM entry on vdev %i after it was supposedly removed\n",
5984 sta->addr, arvif->vdev_id);
5985 peer->sta = NULL;
5986 }
5987 }
5988 spin_unlock_bh(&ar->data_lock);
5989
Michal Kazior29946872016-03-06 16:14:34 +02005990 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5991 ath10k_mac_txq_unref(ar, sta->txq[i]);
5992
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005993 if (!sta->tdls)
5994 goto exit;
5995
5996 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
5997 goto exit;
5998
5999 /* This was the last tdls peer in current vif */
6000 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6001 WMI_TDLS_DISABLE);
6002 if (ret) {
6003 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6004 arvif->vdev_id, ret);
6005 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006006 } else if (old_state == IEEE80211_STA_AUTH &&
6007 new_state == IEEE80211_STA_ASSOC &&
6008 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006009 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03006010 vif->type == NL80211_IFTYPE_ADHOC)) {
6011 /*
6012 * New association.
6013 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006014 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006015 sta->addr);
6016
Michal Kazior590922a2014-10-21 10:10:29 +03006017 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006018 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006019 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006020 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006021 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006022 new_state == IEEE80211_STA_AUTHORIZED &&
6023 sta->tdls) {
6024 /*
6025 * Tdls station authorized.
6026 */
6027 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
6028 sta->addr);
6029
6030 ret = ath10k_station_assoc(ar, vif, sta, false);
6031 if (ret) {
6032 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
6033 sta->addr, arvif->vdev_id, ret);
6034 goto exit;
6035 }
6036
6037 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6038 WMI_TDLS_PEER_STATE_CONNECTED);
6039 if (ret)
6040 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
6041 sta->addr, arvif->vdev_id, ret);
6042 } else if (old_state == IEEE80211_STA_ASSOC &&
6043 new_state == IEEE80211_STA_AUTH &&
6044 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006045 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006046 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006047 /*
6048 * Disassociation.
6049 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006050 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006051 sta->addr);
6052
Michal Kazior590922a2014-10-21 10:10:29 +03006053 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006054 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006055 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006056 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006057 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006058exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006059 mutex_unlock(&ar->conf_mutex);
6060 return ret;
6061}
6062
6063static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006064 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006065{
6066 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02006067 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6068 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006069 u32 value = 0;
6070 int ret = 0;
6071
Michal Kazior548db542013-07-05 16:15:15 +03006072 lockdep_assert_held(&ar->conf_mutex);
6073
Kalle Valo5e3dd152013-06-12 20:52:10 +03006074 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6075 return 0;
6076
6077 switch (ac) {
6078 case IEEE80211_AC_VO:
6079 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6080 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006081 prio = 7;
6082 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006083 break;
6084 case IEEE80211_AC_VI:
6085 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6086 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006087 prio = 5;
6088 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006089 break;
6090 case IEEE80211_AC_BE:
6091 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6092 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006093 prio = 2;
6094 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006095 break;
6096 case IEEE80211_AC_BK:
6097 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6098 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006099 prio = 0;
6100 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006101 break;
6102 }
6103
6104 if (enable)
6105 arvif->u.sta.uapsd |= value;
6106 else
6107 arvif->u.sta.uapsd &= ~value;
6108
6109 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6110 WMI_STA_PS_PARAM_UAPSD,
6111 arvif->u.sta.uapsd);
6112 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006113 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006114 goto exit;
6115 }
6116
6117 if (arvif->u.sta.uapsd)
6118 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6119 else
6120 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6121
6122 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6123 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6124 value);
6125 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006126 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006127
Michal Kazior9f9b5742014-12-12 12:41:36 +01006128 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6129 if (ret) {
6130 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6131 arvif->vdev_id, ret);
6132 return ret;
6133 }
6134
6135 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6136 if (ret) {
6137 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6138 arvif->vdev_id, ret);
6139 return ret;
6140 }
6141
Michal Kaziorb0e56152015-01-24 12:14:52 +02006142 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6143 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6144 /* Only userspace can make an educated decision when to send
6145 * trigger frame. The following effectively disables u-UAPSD
6146 * autotrigger in firmware (which is enabled by default
6147 * provided the autotrigger service is available).
6148 */
6149
6150 arg.wmm_ac = acc;
6151 arg.user_priority = prio;
6152 arg.service_interval = 0;
6153 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6154 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6155
6156 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6157 arvif->bssid, &arg, 1);
6158 if (ret) {
6159 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6160 ret);
6161 return ret;
6162 }
6163 }
6164
Kalle Valo5e3dd152013-06-12 20:52:10 +03006165exit:
6166 return ret;
6167}
6168
6169static int ath10k_conf_tx(struct ieee80211_hw *hw,
6170 struct ieee80211_vif *vif, u16 ac,
6171 const struct ieee80211_tx_queue_params *params)
6172{
6173 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01006174 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006175 struct wmi_wmm_params_arg *p = NULL;
6176 int ret;
6177
6178 mutex_lock(&ar->conf_mutex);
6179
6180 switch (ac) {
6181 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006182 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006183 break;
6184 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006185 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006186 break;
6187 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006188 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006189 break;
6190 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006191 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006192 break;
6193 }
6194
6195 if (WARN_ON(!p)) {
6196 ret = -EINVAL;
6197 goto exit;
6198 }
6199
6200 p->cwmin = params->cw_min;
6201 p->cwmax = params->cw_max;
6202 p->aifs = params->aifs;
6203
6204 /*
6205 * The channel time duration programmed in the HW is in absolute
6206 * microseconds, while mac80211 gives the txop in units of
6207 * 32 microseconds.
6208 */
6209 p->txop = params->txop * 32;
6210
Michal Kazior7fc979a2015-01-28 09:57:28 +02006211 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6212 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6213 &arvif->wmm_params);
6214 if (ret) {
6215 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6216 arvif->vdev_id, ret);
6217 goto exit;
6218 }
6219 } else {
6220 /* This won't work well with multi-interface cases but it's
6221 * better than nothing.
6222 */
6223 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6224 if (ret) {
6225 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6226 goto exit;
6227 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006228 }
6229
6230 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6231 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006232 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006233
6234exit:
6235 mutex_unlock(&ar->conf_mutex);
6236 return ret;
6237}
6238
Kalle Valo14e105c2016-04-13 14:13:21 +03006239#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006240
6241static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6242 struct ieee80211_vif *vif,
6243 struct ieee80211_channel *chan,
6244 int duration,
6245 enum ieee80211_roc_type type)
6246{
6247 struct ath10k *ar = hw->priv;
6248 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6249 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006250 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006251 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006252
6253 mutex_lock(&ar->conf_mutex);
6254
6255 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006256 switch (ar->scan.state) {
6257 case ATH10K_SCAN_IDLE:
6258 reinit_completion(&ar->scan.started);
6259 reinit_completion(&ar->scan.completed);
6260 reinit_completion(&ar->scan.on_channel);
6261 ar->scan.state = ATH10K_SCAN_STARTING;
6262 ar->scan.is_roc = true;
6263 ar->scan.vdev_id = arvif->vdev_id;
6264 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006265 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006266 ret = 0;
6267 break;
6268 case ATH10K_SCAN_STARTING:
6269 case ATH10K_SCAN_RUNNING:
6270 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006271 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006272 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006273 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006274 spin_unlock_bh(&ar->data_lock);
6275
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006276 if (ret)
6277 goto exit;
6278
Michal Kaziorfcf98442015-03-31 11:03:47 +00006279 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006280
Kalle Valo5e3dd152013-06-12 20:52:10 +03006281 memset(&arg, 0, sizeof(arg));
6282 ath10k_wmi_start_scan_init(ar, &arg);
6283 arg.vdev_id = arvif->vdev_id;
6284 arg.scan_id = ATH10K_SCAN_ID;
6285 arg.n_channels = 1;
6286 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006287 arg.dwell_time_active = scan_time_msec;
6288 arg.dwell_time_passive = scan_time_msec;
6289 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006290 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6291 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006292 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006293
6294 ret = ath10k_start_scan(ar, &arg);
6295 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006296 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006297 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006298 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006299 spin_unlock_bh(&ar->data_lock);
6300 goto exit;
6301 }
6302
Kalle Valo14e105c2016-04-13 14:13:21 +03006303 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006304 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006305 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006306
6307 ret = ath10k_scan_stop(ar);
6308 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006309 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006310
Kalle Valo5e3dd152013-06-12 20:52:10 +03006311 ret = -ETIMEDOUT;
6312 goto exit;
6313 }
6314
Michal Kaziorfcf98442015-03-31 11:03:47 +00006315 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6316 msecs_to_jiffies(duration));
6317
Kalle Valo5e3dd152013-06-12 20:52:10 +03006318 ret = 0;
6319exit:
6320 mutex_unlock(&ar->conf_mutex);
6321 return ret;
6322}
6323
6324static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6325{
6326 struct ath10k *ar = hw->priv;
6327
6328 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006329
6330 spin_lock_bh(&ar->data_lock);
6331 ar->scan.roc_notify = false;
6332 spin_unlock_bh(&ar->data_lock);
6333
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006334 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006335
Kalle Valo5e3dd152013-06-12 20:52:10 +03006336 mutex_unlock(&ar->conf_mutex);
6337
Michal Kazior4eb2e162014-10-28 10:23:09 +01006338 cancel_delayed_work_sync(&ar->scan.timeout);
6339
Kalle Valo5e3dd152013-06-12 20:52:10 +03006340 return 0;
6341}
6342
6343/*
6344 * Both RTS and Fragmentation threshold are interface-specific
6345 * in ath10k, but device-specific in mac80211.
6346 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006347
6348static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6349{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006350 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006351 struct ath10k_vif *arvif;
6352 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006353
Michal Kaziorad088bf2013-10-16 15:44:46 +03006354 mutex_lock(&ar->conf_mutex);
6355 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006356 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006357 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006358
Michal Kaziorad088bf2013-10-16 15:44:46 +03006359 ret = ath10k_mac_set_rts(arvif, value);
6360 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006361 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006362 arvif->vdev_id, ret);
6363 break;
6364 }
6365 }
6366 mutex_unlock(&ar->conf_mutex);
6367
6368 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006369}
6370
Michal Kazior92092fe2015-08-03 11:16:43 +02006371static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6372{
6373 /* Even though there's a WMI enum for fragmentation threshold no known
6374 * firmware actually implements it. Moreover it is not possible to rely
6375 * frame fragmentation to mac80211 because firmware clears the "more
6376 * fragments" bit in frame control making it impossible for remote
6377 * devices to reassemble frames.
6378 *
6379 * Hence implement a dummy callback just to say fragmentation isn't
6380 * supported. This effectively prevents mac80211 from doing frame
6381 * fragmentation in software.
6382 */
6383 return -EOPNOTSUPP;
6384}
6385
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02006386static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6387 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006388{
6389 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02006390 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006391 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006392
6393 /* mac80211 doesn't care if we really xmit queued frames or not
6394 * we'll collect those frames either way if we stop/delete vdevs */
6395 if (drop)
6396 return;
6397
Michal Kazior548db542013-07-05 16:15:15 +03006398 mutex_lock(&ar->conf_mutex);
6399
Michal Kazioraffd3212013-07-16 09:54:35 +02006400 if (ar->state == ATH10K_STATE_WEDGED)
6401 goto skip;
6402
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006403 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006404 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006405
Michal Kazioredb82362013-07-05 16:15:14 +03006406 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006407 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006408 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006409
Michal Kazior7962b0d2014-10-28 10:34:38 +01006410 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6411 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6412 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006413
6414 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006415 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006416
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006417 if (time_left == 0 || skip)
6418 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6419 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03006420
Michal Kazioraffd3212013-07-16 09:54:35 +02006421skip:
Michal Kazior548db542013-07-05 16:15:15 +03006422 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006423}
6424
6425/* TODO: Implement this function properly
6426 * For now it is needed to reply to Probe Requests in IBSS mode.
6427 * Propably we need this information from FW.
6428 */
6429static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
6430{
6431 return 1;
6432}
6433
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006434static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
6435 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02006436{
6437 struct ath10k *ar = hw->priv;
6438
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006439 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
6440 return;
6441
Michal Kazioraffd3212013-07-16 09:54:35 +02006442 mutex_lock(&ar->conf_mutex);
6443
6444 /* If device failed to restart it will be in a different state, e.g.
6445 * ATH10K_STATE_WEDGED */
6446 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006447 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02006448 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01006449 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02006450 }
6451
6452 mutex_unlock(&ar->conf_mutex);
6453}
6454
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306455static void
6456ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
6457 struct ieee80211_channel *channel)
6458{
6459 int ret;
6460 enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
6461
6462 lockdep_assert_held(&ar->conf_mutex);
6463
6464 if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
6465 (ar->rx_channel != channel))
6466 return;
6467
6468 if (ar->scan.state != ATH10K_SCAN_IDLE) {
6469 ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
6470 return;
6471 }
6472
6473 reinit_completion(&ar->bss_survey_done);
6474
6475 ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
6476 if (ret) {
6477 ath10k_warn(ar, "failed to send pdev bss chan info request\n");
6478 return;
6479 }
6480
6481 ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
6482 if (!ret) {
6483 ath10k_warn(ar, "bss channel survey timed out\n");
6484 return;
6485 }
6486}
6487
Michal Kazior2e1dea42013-07-31 10:32:40 +02006488static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
6489 struct survey_info *survey)
6490{
6491 struct ath10k *ar = hw->priv;
6492 struct ieee80211_supported_band *sband;
6493 struct survey_info *ar_survey = &ar->survey[idx];
6494 int ret = 0;
6495
6496 mutex_lock(&ar->conf_mutex);
6497
Johannes Berg57fbcce2016-04-12 15:56:15 +02006498 sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006499 if (sband && idx >= sband->n_channels) {
6500 idx -= sband->n_channels;
6501 sband = NULL;
6502 }
6503
6504 if (!sband)
Johannes Berg57fbcce2016-04-12 15:56:15 +02006505 sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006506
6507 if (!sband || idx >= sband->n_channels) {
6508 ret = -ENOENT;
6509 goto exit;
6510 }
6511
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306512 ath10k_mac_update_bss_chan_survey(ar, survey->channel);
6513
Michal Kazior2e1dea42013-07-31 10:32:40 +02006514 spin_lock_bh(&ar->data_lock);
6515 memcpy(survey, ar_survey, sizeof(*survey));
6516 spin_unlock_bh(&ar->data_lock);
6517
6518 survey->channel = &sband->channels[idx];
6519
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03006520 if (ar->rx_channel == survey->channel)
6521 survey->filled |= SURVEY_INFO_IN_USE;
6522
Michal Kazior2e1dea42013-07-31 10:32:40 +02006523exit:
6524 mutex_unlock(&ar->conf_mutex);
6525 return ret;
6526}
6527
Michal Kazior3ae54222015-03-31 10:49:20 +00006528static bool
6529ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006530 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006531 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006532{
Michal Kazior3ae54222015-03-31 10:49:20 +00006533 int num_rates = 0;
6534 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006535
Michal Kazior3ae54222015-03-31 10:49:20 +00006536 num_rates += hweight32(mask->control[band].legacy);
6537
6538 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
6539 num_rates += hweight8(mask->control[band].ht_mcs[i]);
6540
6541 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
6542 num_rates += hweight16(mask->control[band].vht_mcs[i]);
6543
6544 return num_rates == 1;
6545}
6546
6547static bool
6548ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006549 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006550 const struct cfg80211_bitrate_mask *mask,
6551 int *nss)
6552{
6553 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6554 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6555 u8 ht_nss_mask = 0;
6556 u8 vht_nss_mask = 0;
6557 int i;
6558
6559 if (mask->control[band].legacy)
6560 return false;
6561
6562 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6563 if (mask->control[band].ht_mcs[i] == 0)
6564 continue;
6565 else if (mask->control[band].ht_mcs[i] ==
6566 sband->ht_cap.mcs.rx_mask[i])
6567 ht_nss_mask |= BIT(i);
6568 else
6569 return false;
6570 }
6571
6572 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6573 if (mask->control[band].vht_mcs[i] == 0)
6574 continue;
6575 else if (mask->control[band].vht_mcs[i] ==
6576 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6577 vht_nss_mask |= BIT(i);
6578 else
6579 return false;
6580 }
6581
6582 if (ht_nss_mask != vht_nss_mask)
6583 return false;
6584
6585 if (ht_nss_mask == 0)
6586 return false;
6587
6588 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6589 return false;
6590
6591 *nss = fls(ht_nss_mask);
6592
6593 return true;
6594}
6595
6596static int
6597ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006598 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006599 const struct cfg80211_bitrate_mask *mask,
6600 u8 *rate, u8 *nss)
6601{
6602 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6603 int rate_idx;
6604 int i;
6605 u16 bitrate;
6606 u8 preamble;
6607 u8 hw_rate;
6608
6609 if (hweight32(mask->control[band].legacy) == 1) {
6610 rate_idx = ffs(mask->control[band].legacy) - 1;
6611
6612 hw_rate = sband->bitrates[rate_idx].hw_value;
6613 bitrate = sband->bitrates[rate_idx].bitrate;
6614
6615 if (ath10k_mac_bitrate_is_cck(bitrate))
6616 preamble = WMI_RATE_PREAMBLE_CCK;
6617 else
6618 preamble = WMI_RATE_PREAMBLE_OFDM;
6619
6620 *nss = 1;
6621 *rate = preamble << 6 |
6622 (*nss - 1) << 4 |
6623 hw_rate << 0;
6624
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006625 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006626 }
6627
Michal Kazior3ae54222015-03-31 10:49:20 +00006628 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6629 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6630 *nss = i + 1;
6631 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6632 (*nss - 1) << 4 |
6633 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006634
Michal Kazior3ae54222015-03-31 10:49:20 +00006635 return 0;
6636 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006637 }
6638
Michal Kazior3ae54222015-03-31 10:49:20 +00006639 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6640 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6641 *nss = i + 1;
6642 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6643 (*nss - 1) << 4 |
6644 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006645
Michal Kazior3ae54222015-03-31 10:49:20 +00006646 return 0;
6647 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006648 }
6649
Michal Kazior3ae54222015-03-31 10:49:20 +00006650 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006651}
6652
Michal Kazior3ae54222015-03-31 10:49:20 +00006653static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306654 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006655{
6656 struct ath10k *ar = arvif->ar;
6657 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006658 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006659
Michal Kazior3ae54222015-03-31 10:49:20 +00006660 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006661
Michal Kazior3ae54222015-03-31 10:49:20 +00006662 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6663 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006664
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006665 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006666 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006667 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006668 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006669 rate, ret);
6670 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006671 }
6672
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006673 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006674 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006675 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006676 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6677 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006678 }
6679
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006680 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006681 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006682 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006683 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6684 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006685 }
6686
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306687 vdev_param = ar->wmi.vdev_param->ldpc;
6688 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6689 if (ret) {
6690 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6691 return ret;
6692 }
6693
Michal Kazior3ae54222015-03-31 10:49:20 +00006694 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006695}
6696
Michal Kazior45c9abc2015-04-21 20:42:58 +03006697static bool
6698ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006699 enum nl80211_band band,
Michal Kazior45c9abc2015-04-21 20:42:58 +03006700 const struct cfg80211_bitrate_mask *mask)
6701{
6702 int i;
6703 u16 vht_mcs;
6704
6705 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6706 * to express all VHT MCS rate masks. Effectively only the following
6707 * ranges can be used: none, 0-7, 0-8 and 0-9.
6708 */
6709 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6710 vht_mcs = mask->control[band].vht_mcs[i];
6711
6712 switch (vht_mcs) {
6713 case 0:
6714 case BIT(8) - 1:
6715 case BIT(9) - 1:
6716 case BIT(10) - 1:
6717 break;
6718 default:
6719 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6720 return false;
6721 }
6722 }
6723
6724 return true;
6725}
6726
6727static void ath10k_mac_set_bitrate_mask_iter(void *data,
6728 struct ieee80211_sta *sta)
6729{
6730 struct ath10k_vif *arvif = data;
6731 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6732 struct ath10k *ar = arvif->ar;
6733
6734 if (arsta->arvif != arvif)
6735 return;
6736
6737 spin_lock_bh(&ar->data_lock);
6738 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
6739 spin_unlock_bh(&ar->data_lock);
6740
6741 ieee80211_queue_work(ar->hw, &arsta->update_wk);
6742}
6743
Michal Kazior3ae54222015-03-31 10:49:20 +00006744static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
6745 struct ieee80211_vif *vif,
6746 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006747{
6748 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006749 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006750 struct ath10k *ar = arvif->ar;
Johannes Berg57fbcce2016-04-12 15:56:15 +02006751 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006752 const u8 *ht_mcs_mask;
6753 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00006754 u8 rate;
6755 u8 nss;
6756 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306757 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00006758 int single_nss;
6759 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006760
Michal Kazior500ff9f2015-03-31 10:26:21 +00006761 if (ath10k_mac_vif_chan(vif, &def))
6762 return -EPERM;
6763
Michal Kazior500ff9f2015-03-31 10:26:21 +00006764 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006765 ht_mcs_mask = mask->control[band].ht_mcs;
6766 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306767 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006768
Michal Kazior3ae54222015-03-31 10:49:20 +00006769 sgi = mask->control[band].gi;
6770 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006771 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006772
Michal Kazior3ae54222015-03-31 10:49:20 +00006773 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
6774 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
6775 &rate, &nss);
6776 if (ret) {
6777 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
6778 arvif->vdev_id, ret);
6779 return ret;
6780 }
6781 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
6782 &single_nss)) {
6783 rate = WMI_FIXED_RATE_NONE;
6784 nss = single_nss;
6785 } else {
6786 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006787 nss = min(ar->num_rf_chains,
6788 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6789 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6790
6791 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
6792 return -EINVAL;
6793
6794 mutex_lock(&ar->conf_mutex);
6795
6796 arvif->bitrate_mask = *mask;
6797 ieee80211_iterate_stations_atomic(ar->hw,
6798 ath10k_mac_set_bitrate_mask_iter,
6799 arvif);
6800
6801 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006802 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006803
6804 mutex_lock(&ar->conf_mutex);
6805
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306806 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006807 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006808 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
6809 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006810 goto exit;
6811 }
6812
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006813exit:
6814 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00006815
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006816 return ret;
6817}
6818
Michal Kazior9797feb2014-02-14 14:49:48 +01006819static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6820 struct ieee80211_vif *vif,
6821 struct ieee80211_sta *sta,
6822 u32 changed)
6823{
6824 struct ath10k *ar = hw->priv;
6825 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6826 u32 bw, smps;
6827
6828 spin_lock_bh(&ar->data_lock);
6829
Michal Kazior7aa7a722014-08-25 12:09:38 +02006830 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01006831 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
6832 sta->addr, changed, sta->bandwidth, sta->rx_nss,
6833 sta->smps_mode);
6834
6835 if (changed & IEEE80211_RC_BW_CHANGED) {
6836 bw = WMI_PEER_CHWIDTH_20MHZ;
6837
6838 switch (sta->bandwidth) {
6839 case IEEE80211_STA_RX_BW_20:
6840 bw = WMI_PEER_CHWIDTH_20MHZ;
6841 break;
6842 case IEEE80211_STA_RX_BW_40:
6843 bw = WMI_PEER_CHWIDTH_40MHZ;
6844 break;
6845 case IEEE80211_STA_RX_BW_80:
6846 bw = WMI_PEER_CHWIDTH_80MHZ;
6847 break;
6848 case IEEE80211_STA_RX_BW_160:
Masanari Iidad939be32015-02-27 23:52:31 +09006849 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006850 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006851 bw = WMI_PEER_CHWIDTH_20MHZ;
6852 break;
6853 }
6854
6855 arsta->bw = bw;
6856 }
6857
6858 if (changed & IEEE80211_RC_NSS_CHANGED)
6859 arsta->nss = sta->rx_nss;
6860
6861 if (changed & IEEE80211_RC_SMPS_CHANGED) {
6862 smps = WMI_PEER_SMPS_PS_NONE;
6863
6864 switch (sta->smps_mode) {
6865 case IEEE80211_SMPS_AUTOMATIC:
6866 case IEEE80211_SMPS_OFF:
6867 smps = WMI_PEER_SMPS_PS_NONE;
6868 break;
6869 case IEEE80211_SMPS_STATIC:
6870 smps = WMI_PEER_SMPS_STATIC;
6871 break;
6872 case IEEE80211_SMPS_DYNAMIC:
6873 smps = WMI_PEER_SMPS_DYNAMIC;
6874 break;
6875 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02006876 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006877 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006878 smps = WMI_PEER_SMPS_PS_NONE;
6879 break;
6880 }
6881
6882 arsta->smps = smps;
6883 }
6884
Michal Kazior9797feb2014-02-14 14:49:48 +01006885 arsta->changed |= changed;
6886
6887 spin_unlock_bh(&ar->data_lock);
6888
6889 ieee80211_queue_work(hw, &arsta->update_wk);
6890}
6891
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006892static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
6893{
6894 /*
6895 * FIXME: Return 0 for time being. Need to figure out whether FW
6896 * has the API to fetch 64-bit local TSF
6897 */
6898
6899 return 0;
6900}
6901
Peter Oh9f0b7e72016-04-04 16:19:14 -07006902static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
Kalle Valo4d165442016-04-13 14:14:16 +03006903 u64 tsf)
Peter Oh9f0b7e72016-04-04 16:19:14 -07006904{
6905 struct ath10k *ar = hw->priv;
6906 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6907 u32 tsf_offset, vdev_param = ar->wmi.vdev_param->set_tsf;
6908 int ret;
6909
6910 /* Workaround:
6911 *
6912 * Given tsf argument is entire TSF value, but firmware accepts
6913 * only TSF offset to current TSF.
6914 *
6915 * get_tsf function is used to get offset value, however since
6916 * ath10k_get_tsf is not implemented properly, it will return 0 always.
6917 * Luckily all the caller functions to set_tsf, as of now, also rely on
6918 * get_tsf function to get entire tsf value such get_tsf() + tsf_delta,
6919 * final tsf offset value to firmware will be arithmetically correct.
6920 */
6921 tsf_offset = tsf - ath10k_get_tsf(hw, vif);
6922 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
6923 vdev_param, tsf_offset);
6924 if (ret && ret != -EOPNOTSUPP)
6925 ath10k_warn(ar, "failed to set tsf offset: %d\n", ret);
6926}
6927
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006928static int ath10k_ampdu_action(struct ieee80211_hw *hw,
6929 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02006930 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006931{
Michal Kazior7aa7a722014-08-25 12:09:38 +02006932 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006933 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Sara Sharon50ea05e2015-12-30 16:06:04 +02006934 struct ieee80211_sta *sta = params->sta;
6935 enum ieee80211_ampdu_mlme_action action = params->action;
6936 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02006937
Michal Kazior7aa7a722014-08-25 12:09:38 +02006938 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 +02006939 arvif->vdev_id, sta->addr, tid, action);
6940
6941 switch (action) {
6942 case IEEE80211_AMPDU_RX_START:
6943 case IEEE80211_AMPDU_RX_STOP:
6944 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
6945 * creation/removal. Do we need to verify this?
6946 */
6947 return 0;
6948 case IEEE80211_AMPDU_TX_START:
6949 case IEEE80211_AMPDU_TX_STOP_CONT:
6950 case IEEE80211_AMPDU_TX_STOP_FLUSH:
6951 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
6952 case IEEE80211_AMPDU_TX_OPERATIONAL:
6953 /* Firmware offloads Tx aggregation entirely so deny mac80211
6954 * Tx aggregation requests.
6955 */
6956 return -EOPNOTSUPP;
6957 }
6958
6959 return -EINVAL;
6960}
6961
Michal Kazior500ff9f2015-03-31 10:26:21 +00006962static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006963ath10k_mac_update_rx_channel(struct ath10k *ar,
6964 struct ieee80211_chanctx_conf *ctx,
6965 struct ieee80211_vif_chanctx_switch *vifs,
6966 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00006967{
6968 struct cfg80211_chan_def *def = NULL;
6969
6970 /* Both locks are required because ar->rx_channel is modified. This
6971 * allows readers to hold either lock.
6972 */
6973 lockdep_assert_held(&ar->conf_mutex);
6974 lockdep_assert_held(&ar->data_lock);
6975
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006976 WARN_ON(ctx && vifs);
6977 WARN_ON(vifs && n_vifs != 1);
6978
Michal Kazior500ff9f2015-03-31 10:26:21 +00006979 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
6980 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
6981 * ppdu on Rx may reduce performance on low-end systems. It should be
6982 * possible to make tables/hashmaps to speed the lookup up (be vary of
6983 * cpu data cache lines though regarding sizes) but to keep the initial
6984 * implementation simple and less intrusive fallback to the slow lookup
6985 * only for multi-channel cases. Single-channel cases will remain to
6986 * use the old channel derival and thus performance should not be
6987 * affected much.
6988 */
6989 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006990 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00006991 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03006992 ath10k_mac_get_any_chandef_iter,
6993 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02006994
6995 if (vifs)
6996 def = &vifs[0].new_ctx->def;
6997
Michal Kazior500ff9f2015-03-31 10:26:21 +00006998 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05306999 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
7000 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
7001 /* During driver restart due to firmware assert, since mac80211
7002 * already has valid channel context for given radio, channel
7003 * context iteration return num_chanctx > 0. So fix rx_channel
7004 * when restart is in progress.
7005 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007006 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007007 } else {
7008 ar->rx_channel = NULL;
7009 }
7010 rcu_read_unlock();
7011}
7012
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007013static void
7014ath10k_mac_update_vif_chan(struct ath10k *ar,
7015 struct ieee80211_vif_chanctx_switch *vifs,
7016 int n_vifs)
7017{
7018 struct ath10k_vif *arvif;
7019 int ret;
7020 int i;
7021
7022 lockdep_assert_held(&ar->conf_mutex);
7023
7024 /* First stop monitor interface. Some FW versions crash if there's a
7025 * lone monitor interface.
7026 */
7027 if (ar->monitor_started)
7028 ath10k_monitor_stop(ar);
7029
7030 for (i = 0; i < n_vifs; i++) {
7031 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7032
7033 ath10k_dbg(ar, ATH10K_DBG_MAC,
7034 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
7035 arvif->vdev_id,
7036 vifs[i].old_ctx->def.chan->center_freq,
7037 vifs[i].new_ctx->def.chan->center_freq,
7038 vifs[i].old_ctx->def.width,
7039 vifs[i].new_ctx->def.width);
7040
7041 if (WARN_ON(!arvif->is_started))
7042 continue;
7043
7044 if (WARN_ON(!arvif->is_up))
7045 continue;
7046
7047 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7048 if (ret) {
7049 ath10k_warn(ar, "failed to down vdev %d: %d\n",
7050 arvif->vdev_id, ret);
7051 continue;
7052 }
7053 }
7054
7055 /* All relevant vdevs are downed and associated channel resources
7056 * should be available for the channel switch now.
7057 */
7058
7059 spin_lock_bh(&ar->data_lock);
7060 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
7061 spin_unlock_bh(&ar->data_lock);
7062
7063 for (i = 0; i < n_vifs; i++) {
7064 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7065
7066 if (WARN_ON(!arvif->is_started))
7067 continue;
7068
7069 if (WARN_ON(!arvif->is_up))
7070 continue;
7071
7072 ret = ath10k_mac_setup_bcn_tmpl(arvif);
7073 if (ret)
7074 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
7075 ret);
7076
7077 ret = ath10k_mac_setup_prb_tmpl(arvif);
7078 if (ret)
7079 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
7080 ret);
7081
7082 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7083 if (ret) {
7084 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7085 arvif->vdev_id, ret);
7086 continue;
7087 }
7088
7089 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7090 arvif->bssid);
7091 if (ret) {
7092 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7093 arvif->vdev_id, ret);
7094 continue;
7095 }
7096 }
7097
7098 ath10k_monitor_recalc(ar);
7099}
7100
Michal Kazior500ff9f2015-03-31 10:26:21 +00007101static int
7102ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7103 struct ieee80211_chanctx_conf *ctx)
7104{
7105 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007106
7107 ath10k_dbg(ar, ATH10K_DBG_MAC,
7108 "mac chanctx add freq %hu width %d ptr %p\n",
7109 ctx->def.chan->center_freq, ctx->def.width, ctx);
7110
7111 mutex_lock(&ar->conf_mutex);
7112
7113 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007114 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007115 spin_unlock_bh(&ar->data_lock);
7116
7117 ath10k_recalc_radar_detection(ar);
7118 ath10k_monitor_recalc(ar);
7119
7120 mutex_unlock(&ar->conf_mutex);
7121
7122 return 0;
7123}
7124
7125static void
7126ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7127 struct ieee80211_chanctx_conf *ctx)
7128{
7129 struct ath10k *ar = hw->priv;
7130
7131 ath10k_dbg(ar, ATH10K_DBG_MAC,
7132 "mac chanctx remove freq %hu width %d ptr %p\n",
7133 ctx->def.chan->center_freq, ctx->def.width, ctx);
7134
7135 mutex_lock(&ar->conf_mutex);
7136
7137 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007138 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007139 spin_unlock_bh(&ar->data_lock);
7140
7141 ath10k_recalc_radar_detection(ar);
7142 ath10k_monitor_recalc(ar);
7143
7144 mutex_unlock(&ar->conf_mutex);
7145}
7146
Michal Kazior9713e3d2015-09-03 10:44:52 +02007147struct ath10k_mac_change_chanctx_arg {
7148 struct ieee80211_chanctx_conf *ctx;
7149 struct ieee80211_vif_chanctx_switch *vifs;
7150 int n_vifs;
7151 int next_vif;
7152};
7153
7154static void
7155ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
7156 struct ieee80211_vif *vif)
7157{
7158 struct ath10k_mac_change_chanctx_arg *arg = data;
7159
7160 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
7161 return;
7162
7163 arg->n_vifs++;
7164}
7165
7166static void
7167ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
7168 struct ieee80211_vif *vif)
7169{
7170 struct ath10k_mac_change_chanctx_arg *arg = data;
7171 struct ieee80211_chanctx_conf *ctx;
7172
7173 ctx = rcu_access_pointer(vif->chanctx_conf);
7174 if (ctx != arg->ctx)
7175 return;
7176
7177 if (WARN_ON(arg->next_vif == arg->n_vifs))
7178 return;
7179
7180 arg->vifs[arg->next_vif].vif = vif;
7181 arg->vifs[arg->next_vif].old_ctx = ctx;
7182 arg->vifs[arg->next_vif].new_ctx = ctx;
7183 arg->next_vif++;
7184}
7185
Michal Kazior500ff9f2015-03-31 10:26:21 +00007186static void
7187ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7188 struct ieee80211_chanctx_conf *ctx,
7189 u32 changed)
7190{
7191 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007192 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007193
7194 mutex_lock(&ar->conf_mutex);
7195
7196 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007197 "mac chanctx change freq %hu width %d ptr %p changed %x\n",
7198 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007199
7200 /* This shouldn't really happen because channel switching should use
7201 * switch_vif_chanctx().
7202 */
7203 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7204 goto unlock;
7205
Michal Kazior9713e3d2015-09-03 10:44:52 +02007206 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7207 ieee80211_iterate_active_interfaces_atomic(
7208 hw,
7209 IEEE80211_IFACE_ITER_NORMAL,
7210 ath10k_mac_change_chanctx_cnt_iter,
7211 &arg);
7212 if (arg.n_vifs == 0)
7213 goto radar;
7214
7215 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7216 GFP_KERNEL);
7217 if (!arg.vifs)
7218 goto radar;
7219
7220 ieee80211_iterate_active_interfaces_atomic(
7221 hw,
7222 IEEE80211_IFACE_ITER_NORMAL,
7223 ath10k_mac_change_chanctx_fill_iter,
7224 &arg);
7225 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7226 kfree(arg.vifs);
7227 }
7228
7229radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007230 ath10k_recalc_radar_detection(ar);
7231
7232 /* FIXME: How to configure Rx chains properly? */
7233
7234 /* No other actions are actually necessary. Firmware maintains channel
7235 * definitions per vdev internally and there's no host-side channel
7236 * context abstraction to configure, e.g. channel width.
7237 */
7238
7239unlock:
7240 mutex_unlock(&ar->conf_mutex);
7241}
7242
7243static int
7244ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7245 struct ieee80211_vif *vif,
7246 struct ieee80211_chanctx_conf *ctx)
7247{
7248 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007249 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7250 int ret;
7251
7252 mutex_lock(&ar->conf_mutex);
7253
7254 ath10k_dbg(ar, ATH10K_DBG_MAC,
7255 "mac chanctx assign ptr %p vdev_id %i\n",
7256 ctx, arvif->vdev_id);
7257
7258 if (WARN_ON(arvif->is_started)) {
7259 mutex_unlock(&ar->conf_mutex);
7260 return -EBUSY;
7261 }
7262
Michal Kazior089ab7a2015-06-03 12:16:55 +02007263 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007264 if (ret) {
7265 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7266 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007267 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007268 goto err;
7269 }
7270
7271 arvif->is_started = true;
7272
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007273 ret = ath10k_mac_vif_setup_ps(arvif);
7274 if (ret) {
7275 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7276 arvif->vdev_id, ret);
7277 goto err_stop;
7278 }
7279
Michal Kazior500ff9f2015-03-31 10:26:21 +00007280 if (vif->type == NL80211_IFTYPE_MONITOR) {
7281 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7282 if (ret) {
7283 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7284 arvif->vdev_id, ret);
7285 goto err_stop;
7286 }
7287
7288 arvif->is_up = true;
7289 }
7290
7291 mutex_unlock(&ar->conf_mutex);
7292 return 0;
7293
7294err_stop:
7295 ath10k_vdev_stop(arvif);
7296 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007297 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007298
7299err:
7300 mutex_unlock(&ar->conf_mutex);
7301 return ret;
7302}
7303
7304static void
7305ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7306 struct ieee80211_vif *vif,
7307 struct ieee80211_chanctx_conf *ctx)
7308{
7309 struct ath10k *ar = hw->priv;
7310 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7311 int ret;
7312
7313 mutex_lock(&ar->conf_mutex);
7314
7315 ath10k_dbg(ar, ATH10K_DBG_MAC,
7316 "mac chanctx unassign ptr %p vdev_id %i\n",
7317 ctx, arvif->vdev_id);
7318
7319 WARN_ON(!arvif->is_started);
7320
7321 if (vif->type == NL80211_IFTYPE_MONITOR) {
7322 WARN_ON(!arvif->is_up);
7323
7324 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7325 if (ret)
7326 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7327 arvif->vdev_id, ret);
7328
7329 arvif->is_up = false;
7330 }
7331
7332 ret = ath10k_vdev_stop(arvif);
7333 if (ret)
7334 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7335 arvif->vdev_id, ret);
7336
7337 arvif->is_started = false;
7338
7339 mutex_unlock(&ar->conf_mutex);
7340}
7341
7342static int
7343ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7344 struct ieee80211_vif_chanctx_switch *vifs,
7345 int n_vifs,
7346 enum ieee80211_chanctx_switch_mode mode)
7347{
7348 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007349
7350 mutex_lock(&ar->conf_mutex);
7351
7352 ath10k_dbg(ar, ATH10K_DBG_MAC,
7353 "mac chanctx switch n_vifs %d mode %d\n",
7354 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007355 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007356
7357 mutex_unlock(&ar->conf_mutex);
7358 return 0;
7359}
7360
Kalle Valo5e3dd152013-06-12 20:52:10 +03007361static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01007362 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02007363 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007364 .start = ath10k_start,
7365 .stop = ath10k_stop,
7366 .config = ath10k_config,
7367 .add_interface = ath10k_add_interface,
7368 .remove_interface = ath10k_remove_interface,
7369 .configure_filter = ath10k_configure_filter,
7370 .bss_info_changed = ath10k_bss_info_changed,
7371 .hw_scan = ath10k_hw_scan,
7372 .cancel_hw_scan = ath10k_cancel_hw_scan,
7373 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02007374 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007375 .sta_state = ath10k_sta_state,
7376 .conf_tx = ath10k_conf_tx,
7377 .remain_on_channel = ath10k_remain_on_channel,
7378 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
7379 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02007380 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007381 .flush = ath10k_flush,
7382 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03007383 .set_antenna = ath10k_set_antenna,
7384 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007385 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02007386 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00007387 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01007388 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02007389 .get_tsf = ath10k_get_tsf,
Peter Oh9f0b7e72016-04-04 16:19:14 -07007390 .set_tsf = ath10k_set_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007391 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03007392 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7393 .get_et_stats = ath10k_debug_get_et_stats,
7394 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00007395 .add_chanctx = ath10k_mac_op_add_chanctx,
7396 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7397 .change_chanctx = ath10k_mac_op_change_chanctx,
7398 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7399 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7400 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Kalle Valo43d2a302014-09-10 18:23:30 +03007401
7402 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7403
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007404#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007405 .suspend = ath10k_wow_op_suspend,
7406 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007407#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007408#ifdef CONFIG_MAC80211_DEBUGFS
7409 .sta_add_debugfs = ath10k_sta_add_debugfs,
Mohammed Shafi Shajakhan120a1f02016-06-30 15:23:50 +03007410 .sta_statistics = ath10k_sta_statistics,
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007411#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03007412};
7413
Kalle Valo5e3dd152013-06-12 20:52:10 +03007414#define CHAN2G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007415 .band = NL80211_BAND_2GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007416 .hw_value = (_channel), \
7417 .center_freq = (_freq), \
7418 .flags = (_flags), \
7419 .max_antenna_gain = 0, \
7420 .max_power = 30, \
7421}
7422
7423#define CHAN5G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007424 .band = NL80211_BAND_5GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007425 .hw_value = (_channel), \
7426 .center_freq = (_freq), \
7427 .flags = (_flags), \
7428 .max_antenna_gain = 0, \
7429 .max_power = 30, \
7430}
7431
7432static const struct ieee80211_channel ath10k_2ghz_channels[] = {
7433 CHAN2G(1, 2412, 0),
7434 CHAN2G(2, 2417, 0),
7435 CHAN2G(3, 2422, 0),
7436 CHAN2G(4, 2427, 0),
7437 CHAN2G(5, 2432, 0),
7438 CHAN2G(6, 2437, 0),
7439 CHAN2G(7, 2442, 0),
7440 CHAN2G(8, 2447, 0),
7441 CHAN2G(9, 2452, 0),
7442 CHAN2G(10, 2457, 0),
7443 CHAN2G(11, 2462, 0),
7444 CHAN2G(12, 2467, 0),
7445 CHAN2G(13, 2472, 0),
7446 CHAN2G(14, 2484, 0),
7447};
7448
7449static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02007450 CHAN5G(36, 5180, 0),
7451 CHAN5G(40, 5200, 0),
7452 CHAN5G(44, 5220, 0),
7453 CHAN5G(48, 5240, 0),
7454 CHAN5G(52, 5260, 0),
7455 CHAN5G(56, 5280, 0),
7456 CHAN5G(60, 5300, 0),
7457 CHAN5G(64, 5320, 0),
7458 CHAN5G(100, 5500, 0),
7459 CHAN5G(104, 5520, 0),
7460 CHAN5G(108, 5540, 0),
7461 CHAN5G(112, 5560, 0),
7462 CHAN5G(116, 5580, 0),
7463 CHAN5G(120, 5600, 0),
7464 CHAN5G(124, 5620, 0),
7465 CHAN5G(128, 5640, 0),
7466 CHAN5G(132, 5660, 0),
7467 CHAN5G(136, 5680, 0),
7468 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07007469 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02007470 CHAN5G(149, 5745, 0),
7471 CHAN5G(153, 5765, 0),
7472 CHAN5G(157, 5785, 0),
7473 CHAN5G(161, 5805, 0),
7474 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03007475};
7476
Michal Kaziore7b54192014-08-07 11:03:27 +02007477struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007478{
7479 struct ieee80211_hw *hw;
7480 struct ath10k *ar;
7481
Michal Kaziore7b54192014-08-07 11:03:27 +02007482 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007483 if (!hw)
7484 return NULL;
7485
7486 ar = hw->priv;
7487 ar->hw = hw;
7488
7489 return ar;
7490}
7491
7492void ath10k_mac_destroy(struct ath10k *ar)
7493{
7494 ieee80211_free_hw(ar->hw);
7495}
7496
7497static const struct ieee80211_iface_limit ath10k_if_limits[] = {
7498 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307499 .max = 8,
7500 .types = BIT(NL80211_IFTYPE_STATION)
7501 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02007502 },
7503 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307504 .max = 3,
7505 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02007506 },
7507 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307508 .max = 1,
7509 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01007510 },
7511 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307512 .max = 7,
7513 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007514#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307515 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007516#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02007517 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007518};
7519
Bartosz Markowskif2595092013-12-10 16:20:39 +01007520static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007521 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307522 .max = 8,
7523 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007524#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307525 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007526#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007527 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307528 {
7529 .max = 1,
7530 .types = BIT(NL80211_IFTYPE_STATION)
7531 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007532};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007533
7534static const struct ieee80211_iface_combination ath10k_if_comb[] = {
7535 {
7536 .limits = ath10k_if_limits,
7537 .n_limits = ARRAY_SIZE(ath10k_if_limits),
7538 .max_interfaces = 8,
7539 .num_different_channels = 1,
7540 .beacon_int_infra_match = true,
7541 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01007542};
7543
7544static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007545 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01007546 .limits = ath10k_10x_if_limits,
7547 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007548 .max_interfaces = 8,
7549 .num_different_channels = 1,
7550 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01007551#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007552 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7553 BIT(NL80211_CHAN_WIDTH_20) |
7554 BIT(NL80211_CHAN_WIDTH_40) |
7555 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007556#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01007557 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007558};
7559
Michal Kaziorcf327842015-03-31 10:26:25 +00007560static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
7561 {
7562 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02007563 .types = BIT(NL80211_IFTYPE_STATION),
7564 },
7565 {
7566 .max = 2,
7567 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007568#ifdef CONFIG_MAC80211_MESH
7569 BIT(NL80211_IFTYPE_MESH_POINT) |
7570#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00007571 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7572 BIT(NL80211_IFTYPE_P2P_GO),
7573 },
7574 {
7575 .max = 1,
7576 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7577 },
7578};
7579
Michal Kaziored25b112015-07-09 13:08:39 +02007580static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
7581 {
7582 .max = 2,
7583 .types = BIT(NL80211_IFTYPE_STATION),
7584 },
7585 {
7586 .max = 2,
7587 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
7588 },
7589 {
7590 .max = 1,
7591 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007592#ifdef CONFIG_MAC80211_MESH
7593 BIT(NL80211_IFTYPE_MESH_POINT) |
7594#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007595 BIT(NL80211_IFTYPE_P2P_GO),
7596 },
7597 {
7598 .max = 1,
7599 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7600 },
7601};
7602
Michal Kaziorcf327842015-03-31 10:26:25 +00007603static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7604 {
7605 .max = 1,
7606 .types = BIT(NL80211_IFTYPE_STATION),
7607 },
7608 {
7609 .max = 1,
7610 .types = BIT(NL80211_IFTYPE_ADHOC),
7611 },
7612};
7613
7614/* FIXME: This is not thouroughly tested. These combinations may over- or
7615 * underestimate hw/fw capabilities.
7616 */
7617static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7618 {
7619 .limits = ath10k_tlv_if_limit,
7620 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007621 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007622 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7623 },
7624 {
7625 .limits = ath10k_tlv_if_limit_ibss,
7626 .num_different_channels = 1,
7627 .max_interfaces = 2,
7628 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7629 },
7630};
7631
7632static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7633 {
7634 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007635 .num_different_channels = 1,
7636 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007637 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7638 },
7639 {
Michal Kaziored25b112015-07-09 13:08:39 +02007640 .limits = ath10k_tlv_qcs_if_limit,
7641 .num_different_channels = 2,
7642 .max_interfaces = 4,
7643 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7644 },
7645 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007646 .limits = ath10k_tlv_if_limit_ibss,
7647 .num_different_channels = 1,
7648 .max_interfaces = 2,
7649 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7650 },
7651};
7652
Raja Manicf36fef2015-06-22 20:22:25 +05307653static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
7654 {
7655 .max = 1,
7656 .types = BIT(NL80211_IFTYPE_STATION),
7657 },
7658 {
7659 .max = 16,
7660 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007661#ifdef CONFIG_MAC80211_MESH
7662 | BIT(NL80211_IFTYPE_MESH_POINT)
7663#endif
Raja Manicf36fef2015-06-22 20:22:25 +05307664 },
7665};
7666
7667static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
7668 {
7669 .limits = ath10k_10_4_if_limits,
7670 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
7671 .max_interfaces = 16,
7672 .num_different_channels = 1,
7673 .beacon_int_infra_match = true,
7674#ifdef CONFIG_ATH10K_DFS_CERTIFIED
7675 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7676 BIT(NL80211_CHAN_WIDTH_20) |
7677 BIT(NL80211_CHAN_WIDTH_40) |
7678 BIT(NL80211_CHAN_WIDTH_80),
7679#endif
7680 },
7681};
7682
Kalle Valo5e3dd152013-06-12 20:52:10 +03007683static void ath10k_get_arvif_iter(void *data, u8 *mac,
7684 struct ieee80211_vif *vif)
7685{
7686 struct ath10k_vif_iter *arvif_iter = data;
7687 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7688
7689 if (arvif->vdev_id == arvif_iter->vdev_id)
7690 arvif_iter->arvif = arvif;
7691}
7692
7693struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
7694{
7695 struct ath10k_vif_iter arvif_iter;
7696 u32 flags;
7697
7698 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
7699 arvif_iter.vdev_id = vdev_id;
7700
7701 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
7702 ieee80211_iterate_active_interfaces_atomic(ar->hw,
7703 flags,
7704 ath10k_get_arvif_iter,
7705 &arvif_iter);
7706 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007707 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007708 return NULL;
7709 }
7710
7711 return arvif_iter.arvif;
7712}
7713
7714int ath10k_mac_register(struct ath10k *ar)
7715{
Johannes Berg3cb10942015-01-22 21:38:45 +01007716 static const u32 cipher_suites[] = {
7717 WLAN_CIPHER_SUITE_WEP40,
7718 WLAN_CIPHER_SUITE_WEP104,
7719 WLAN_CIPHER_SUITE_TKIP,
7720 WLAN_CIPHER_SUITE_CCMP,
7721 WLAN_CIPHER_SUITE_AES_CMAC,
7722 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03007723 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007724 void *channels;
7725 int ret;
7726
7727 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
7728
7729 SET_IEEE80211_DEV(ar->hw, ar->dev);
7730
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00007731 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
7732 ARRAY_SIZE(ath10k_5ghz_channels)) !=
7733 ATH10K_NUM_CHANS);
7734
Kalle Valo5e3dd152013-06-12 20:52:10 +03007735 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
7736 channels = kmemdup(ath10k_2ghz_channels,
7737 sizeof(ath10k_2ghz_channels),
7738 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02007739 if (!channels) {
7740 ret = -ENOMEM;
7741 goto err_free;
7742 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007743
Johannes Berg57fbcce2016-04-12 15:56:15 +02007744 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007745 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
7746 band->channels = channels;
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +03007747
7748 if (ar->hw_params.cck_rate_map_rev2) {
7749 band->n_bitrates = ath10k_g_rates_rev2_size;
7750 band->bitrates = ath10k_g_rates_rev2;
7751 } else {
7752 band->n_bitrates = ath10k_g_rates_size;
7753 band->bitrates = ath10k_g_rates;
7754 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007755
Johannes Berg57fbcce2016-04-12 15:56:15 +02007756 ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007757 }
7758
7759 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
7760 channels = kmemdup(ath10k_5ghz_channels,
7761 sizeof(ath10k_5ghz_channels),
7762 GFP_KERNEL);
7763 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02007764 ret = -ENOMEM;
7765 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007766 }
7767
Johannes Berg57fbcce2016-04-12 15:56:15 +02007768 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007769 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
7770 band->channels = channels;
7771 band->n_bitrates = ath10k_a_rates_size;
7772 band->bitrates = ath10k_a_rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02007773 ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007774 }
7775
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05307776 ath10k_mac_setup_ht_vht_cap(ar);
7777
Kalle Valo5e3dd152013-06-12 20:52:10 +03007778 ar->hw->wiphy->interface_modes =
7779 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007780 BIT(NL80211_IFTYPE_AP) |
7781 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01007782
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05307783 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
7784 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03007785
Kalle Valoc4cdf752016-04-20 19:45:18 +03007786 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))
Bartosz Markowskid3541812013-12-10 16:20:40 +01007787 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01007788 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01007789 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7790 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007791
Johannes Berg30686bf2015-06-02 21:39:54 +02007792 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
7793 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
7794 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
7795 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
7796 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
7797 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
7798 ieee80211_hw_set(ar->hw, AP_LINK_PS);
7799 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02007800 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
7801 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
7802 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
7803 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
7804 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
7805 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007806
David Liuccec9032015-07-24 20:25:32 +03007807 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7808 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
7809
Eliad Peller0d8614b2014-09-10 14:07:36 +03007810 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00007811 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03007812
Kalle Valo5e3dd152013-06-12 20:52:10 +03007813 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03007814 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007815
7816 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02007817 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
7818 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007819 }
7820
7821 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
7822 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
7823
7824 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01007825 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02007826 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007827
Kalle Valo5e3dd152013-06-12 20:52:10 +03007828 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
7829
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02007830 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
7831 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
7832
7833 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
7834 * that userspace (e.g. wpa_supplicant/hostapd) can generate
7835 * correct Probe Responses. This is more of a hack advert..
7836 */
7837 ar->hw->wiphy->probe_resp_offload |=
7838 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
7839 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
7840 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
7841 }
7842
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03007843 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
7844 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7845
Kalle Valo5e3dd152013-06-12 20:52:10 +03007846 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01007847 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007848 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
7849
7850 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05307851 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
7852 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02007853
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01007854 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
7855
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007856 ret = ath10k_wow_init(ar);
7857 if (ret) {
7858 ath10k_warn(ar, "failed to init wow: %d\n", ret);
7859 goto err_free;
7860 }
7861
Janusz Dziedzicc7025342015-06-15 14:46:41 +03007862 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
7863
Kalle Valo5e3dd152013-06-12 20:52:10 +03007864 /*
7865 * on LL hardware queues are managed entirely by the FW
7866 * so we only advertise to mac we can do the queues thing
7867 */
Michal Kazior96d828d2015-03-31 10:26:23 +00007868 ar->hw->queues = IEEE80211_MAX_QUEUES;
7869
7870 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
7871 * something that vdev_ids can't reach so that we don't stop the queue
7872 * accidentally.
7873 */
7874 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007875
Kalle Valobf3c13a2016-04-20 19:45:33 +03007876 switch (ar->running_fw->fw_file.wmi_op_version) {
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007877 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01007878 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
7879 ar->hw->wiphy->n_iface_combinations =
7880 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03007881 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007882 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00007883 case ATH10K_FW_WMI_OP_VERSION_TLV:
7884 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
7885 ar->hw->wiphy->iface_combinations =
7886 ath10k_tlv_qcs_if_comb;
7887 ar->hw->wiphy->n_iface_combinations =
7888 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
7889 } else {
7890 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
7891 ar->hw->wiphy->n_iface_combinations =
7892 ARRAY_SIZE(ath10k_tlv_if_comb);
7893 }
7894 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
7895 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007896 case ATH10K_FW_WMI_OP_VERSION_10_1:
7897 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02007898 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007899 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
7900 ar->hw->wiphy->n_iface_combinations =
7901 ARRAY_SIZE(ath10k_10x_if_comb);
7902 break;
Raja Mani9bd21322015-06-22 20:10:09 +05307903 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05307904 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
7905 ar->hw->wiphy->n_iface_combinations =
7906 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05307907 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02007908 case ATH10K_FW_WMI_OP_VERSION_UNSET:
7909 case ATH10K_FW_WMI_OP_VERSION_MAX:
7910 WARN_ON(1);
7911 ret = -EINVAL;
7912 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01007913 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007914
David Liuccec9032015-07-24 20:25:32 +03007915 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7916 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02007917
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007918 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
7919 /* Init ath dfs pattern detector */
7920 ar->ath_common.debug_mask = ATH_DBG_DFS;
7921 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
7922 NL80211_DFS_UNSET);
7923
7924 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02007925 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007926 }
7927
Kalle Valo5e3dd152013-06-12 20:52:10 +03007928 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
7929 ath10k_reg_notifier);
7930 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007931 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007932 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007933 }
7934
Johannes Berg3cb10942015-01-22 21:38:45 +01007935 ar->hw->wiphy->cipher_suites = cipher_suites;
7936 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
7937
Kalle Valo5e3dd152013-06-12 20:52:10 +03007938 ret = ieee80211_register_hw(ar->hw);
7939 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007940 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07007941 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007942 }
7943
7944 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
7945 ret = regulatory_hint(ar->hw->wiphy,
7946 ar->ath_common.regulatory.alpha2);
7947 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02007948 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007949 }
7950
7951 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02007952
7953err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03007954 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07007955
7956err_dfs_detector_exit:
7957 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7958 ar->dfs_detector->exit(ar->dfs_detector);
7959
Michal Kaziord6015b22013-07-22 14:13:30 +02007960err_free:
Johannes Berg57fbcce2016-04-12 15:56:15 +02007961 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
7962 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Michal Kaziord6015b22013-07-22 14:13:30 +02007963
Jeff Johnson0e339442015-10-08 09:15:53 -07007964 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007965 return ret;
7966}
7967
7968void ath10k_mac_unregister(struct ath10k *ar)
7969{
7970 ieee80211_unregister_hw(ar->hw);
7971
Janusz Dziedzic9702c682013-11-20 09:59:41 +02007972 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
7973 ar->dfs_detector->exit(ar->dfs_detector);
7974
Johannes Berg57fbcce2016-04-12 15:56:15 +02007975 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
7976 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007977
7978 SET_IEEE80211_DEV(ar->hw, NULL);
7979}